2014-07-16 00:56:45 +01:00
: - module ( prosqlite ,
[ sqlite_connect / 2 , % + FileName , - Conn
sqlite_connect / 3 , % + FileName , - Conn , + Opts
sqlite_disconnect / 1 , % + Conn
sqlite_current_connection / 1 , % - Conn
sqlite_query / 2 , % + SQL , - Row
sqlite_query / 3 , % + Conn , + SQL , - Row
sqlite_format_query / 3 , % + Conn , + SQL , - Row
sqlite_current_table / 2 , % + Conn , - Table
sqlite_current_table / 3 , % + Conn , ? Table , - Facet
sqlite_table_column / 3 , % + Conn , ? Table , ? Column
sqlite_table_column / 4 , % + Conn , ? Table , ? Column , - Facet
sqlite_table_count / 3 , % + Conn , + Table , - Count
sqlite_default_connection / 1 , % - Conn
sqlite_date_sql_atom / 2 , % ? Date , ? SqlAtom
sqlite_pragma / 3 , % ? Date , ? SqlAtom
sqlite_version / 2 , % - Version , - Date
sqlite_binary_version / 2 , % - Version , - Date
sqlite_citation / 2 % - Atom , Bibterm
] ) .
: - use_module ( library ( lists ) ) .
% android does it by loading the code at startup .
2014-08-05 03:54:04 +01:00
: - if ( prolog_flag ( host_type , Host ) , \ + sub_atom ( Host , _ , _ , 0 , androideabi ) ) .
2014-07-16 00:56:45 +01:00
: - use_module ( library ( shlib ) ) .
: - load_foreign_library ( foreign ( prosqlite ) ) .
: - endif .
: - dynamic ( sqlite_connection / 3 ) .
: - dynamic ( sqlite_db:sqlite_asserted / 4 ) .
/ ** <module> proSQLite: a Prolog interface to the SQLite database system .
2014-09-15 09:13:50 +01:00
\ ingroup SWILibrary
2014-07-16 00:56:45 +01:00
This library follows the design and borrows code from the ODBC library of SWI - Prolog
http: // www . swi - prolog . org /pldoc/ packasqlite_connectge / odbc . html .
The SQLite system is a powerful zero - configuration management systme that interacts
with single - file databases that are cross - platform compatible binaries .
ProSQLite provides three layers of interaction with SQLite databases .
At the lower level is the querying via SQL statements . A second layer
allows the interogation of the database dictionary , and the final level
facilitates the viewing of database tables as predicates .
See the publication pointed to by sqlite_citation / 2 , for further details .
If you use prosqlite in your research , please consider citing this publication .
The library has been developed and tested on SWI 6.3 .2 but it should
also work on YAP Prolog .
The easiest way to install on SWI is via the package manager .
Simply do :
==
? - pack_install ( prosqlite ) .
==
And you are good to go .
There are good /full examples in the sources, directory examples/ .
For instance test by :
==
? - [ predicated ] .
? - predicated .
==
There is a sister package , db_facts ( also installable via the manager ) .
Db_facts , allow interaction with the underlying database via Prolog terms ,
That library can also be used as a common compatibility layer for the ODBC
and proSQLite libraries of SWI - Prolog , as it works on both type of connections .
ProSQLite is debug / 1 aware: call = | debug ( sqlite ) |= to see what is sent to
the sqlite engine .
There are MS wins DLLs included in the sources and recent version of the SWI package
manager will install these properly .
@ version 0.1 .2 , 2013 /11/ 1
@ license Perl Artistic License
@ author Nicos Angelopoulos
@ author Sander Canisius
@ see Sander Canisius , Nicos Angelopoulos and Lodewyk Wessels . proSQLite: Prolog file based databases via an SQLite interface . In the proceedings of Practical Aspects of Declarative languages ( PADL 2013 ) , ( 2013 , Rome , Italy ) .
@ see Sander Canisius , Nicos Angelopoulos and Lodewyk Wessels . Exploring file based databases via an Sqlite interface . In the ICLP Workshop on Logic - based methods in Programming Environments , p . 2 - 9 , ( 2012 , Budapest , Hungary ) .
@ see http: //s toics . org . uk /~nicos/ pbs / wlpe2012_sqlite . pdf
@ see http: //s toics . org . uk /~nicos/s ware / prosqlite
@ see http: //s toics . org . uk /~nicos/s ware / db_facts
@ see http: // www . sqlite . org /
@ see files in examples / directory
@ see also available as a SWI pack http: // www . swi - prolog . org /pack/ list
@ tbd set pragmas
* /
: - use_module ( library ( debug ) ) .
: - at_halt ( sqlite_disconnect ) .
/* defaults and start ups */
arity_flag_values ( [ arity , unary , both , palette ] ) .
% - Section interface predicates
%
%% sqlite_version ( - Version , - Date ) .
% The current version . Version is a Mj:Mn:Fx term , and date is a date ( Y , M , D ) term .
%
sqlite_version ( 0 : 1 : 2 , date ( 2013 , 11 , 1 ) ) .
%% sqlite_binary_version ( - Version , - Date ) .
% The current version of the binaries . If the installed binaries are not compiled from
% the sources , then this might be different ( = older ) that the sqlite Porlog source version
% returned by sqlite_version / 2 . Version is a Mj:Mn:Fx term , and date is a date ( Y , M , D ) term .
%
sqlite_binary_version ( Ver , Date ) : -
c_sqlite_version ( Ver , Date ) .
%% sqlite_citation ( - Atom , - Bibterm ) .
% Succeeds once for each publication related to this library . Atom is the atom representation
% suitable for printing while Bibterm is a bibtex ( Type , Key , Pairs ) term of the same publication .
% Produces all related publications on backtracking .
sqlite_citation ( Atom , bibtex ( Type , Key , Pairs ) ) : -
Atom = 'Sander Canisius, Nicos Angelopoulos and Lodewyk Wessels. proSQLite: Prolog file based databases via an SQLite interface. In the proceedings of Practical Aspects of Declarative languages (PADL 2013), (2013, Rome, Italy).' ,
Type = inproceedings ,
Key = 'CanisiusS+2013' ,
Pairs = [
author = 'Sander Canisius and Nicos Angelopoulos and Lodewyk Wessels' ,
title = 'Exploring file based databases via an Sqlite interface' ,
booktitle = 'In ICLP Workshop on Logic-based methods in Programming Environments (WLPE\'12)' ,
year = 2012 ,
pages = '2-9' ,
month = 'September' ,
address = 'Budapest, Hungary' ,
url = 'http://stoics.org.uk/~nicos/pbs/padl2013-prosqlite.pdf'
] .
sqlite_citation ( Atom , bibtex ( Type , Key , Pairs ) ) : -
Atom = 'Exploring file based databases via an Sqlite interface. \n Canisius Sander, Nicos Angelopoulos and Lodewyk Wessels \n In the ICLP Workshop on Logic-based methods in Programming Environments (WLPE\'12),\n p.2-9, 2012. Budapest, Hungary.' ,
Type = inproceedings ,
Key = 'CanisiusS+2012' ,
Pairs = [
author = 'Sander Canisius and Nicos Angelopoulos and Lodewyk Wessels' ,
title = 'Exploring file based databases via an Sqlite interface' ,
booktitle = 'In ICLP Workshop on Logic-based methods in Programming Environments (WLPE\'12)' ,
year = 2012 ,
pages = '2-9' ,
month = 'September' ,
address = 'Budapest, Hungary' ,
url = 'http://stoics.org.uk/~nicos/pbs/wlpe2012_sqlite.pdf'
] .
%% sqlite_connect ( + File , ? Alias ) .
%
% Open a connection to an sqlite File . If Alias is a variable , an opaque atom
% is generated and unified to it . The opened db connection to file can be accessed via Alias .
%
% = =
% sqlite_connect ( 'uniprot.sqlite' , uniprot ) .
% = =
%
sqlite_connect ( File , Conn ) : -
sqlite_connect ( File , Conn , [] ) .
/ ** sqlite_connect ( + File , ? Connection , + Options ) .
Open a connection to an sqlite File . If Connection is a variable , an opaque atom
is generated , otherwise the opened file is connected to handle Connecction .
Options is a sinlge term or a list of terms from the following:
* alias ( Atom ) identify the connection as Alias in all transactions
* as_predicates ( AsPred ) if true , create hook predicates that map
each sqlite table to a prolog predicate .
These are created in module user , and it is
the user ' s responsibility to be unique in this module .
* at_module ( AtMod ) the module at which the predicates will be asserted at
( if as_predicates ( true ) ) is also given ) . Default is = | user |= .
* table_as ( Table , Pname , Arity ) map the table to predicate with name Pname . Arity should be
defined for this representaition as per with_arity ( ) option .
* arity ( arity ) Arity denotes the arity of access clauses to be added in the prolog database that
correspond to SQLite tables . The default is = | arity |= , which asserts a
predicate matching the arity of the table .
= | both |= adds two predicates , one matching the arity and a single argument one .
The later can be interrogated with something like
==
? - phones ( [ name = naku , telephone = T ] ) .
==
= | unary |= only adds the unary version , and = | palette |= adds a suite of predicates
with arities from 1 to N , where N is the number of columns .
These can be interrogated by :
==
? - phones ( name = Name ) .
? - phones ( name = naku , telephone = T ) .
? - phones ( [ name = naku , telephone = T ] ) .
==
Predicated tables can be used to insert values to the database by virtue of all
their columns are give ground values .
* exists ( Boolean ) do not throw an error if file does not exist and
Boolean is false . Default is true and an error is
thrown if the Sqlite file does not exist .
* ext ( Ext ) database files are assumed to have an sqlite extension at their end .
To ovewrite this give Ext ( '' for no extension ) .
* verbose ( Verb ) Iff Verb == true printa message about which file is used - from within C ( false ) .
When unary predicates are defined the columns can be interrogated / accessed by list pairs of the form Column = Value .
Column - Value and Column:Value are also recognised .
So for example , for table = | phones |= with columns Name , Address and Phone , prosqlite will add
==
phones ( _ , _ , _ )
==
as a response to as_predicates , and
==
phones ( _ )
==
if Arity is = | unary |=
The latter can be interrogated by
==
phones ( [ 'Name' = naku ',' Phone ' = Phone ] ) .
==
which will return the phone number ( s ) associated with individual named by = | naku |= .
See source file examples / predicated . pl .
* /
sqlite_connect ( FileIn , Conn , OptIn ) : -
to_list ( OptIn , Opts ) ,
( memberchk ( ext ( Ext ) , Opts ) - > true ; Ext = sqlite ) ,
( file_name_extension ( _ , Ext , FileIn ) - > File = FileIn ; file_name_extension ( FileIn , Ext , File ) ) ,
sqlite_connect_1 ( File , Conn , Opts ) .
sqlite_connect_1 ( File , _Conn , Opts ) : -
\ + exists_file ( File ) ,
\ + memberchk ( exists ( false ) , Opts ) ,
! ,
open ( File , read , _ ) . % just so it throws a nice error
sqlite_connect_1 ( File1 , Conn , Opts ) : -
sqlite_alias ( Opts , Conn , Alias ) ,
\ + var ( Alias ) ,
sqlite_connection ( Conn , File2 , _ ) ,
! ,
( File1 == File2 - >
print_message ( informational , sqlite ( connection_already_open ( Conn ) ) )
;
sqlite_error ( alias_in_use ( Conn , File2 ) )
) .
sqlite_connect_1 ( File , Alias , Opts ) : -
sqlite_alias ( Opts , Conn , Alias ) ,
( sqlite_connection ( _Conn1 , File , Alias1 ) - >
portray_message ( informational , file_already_open ( File , Alias1 ) )
;
true
) ,
( ( memberchk ( verbose ( Verb ) , Opts ) , Verb == true ) - >
print_message ( informational , sqlite ( db_at ( File ) ) )
;
true
) ,
c_sqlite_connect ( File , Conn ) ,
asserta ( sqlite_connection ( Alias , File , Conn ) ) ,
( sqlite_establish_predicates ( Opts , Conn ) - >
true
;
retractall ( sqlite_connection ( Alias , File , Conn ) ) ,
c_sqlite_disconnect ( Conn ) ,
sqlite_error ( predicated_creation_error ( File , Alias ) )
) .
/ *
sqlite_connect ( File , Conn , Opts ) : -
c_sqlite_connect ( File , Internal ) ,
! ,
assert ( sqlite_connection ( Conn , File , Internal ) ) .
* /
% this is currently private only for use with at_halt .
%
sqlite_disconnect : -
sqlite_connection ( Alias , _ , _ ) ,
sqlite_disconnect ( Alias ) ,
fail .
sqlite_disconnect .
%% sqlite_disconnect ( + Alias ) .
%
% Terminate the connection to a SQLite database file .
%
% = =
% sqlite_disconnect ( uniprot ) .
% = =
%
sqlite_disconnect ( Alias ) : -
once ( sqlite_connection ( Alias , _ , Conn ) ) ,
! ,
debug ( sqlite , 'Disconnecting from db with alias: ~w.' , [ Alias ] ) ,
c_sqlite_disconnect ( Conn ) ,
retractall ( sqlite_connection ( Alias , _ , Conn ) ) ,
findall ( pam ( Pname , Arity , Mod ) , sqlite_db:sqlite_asserted ( Conn , Pname , Arity , Mod ) , PAs ) ,
maplist ( sqlite_clean_up_predicated_for ( Conn ) , PAs ) .
sqlite_disconnect ( Alias ) : -
sqlite_fail ( not_a_connection ( Alias ) ) .
sqlite_clean_up_predicated_for ( Conn , pam ( Pname , Arity , Mod ) ) : -
% functor ( Head , Pname , Arity ) ,
% retractall ( Mod:Head ) ,
abolish ( Mod:Pname , Arity ) ,
retractall ( sqlite_db:sqlite_asserted ( Conn , Pname , Arity , Mod ) ) .
%% sqlite_current_connection ( - Connection ) .
%
% Return or interrogate the name of open connection handles .
%
sqlite_current_connection ( Conn ) : -
sqlite_connection ( Conn , _ , _ ) .
%% sqlite_default_connection ( - Connection ) .
%
% Return or interrogate the name of the default connection . This is the
% last connection opened .
%
sqlite_default_connection ( Alias ) : -
sqlite_connection ( Alias , _ , _ ) ,
! .
%% sqlite_query ( + Sql , - Row ) .
%
% Post an Sql query to default connection and get row result in Row .
%
sqlite_query ( Sql , Row ) : -
sqlite_default_connection ( Alias ) ,
sqlite_query ( Alias , Sql , Row ) .
%% sqlite_query ( + Connection , + Sql , - Row ) .
%
% Post an Sql query to Sqlite Connection and get row result in Row .
%
sqlite_query ( Alias , Query , Row ) : -
sqlite_alias_connection ( Alias , Connection ) ,
debug ( sqlite , 'Alias: ~w, sending: ~a' , [ Alias , Query ] ) ,
c_sqlite_query ( Connection , Query , Row ) .
%% sqlite_format_query ( + Connection , + FAs , - Row ) .
%
% Post a format style Sql query to Sqlite Connection and get row result in Row .
% FAs is a - pair structure : Format - Arguments .
%
% = =
% sqlite_format_query ( uniprot , 'PRAGMA table_info(~w)' - Table , row ( _ , Column , _ , _ , _ , _ ) )
% = =
%
%
sqlite_format_query ( Alias , Format - Arguments , Row ) : -
format ( atom ( Query ) , Format , Arguments ) ,
sqlite_query ( Alias , Query , Row ) .
%% sqlite_current_table ( + Connection , - Table ) .
%
% Return or interrogate tables in the Sqlite database associated with Connection .
%
sqlite_current_table ( Alias , Table ) : -
var ( Table ) ,
! ,
sqlite_query ( Alias , 'SELECT name FROM sqlite_master WHERE type = "table"' , row ( Table ) ) .
sqlite_current_table ( Alias , Table ) : -
ground ( Table ) ,
sqlite_query ( Alias , 'SELECT name FROM sqlite_master WHERE type = "table"' , row ( TableIn ) ) ,
% 13 .10 .26 : have a look at the C code above to see if 'row(Table)' can work on the above line .
Table = TableIn ,
! .
%% sqlite_current_table ( + Connection , ? Table , - Facet ) .
%
% Facet is a property of Table found at Connection . Currently only arity ( Arity ) is
% delivered .
sqlite_current_table ( Connection , Table , Facet ) : -
sqlite_current_table ( Connection , Table ) ,
sqlite_facet_table ( Facet , Connection , Table ) .
%% sqlite_table_column ( + Connection , ? Table , - Column ) .
%
% Return or interrogate tables and columns in the Sqlite database associated with Connection .
%
sqlite_table_column ( Alias , Table , Column ) : -
set_table ( Alias , Table ) ,
sqlite_format_query ( Alias , 'PRAGMA table_info(~w)' - Table , row ( _ , Column , _ , _ , _ , _ ) ) .
%% sqlite_table_column ( + Connection , ? Table , ? Column , - Facet ) .
%
% Facet is one of:
% * position ( Nth0 ) position of the Column in the table , first being 0 .
% * data_type ( Dtype ) the data type for the column
% * nullable ( Null ) can this column be set to the null value
% * defautl ( Default ) the default value for the
% * primary_key ( Key ) is this column part of the primary key ?
%
sqlite_table_column ( Alias , Table , Column , Facet ) : -
set_table ( Alias , Table ) ,
sqlite_format_query ( Alias , 'PRAGMA table_info(~w)' - Table , Row ) ,
Row = row ( _ , Column , _ , _ , _ , _ ) ,
sqlite_pragma_info_facet ( Row , Facet ) .
sqlite_pragma_info_facet ( row ( Nth0 , _ , _ , _ , _ , _ ) , position ( Nth0 ) ) .
sqlite_pragma_info_facet ( row ( _ , _ , Dtype , _ , _ , _ ) , data_type ( Dtype ) ) .
sqlite_pragma_info_facet ( row ( _ , _ , _ , Null , _ , _ ) , nullable ( Null ) ) . % fixme , ensure same semantics as ODBC
sqlite_pragma_info_facet ( row ( _ , _ , _ , _ , Default , _ ) , default ( Default ) ) .
sqlite_pragma_info_facet ( row ( _ , _ , _ , _ , _ , Key ) , primary_key ( Key ) ) .
%% sqlite_pragma ( + Alias , + Pragma , - Row ) .
%
% Interrogate SQLite Pragmas . Currently only reading is supported .
% Pragma can be an atom or a - separated pair , as in = | table_info - TableName |= .
%
% = =
% sqlite_pragma ( phone_db , encoding , Row ) .
% = =
sqlite_pragma ( Alias , Pragma - Par , Row ) : -
! ,
atomic_list_concat ( [ 'PRAGMA' , Pragma , '(~w)' ] , ' ' , Query ) ,
sqlite_format_query ( Alias , Query - Par , Row ) .
sqlite_pragma ( Alias , Pragma , Row ) : -
atomic_list_concat ( [ 'PRAGMA' , Pragma ] , ' ' , Query ) ,
sqlite_query ( Alias , Query , Row ) .
% pragmas_info ( [ ... , encoding , ... , secure_delete , synchronous , temp_store , writable_schema ] ) .
pragmas_comm ( [ shrink_memory ] ) .
set_table ( Alias , Table ) : -
( var ( Table ) - >
sqlite_current_table ( Alias , Table )
;
true
) .
%% sqlite_table_count ( + Connection , + Table , - Count ) .
%
% True if Count is the number of rows in Sqlite Connection associated Table .
%
sqlite_table_count ( Alias , Table , Count ) : -
Sel = 'Select count (*) from ~w' ,
sqlite_format_query ( Alias , Sel - Table , row ( Count ) ) ,
! .
/ ** sqlite_date_sql_atom ( Date , Sql ) .
Convert between a Prolog date / 3 term and an Sql atom .
The conversion is bidirectional .
* /
sqlite_date_sql_atom ( date ( Y , M , D ) , Sql ) : -
ground ( Sql ) ,
! ,
atomic_list_concat ( Consts , '/' , Sql ) ,
maplist ( atom_number , Consts , [ Y , M , D ] ) .
sqlite_date_sql_atom ( date ( Y , M , D ) , Sql ) : -
atomic_list_concat ( [ '"' , Y ] , Ya ) ,
atomic_list_concat ( [ D , '"' ] , Da ) ,
atomic_list_concat ( [ Ya , M , Da ] , '/' , Sql ) .
% - Section non - interface sqlite specific predicates
%
sqlite_alias ( Opts , _Conn , Alias ) : -
memberchk ( alias ( Alias ) , Opts ) ,
! .
sqlite_alias ( _Opts , _Conn , Alias ) : -
atomic ( Alias ) ,
! .
sqlite_alias ( _Opts , Conn , Conn ) .
sqlite_establish_predicates ( Opts , Conn ) : -
memberchk ( as_predicates ( true ) , Opts ) ,
! ,
findall ( T - C , sqlite_table_column ( Conn , T , C ) , TCs ) ,
findall ( T , member ( T - _ , TCs ) , RepTs ) ,
sort ( RepTs , Ts ) ,
findall ( T - Cs , ( member ( T , Ts ) , findall ( C , member ( T - C , TCs ) , Cs ) ) , TdCs ) ,
( memberchk ( at_module ( Mod ) , Opts ) - > true ; Mod = user ) ,
arity_option ( Opts , ArityF ) ,
sqlite_establish_tables ( TdCs , Conn , Mod , ArityF , Opts ) .
sqlite_establish_predicates ( _Opts , _Conn ) .
sqlite_establish_tables ( [] , _Conn , _Mod , _ArityF , _Opts ) .
sqlite_establish_tables ( [ Table - Columns | T ] , Conn , Mod , ArityF , Opts ) : -
( memberchk ( table_as ( Table , Pname , TArityF ) , Opts ) - >
true
;
Pname = Table , TArityF = ArityF
) ,
sqlite_establish_table ( TArityF , Table , Pname , Columns , Conn , Mod ) ,
% Internal = 'Internal prosqlite error. Unable to establish table' ,
% throw ( Internal:TArityF / Table ) % handled furter up now
sqlite_establish_tables ( T , Conn , Mod , ArityF , Opts ) .
sqlite_establish_table ( arity , Table , Pname , Columns , Conn , Mod ) : -
length ( Columns , Arity ) ,
sqlite_establish_table_typed ( Table , Pname , Columns , Conn , Mod , predicate , Arity ) .
sqlite_establish_table ( both , Table , Pname , Columns , Conn , Mod ) : -
sqlite_establish_table_typed ( Table , Pname , Columns , Conn , Mod , unary , 1 ) ,
length ( Columns , Arity ) ,
sqlite_establish_table_typed ( Table , Pname , Columns , Conn , Mod , predicate , Arity ) .
sqlite_establish_table ( unary , Table , Pname , Columns , Conn , Mod ) : -
sqlite_establish_table_typed ( Table , Pname , Columns , Conn , Mod , unary , 1 ) .
sqlite_establish_table ( palette , Table , Pname , Columns , Conn , Mod ) : -
length ( Columns , Arity ) ,
% Shorter is Arity - 1 ,
findall ( _ , ( between ( 1 , Arity , I ) ,
sqlite_establish_table_typed ( Table , Pname , Columns , Conn , Mod , palette , I )
) , _ ) .
sqlite_establish_table_typed ( Table , Pname , Columns , Conn , Mod , ArityF , Arity ) : -
functor ( Head , Pname , Arity ) ,
Head = .. [ Pname | Args ] ,
Body = prosqlite:sqlite_holds ( Conn , Table , Arity , ArityF , Columns , Args ) ,
( clause ( Mod:Head , _Body ) - >
sqlite_fail ( maps_to_existing_predicate ( Pname , Arity ) )
;
true
) ,
% retractall ( Mod:Head ) , % fixme: double check this and test it works
( sqlite_db:sqlite_asserted ( Conn1 , Pname , Args , _Mod1 ) - >
sqlite_fail ( predicate_already_registered ( Conn1 , Pname , Arity ) )
;
Mod:assert ( ( Head : - Body ) )
) ,
assert ( sqlite_db:sqlite_asserted ( Conn , Pname , Arity , Mod ) ) .
% assert ( ( Head : - Body ) ) ,
sqlite_holds ( AliasOr , Name , _Arity , Type , Columns , Args ) : -
sqlite_alias_connection ( AliasOr , Conn ) ,
pl_as_predicate_to_sql_ready_data ( Type , Columns , Args , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) ,
sqlite_holds_unknown ( UnKnwnCs , UnKnwnAs , KnwnClmPrs , Name , Columns , Conn ) .
/ * fixme:
sqlite_holds_unknown ( [] , _UnKnwnAs , KnwnClmPrs , Name , Columns , Conn ) : -
shall we throw an error if there is nothing to report and nothing to assert ?
* /
sqlite_holds_unknown ( UnKnwnCs , UnKnwnAs , KnwnClmPrs , Name , _Columns , Conn ) : -
sql_clm_value_pairs_to_where ( KnwnClmPrs , Where ) ,
atomic_list_concat ( UnKnwnCs , ',' , UnC ) ,
atomic_list_concat ( [ 'Select ' , UnC , 'From' , Name , Where , ';' ] , ' ' , Sql ) ,
Row = .. [ row | UnKnwnAs ] ,
debug ( sqlite , 'Conn: ~w, sending: ~a' , [ Conn , Sql ] ) ,
c_sqlite_query ( Conn , Sql , Row ) .
sqlite_alias_connection ( Alias , Connection ) : -
sqlite_connection ( Alias , _ , Connection ) ,
! .
% allows access with either alias or connection :
sqlite_alias_connection ( Connection , Connection ) : -
sqlite_connection ( _ , _ , Connection ) ,
! .
sqlite_alias_connection ( Alias , _Connection ) : -
sqlite_error ( unknown_alias ( Alias ) ) .
% fixme: we should really use the db_facts code here .
pl_as_predicate_to_sql_ready_data ( unary , Columns , [ Args ] , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) : -
pl_look_for_args_to_un_known ( Args , Columns , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) .
pl_as_predicate_to_sql_ready_data ( palette , Columns , ArgsIn , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) : -
( ( ArgsIn = [ Args ] , is_list ( Args ) ) - > true ; Args = ArgsIn ) ,
pl_args_column_arg_ground_or_not_pairs ( Args , Columns , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) ,
( maplist ( var , Args ) - >
true % then a palette predicate has been called with full arity and all variables
;
% maplist ( look_for_pair , Args , _ , _ ) ,
findall ( LFA , ( member ( LFA , Args ) , look_for_pair_silent ( LFA , _ , _ ) ) , [] )
% then a palette predicate has been called with full arity and look_for_pair
) ,
! .
pl_as_predicate_to_sql_ready_data ( palette , Columns , ArgsIn , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) : -
( ( ArgsIn = [ Args ] , is_list ( Args ) ) - > true ; Args = ArgsIn ) ,
pl_look_for_args_to_un_known ( Args , Columns , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) .
pl_as_predicate_to_sql_ready_data ( predicate , Columns , Args , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) : -
pl_args_column_arg_ground_or_not_pairs ( Args , Columns , KnwnClmPrs , UnKnwnCs , UnKnwnAs ) .
pl_args_column_arg_ground_or_not_pairs ( [] , [] , [] , [] , [] ) .
pl_args_column_arg_ground_or_not_pairs ( [ A | As ] , [ C | Cs ] , Knwn , UnCs , UnAs ) : -
( ground ( A ) - >
Knwn = [ C - A | TKnwn ] ,
TUnCs = UnCs ,
TUnAs = UnAs
;
TKnwn = Knwn ,
UnCs = [ C | TUnCs ] ,
UnAs = [ A | TUnAs ]
) ,
pl_args_column_arg_ground_or_not_pairs ( As , Cs , TKnwn , TUnCs , TUnAs ) .
pl_look_for_args_to_un_known ( [] , _Columns , [] , [] , [] ) .
pl_look_for_args_to_un_known ( [ A | As ] , Columns , Knwn , UnKnwnCs , UnKnownAs ) : -
look_for_pair ( A , Clm , Val ) ,
is_one_of_columns ( Clm , Columns ) ,
( ground ( Val ) - >
Knwn = [ Clm - Val | TKnwn ] ,
TUnKnwnCs = UnKnwnCs ,
TUnKnownAs = UnKnownAs
;
TKnwn = Knwn ,
UnKnwnCs = [ Clm | TUnKnwnCs ] ,
UnKnownAs = [ Val | TUnKnownAs ]
) ,
pl_look_for_args_to_un_known ( As , Columns , TKnwn , TUnKnwnCs , TUnKnownAs ) .
is_one_of_columns ( Clm , Columns ) : -
memberchk ( Clm , Columns ) ,
! .
is_one_of_columns ( Clm , Columns ) : -
sqlite_error ( unknown_column ( Clm , Columns ) ) .
look_for_pair ( Pair , K , V ) : -
look_for_pair_silent ( Pair , K , V ) ,
! .
look_for_pair ( Term , _A , _B ) : -
% print_message ( informational , pack ( git_fetch ( Dir ) ) ) .
sqlite_error ( pair_representation ( Term ) ) .
% type_error ( 'Binary compound with functor {=,-,:}' , Term ) .
% Type = 'Binary compound with functor {=,-,:}' ,
% print_message ( error , error ( type_error ( Type , Term ) ) ) ,
% abort .
look_for_pair_silent ( A = B , A , B ) .
look_for_pair_silent ( A - B , A , B ) .
look_for_pair_silent ( A:B , A , B ) .
/* error messages */
sqlite_error ( Term ) : -
Type = error ,
print_message ( Type , sqlite ( Term ) ) ,
abort .
sqlite_fail ( Term ) : -
Type = informational ,
sqlite_fail ( Type , Term ) .
sqlite_fail ( Type , Term ) : -
print_message ( Type , sqlite ( Term ) ) ,
fail .
% - Section error handling .
: - multifile prolog:message // 1 .
prolog:message ( sqlite ( Message ) ) - - >
message ( Message ) .
message ( pair_representation ( Term ) ) - - >
[ 'Wrong term type ~q in predicated table arguments. Expected binary with functor, {=,:,-}.' - [ Term ] ] .
message ( unknown_column ( Clm , Columns ) ) - - >
[ 'Unkown column, ~q expected one in ~q.' - [ Clm , Columns ] ] .
message ( unknown_alias ( Alias ) ) - - >
[ 'Not a known alias or connection:~q.' - Alias ] .
message ( wrong_arity_value ( ArityF ) ) - - >
{ arity_flag_values ( Arities ) } ,
[ 'Unrecognised arity option value ~q, expected ~q.' - [ ArityF , Arities ] ] .
message ( predicated_creation_error ( File , Alias ) ) - - >
[ 'Closed connection ~q to file ~q due to failure in predicated table creation.' - [ Alias , File ] ] .
message ( connection_already_open ( Conn ) ) - - >
[ 'Connection already open ~q.' - [ Conn ] ] .
message ( alias_in_use ( Conn , File ) ) - - >
[ 'Alias/connection ~q already in use for file ~q.' - [ Conn , File ] ] .
message ( not_a_connection ( Alias ) ) - - >
[ 'Not an open connection or known alias to a connection: ~q' - [ Alias ] ] .
message ( insufficient_columns ( Goal , Op ) ) - - >
[ 'Insufficient number of known column values in ~q for operation ~q.' - [ Goal , Op ] ] .
message ( predicate_already_registered ( Conn , Pname , Arity ) ) - - >
[ 'Predicate ~q already registered by connection ~q' - [ Pname / Arity , Conn ] ] .
message ( maps_to_existing_predicate ( Pname , Arity ) ) - - >
[ 'Predicated table maps to existing predicate ~q.' - [ Pname / Arity ] ] .
message ( file_already_open ( File , Alias ) ) - - >
[ 'File, ~q already open with alias ~q.' - [ File , Alias ] ] .
message ( db_at ( File ) ) - - >
[ 'Using database from file: ~q.' - [ File ] ] .
message ( asserting_non_ground ( Goal ) ) - - >
[ 'Asserting non ground term ~q.' - [ Goal ] ] .
message ( debug ( Format , Args ) ) - - >
[ 'Found Format (1st arg) ~q and Args (2nd arg) ~q.' - [ Format , Args ] ] .
% - Section sqlite non - specific auxiliary predicates
%
to_list ( OptIn , Opts ) : -
is_list ( OptIn ) ,
! ,
Opts = OptIn .
to_list ( Opt , [ Opt ] ) .
dquote ( Val , Quoted ) : -
number ( Val ) ,
! ,
Quoted = Val .
dquote ( Val , Quoted ) : -
atom ( Val ) ,
! ,
atomic_list_concat ( [ '"' , Val , '"' ] , Quoted ) .
dquote ( Val , Quoted ) : -
is_list ( Val ) ,
append ( [ 0 '"|Val], [0' " ] , QuotedCs ) ,
atom_codes ( Quoted , QuotedCs ) .
sql_clm_value_pairs_to_where ( Known , Where ) : -
sql_clm_value_pairs_to_where_conjunction ( Known , Conjunction ) ,
sql_where_conjunction_to_where ( Conjunction , Where ) .
sql_where_conjunction_to_where ( '' , '' ) : - ! .
sql_where_conjunction_to_where ( Conjunction , Where ) : -
atom_concat ( 'Where ' , Conjunction , Where ) .
sql_clm_value_pairs_to_where_conjunction ( [] , '' ) .
sql_clm_value_pairs_to_where_conjunction ( [ K - V | T ] , Where ) : -
sql_clm_value_pairs_to_where_conjunction ( T , InWhere ) ,
sql_clm_and_val_to_sql_equals_atom ( K , V , KVAtm ) ,
( InWhere == '' - >
Where = KVAtm
;
atomic_list_concat ( [ KVAtm , ' AND ' , InWhere ] , Where )
) .
sql_clm_and_val_to_sql_equals_atom ( K , V , KVAtm ) : -
( number ( V ) - >
atom_number ( Vatm , V ) ,
atom_concat ( '=' , Vatm , EqV )
;
atom_concat ( V , '\'' , VDsh ) ,
atom_concat ( '=\'' , VDsh , EqV )
) ,
atom_concat ( K , EqV , KVAtm ) .
sqlite_facet_table ( arity ( Arity ) , Connection , Table ) : -
findall ( Column , sqlite_table_column ( Connection , Table , Column ) , Columns ) ,
length ( Columns , Arity ) .
arity_option ( Opts , ArityF ) : -
memberchk ( arity ( ArityF ) , Opts ) ,
arity_flag_values ( Arities ) ,
memberchk ( ArityF , Arities ) ,
! .
arity_option ( Opts , ArityF ) : -
memberchk ( arity ( ArityF ) , Opts ) ,
! ,
sqlite_fail ( wrong_arity_value ( ArityF ) ) .
arity_option ( _Opts , arity ) . % default for this flag , although we should
% move all defaults to one location / list ( fixme )
kv_decompose ( [] , [] , [] ) .
kv_decompose ( [ K - V | T ] , [ K | Ks ] , [ V | Vs ] ) : -
kv_decompose ( T , Ks , Vs ) .