DateTime-Lite
view release on metacpan or search on metacpan
lib/DateTime/Lite/TimeZone.pm view on Meta::CPAN
$sth->finish;
return( $this->error( "Error executing the query to check if SQLite has math functions: ", $sth->errstr, "\nSQL query was ", $sth->{Statement} ) );
}
my $row = eval{ $sth->fetchrow_arrayref };
if( $@ )
{
$sth->finish;
return( $this->error( "Error retrieving the value to check if SQLite has math functions: $@", "\nSQL query was ", $sth->{Statement} ) );
}
# We check for definedness, which means an error in DBI
elsif( !defined( $row ) && $sth->errstr )
{
$sth->finish;
return( $this->error( "Error retrieving the value to check if SQLite has math functions: ", $sth->errstr, "\nSQL query was ", $sth->{Statement} ) );
}
$sth->finish;
# Don't assume anything.
if( $row && ref( $row ) eq 'ARRAY' && $row->[0] )
{
$has_math = 1;
}
}
if( $has_math )
{
# <https://sqlite.org/lang_mathfunc.html>
$SQLITE_HAS_MATH_FUNCTIONS = 1;
}
else
{
# Native math functions are absent or unconfirmed; register Perl UDFs.
require POSIX;
$dbh->sqlite_create_function( 'sqrt', 1, sub{ CORE::sqrt( $_[0] ) } );
$dbh->sqlite_create_function( 'sin', 1, sub{ CORE::sin( $_[0] ) } );
$dbh->sqlite_create_function( 'cos', 1, sub{ CORE::cos( $_[0] ) } );
$dbh->sqlite_create_function( 'asin', 1, sub{ POSIX::asin( $_[0] ) } );
$SQLITE_HAS_MATH_FUNCTIONS = 0;
}
return(1);
}
# _decode_sql_array() decode the JSON array and returns an array reference.
sub _decode_sql_array
{
my $self = shift( @_ );
die( "\$cldr->_decode_sql_array( \$data )" ) if( @_ != 1 );
my $data = shift( @_ );
# No data was provided
if( !defined( $data ) )
{
return;
}
# Should not be a reference, but a plain string
elsif( ref( $data ) )
{
die( "\$cldr->_decode_sql_array( \$data )" );
}
my $j = $JSON_CLASS->new->relaxed;
local $@;
my $decoded = eval
{
$j->decode( $data );
};
if( $@ )
{
warn( "Warning only: error attempting to decode $JSON_CLASS array: $@" );
$decoded = [];
}
return( $decoded );
}
# _decode_sql_arrays() takes an hash reference, or an array of hash reference,
# and decode the array fields of those tuples
sub _decode_sql_arrays
{
my $self = shift( @_ );
die( "\$cldr->_decode_sql_arrays( \$array_ref_of_array_fields, \$data )" ) if( @_ != 2 );
my( $where, $ref ) = @_;
if( ref( $where ) ne 'ARRAY' )
{
die( "\$cldr->_decode_sql_arrays( \$array_ref_of_array_fields, \$data )" );
}
# No data was provided
elsif( !defined( $ref ) )
{
return;
}
elsif( ref( $ref // '' ) ne 'HASH' && Scalar::Util::reftype( $ref // '' ) ne 'ARRAY' )
{
die( "\$cldr->_decode_sql_arrays( \$array_ref_of_array_fields, \$data )" );
}
my $j = $JSON_CLASS->new->relaxed;
local $@;
if( ref( $ref ) eq 'HASH' )
{
foreach my $field ( @$where )
{
if( exists( $ref->{ $field } ) &&
defined( $ref->{ $field } ) &&
length( $ref->{ $field } ) )
{
my $decoded = eval
{
$j->decode( $ref->{ $field } );
};
if( $@ )
{
warn( "Warning only: error attempting to decode $JSON_CLASS array in field \"${field}\" for value '", $ref->{ $field }, "': $@" );
$ref->{ $field } = [];
}
else
{
$ref->{ $field } = $decoded;
}
}
}
}
elsif( Scalar::Util::reftype( $ref ) eq 'ARRAY' )
{
for( my $i = 0; $i < scalar( @$ref ); $i++ )
{
if( ref( $ref->[$i] ) ne 'HASH' )
{
warn( "SQL data at offset ${i} is not an HASH reference." );
next;
}
$self->_decode_sql_arrays( $where, $ref->[$i] );
}
}
return( $ref );
}
# Retrieve a cached prepared statement by ID.
# Keyed by db file path so statements survive interpreter-level reuse.
sub _get_cached_statement
{
my $self = shift( @_ );
my $id = shift( @_ );
die( "No statement ID provided." ) unless( defined( $id ) && length( $id ) );
my $file = $DB_FILE;
my $tid = ( $Config{useithreads} && $INC{'threads.pm'} && threads->can('tid') ) ? threads->tid() : $$;
$STHS->{ $tid } //= {};
$STHS->{ $tid }->{ $file } //= {};
my $sth = $STHS->{ $tid }->{ $file }->{ $id };
if( defined( $sth ) &&
Scalar::Util::blessed( $sth ) &&
$sth->isa( 'DBI::st' ) )
{
return( $sth );
}
return;
}
# DateTime::Lite::TimeZone->_get_zone_info( $name );
# $tz->_get_zone_info( $name );
sub _get_zone_info
{
my $self = shift( @_ );
my $name = shift( @_ );
local $@;
# Verify the zone exists and cache its metadata
my $sth;
unless( $sth = $self->_get_cached_statement( 'get_zone_info' ) )
{
my $dbh = $self->_dbh || return( $self->pass_error );
# We handle each step of building the query, so we can report on any error with better accuracy.
my $query = q{SELECT * FROM zones WHERE name = ?};
$sth = eval
{
$dbh->prepare( $query );
} || return( $self->error( "Error preparing the query to get the timezone information: ", ( $@ || $dbh->errstr ), "\nSQL query was $query" ) );
$self->_set_cached_statement( get_zone_info => $sth );
}
( run in 1.338 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )