DB-Object
view release on metacpan or search on metacpan
lib/DB/Object/SQLite.pm view on Meta::CPAN
sub attribute($;$@)
{
my $self = shift( @_ );
# $h->{AttributeName} = ...; # set/write
# ... = $h->{AttributeName}; # get/read
# 1 means that the attribute may be modified
# 0 mneas that the attribute may only be read
my $name = shift( @_ ) if( @_ == 1 );
my %arg = ( @_ );
my %attr =
(
ActiveKids => 0,
AutoCommit => 1,
AutoInactiveDestroy => 1,
CachedKids => 0,
ChildHandles => 0,
ChopBlanks => 1,
CursorName => 0,
Driver => 0,
ErrCount => 1,
Executed => 0,
FetchHashKeyName => 1,
HandleError => 1,
HandleSetErr => 1,
InactiveDestroy => 1,
Kids => 0,
NAME => 0,
NULLABLE => 0,
NUM_OF_FIELDS => 0,
NUM_OF_PARAMS => 0,
# Current database name
Name => 0,
PRECISION => 0,
PrintError => 1,
PrintWarn => 1,
Profile => 1,
RaiseError => 1,
RowCacheSize => 0,
RowsInCache => 0,
SCALE => 0,
ShowErrorStatement => 1,
Statement => 0,
TYPE => 0,
Taint => 1,
TaintIn => 1,
TaintOut => 1,
TraceLevel => 1,
Type => 1,
Username => 0,
Warn => 1,
# Not used
# LongReadLen => 1,
# LongTruncOk => 1,
# CompatMode => 1,
# If you set this to true, "do" method will process multiple statements at one go.
# This may be handy, but with performance penalty. See above for details.
sqlite_allow_multiple_statements => 1,
# If you set this to true, DBD::SQLite tries to see if the bind values are number or
# not, and does not quote if they are numbers.
sqlite_see_if_its_a_number => 1,
sqlite_unicode => 1,
# Returns an unprepared part of the statement you pass to "prepare". Typically this
# contains nothing but white spaces after a semicolon.
sqlite_unprepared_statements => 0,
# If you set this to true, DBD::SQLite tries to issue a "begin immediate transaction"
# (instead of "begin transaction") when necessary.
sqlite_use_immediate_transaction => 1,
sqlite_version => 0,
);
# Only those attribute exist
# Using an a non existing attribute produce an exception, so we better avoid
if( $name )
{
return( $self->{dbh}->{ $name } ) if( exists( $attr{ $name } ) );
}
else
{
my $value;
while( ( $name, $value ) = each( %arg ) )
{
# We intend to modifiy the value of an attribute
# we are allowed to modify this value if it is true
if( exists( $attr{ $name } ) &&
defined( $value ) &&
$attr{ $name } )
{
$self->{dbh}->{ $name } = $value;
}
}
}
}
# sub available_drivers(@)
sub begin_work($;$@)
{
my $self = shift( @_ );
$self->{transaction} = 1;
return( $self->{dbh}->begin_work( @_ ) );
}
# This method is common to DB::Object and DB::Object::Statement
# sub bind
# sub cache
sub can_update_delete_limit { return( shift->has_compile_option( 'ENABLE_UPDATE_DELETE_LIMIT' ) ); }
# sub check_driver(@;$@)
sub commit($;$@)
{
my $self = shift( @_ );
$self->{transaction} = 0;
return( $self->{dbh}->commit( @_ ) );
}
sub compile_options
{
my $self = shift( @_ );
return( [ @$COMPILE_OPTIONS ] ) if( scalar( @$COMPILE_OPTIONS ) );
lib/DB/Object/SQLite.pm view on Meta::CPAN
$sth->execute() || return( $self->error( sprintf( "Error while executing query $query: %s", $sth->errstr ) ) );
my $all = $sth->fetchall_arrayref( {} );
return( $all );
}
sub trace { return( shift->error( "Trace is unsupported on SQLite." ) ); }
sub unlock { return( shift->error( "unlock() does not work with SQLite." ) ); }
sub variables
{
return( shift->error( "variables is currently unsupported in Postgres" ) );
}
# https://www.sqlite.org/versionnumbers.html
sub version
{
my $self = shift( @_ );
# If we already have the information, let's use our cache instead of making a query
return( $self->{_db_version} ) if( length( $self->{_db_version} ) );
my $sql = 'SELECT sqlite_version()';
my $sth = $self->do( $sql ) || return( $self->error( "Unable to issue the sql statement '$sql' to get the server version: ", $self->errstr ) );
my $ver = $sth->fetchrow;
$sth->finish;
# We cache it
$self->{_db_version} = version->parse( $ver );
return( $ver );
}
sub _check_connect_param
{
my $self = shift( @_ );
my $param = $self->SUPER::_check_connect_param( @_ );
if( !$param->{database_file} && $param->{database} )
{
my( $filename, $path, $ext );
my $uri = CORE::exists( $param->{uri} ) ? $param->{uri} : '';
my $db = $param->{database} ? $param->{database} : ( $uri->path_segments )[-1];
$path = $uri ? $uri->path : $db;
# $db = Cwd::abs_path( $uri ? $uri->path : $db );
# $db = File::Spec->rel2abs( $path );
$db = $self->new_file( $path );
# If we cannot find the file and it does not end with .sqlite, let's add the extension
# So the user can provide the database parameter just like database => 'test' or database => './test'
$db = "$db.sqlite" if( !-e( $db ) && $db !~ /\.sqlite$/i );
# ( $filename, $path, $ext ) = File::Basename::fileparse( $db, qr/\.[^\.]+$/ );
( $filename, $path, $ext ) = $db->baseinfo( qr/\.[^\.]+$/ );
$param->{database} = $filename;
$param->{database_file} = $self->{database_file} = $db;
}
$param->{host} = 'localhost' if( !length( $param->{host} ) );
$param->{port} = 0 if( !CORE::exists( $param->{port} ) );
return( $param );
}
sub _check_default_option
{
my $self = shift( @_ );
my $opts = $self->_get_args_as_hash( @_ );
return( $self->error( "Provided option is not a hash reference." ) ) if( !$self->_is_hash( $opts => 'strict' ) );
$opts->{sqlite_unicode} = 1 if( !CORE::exists( $opts->{sqlite_unicode} ) );
return( $opts );
}
sub _connection_options
{
my $self = shift( @_ );
my $param = shift( @_ );
my @sqlite_params = grep( /^sqlite_/, keys( %$param ) );
my $opt = $self->SUPER::_connection_options( $param );
@$opt{ @sqlite_params } = @$param{ @sqlite_params };
return( $opt );
}
sub _connection_params2hash_driver
{
my $self = shift( @_ );
my $opts = $self->_get_args_as_hash( @_ );
$opts->{sqlite_unicode} = 1 if( !length( $opts->{sqlite_unicode} ) );
return( $opts );
}
sub _connection_parameters
{
my $self = shift( @_ );
my $param = shift( @_ );
# Even though login, password, server, host are not used, I was hesitating, but decided to leave them as ok, and ignore them
# Or maybe should I issue an error when they are provided?
my $core = [qw( db login passwd host port driver database server opt uri debug cache_connections cache_dir cache_query cache_table unknown_field use_cache )];
my @sqlite_params = grep( /^sqlite_/, keys( %$param ) );
# See DBD::SQLite for the list of valid parameters
# E.g.: sqlite_open_flags sqlite_busy_timeout sqlite_use_immediate_transaction sqlite_see_if_its_a_number sqlite_allow_multiple_statements sqlite_unprepared_statements sqlite_unicode sqlite_allow_multiple_statements sqlite_use_immediate_transacti...
push( @$core, @sqlite_params );
return( $core );
}
sub _dbi_connect
{
my $self = shift( @_ );
my $dbh = $self->{dbh} = $self->SUPER::_dbi_connect( @_ );
# my $func = $self->{_func};
my $func = $self->{_func};
foreach my $k ( sort( keys( %$PRIVATE_FUNCTIONS ) ) )
{
my $this = $PRIVATE_FUNCTIONS->{ $k };
my $ref =
{
name => $k,
argc => $this->[0],
code => $this->[1],
};
$func->{ $k } = $ref;
}
foreach my $name ( sort( keys( %$func ) ) )
{
my $ref = $func->{ $name };
if( $ref->{_registered_on} )
{
next;
}
$self->sql_function_register( $ref );
$ref->{_registered_on} = time();
}
return( $dbh );
}
sub _dsn
{
my $self = shift( @_ );
my $db = $self->{database_file} || return( $self->error( "No database file was specified." ) );
# return( $self->error( "Database file \"$db\" does not exist." ) ) if( !-e( $db ) );
return( $self->error( "Database file \"$db\" is not writable." ) ) if( -e( $db ) && !-w( $db ) );
my @params = ( sprintf( 'dbi:%s:', $self->{driver} ) );
push( @params, sprintf( 'dbname=%s', $db ) );
return( join( ';', @params ) );
}
sub _parse_timestamp
{
my $self = shift( @_ );
my $str = shift( @_ );
# No value was actually provided
return if( !length( $str ) );
# try-catch
local $@;
my $tz = eval
{
return( DateTime::TimeZone->new( name => 'local' ) );
};
if( $@ )
{
$tz = DateTime::TimeZone->new( name => 'UTC' );
lib/DB/Object/SQLite.pm view on Meta::CPAN
=item * C<RowCacheSize>
Is read-only.
=item * C<RowsInCache>
Is read-only.
=item * C<SCALE>
Is read-only.
=item * C<ShowErrorStatement>
Can be changed.
=item * C<Statement>
Is read-only.
=item * C<TYPE>
Is read-only.
=item * C<Taint>
Can be changed.
=item * C<TaintIn>
Can be changed.
=item * C<TaintOut>
Can be changed.
=item * C<TraceLevel>
Can be changed.
=item * C<Type>
Can be changed.
=item * C<Username>
Is read-only.
=item * C<Warn>
Can be changed.
=item * C<sqlite_allow_multiple_statements>
Can be changed.
=item * C<sqlite_see_if_its_a_number>
Can be changed.
=item * C<sqlite_unicode>
Can be changed.
=item * C<sqlite_unprepared_statements>
Is read-only.
=item * C<sqlite_use_immediate_transaction>
Can be changed.
=item * C<sqlite_version>
Is read-only.
=back
=head2 available_drivers
Return the list of available drivers.
This is an inherited method from L<DB::Object/available_drivers>
=head2 begin_work
Mark the beginning of a transaction.
Any arguments provided are passed along to L<DBD::SQLite/begin_work>
=head2 bind
This is an inherited method from L<DB::Object/bind>
=head2 cache
This is an inherited method from L<DB::Object/cache>
=head2 can_update_delete_limit
Returns the boolean value for the SQLite compiled option C<ENABLE_UPDATE_DELETE_LIMIT> by calling L</has_compile_option>
=head2 check_driver
This is an inherited method from L<DB::Object/check_driver>
=head2 commit
Make any change to the database irreversible.
This must be used only after having called L</begin_work>
Any arguments provided are passed along to L<DBD::SQLite/commit>
=head2 compile_options
Returns the cached list of SQLite compiled options. The cached file is in the file C<sql_sqlite_compile_options.cfg> in the sytem directory.
=head2 connect
Same as L<DB::Object/connect>, only specific to SQLite.
It sets C<sqlite_unicode> to a true value in the connection parameters returned by L</_connection_params2hash>
See L</_connection_params2hash>
=head2 copy
This is an inherited method from L<DB::Object/copy>
=head2 create_table
This is an inherited method from L<DB::Object/create_table>
=head2 data_sources
This is an inherited method from L<DB::Object/data_sources>
=head2 data_type
This is an inherited method from L<DB::Object/data_type>
=head2 database
This is an inherited method from L<DB::Object/database>
=head2 database_file
Returns the file path to the database file.
=head2 databases
Returns a list of databases, which in SQLite, means a list of opened sqlite database files.
=head2 datatype_dict
Returns an hash reference of each data type with their equivalent C<constant>, regular expression (C<re>), constant C<name> and C<type> name.
Each data type is an hash with the following properties for each type: C<constant>, C<name>, C<re>, C<type>
=head2 delete
This is an inherited method from L<DB::Object/database>
=head2 disconnect
This is an inherited method from L<DB::Object/disconnect>
=head2 do
This is an inherited method from L<DB::Object/do>
=head2 enhance
This is an inherited method from L<DB::Object/enhance>
=head2 func
Provided with a table name and a function name and this will call L<DB::SQLite> passing it the table name and the function name.
It returns the value received from the function call.
=head2 get_sql_type
lib/DB/Object/SQLite.pm view on Meta::CPAN
=item * C<name>
The table name
=item * C<type>
The object type, which may be one of: C<table>, C<view>, C<materialized view>, C<special>, C<foreign table>
=back
=head2 tables
Connects to the database and finds out the list of all available tables.
Returns undef or empty list in scalar or list context respectively if no table found.
Otherwise, it returns the list of table in list context or a reference of it in scalar context.
=head2 tables_info
Provided with a database or using by default the current database and this will issue a query to get an array reference of all tables.
It returns the array reference.
=head2 trace
Trace is unsupported on SQLite.
=head2 unlock
Unlock is unsupported on SQLite.
=head2 variables
Variables are unsupported on SQLite.
=head2 version
This returns the, possibly cached, SQLite server version as a L<version> object.
=head2 _check_connect_param
This returns an hash reference of connection parameters.
If there is no L</database_file> currently set, it will use the property I<uri>.
The database is taken from the property I<database>, or derived from the last path segment of the I<uri>.
The database file is made absolute and is et as the I<database_file> property
The database is name, if not set, is derived from the base path of the I<database_file>
The I<host> property is set to C<localhost> and I<port> property to C<0>
It returns the hash reference of parameters thus processed.
=head2 _check_default_option
Provided with an hash or hash reference of options and this will check it and set some default value.
The only default property this sets is C<sqlite_unicode> to true.
It returns the hash reference of options.
=head2 _connection_options
Provided with an hash reference of parameters and this will check them and returns an hash reference of options who name start with C<sqlite_>
=head2 _connection_parameters
Provided with an hash or hash reference of connection parameters and this will extra all the properties that start with C<sqlite_/> and add them to an array of core properties: db login passwd host port driver database server opt uri debug
It returns those properties as an array reference.
=head2 _dbi_connect
This calls L<DB::Connect/_dbi_connect> and do more driver specific processing.
It will register all the functions set in the global hash reference C<$PRIVATE_FUNCTIONS> which is a function name to code reference pairs. For each of those function, they will be added by calling L</sql_function_register>
It returns the database handler object (L<DBD::Object::SQLite>)
=head2 _dsn
Using the L</database_file> set and this will issue a connection to the SQLite database file.
If the file does not exist or is not writable, this will return an error, otherwise this will return the string representing the dsn, which are connection parameters separated by C<;>
=head2 _parse_timestamp
Provided a string and this will parse it to return a L<DateTime> object.
=head1 SQLITE FUNCTIONS AVAILABLE
=head2 ceiling
This is a sql function to be registered automatically upon connection to the SQLite database file.
It leverages L<POSIX/ceil>
=head2 concat
This returns the arguments provided concatenated as a string.
=head2 curdate
Returns a string representing the year, month and date separated by a C<->
This is computed using L<DateTime>
=head2 curtime
Returns a string representing the hours, minutes and seconds separated by a C<:>
This is computed using L<DateTime>
=head2 dayname
Based on a datetime that is parsed using L</_parse_timestamp>, this returns the day name of the week, such as C<Monday>
=head2 dayofmonth
( run in 3.202 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )