Support sqlite3, basic ops

This commit is contained in:
Vitor Santos Costa 2017-11-18 00:04:42 +00:00
parent b8f0a34833
commit 746a4b4ef8
9 changed files with 566 additions and 440 deletions

View File

@ -55,6 +55,7 @@ SET_PROPERTY(SOURCE ${MYDDAS_SOURCES}
MY_add_dependencies(myddas plmyddas)
add_subdirectory(pl)
MY_set_target_properties(myddas PROPERTIES
POSITION_INDEPENDENT_CODE ON
)

View File

@ -1,9 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#if MYDDAS_SQLITE3
#include <sqlite3.h>
#endif
#include "Yap.h"
#include "myddas.h"
#ifdef MYDDAS_STATS

View File

@ -24,9 +24,38 @@
:- yap_flag(single_var_warnings,on).
#endif
#define SWITCH(Contype, G) \
( Contype == mysql -> \
my_ ## G \
; \
Contype == sqlite3 -> \
sqlite3_ ## G \
; \
Contype == postgres -> \
postgres_ ## G \
; \
Contype == odbc -> \
odbc_ ## G \
)
#define C_SWITCH(Contype, G) \
( Contype == mysql -> \
c_my_ ## G \
; \
Contype == sqlite3 -> \
c_sqlite3_ ## G \
; \
Contype == postgres -> \
c_postgres_ ## G \
; \
Contype == odbc -> \
c_odbc_ ## G \
)
:- module(myddas,[
db_open/5,
db_open/4,
db_open/2,
db_open/1,
db_open/0,
db_close/1,
@ -52,21 +81,26 @@
db_create_table/3,
db_export_view/4,
db_update/2,
db_describe/2,
db_describe/3,
db_show_tables/2,
db_show_tables/1,
db_get_attributes_types/2,
db_get_attributes_types/3,
db_number_of_fields/2,
db_number_of_fields/3,
db_multi_queries_number/2,
db_multi_queries_number/2
% myddas_top_level.ypp
#ifdef MYDDAS_TOP_LEVEL
,
db_top_level/4,
db_top_level/5,
db_datalog_select/3,
db_datalog_select/3
#endif
% myddas_assert_predicates.ypp
,
db_import/2,
db_import/3,
db_view/2,
@ -76,34 +110,8 @@
db_abolish/2,
db_listing/0,
db_listing/1
#ifdef MYDDAS_MYSQL
% myddas_mysql.ypp
,
db_my_result_set/1,
db_datalog_describe/1,
db_datalog_describe/2,
db_describe/3,
db_describe/2,
db_datalog_show_tables/1,
db_datalog_show_tables/0,
db_show_tables/2,
db_show_tables/1,
db_show_database/2,
db_show_databases/2,
db_show_databases/1,
db_change_database/2,
db_call_procedure/4,
db_call_procedure/3,
db_my_sql_mode/1,
db_my_sql_mode/2,
db_sql_mode/1,
db_sql_mode/2
#endif
]).
%% @}
]).
#ifdef MYDDAS_TOP_LEVEL
:- use_module(myddas_top_level,[
@ -125,39 +133,19 @@
db_listing/1
]).
#ifdef MYDDAS_MYSQL
:- use_module(myddas_mysql,[
db_my_result_set/1,
db_datalog_describe/1,
db_datalog_describe/2,
db_describe/3,
db_describe/2,
db_datalog_show_tables/1,
db_datalog_show_tables/0,
db_show_tables/2,
db_show_tables/1,
db_show_database/2,
db_show_databases/2,
db_show_databases/1,
db_change_database/2,
db_call_procedure/4,
db_call_procedure/3,
db_my_sql_mode/1,
db_my_sql_mode/2,
db_sql_mode/1,
db_sql_mode/2
]).
#endif /* MYDDAS_MYSQL */
:- use_module(myddas_sqlite3,[
% myddas_mysql.ypp
c_sqlite3_connect/4,
c_sqlite3_disconnect/1,
c_sqlite3_query/5,
sqlite3_result_set/1,
c_sqlite3_number_of_fields/3
c_sqlite3_number_of_fields/3,
c_sqlite3_get_attributes_types/3,
sqlite3_describe/3,
sqlite3_show_tables/2,
sqlite3_row/3
]).
:- use_module(myddas_util_predicates,[
'$prolog2sql'/3,
'$create_multi_query'/3,
@ -201,9 +189,18 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_open/5
% db_open/4
%% @pred db_open(+Interface,-Handle,+HostDb,+User,+Password)
%% @pred db_open(+Interface,+HostDb,+User,+Password)
%
% Connect to a database-server, or open a file as a database, Paraameters are:
%
% _Interface_ : a supported server, it may be one of mysql, odbc, postgres, sqlite3.
% _Handle_ : a name that refers to the database-conectionn. By default is `myddas`,
% _Connection Info': either a sequence Host/Db/Port/Socket or a file name. You can use 0 for the defaukt port and sockets,
% _UserId_; the use identifier, ignored by sqlite3;
% _Password_ : access control, ignored by sqlite3,
%
%
%
db_open(Interface,HostDb,User,Password):-
db_open(Interface,myddas,HostDb,User,Password).
@ -233,7 +230,7 @@ db_open(postgres,Connection,Host/Db/Port,User,Password) :-
db_open(postgres,Connection,Host/Db/Socket,User,Password) :- !,
db_open(postgres,Connection,Host/Db/0/Socket,User,Password). % 0 is default port
db_open(postgres,Connection,Host/Db,User,Password) :-
db_open(postgres,Connection,Host/Db/0/_,User,Password). % 0 is default port and Var to be NULL, the default socket
db_open(postgres,Connection,Host/Db/0/_,User,Password). % 0 is default port and Var to be NULL, the default socpket
#endif
#ifdef MYDDAS_ODBC
@ -242,38 +239,32 @@ db_open(odbc,Connection,ODBCEntry,User,Password) :-
c_odbc_connect(ODBCEntry,User,Password,Con),
set_value(Connection,Con).
#endif
%% sqlite3
db_open(sqlite3,Connection,File,User,Password) :-
'$error_checks'(db_open(sqlite3,Connection,File,User,Password)),
c_sqlite3_connect(File,User,Password,Con),
absolute_file_name(File,FullFile,[access(exist),file_errors(error),expand(true)]),
c_sqlite3_connect(FullFile,User,Password,Con),
set_value(Connection,Con).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_close/1
% db_close/0
%% db_close/1
%% db_close/0
%
% close a connection _Con_: all its resources are returned, and all undefined
% predicates are abolished. Default is to close `myddas`.
db_close:-
db_close(myddas).
db_close(Protocol):-
'$error_checks'(db_close(Protocol)),
get_value(Protocol,Con),
'$abolish_all'(Con).
db_close(Protocol) :-
'$error_checks'(db_close(Protocol)),
get_value(Protocol,Con),
c_db_connection_type(Con,ConType),
( ConType == mysql ->
c_db_my_disconnect(Con)
;ConType == postgres ->
c_postgres_disconnect(Con)
;ConType == sqlite3 ->
c_sqlite3_disconnect(Con)
;
c_odbc_disconnect(Con)
),
set_value(Protocol,[]). % "deletes" atom
( '$abolish_all'(Con) ;
set_value(Protocol,[]), % "deletes" atom
C_SWITCH( ConType, disconnect(Con) )
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -362,10 +353,14 @@ db_sql_select(Protocol,SQL,LA):-
db_sql(SQL,LA):-
db_sql(myddas,SQL,LA).
db_sql(Connection,SQL,LA):-
'$error_checks'(db_sql(Connection,SQL,LA)),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
db_sql_(ConType, Con, SQL, LA).
db_sql_(ConType, Con, SQL,LA):-
'$write_or_not'(SQL),
( ConType == mysql ->
db_my_result_set(Mode),
@ -377,16 +372,12 @@ db_sql(Connection,SQL,LA):-
sqlite3_result_set(Mode),
c_sqlite3_query(SQL,ResultSet,Con,Mode,Arity)
;
c_odbc_query(SQL,ResultSet,Arity,LA,Con),
c_odbc_number_of_fields_in_query(SQL,Con,Arity)
),
'$make_a_list'(Arity,LA),
( ConType == mysql ->
!,c_db_my_row(ResultSet,Arity,LA)
;
'$make_a_list'(Arity,BindList),
c_odbc_query(SQL,ResultSet,Arity,BindList,Con),!,
c_odbc_row(ResultSet,BindList,LA)
).
SWITCH( ConType, row(ResultSet,Arity,LA) ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -397,37 +388,15 @@ db_sql(Connection,SQL,LA):-
db_prolog_select(LA,DbGoal):-
db_prolog_select(myddas,LA,DbGoal).
db_prolog_select(Connection,LA,DbGoal):-
'$lenght'(LA,Arity),
lenght(LA,Arity),
Name=viewname,
functor(ViewName,Name,Arity),
% build arg list for viewname/Arity
ViewName=..[Name|LA],
'$prolog2sql'(ViewName,DbGoal,SQL),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
'$write_or_not'(SQL),
( ConType == mysql ->
db_my_result_set(Mode),
c_db_my_query(SQL,ResultSet,Con,Mode,_),
!,c_db_my_row(ResultSet,Arity,LA)
; ConType == postgres ->
postgres_result_set(Mode),
c_postgres_query(SQL,ResultSet,Con,Mode,_),
!,c_postgres_row(ResultSet,Arity,LA)
; ConType == odbc ->
odbc_result_set(Mode),
c_odbc_query(SQL,ResultSet,Con,Mode,_),
!,c_odbc_row(ResultSet,Arity,LA)
; ConType == sqlite3 ->
sqlite3_result_set(Mode),
c_sqlite3_query(SQL,ResultSet,Con,Mode,_),
!,c_sqlite3_row(ResultSet,Arity,LA)
;
true
).
db_sql_(ConType, Con, SQL,LA).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -443,24 +412,7 @@ db_prolog_select_multi(Connection,DbGoalsList,ListOfResults) :-
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
'$write_or_not'(SQL),
( ConType == mysql ->
db_my_result_set(Mode),
c_db_my_query(SQL,ResultSet,Con,Mode,_)
;
ConType == postgres ->
postgres_result_set(Mode),
c_postgres_query(SQL,ResultSet,Con,Mode,_)
;
ConType == mysql ->
sqlite3_result_set(Mode),
c_sqlite3_query(SQL,ResultSet,Con,Mode,_)
;
ConType == mysql ->
odbc_result_set(Mode),
c_odbc_query(SQL,ResultSet,Con,Mode,_)
;
true
),
C_SWITCH(ConType, query(SQL,ResultSet,Con,Mode,_) ),
'$get_multi_results'(Con,ConType,ResultSet,ListOfResults).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -621,42 +573,50 @@ db_update(Connection,WherePred-SetPred):-
c_odbc_query(SQL,_,Conn,Mode,_)
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_get_attributes_types/3
% db_get_attributes_types/2
%
/**
*
@pred db_get_attributes_types(+Conn,+RelationName,-ListOfFields)
@pred db_get_attributes_types(RelationName,ListOfFields)
Y
ou can use the predicate db_get_attributes_types/2 or db_get_attributes_types/3, to know what
are the names and attributes types of the fields of a given relation. For example:
~~~~
?- db_get_attributes_types(myddas,Hello World,LA).
LA = [Number,integer,Name,string,Letter,string] ?
yes
˜˜˜˜
where `Hello World` is the name of the relation and `myddas` is the connection identifier.
*/
db_get_attributes_types(RelationName,TypesList) :-
db_get_attributes_types(myddas,RelationName,TypesList).
db_get_attributes_types(Connection,RelationName,TypesList) :-
'$error_checks'(db_get_attributes_types(Connection,RelationName,TypesList)),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
( ConType == mysql ->
c_db_my_number_of_fields(RelationName,Con,Arity)
;
ConType == postgres ->
c_postgres_number_of_fields(RelationName,Con,Arity)
;
ConType == sqlite3 ->
c_sqlite3_number_of_fields(RelationName,Con,Arity)
;
ConType == odbc ->
c_odbc_number_of_fields(RelationName,Con,Arity)
),
Size is 2*Arity,
'$make_a_list'(Size,TypesList),
c_db_connection_type(Con,ConType),
( ConType == mysql ->
c_db_my_get_attributes_types(RelationName,Con,TypesList)
;
ConType == odbc ->
c_odbc_get_attributes_types(RelationName,Con,TypesList)
).
C_SWITCH(ConType, get_attributes_types(RelationName,Con,TypesList) ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_number_of_fields/3
%
/**
@pred db_number_of_fields(+Conn,+RelationName,-Arity).
@pred db_number_of_fields(+RelationName,-Arity).
You can use the predicate db number of fields/2 or db number of fields/3, to know what is the arity
of a given relation.
@Example
~~~~
?- db_number_of_fields(myddas,Hello World,Arity).
Arity = 3 ?
yes
˜˜˜˜
where `Hello World` is the name of the relation and `myddas` is the connection identifier.
*/
%
db_number_of_fields(RelationName,Arity) :-
db_number_of_fields(myddas,RelationName,Arity).
@ -664,15 +624,7 @@ db_number_of_fields(Connection,RelationName,Arity) :-
'$error_checks'(db_number_of_fields(Connection,RelationName,Arity)),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
( ConType == mysql ->
c_db_my_number_of_fields(RelationName,Con,Arity)
;ConType == postgres ->
c_postgres_number_of_fields(RelationName,Con,Arity)
;ConType == sqlite3 ->
c_sqlite3_number_of_fields(RelationName,Con,Arity)
;
c_odbc_number_of_fields(RelationName,Con,Arity)
).
C_SWITCH(ConType, number_of_fields(RelationName,Con,Arity) ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -688,3 +640,115 @@ db_multi_queries_number(Connection,Number) :-
db_result_set(X) :-
'$error_checks'(db_result_set(X) ),
get_value(myddas,Con),
c_db_connection_type(Con,DBMS),
DBMS:result_set(X).
db_datalog_describe(X) :-
'$error_checks'(db_datalog_describe(X) ),
get_value(myddas,Con),
c_db_connection_type(Con,DBMS),
DBMS:datalog_describe(X).
db_datalog_describe(Connection,Y) :-
'$error_checks'(db_datalog_describe(Connection,Y) ),
get_value(Connection,Con),
c_db_connection_type(Con,DBMS),
DBMS:datalog_describe(Connection,Y).
/**
@pred db_describe(+,+,?)
@pred db_describe(+,?)
The db describe/3 predicate does the same action as db_datalog_describe/2 predicate but with one
major difference. The results are returned by backtracking. For example, the last query done:
~~~~
?- db_describe(myddas,Hello World,Term).
Term = tableInfo(Number,int(11),YES,,null(0),) ? ;
Term = tableInfo(Name,char(10),YES,,null(1),) ? ;
Term = tableInfo(Letter,char(1),YES,,null(2),) ? ;
no
~~~~
*/
db_describe(Y,Z) :-
db_describe(myddas,Y,Z).
db_describe(Connection,Y,Z) :-
'$error_checks'(db_describe(Connection,Y,Z) ),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
SWITCH(ConType, describe(Connection,Y,Z) ).
db_datalog_show_tables :-
db_datalog_show_tables(myddas).
db_datalog_show_tables(Connection) :-
'$error_checks'(db_datalog_show_tables(Connection) ),
get_value(Connection,Con),
c_db_connection_type(Con,DBMS),
switch( DBMS, datalog_show_tables(Connection) ).
db_datalog_show_tables :-
'$error_checks'(db_datalog_show_tables),
get_value(myddas,Con),
c_db_connection_type(Con,DBMS),
DBMS:datalog_show_tables.
/**
@pred db_show_tables(+,?).
@pred db_show_tables(?).
The db show tables/2 predicate does the same action as db show tables/1 predicate but with one
major difference. The results are returned by backtracking.
For example, the last query done:
~~~~`
`?- db_show_tables(myddas,Table).
Table = table(Hello World) ? ;
~~~~
``*/
db_show_tables(Y) :-
db_show_tables(myddas,Y).
db_show_tables(Connection,Y) :-
'$error_checks'(db_show_tables(Connection,Y) ),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
SWITCH( ConType, show_tables(Connection,Y) ).
db_show_database(Connection,Y) :-
'$error_checks'(db_show_database(Connection,Y) ),
get_value(Connection,Con),
c_db_connection_type(Con,DBMS),
DBMS:show_database(Connection,Y).
db_show_databases(Connection,Y) :-
'$error_checks'(db_show_databases(Connection,Y) ),
get_value(Connection,Con),
c_db_connection_type(Con,DBMS),
DBMS:show_databases(Connection,Y).
db_show_databases(X) :-
'$error_checks'(db_show_databases(X) ),
get_value(myddas,Con),
c_db_connection_type(Con,DBMS),
DBMS:show_databases(X).
db_change_database(Connection,Y) :-
'$error_checks'(db_change_database(Connection,Y) ),
get_value(Connection,Con),
c_db_connection_type(Con,DBMS),
DBMS:change_database(Connection,Y).
db_call_procedure(Connection,Y,Z,W) :-
'$error_checks'(db_call_procedure(Connection,Y,Z,W) ),
get_value(Connection,Con),
c_db_connection_type(Con,DBMS),
DBMS:call_procedure(Connection,Y,Z,W).
db_call_procedure(X,Y,Z) :-
'$error_checks'(db_call_procedure(X,Y,Z) ),
get_value(myddas,Con),
c_db_connection_type(Con,DBMS),
DBMS:call_procedure(X,Y,Z).

View File

@ -66,7 +66,7 @@
c_sqlite3_get_next_result_set/3,
c_sqlite3_query/5,
c_sqlite3_number_of_fields/3,
c_sqlite3_row/3
sqlite3_row/3
]).
:- use_module(myddas_odbc,[
odbc_result_set/1,
@ -315,7 +315,7 @@ table_access_predicate( sqlite3, Con, Arity, P, LA, M,
'$write_or_not'(FinalSQL),
c_sqlite3_query(FinalSQL,ResultSet,Con,Mode,_),
!,
c_sqlite3_row(ResultSet,Arity,LA)
sqlite3_row(ResultSet,Arity,LA)
) )).
table_access_predicate( odbc, Con, Arity, P, LA, M,

View File

@ -40,21 +40,6 @@
#if defined(DBMS)
:- module(MODULE(),[
DBMS(result_set)/1,
DBMS(datalog_describe)/1,
DBMS(datalog_describe)/2,
DBMS(describe)/3,
DBMS(describe)/2,
DBMS(datalog_show_tables)/1,
DBMS(datalog_show_tables)/0,
DBMS(show_tables)/2,
DBMS(show_tables)/1,
DBMS(show_database)/2,
DBMS(show_databases)/2,
DBMS(show_databases)/1,
DBMS(change_database)/2,
DBMS(call_procedure)/4,
DBMS(call_procedure)/3,
c_DBMS(change_database)/2,
c_DBMS(connect)/4,
c_DBMS(disconnect)/1,
@ -64,7 +49,9 @@
c_DBMS(get_next_result_set)/3,
c_DBMS(query)/5,
c_DBMS(number_of_fields)/3,
c_DBMS(row)/3
DBMS(describe)/3,
DBMS(show_tables)/2,
DBMS(row)/3
]).
:- use_module(myddas,[
@ -107,7 +94,7 @@ DBMS(result_set)(store_result):-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DBMS(describe)/2
% DBMS(db_datalog_describe)/2
%
%
DBMS(datalog_describe)(Relation):-
@ -125,20 +112,18 @@ DBMS(datalog_describe)(Connection,Relation) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DBMS(describe)/3
% DBMS(describe)/2
% gives the results of the DESCRIBE statement
% by backtracking
DBMS(describe)(Relation,TableInfo) :-
DBMS(describe)(myddas,Relation,TableInfo).
DBMS(describe)(Connection,Relation,tableinfo(A1,A2,A3,A4,A5,A6)) :-
'$error_checks'(DBMS(describe)(Relation,Connection,_)),
%#if sqlite3
DBMS(describe)(Connection,Relation,tableinfo(FieldID,Type,Null,Primary,Default,'')) :-
'$get_value'(Connection,Conn),
'$make_atom'(['DESCRIBE ',Relation],SQL),
'$make_atom'(['PRAGMA table_info(\'',Relation,'\')'],SQL),
DBMS(result_set)(Mode),
'$write_or_not'(SQL),
c_DBMS(query)(SQL,ResultSet,Conn,Mode,_),
!,
c_DBMS(row)(ResultSet,6,[A1,A2,A3,A4,A5,A6]).
DBMS(row)(ResultSet,6,[_A1,FieldID,Type,Null,Default,Primary]).
%#endif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -150,7 +135,6 @@ DBMS(describe)(Connection,Relation,tableinfo(A1,A2,A3,A4,A5,A6)) :-
DBMS(datalog_show_tables):-
DBMS(datalog_show_tables)(myddas).
DBMS(datalog_show_tables)(Connection) :-
'$error_checks'(DBMS(show_tables)(Connection)),
'$get_value'(Connection,Conn),
DBMS(result_set)(Mode),
'$write_or_not'('.tables'),
@ -162,19 +146,19 @@ DBMS(datalog_show_tables)(Connection) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DBMS(show_tables)/2
% DBMS(show_tables)/1
% gives the results of the SHOW TABLES statement
% by backtracking
DBMS(show_tables)(Table) :-
DBMS(show_tables)(myddas,Table).
%#if sqlite3
DBMS(show_tables)(Connection,table(Table)) :-
'$error_checks'(DBMS(show_tables)(Connection)),
'$get_value'(Connection,Conn),
SQL = 'SELECT name FROM sqlite_master WHERE type=\'table\' ORDER BY name',
DBMS(result_set)(Mode),
'$write_or_not'('.tables'),
c_DBMS(query)('.tables',ResultSet,Conn,Mode,_),
!,c_DBMS(row)(ResultSet,1,[Table]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'$write_or_not'(SQL),
c_DBMS(query)(SQL,ResultSet,Conn,Mode,_),
!,
DBMS(row)(ResultSet,1,[Table]).
%#endif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -246,10 +230,11 @@ DBMS(call_procedure)(Connection,Procedure,Args,LA) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DBMS(row)(ResultSet,Arity,Args) :-
setup_call_cleanup(
c_DBMS(row_initialise)(ResultSet,Arity,Args,State),
setup_call_catcher_cleanup(
c_DBMS(row_initialise)(ResultSet,State),
c_DBMS(row_get)(ResultSet,Arity,Args,State),
DBMS(row_terminate)(State)
Caught,
c_DBMS(row_terminate)(State, Caught)
).

View File

@ -166,7 +166,8 @@
'$error_checks'(db_describe(Connection,Relation,_)) :- !,
atom(Connection),
nonvar(Relation).
'$error_checks'(db_my_show_tables(_)):- !.
'$error_checks'(db_show_tables(Connection,_)):- !,
atom(Connection).
'$error_checks'(db_is_database_predicate(PredName,Arity,Module)):-!,
nonvar(PredName),
nonvar(Arity),

View File

@ -52,14 +52,15 @@ if (ANDROID)
endif (ANDROID)
add_lib( Yapsqlite3
add_library( Yapsqlite3 SHARED
${YAPSQLITE3_SOURCES} )
MY_set_target_properties(Yapsqlite3
set_target_properties(Yapsqlite3
PROPERTIES
# RPATH ${libdir} VERSION ${LIBYAPTAI_FULL_VERSION}
# SOVERSION ${LIBYAPTAI_MAJOR_VERSION}.${LIBYAPTAI_MINOR_VERSION}
POSITION_INDEPENDENT_CODE TRUE
PREFIX ""
)
target_link_libraries(Yapsqlite3 libYap)
@ -68,3 +69,9 @@ if (ANDROID)
target_link_libraries(Yapsqlite3 android log)
endif ()
install(TARGETS Yapsqlite3
RUNTIME DESTINATION ${dlls}
ARCHIVE DESTINATION ${dlls}
LIBRARY DESTINATION ${dlls}
)

View File

@ -1,44 +1,43 @@
/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: myddas_sqlite3.c *
* Last rev: 22/03/05 *
* mods: *
* comments: Predicates for comunicating with a sqlite3 database system *
* *
*************************************************************************/
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: myddas_sqlite3.c *
* Last rev: 22/03/05 *
* mods: *
* comments: Predicates for comunicating with a sqlite3 database system *
* *
*************************************************************************/
#include <sqlite3.h>
#include "Yap.h"
#include "YapEval.h"
#include "YapText.h"
#include "Yatom.h"
#include "cut_c.h"
#include "myddas.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include "Yap.h"
#include "Yatom.h"
#include "YapText.h"
#include "cut_c.h"
#include "YapEval.h"
#include "myddas.h"
#ifdef MYDDAS_STATS
#include "myddas_structs.h"
#include "myddas_statistics.h"
#include "myddas_structs.h"
#endif
//#include "myddas_wkb2prolog.h"
#define CALL_SQLITE(f) \
#define CALL_SQLITE(t, f) \
{ \
int i; \
i = sqlite3_##f; \
if (i != SQLITE_OK) { \
fprintf(stderr, "%s failed with status %d: %s\n", #f, i, \
sqlite3_errmsg(db)); \
exit(1); \
Yap_Error(EVALUATION_ERROR_DBMS, t, "%s failed with status %d: %s\n", \
#f, i, sqlite3_errmsg(db)); \
} \
}
@ -62,8 +61,8 @@ typedef struct result_set {
int length;
} resultSet;
void Yap_InitMYDDAS_SQLITE3Preds(void);
void Yap_InitBackMYDDAS_SQLITE3Preds(void);
static void Yap_InitMYDDAS_SQLITE3Preds(void);
static void Yap_InitBackMYDDAS_SQLITE3Preds(void);
static Int c_sqlite3_connect(USES_REGS1);
static Int c_sqlite3_disconnect(USES_REGS1);
@ -87,7 +86,7 @@ static Int c_sqlite3_connect(USES_REGS1) {
const char *file = AtomName(AtomOfTerm(arg_file));
CALL_SQLITE(open(file, &db));
CALL_SQLITE(ARG1, open(file, &db));
if (!Yap_unify(arg_db, MkAddressTerm(db)))
return FALSE;
@ -122,8 +121,7 @@ static MYDDAS_STATS_TIME myddas_stat_init_query(sqlite3 *db) {
return NULL;
}
static MYDDAS_STATS_TIME
myddas_stat_end_query(MYDDAS_STATS_TIME start) {
static MYDDAS_STATS_TIME myddas_stat_end_query(MYDDAS_STATS_TIME start) {
MYDDAS_STATS_TIME diff = NULL;
/* Measure time spent by the sqlite3 Server
processing the SQL Query */
@ -239,24 +237,23 @@ static Int c_sqlite3_query(USES_REGS1) {
sqlite3 *db = AddressOfTerm(arg_db);
sqlite3_stmt *stmt;
#if MYDDAS_STATS
#if MYDDAS_STATS
MYDDAS_STATS_TIME start, end;
#endif
#endif
struct result_set *rs = malloc(sizeof(struct result_set));
if (!rs)
return FALSE;
rs->db = db;
#if MYDDAS_STATS
#if MYDDAS_STATS
start = myddas_stat_init_query(db);
#endif
#endif
// printf("Query %s\n", sql);
/* Send query to server and process it */
// Leave data for extraction
CALL_SQLITE(prepare_v2(db, sql, -1, &stmt, NULL));
CALL_SQLITE(ARG1, prepare_v2(db, sql, -1, &stmt, NULL));
rs->stmt = stmt;
rs->nrows = -1;
rs->length = sqlite3_column_count(stmt);
@ -269,7 +266,6 @@ static Int c_sqlite3_query(USES_REGS1) {
return false;
}
return true;
}
static Int c_sqlite3_number_of_fields(USES_REGS1) {
@ -286,11 +282,11 @@ static Int c_sqlite3_number_of_fields(USES_REGS1) {
sprintf(sql, "SELECT * FROM `%s`", relation);
/* executar a query SQL */
CALL_SQLITE(prepare_v2(db, sql, -1, &stmt, NULL));
CALL_SQLITE(ARG1, prepare_v2(db, sql, -1, &stmt, NULL));
int fields = sqlite3_column_count(stmt);
CALL_SQLITE(finalize(stmt));
CALL_SQLITE(ARG1, finalize(stmt));
return Yap_unify(arg_fields, MkIntegerTerm(fields));
}
@ -299,8 +295,7 @@ static Int c_sqlite3_number_of_fields(USES_REGS1) {
static Int c_sqlite3_get_attributes_types(USES_REGS1) {
Term arg_relation = Deref(ARG1);
Term arg_db = Deref(ARG2);
Term arg_types_list = Deref(ARG3);
Term list, head;
Term list, tf, *tfp = &tf;
const char *relation = AtomName(AtomOfTerm(arg_relation));
sqlite3 *db = (sqlite3 *)IntegerOfTerm(arg_db);
@ -308,26 +303,22 @@ static Int c_sqlite3_get_attributes_types(USES_REGS1) {
int row;
sqlite3_stmt *stmt;
Int rc = TRUE;
sprintf(sql, "SELECT * FROM `%s`", relation);
/* executar a query SQL */
CALL_SQLITE(prepare_v2(db, sql, -1, &stmt, NULL));
CALL_SQLITE(MkStringTerm(sql), prepare_v2(db, sql, -1, &stmt, NULL));
int fields = sqlite3_column_count(stmt);
list = arg_types_list;
for (row = 0; row < fields; row++) {
const char *tm;
head = HeadOfTerm(list);
rc = (rc && Yap_unify(head, MkAtomTerm(Yap_LookupAtom(
sqlite3_column_name(stmt, row)))));
list = TailOfTerm(list);
head = HeadOfTerm(list);
list = TailOfTerm(list);
list = Yap_MkNewPairTerm();
*tfp = list;
RepPair(list)[0] =
MkAtomTerm(Yap_LookupAtom(sqlite3_column_name(stmt, row)));
tfp = RepPair(list) + 1;
int type = sqlite3_column_type(stmt, row);
switch (type) {
@ -344,17 +335,22 @@ static Int c_sqlite3_get_attributes_types(USES_REGS1) {
tm = "blob";
break;
case SQLITE_NULL:
default:
tm = "";
break;
default:
tm = "?";
break;
}
if (!Yap_unify(head, MkAtomTerm(Yap_LookupAtom(tm))))
rc = FALSE;
list = Yap_MkNewPairTerm();
*tfp = list;
RepPair(list)[0] = MkAtomTerm(Yap_LookupAtom(tm));
tfp = RepPair(list) + 1;
tfp = RepPair(list) + 1;
}
*tfp = TermNil;
CALL_SQLITE(ARG1, finalize(stmt));
CALL_SQLITE(finalize(stmt));
return rc;
return Yap_unify(tf, ARG3);
}
/* db_disconnect */
@ -401,7 +397,7 @@ static Int c_sqlite3_get_fields_properties(USES_REGS1) {
/* executar a query SQL */
// printf(" SQL 4: %s\n", sql);
CALL_SQLITE(prepare_v2(db, sql, -1, &stmt, NULL));
CALL_SQLITE(ARG1, prepare_v2(db, sql, -1, &stmt, NULL));
Functor functor = Yap_MkFunctor(Yap_LookupAtom("property"), 4);
@ -419,7 +415,8 @@ static Int c_sqlite3_get_fields_properties(USES_REGS1) {
const char *col = sqlite3_column_name(stmt, i);
properties[0] = MkAtomTerm(Yap_LookupAtom(col));
CALL_SQLITE(table_column_metadata(db, NULL, relation, col, NULL, NULL,
CALL_SQLITE(properties[0],
table_column_metadata(db, NULL, relation, col, NULL, NULL,
&not_null, &prim, &auto_inc));
properties[1] = MkIntegerTerm(not_null); // Can't be NULL
@ -484,7 +481,7 @@ static Int c_sqlite3_row_terminate(USES_REGS1) {
struct result_set *res_set = rs->res_set;
sqlite3 *db = res_set->db;
// no more data
CALL_SQLITE(finalize(res_set->stmt));
CALL_SQLITE(ARG1, finalize(res_set->stmt));
free(res_set);
free(rs);
return true;
@ -500,14 +497,12 @@ static Int c_sqlite3_row_initialise(USES_REGS1) {
start = myddas_stats_walltime();
#endif
Term arg_result_set = Deref(ARG1);
// Term arg_arity = Deref(ARG2);
// Term arg_list_args = Deref(ARG3);
struct result_set *res_set;
struct row_state *rs = malloc( sizeof( struct row_state ));
struct row_state *rs = malloc(sizeof(struct row_state));
if (rs == NULL) {
Yap_Error(RESOURCE_ERROR_HEAP, ARG1, "sqlite3_row");
} else {
if (!Yap_unify(ARG4, MkAddressTerm(rs)))
if (!Yap_unify(ARG2, MkAddressTerm(rs)))
return false;
}
@ -546,7 +541,9 @@ static Int c_sqlite3_row(USES_REGS1) {
// busy-waiting
int res;
if ((res = sqlite3_step(res_set->stmt)) == SQLITE_BUSY)
Yap_Error(SYSTEM_ERROR_INTERNAL, ARG1, "sqlite3_row deadlocked (SQLITE_BUSY)");;
Yap_Error(SYSTEM_ERROR_INTERNAL, ARG1,
"sqlite3_row deadlocked (SQLITE_BUSY)");
;
if (res == SQLITE_DONE) {
#ifdef MYDDAS_STATS
end = myddas_stats_walltime();
@ -584,15 +581,14 @@ static Int c_sqlite3_row(USES_REGS1) {
break;
case SQLITE_TEXT:
tf = MkAtomTerm(Yap_LookupAtom(
(const char *) sqlite3_column_text(res_set->stmt, i)));
(const char *)sqlite3_column_text(res_set->stmt, i)));
break;
case SQLITE_BLOB: {
size_t bytes = sqlite3_column_bytes(res_set->stmt, i);
void *pt;
tf = Yap_AllocExternalDataInStack(EXTERNAL_BLOB, bytes, &pt);
memcpy(pt, sqlite3_column_blob(res_set->stmt, i), bytes);
}
break;
} break;
case SQLITE_NULL:
null_atom[0] = MkIntegerTerm(null_id++);
tf = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("null"), 1), 1,
@ -625,8 +621,7 @@ static Int c_sqlite3_row(USES_REGS1) {
return rc;
}
void Yap_InitMYDDAS_SQLITE3Preds(void) {
static void Yap_InitMYDDAS_SQLITE3Preds(void) {
/* db_dbect: Host x User x Passwd x Database x dbection x ERROR_CODE */
Yap_InitCPred("c_sqlite3_connect", 4, c_sqlite3_connect, 0);
@ -659,30 +654,24 @@ void Yap_InitMYDDAS_SQLITE3Preds(void) {
/* c_sqlite3_change_database: connection x DataBaseName */
Yap_InitCPred("c_sqlite3_change_database", 2, c_sqlite3_change_database, 0);
}
void Yap_InitBackMYDDAS_SQLITE3Preds(void) {
static void Yap_InitBackMYDDAS_SQLITE3Preds(void) {
/* db_row: ResultSet x Arity x ListOfArgs */
Yap_InitCPredBack("c_sqlite3_row", 3, 0, c_sqlite3_row,
c_sqlite3_row, 0);
Yap_InitCPred("c_sqlite3_row_initialize", 3, c_sqlite3_row_initialise, 0);
Yap_InitCPred("c_sqlite3_row_terminate", 3, c_sqlite3_row_terminate, 0);
Yap_InitCPredBack("c_sqlite3_row", 3, 0, c_sqlite3_row,
c_sqlite3_row, 0);
// Yap_InitCPredBack("c_sqlite3_row", 3, 0, c_sqlite3_row_initialise,
// c_sqlite3_row, c_sqlite3_row_terminate);
Yap_InitCPred("c_sqlite3_row_initialise", 2, c_sqlite3_row_initialise, 0);
Yap_InitCPred("c_sqlite3_row_terminate", 1, c_sqlite3_row_terminate, 0);
Yap_InitCPredBack("c_sqlite3_row_get", 4, 0, c_sqlite3_row, c_sqlite3_row, 0);
}
void init_sqlite3( void )
{
X_API void init_sqlite3(void) {
Yap_InitMYDDAS_SQLITE3Preds();
Yap_InitBackMYDDAS_SQLITE3Preds();
}
#if _ANDROID_
JNIEXPORT void JNICALL
lib_yap_up_pt_init_sqlite(JNIEnv *env);
JNIEXPORT void JNICALL lib_yap_up_pt_init_sqlite(JNIEnv *env);
JNIEXPORT void JNICALL
lib_yap_up_pt_init_sqlite(JNIEnv *env)
{
JNIEXPORT void JNICALL lib_yap_up_pt_init_sqlite(JNIEnv *env) {
init_sqlite3();
}

View File

@ -0,0 +1,81 @@
:- [library(myddas)].
:- initialization(main).
main :-
setup_call_cleanup(
init,
main_ ,
(trace,
close)).
main_ :-
go,
fail.
main_ .
init :-
db_open(sqlite3, '~/Yap/Chinook/Chinook_Sqlite.sqlite', _, _),
db_import('Artist', artist),
db_import('Album', album),
db_import('Track', track).
go :-
db_get_attributes_types(album,Als),
db_get_attributes_types(track,Ts),
db_get_attributes_types(artist,As),
writeln(As:Als:Ts).
go :-
db_number_of_fields(album,Als),
db_number_of_fields(track,Ts),
db_number_of_fields(artist,As),
writeln(As:Als:Ts).
go :-
db_describe(album, Desc), writeln(Desc) ;
db_describe(track, Desc), writeln(Desc) ;
db_describe(artist, Desc), writeln(Desc).
go :-
db_show_tables(Desc), writeln(Desc).
go :-
db_show_tables(table(T)),
db_describe(T,tableinfo(FieldID,Type,Null,Primary,Default,'')),
writeln(T:tableinfo(FieldID,Type,Null,Primary,Default,'')).
go :-
go_cut0.
go :-
%stop_low_level_trace,
findall(X:Y,artist(X,Y),Ls),
length(Ls,Total),
sort(Ls, LLs),
length(LLs, T),
writeln(T:Total).
go :-
go_cut1.
go :-
X=1,
artist(X,Y),
writeln(X:Y).
go_cut0 :-
% start_low_level_trace,
artist(X,Y),
writeln(X:Y),
!.
go_cut1 :-
X=1,
artist(X,Y),
writeln(X:Y),
!.
close :-
db_close.