basic myddas with SQLITE3

This commit is contained in:
Vitor Santos Costa 2015-02-14 11:35:07 +00:00
parent 071bb36f0e
commit ada2ad44de
11 changed files with 346 additions and 281 deletions

View File

@ -4,7 +4,7 @@
/* myddas_initialization.c */
MYDDAS_GLOBAL myddas_init_initialize_myddas(void);
MYDDAS_UTIL_CONNECTION myddas_init_initialize_connection(void *,void *,MYDDAS_UTIL_CONNECTION);
MYDDAS_UTIL_CONNECTION myddas_init_initialize_connection(void *,void *,MYDDAS_API,MYDDAS_UTIL_CONNECTION);
MYDDAS_UTIL_PREDICATE myddas_init_initialize_predicate(char *, int, char *,MYDDAS_UTIL_PREDICATE);
#ifdef MYDDAS_STATS
@ -19,7 +19,7 @@ void myddas_stats_delete_stats_list(MYDDAS_STATS_STRUCT);
void myddas_util_table_write(MYSQL_RES *);
#endif
Short myddas_util_connection_type(void *);
MYDDAS_UTIL_CONNECTION myddas_util_add_connection(void *,void *);
MYDDAS_UTIL_CONNECTION myddas_util_add_connection(void *,void *,MYDDAS_API);
MYDDAS_UTIL_CONNECTION myddas_util_search_connection(void *);
void myddas_util_delete_connection(void *);
MYDDAS_UTIL_CONNECTION myddas_util_add_predicate(char * ,Int , char *,void *);

View File

@ -157,6 +157,7 @@ typedef void *MYDDAS_STATS_TIME;
NUMBER = Yap_REGS.MYDDAS_GLOBAL_POINTER->memory_freed;
#endif
#include "myddas_structs.h"
#include "MyddasProto.h"

View File

@ -7,7 +7,6 @@
#endif
#include "Yap.h"
#include "myddas.h"
#include "myddas_structs.h"
#ifdef MYDDAS_STATS
#include "myddas_statistics.h"
#endif
@ -19,7 +18,7 @@ myddas_init_initialize_myddas(void){
/* We cannot call MYDDAS_MALLOC were because the global
register isn't yet initialized */
global = (MYDDAS_GLOBAL) malloc (sizeof(struct myddas_global));
#ifdef DEBUG
#ifdef DEBUGX
printf ("MALLOC %p %s %d\n",global,__FILE__,__LINE__);
#endif
global->myddas_top_connections = NULL;
@ -53,6 +52,7 @@ myddas_init_initialize_myddas(void){
/* Inserts the new node on the front of the list */
MYDDAS_UTIL_CONNECTION
myddas_init_initialize_connection(void *conn,void *enviromment,
MYDDAS_API api,
MYDDAS_UTIL_CONNECTION next){
CACHE_REGS
MYDDAS_UTIL_CONNECTION new = NULL;
@ -62,6 +62,7 @@ myddas_init_initialize_connection(void *conn,void *enviromment,
{
return NULL;
}
new->api = api;
new->predicates=NULL;
new->connection=conn;
new->odbc_enviromment=enviromment;

View File

@ -149,7 +149,7 @@ c_db_my_connect( USES_REGS1 ) {
else
{
/* Criar um novo no na lista de ligacoes*/
new = myddas_util_add_connection(conn,NULL);
new = myddas_util_add_connection(conn,NULL,MYDDAS_API);
if (new == NULL){
#ifdef DEBUG
@ -515,7 +515,7 @@ c_db_my_row( USES_REGS1 ) {
for (i = 0; i < arity; i++)
{
/* Aqui ser<65>o feitas as convers<72>es de tipos de dados */
/* Here we perform data type conversion. */
field = mysql_fetch_field(res_set);
head = HeadOfTerm(list);
list = TailOfTerm(list);

View File

@ -348,7 +348,7 @@ c_db_odbc_connect( USES_REGS1 ) {
{
/* Criar um novo no na lista de ligacoes*/
//new = add_connection(&TOP,hdbc,henv);
new = myddas_util_add_connection(hdbc,henv);
new = myddas_util_add_connection(hdbc,henv,MYDDAS_ODBC);
if (new == NULL){
fprintf(stderr,"Error: could not allocate list memory\n");
return FALSE;

View File

@ -22,7 +22,6 @@
#include "cut_c.h"
#include "myddas.h"
#include <stdlib.h>
#include "myddas_structs.h"
#ifdef MYDDAS_STATS
#include "myddas_statistics.h"
#endif
@ -121,19 +120,26 @@ c_db_initialize_myddas( USES_REGS1 ){
static Int
c_db_connection_type ( USES_REGS1 ){
Term arg_con = Deref(ARG1);
Term arg_type = Deref(ARG2);
Term arg_type =ARG2;
Int *con = (Int *) IntegerOfTerm(arg_con);
Int type = myddas_util_connection_type(con);
MYDDAS_API type = myddas_util_connection_type(con);
if (type == 1) /* MYSQL Connection */
Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("mysql")));
else if (type ==2) /* ODBC Connection */
Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("odbc")));
else /* Not a valid connection*/
return FALSE;
return TRUE;
switch (type) {
case API_MYSQL:
/* MYSQL Connection */
return Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("mysql")));
case API_ODBC:
/* ODBC Connection */
return Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("odbc")));
case API_SQLITE3:
/* SQLITE3 Connection */
return Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("sqlite3")));
case API_POSTGRES:
/* SQLITE3 Connection */
return Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("postgres")));
}
return Yap_Error(SYSTEM_ERROR, TermNil, "Unverified DBMS");
}
/* db_add_preds: PredName * Arity * Module * Connection*/

View File

@ -54,7 +54,7 @@
exit (1); \
} \
} \
static Int null_id = 0;
typedef struct result_set {
@ -66,7 +66,7 @@ typedef struct result_set {
} resultSet;
void Yap_InitMYDDAS_SQLITE3Preds(void);
void Yap_InitBackMYDDAS_SQLITE3Preds(void);
void Yap_InitBackMYDDAS_SQLITE3Preds(void);
static Int c_sqlite3_connect( USES_REGS1 );
@ -85,7 +85,7 @@ static Int c_sqlite3_change_database( USES_REGS1 );
void Yap_InitMYDDAS_SQLITE3Preds(void)
{
/* db_dbect: Host x User x Passwd x Database x dbection x ERROR_CODE */
Yap_InitCPred("c_db_sqlite3_connect", 4, c_sqlite3_connect, 0);
Yap_InitCPred("c_sqlite3_connect", 4, c_sqlite3_connect, 0);
/* db_number_of_fields: Relation x connection x NumberOfFields */
Yap_InitCPred("c_sqlite3_number_of_fields",3, c_sqlite3_number_of_fields, 0);
@ -104,7 +104,7 @@ void Yap_InitMYDDAS_SQLITE3Preds(void)
/* db_get_fields_properties: PredName x connection x PropertiesList*/
Yap_InitCPred("c_sqlite3_get_fields_properties",3,c_sqlite3_get_fields_properties,0);
Yap_InitCPred("c_sqlite3_get_next_result_set",2,c_sqlite3_get_next_result_set,0);
/* c_sqlite3_get_database: connection x DataBaseName */
@ -144,7 +144,7 @@ c_sqlite3_connect( USES_REGS1 ) {
else
{
/* Criar um novo no na lista de ligacoes*/
new = myddas_util_add_connection(db,NULL);
new = myddas_util_add_connection(db,NULL,API_SQLITE3);
if (new == NULL){
#ifdef DEBUG
@ -191,10 +191,10 @@ myddas_stat_end_query( MYDDAS_STATS_TIME start )
MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy);
myddas_stats_subtract_time(diff,end,start);
diff = myddas_stats_time_copy_to_final(diff);
MYDDAS_FREE(end,struct myddas_stats_time_struct);
MYDDAS_FREE(start,struct myddas_stats_time_struct);
MYDDAS_STATS_CON_GET_TOTAL_TIME_DBSERVER(node,total_time);
/* Automacally updates the MYDDAS_STRUCTURE */
myddas_stats_add_time(total_time,diff,total_time);
@ -253,7 +253,7 @@ myddas_stat_transfer_query( MYDDAS_STATS_TIME diff )
MyddasUInt numberRows = sqlite3_num_rows(res_set);
MyddasUInt rows;
myddas_stat_transfer_query( diff );
MYDDAS_STATS_CON_GET_TOTAL_ROWS(node,rows);
numberRows = numberRows + rows;
MYDDAS_STATS_CON_SET_TOTAL_ROWS(node,numberRows);
@ -285,7 +285,7 @@ myddas_stat_transfer_query( MYDDAS_STATS_TIME diff )
MYDDAS_STATS_CON_SET_TOTAL_BYTES_TRANSFERING_FROM_DBSERVER_COUNT(node,++count);
}
}
#endif
#endif
/* db_query: SQLQuery x ResultSet x connection */
static Int
@ -300,19 +300,20 @@ c_sqlite3_query( USES_REGS1 ) {
char *mode = AtomName(AtomOfTerm(arg_mode));
sqlite3 *db = AddressOfTerm(arg_db);
sqlite3_stmt *stmt;
MYDDAS_STATS_TIME start, end;
MYDDAS_STATS_TIME start, end;
int length=strlen(sql);
struct result_set *rs = malloc(sizeof( struct result_set));
if (!rs)
return FALSE;
rs->db = db;
rs->db = db;
start = myddas_stat_init_query( db );
/* Send query to server and process it */
if (strcmp(mode,"store_result")!=0) {
// Leave data for extraction
printf(" SQL 0: %s\n", sql);
CALL_SQLITE (prepare_v2(db, sql, -1, &stmt, NULL) );
rs->stmt = stmt;
rs->res_set = NULL;
@ -334,10 +335,10 @@ c_sqlite3_query( USES_REGS1 ) {
char **res_set;
char *msg;
int nrows;
CALL_SQLITE (get_table(db, sql, &res_set, &nrows, &length, &msg) );
end = myddas_stat_end_query( start );
//end = myddas_stat_end_query( start );
if (res_set == NULL)
{
#ifdef DEBUG
@ -378,18 +379,19 @@ c_sqlite3_number_of_fields( USES_REGS1 ) {
char *relation = AtomName(AtomOfTerm(arg_relation));
sqlite3 *db = AddressOfTerm(arg_db);
sqlite3_stmt *stmt;
char sql[256];
sprintf(sql,"SELECT * FROM TABLE `%s`",relation);
sprintf(sql,"SELECT * FROM `%s`",relation);
/* executar a query SQL */
CALL_SQLITE (prepare_v2(db, sql, -1, &stmt, NULL) );
printf(" SQL 1: %s\n", sql);
CALL_SQLITE (prepare_v2(db, sql, -1, &stmt, NULL) );
int fields = sqlite3_column_count( stmt );
CALL_SQLITE (finalize( stmt ) );
return Yap_unify(arg_fields, MkIntegerTerm( fields ));
}
@ -409,12 +411,13 @@ c_sqlite3_get_attributes_types( USES_REGS1 ) {
sqlite3_stmt *stmt;
Int rc = TRUE;
sprintf(sql,"SELECT * FROM TABLE `%s`",relation);
sprintf(sql,"SELECT * FROM `%s`",relation);
/* executar a query SQL */
printf(" SQL 3: %s\n", sql);
CALL_SQLITE (prepare_v2(db, sql, -1, &stmt, NULL) );
int fields = sqlite3_column_count( stmt );
list = arg_types_list;
@ -422,7 +425,7 @@ c_sqlite3_get_attributes_types( USES_REGS1 ) {
for (row = 0; row < fields; row++)
{
const char *tm;
head = HeadOfTerm(list);
rc = (
@ -446,7 +449,8 @@ c_sqlite3_get_attributes_types( USES_REGS1 ) {
tm = "blob";
break;
case SQLITE_NULL:
tm = "null";
default:
tm = "";
break;
}
if (!Yap_unify(head, MkAtomTerm(Yap_LookupAtom(tm))) )
@ -454,7 +458,7 @@ c_sqlite3_get_attributes_types( USES_REGS1 ) {
}
CALL_SQLITE (finalize( stmt ) );
return rc;
}
@ -504,10 +508,11 @@ c_sqlite3_get_fields_properties( USES_REGS1 ) {
sqlite3 *db = (sqlite3 *) (IntegerOfTerm(arg_db));
sqlite3_stmt *stmt;
sprintf(sql,"SELECT * FROM TABLE `%s`",relation);
sprintf(sql,"SELECT * FROM `%s`",relation);
/* executar a query SQL */
printf(" SQL 4: %s\n", sql);
CALL_SQLITE (prepare_v2(db, sql, -1, &stmt, NULL) );
Functor functor = Yap_MkFunctor(Yap_LookupAtom("property"),4);
@ -521,7 +526,7 @@ c_sqlite3_get_fields_properties( USES_REGS1 ) {
for (i=0;i<num_fields;i++)
{
int not_null, prim, auto_inc;
head = HeadOfTerm(list);
const char *col = sqlite3_column_name(stmt, i);
@ -532,9 +537,9 @@ c_sqlite3_get_fields_properties( USES_REGS1 ) {
properties[1] = MkIntegerTerm(not_null); //Can't be NULL
properties[2] = MkIntegerTerm(prim); //It''s a primary key
properties[3] = MkIntegerTerm(auto_inc);
list = TailOfTerm(list);
if (!Yap_unify(head, Yap_MkApplTerm(functor,4,properties))){
return FALSE;
@ -590,9 +595,9 @@ c_sqlite3_change_database( USES_REGS1 ) {
static Int
c_sqlite3_row_cut( USES_REGS1 ) {
struct result_set *res_set=NULL;
res_set = AddressOfTerm(CBACK_CUT_ARG(1));
sqlite3 *db = res_set->db;
res_set = AddressOfTerm(EXTRA_CBACK_CUT_ARG(Term,1));
CALL_SQLITE( finalize( res_set->stmt ) );
free(res_set);
return TRUE;
@ -614,7 +619,7 @@ c_sqlite3_row( USES_REGS1 ) {
//MYDDAS_STATS_TIME start,end,total_time,diff;
MyddasULInt count = 0;
start = myddas_stats_walltime();
#endif
#endif
Term arg_result_set = Deref(ARG1);
Term arg_arity = Deref(ARG2);
Term arg_list_args = Deref(ARG3);
@ -625,11 +630,11 @@ c_sqlite3_row( USES_REGS1 ) {
cut_fail();
}
arg_result_set = Deref(ARG1);
EXTRA_CBACK_ARG(3,1)= arg_result_set ;
EXTRA_CBACK_ARG(3,2)= MkIntegerTerm(0) ;
EXTRA_CBACK_ARG(3,1)= arg_result_set ;
EXTRA_CBACK_ARG(3,2)= MkIntegerTerm(0) ;
}
struct result_set *res_set = (struct result_set *) IntegerOfTerm(arg_result_set);
struct result_set *res_set = AddressOfTerm(arg_result_set);
Term head, list, null_atom[1];
Int i, arity;
list = arg_list_args;
@ -637,13 +642,13 @@ c_sqlite3_row( USES_REGS1 ) {
sqlite3 *db = res_set->db;
if (res_set->stmt == NULL ) {
CACHE_REGS
Int indx = IntegerOfTerm(EXTRA_CBACK_CUT_ARG(Term,2));
Int indx = IntegerOfTerm(EXTRA_CBACK_ARG(3,2));
Int rc = true;
// data needs to be copied to Prolog
// row by row
#ifdef MYDDAS_STATS
MYDDAS_STATS_TIME diff;
MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy);
#endif
while (indx/arity < res_set->nrows)
@ -673,27 +678,27 @@ c_sqlite3_row( USES_REGS1 ) {
free(res_set);
#ifdef MYDDAS_STATS
end = myddas_stats_walltime();
MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy);
myddas_stats_subtract_time(diff,end,start);
diff = myddas_stats_time_copy_to_final(diff);
MYDDAS_FREE(end,struct myddas_stats_time_struct);
MYDDAS_FREE(start,struct myddas_stats_time_struct);
MYDDAS_STATS_GET_DB_ROW_FUNCTION(total_time);
myddas_stats_add_time(total_time,diff,total_time);
MYDDAS_STATS_GET_DB_ROW_FUNCTION_COUNT(count);
MYDDAS_STATS_SET_DB_ROW_FUNCTION_COUNT(++count);
MYDDAS_FREE(diff,struct myddas_stats_time_struct);
#endif /* MYDDAS_STATS */
cut_fail(); /* This macro already does a return FALSE */
} else if (res == SQLITE_ROW) {
list = arg_list_args;
Term tf;
for (i = 0; i < arity; i++)
{
/* convert data types here */
@ -723,23 +728,23 @@ c_sqlite3_row( USES_REGS1 ) {
tf = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("null"),1),1,null_atom);
break;
}
if (!Yap_unify(head, tf))
rc = FALSE;
}
if (!Yap_unify(head, tf))
rc = FALSE;
#ifdef MYDDAS_STATS
end = myddas_stats_walltime();
myddas_stats_subtract_time(diff,end,start);
diff = myddas_stats_time_copy_to_final(diff);
MYDDAS_FREE(end,struct myddas_stats_time_struct);
MYDDAS_FREE(start,struct myddas_stats_time_struct);
MYDDAS_STATS_GET_DB_ROW_FUNCTION(total_time);
myddas_stats_add_time(total_time,diff,total_time);
MYDDAS_STATS_GET_DB_ROW_FUNCTION_COUNT(count);
MYDDAS_STATS_SET_DB_ROW_FUNCTION_COUNT(++count);
MYDDAS_FREE(diff,struct myddas_stats_time_struct);
#endif /* MYDDAS_STATS */
} else

View File

@ -36,9 +36,17 @@ struct myddas_list_preds {
MYDDAS_UTIL_PREDICATE previous;
};
typedef enum myddas_api {
API_MYSQL = 0,
API_ODBC = 1,
API_SQLITE3 = 2,
API_POSTGRES } MYDDAS_API;
struct myddas_list_connection {
void *connection;
int tag;
MYDDAS_API api;
/*If variable env is NULL, then it's a
MySQL connection, if not then it as the pointer
to the ODBC enviromment variable */

View File

@ -49,10 +49,11 @@ myddas_util_connection_type(void *con){
if (con_node == NULL)
return 0;
if (con_node->odbc_enviromment != NULL) /* ODBC */
return 2;
else
return 1;
return con_node->api;
// if (con_node->odbc_enviromment != NULL) /* ODBC */
// return 2;
//else
// return 1;
}
@ -161,7 +162,7 @@ myddas_util_search_connection(void *conn){
}
MYDDAS_UTIL_CONNECTION
myddas_util_add_connection(void *conn, void *enviromment){
myddas_util_add_connection(void *conn, void *enviromment, MYDDAS_API api){
CACHE_REGS
MYDDAS_UTIL_CONNECTION node=NULL;
MYDDAS_UTIL_CONNECTION temp=NULL;
@ -171,7 +172,7 @@ myddas_util_add_connection(void *conn, void *enviromment){
return node;
}
//put the new connection node on the top of the list
temp = myddas_init_initialize_connection(conn,enviromment,Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections);
temp = myddas_init_initialize_connection(conn,enviromment,api,Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections);
if (temp == NULL)
{
#ifdef DEBUG
@ -354,7 +355,7 @@ myddas_util_get_pred_name(void *pointer){
}
char *
myddas_util_get_pred_module(void *pointer){
vmyddas_util_get_pred_module(void *pointer){
MYDDAS_UTIL_PREDICATE temp = (MYDDAS_UTIL_PREDICATE) pointer;
return temp->pred_module;
}
@ -383,7 +384,7 @@ void check_int( void ){
if (top->predicates != NULL)
{
printf ("\t******\n");
printf ("\t===== PREDICADOS =====\n");
printf ("\t===== PREDICATES =====\n");
for (pred = top->predicates ; pred != NULL ; pred = pred->next)
{
printf ("\t--------------\n");

View File

@ -1,4 +1,4 @@
/*************************************************************************
/*************************************************************************
* *
* YAP Prolog *
* *
@ -31,7 +31,7 @@
db_open/4,
db_close/1,
db_close/0,
db_verbose/1,
db_module/1,
db_is_database_predicate/3,
@ -40,7 +40,7 @@
db_stats/2,
db_stats_time/2,
#endif
db_sql/2,
db_sql/2,
db_sql/3,
db_sql_select/3,
db_prolog_select/2,
@ -76,7 +76,7 @@
db_abolish/2,
db_listing/0,
db_listing/1
#ifdef MYDDAS_MYSQL
#ifdef MYDDAS_MYSQL
% myddas_mysql.ypp
,
db_my_result_set/1,
@ -129,23 +129,23 @@ At the same time, without any problem. The MYDDAS system automatically
controls the two options. Currently, MYDDAS is know to compile without
problems in Linux. The usage of this system on Windows has not been
tested yet. MYDDAS must be enabled at configure time. This can be done
with the following options:
with the following options:
+ --enable-myddas
This option will detect which development libraries are installed on the computer system, MySQL, ODBC or both, and will compile the Yap system with the support for which libraries it detects;
+ --enable-myddas-stats
This option is only available in MySQL. It includes code to get
statistics from the MYDDAS system;
+ --enable-top-level
This option is only available in MySQL. It enables the option to interact with the MySQL server in
two different ways. As if we were on the MySQL Client Shell, and as if
we were using Datalog.
we were using Datalog.
*/
@ -162,7 +162,7 @@ MySQL interface rather than on the ODBC interface. If you want to use
the full power of the MYDDAS interface we recommend you to use a MySQL
database. Other databases, such as Oracle, PostGres or Microsoft SQL
Server, can be interfaced through the ODBC layer, but with limited
performance and features support.
performance and features support.
The main structure of the MYDDAS interface is simple. Prolog queries
involving database goals are translated to SQL using the Prolog to SQL
@ -181,25 +181,25 @@ defined in database as relations.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Name = 'John Doe',
Number = 123456789 ?
Number = 123456789 ?
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Backtracking can then be used to retrieve the next row
of the relation phonebook. Records with particular field values may be
selected in the same way as in Prolog. (In particular, no mode
specification for database predicates is required). For instance:
specification for database predicates is required). For instance:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- phonebook(Letter,'John Doe',Letter).
Letter = 'D',
?- phonebook(Letter,'John Doe',Letter).
Letter = 'D',
Number = 123456789 ?
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generates the query
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT A.Letter , 'John Doe' , A.Number
FROM 'phonebook' A
SELECT A.Letter , 'John Doe' , A.Number
FROM 'phonebook' A
WHERE A.Name = 'John Doe';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -215,7 +215,7 @@ WHERE A.Name = 'John Doe';
*/
/**
@pred db view(+,+,+).
@pred db view(+,+,+).
@ -225,15 +225,15 @@ WHERE A.Name = 'John Doe';
If we import a database relation, such as an edge relation representing the edges of a directed graph, through
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_import('Edge',edge).
?- db_import('Edge',edge).
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
and we then write a query to retrieve all the direct cycles in the
sqliand we then write a query to retrieve all the direct cycles in the
graph, such as
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- edge(A,B), edge(B,A).
A = 10,
?- edge(A,B), edge(B,A).
A = 10,
B = 20 ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
this is clearly inefficient [3], because of relation-level
@ -253,7 +253,7 @@ predicates. One can use the view level interface through the predicates
db_view/3 and `db_view/2`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_view(Conn,PredName(Arg_1,...,Arg_n),DbGoal).
?- db_view(Conn,PredName(Arg_1,...,Arg_n),DbGoal).
?- db_view(PredName(Arg_1,...,Arg_n),DbGoal).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All arguments are standard Prolog terms. _Arg1_ through _Argn_
@ -263,28 +263,28 @@ conditions. _Conn_ is the connection identifier, which again can be
dropped. Calling predicate `PredName/n` will retrieve database
tuples using a single SQL query generated for the _DbGoal_. We next show
an example of a view definition for the direct cycles discussed
above. Assuming the declaration:
above. Assuming the declaration:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_import('Edge',edge).
?- db_import('Edge',edge).
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
we
write:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_view(direct_cycle(A,B),(edge(A,B), edge(B,A))).
yes
?- direct_cycle(A,B)).
A = 10,
B = 20 ?
?- db_view(direct_cycle(A,B),(edge(A,B), edge(B,A))).
yes
?- direct_cycle(A,B)).
A = 10,
B = 20 ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This call generates the SQL
statement:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT A.attr1 , A.attr2
FROM Edge A , Edge B
FROM Edge A , Edge B
WHERE B.attr1 = A.attr2 AND B.attr2 = A.attr1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -299,24 +299,24 @@ instance:
generates the query :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT COUNT(A.attr2)
SELECT COUNT(A.attr2)
FROM Edge A WHERE A.attr1 = 10;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To know how to use db `view/3`, please refer to Draxler's Prolog to
SQL Compiler Manual.
SQL Compiler Manual.
*/
%% @}
/** @defgroup Accessing_Tables_in_Data_Sources_Using_SQL Accessing Tables in Data Sources Using SQL
/** @defgroup Accessing_Tables_in_Data_Sources_Using_SQL Accessing Tables in Data Sources Using SQL
@ingroup MYDDAS
@{
*/
/** @pred db_sql(+,+,?).
/** @pred db_sql(+,+,?).
@ -351,7 +351,7 @@ LA = ['D','John Doe',123456789] ?
*/
/** @pred db_assert(+,+).
/** @pred db_assert(+,+).
@pred db_assert(+).
@ -372,10 +372,10 @@ constants. For example assuming `helloWorld` is imported through
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_import('Hello World',helloWorld).
yes
?- db_assert(helloWorld('A' ,'Ana',31)).
?- db_assert(helloWorld('A' ,'Ana',31)).
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This, would generate the following query
This, would generate the following query
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
INSERT INTO helloWorld
@ -397,8 +397,8 @@ Would insert the row: `A,null value,31` into the relation
*/
/** @pred db insert(+,+,+).
@pred db insert(+,+).
/** @pred db insert(+,+,+).
@pred db insert(+,+).
@ -412,10 +412,10 @@ any given tuple into the database.
This would create a new predicate with name _PredName_, that will
insert tuples into the relation _RelationName_. is the connection
identifier. For example, if we wanted to insert the new tuple
`('A',null,31)` into the relation `Hello World`, we do:
`('A',null,31)` into the relation `Hello World`, we do:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_insert('Hello World',helloWorldInsert).
?- db_insert('Hello World',helloWorldInsert).
yes
?- helloWorldInsert('A',NULL,31).
yes
@ -425,52 +425,52 @@ yes
%% @}
/** @defgroup Types_of_Attributes Types of AttributesL
/** @defgroup Types_of_Attributes Types of AttributesL
@ingroup MYDDAS
@{
*/
/** @pred db_get_attributes_types(+,+,?).
/** @pred db_get_attributes_types(+,+,?).
@pred db_get_attributes_types(+,?).
@pred db_get_attributes_types(+,?).
The prototype for this predicate is the following:
The prototype for this predicate is the following:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_get_attributes_types(Conn,RelationName,ListOfFields).
?- db_get_attributes_types(RelationName,ListOfFields).
?- db_get_attributes_types(RelationName,ListOfFields).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You 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:
relation. For example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_get_attributes_types(myddas,'Hello World',LA).
LA = ['Number',integer,'Name',string,'Letter',string] ?
LA = ['Number',integer,'Name',string,'Letter',string] ?
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where <tt>Hello World</tt> is the name of the relation and <tt>myddas</tt> is the
connection identifier.
connection identifier.
*/
%% @}
/** @defgroup Number_of_Fields Number of Fields
/** @defgroup Number_of_Fields Number of Fields
@ingroup MYDDAS
@{
*/
/** @pred db_number_of_fields(+,?).
/** @pred db_number_of_fields(+,?).
@pred db_number_of_fields(+,+,?).
@ -480,16 +480,16 @@ predicate is the following:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_number_of_fields(Conn,RelationName,Arity).
?- db_number_of_fields(RelationName,Arity).
?- 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:
relation. Example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_number_of_fields(myddas,'Hello World',Arity).
Arity = 3 ?
yes
?- 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.
@ -506,7 +506,7 @@ relation and `myddas` is the connection identifier.
*/
/** @pred db_datalog_describe(+,+).
/** @pred db_datalog_describe(+,+).
@pred db_datalog_describe(+).
@ -516,8 +516,8 @@ value. It simply prints to the screen the result of the MySQL describe
command, the same way as `DESCRIBE` in the MySQL prompt would.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_datalog_describe(myddas,'Hello World').
+----------+----------+------+-----+---------+-------+
?- db_datalog_describe(myddas,'Hello World').
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
+ Number | int(11) | YES | | NULL | |
@ -529,7 +529,7 @@ yes
*/
/** @pred db_describe(+,+).
/** @pred db_describe(+,+).
@ -541,9 +541,9 @@ difference. The results are returned by backtracking. For example, the
last query:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_describe(myddas,'Hello World',Term).
?- db_describe(myddas,'Hello World',Term).
Term = tableInfo('Number',int(11),'YES','',null(0),'') ? ;
Term = tableInfo('Name',char(10),'YES','',null(1),'' ? ;
Term = tableInfo('Name',char(10),'YES','',null(1),'' ? ;
Term = tableInfo('Letter',char(1),'YES','',null(2),'') ? ;
no
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -566,7 +566,7 @@ no
If we need to know what relations exists in a given MySQL Schema, we can use
the `db_datalog_show_tables/1` predicate. As <tt>db_datalog_describe/2</tt>,
it does not returns any value, but instead prints to the screen the result of the
`SHOW TABLES` command, the same way as it would be in the MySQL prompt.
`SHOW TABLES` command, the same way as it would be in the MySQL prompt.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_datalog_show_tables(myddas).
@ -574,13 +574,13 @@ it does not returns any value, but instead prints to the screen the result of th
| Tables_in_guest |
+-----------------+
| Hello World |
+-----------------+
+-----------------+
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/** @pred db_show_tables(+, ?).
/** @pred db_show_tables(+, ?).
@ -611,7 +611,7 @@ no
*/
/**
@pred db_top_level(+,+,+,+,+).
@pred db_top_level(+,+,+,+,+).
@pred db_top_level(+,+,+,+).
@ -619,14 +619,14 @@ no
Through MYDDAS is also possible to access the MySQL Database Server, in
the same wthe mysql client. In this mode, is possible to query the
SQL server by just using the standard SQL language. This mode is exactly the same as
SQL server by just using the standard SQL language. This mode is exactly the same as
different from the standard mysql client. We can use this
mode, by invoking the db top level/5. as one of the following:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_top_level(mysql,Connection,Host/Database,User,Password).
?- db_top_level(mysql,Connection,Host/Database/Port,User,Password).
?- db_top_level(mysql,Connection,Host/Database/UnixSocket,User,Password).
?- db_top_level(mysql,Connection,Host/Database,User,Password).
?- db_top_level(mysql,Connection,Host/Database/Port,User,Password).
?- db_top_level(mysql,Connection,Host/Database/UnixSocket,User,Password).
?- db_top_level(mysql,Connection,Host/Database/Port/UnixSocket,User,Password).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -635,7 +635,7 @@ discussed above. If the login is successful, automatically the prompt of
the mysql client will be used. For example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_top_level(mysql,con1,localhost/guest_db,guest,'').
?- db_top_level(mysql,con1,localhost/guest_db,guest,'').
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
opens a
connection identified by the `con1` atom, to an instance of a MySQL server
@ -644,7 +644,7 @@ empty password. After this is possible to use MYDDAS as the mysql
client.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_top_level(mysql,con1,localhost/guest_db,guest,'').
?- db_top_level(mysql,con1,localhost/guest_db,guest,'').
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
@ -653,25 +653,25 @@ Commands end with ; or \g.
Your MySQL connection id is 4468 to server version: 4.0.20
Type 'help;' or '\h' for help.
Type '\c' to clear the buffer.
Type '\c' to clear the buffer.
mysql> exit
Bye
Bye
yes
?-
?-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
%%@}
/** @defgroup Other_MYDDAS_Properties Other MYDDAS Properties
/** @defgroup Other_MYDDAS_Properties Other MYDDAS Properties
@ingroup MYDDAS
@{
*/
/**
@pred db_verbose(+).
@pred db_verbose(+).
When we ask a question to YAP, using a predicate asserted by
@ -681,8 +681,8 @@ point in our session on YAP.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_verbose(1).
yes
?-
yes
?-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we want to
disable this feature, we must call the `db_verbose/1` predicate with the value 0.
@ -695,7 +695,7 @@ disable this feature, we must call the `db_verbose/1` predicate with the value 0
*/
/** @pred db_module(?).
/** @pred db_module(?).
@ -714,7 +714,7 @@ yes
By executing this predicate, all of the predicates asserted by the
predicates enumerated earlier will created in the lists module.
If we want to put back the value on default, we can manually put the
value user. Example:
value user. Example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_module(user).
@ -725,7 +725,7 @@ yes
We can also see in what module the predicates are being asserted by doing:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_module(X).
?- db_module(X).
X=user
yes
?-
@ -733,7 +733,7 @@ yes
*/
/** @pred db_my_result_set(?).
/** @pred db_my_result_set(?).
The MySQL C API permits two modes for transferring the data generated by
a query to the client, in our case YAP. The first mode, and the default
@ -751,16 +751,16 @@ set created directly from the server. If we want to use this mode, he
simply do
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?- db_my_result_set(use_result).
?- db_my_result_set(use_result).
yes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After this command, all
of the database predicates will use use result by default. We can change
this by doing again `db_my_result_set(store_result)`.
this by doing again `db_my_result_set(store_result)`.
*/
/** @pred db_my_sql_mode(+Conn,?SQL_Mode).
/** @pred db_my_sql_mode(+Conn,?SQL_Mode).
@ -864,7 +864,7 @@ You can see the available SQL Modes at the MySQL homepage at
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_open/5
% db_open/5
% db_open/4
%
db_open(Interface,HostDb,User,Password):-
@ -891,9 +891,9 @@ db_open(odbc,Connection,ODBCEntry,User,Password) :-
set_value(Connection,Con).
#endif
#ifdef MYDDAS_SQLITE3
db_open(sqlite3,Connection,ODBCEntry,User,Password) :-
'$error_checks'(db_open(odbc,Connection,ODBCEntry,User,Password)),
c_db_sqlite3_connect(ODBCEntry,User,Password,Con),
db_open(sqlite3,Connection,File,User,Password) :-
'$error_checks'(db_open(odbc,Connection,File,User,Password)),
c_sqlite3_connect(File,User,Password,Con),
set_value(Connection,Con).
#endif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -919,7 +919,7 @@ db_close(Connection) :-
;
c_db_odbc_disconnect(Con)
),
set_value(Connection,[]). % "deletes" atom
set_value(Connection,[]). % "deletes" atom
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -979,18 +979,18 @@ db_stats(Connection,List):-
;
get_value(Connection,Conn),
c_db_stats(Conn,ListX1)
),
),
'$make_stats_list'(ListX1,List).
#ifdef DEBUG
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_stats_time(+,-)
% Reference is C pointer (memory reference)
%
%
db_stats_time(Reference,Time):-
'$error_checks'(db_stats_time(Reference,Time)),
c_db_stats_time(Reference,Time).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif /* DEBUG */
@ -999,7 +999,7 @@ db_stats_time(Reference,Time):-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_sql(+,+,-)
%
%
%
%compatibility
@ -1037,7 +1037,7 @@ 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),
Name=viewname,
functor(ViewName,Name,Arity),
@ -1045,7 +1045,7 @@ db_prolog_select(Connection,LA,DbGoal):-
ViewName=..[Name|LA],
'$prolog2sql'(ViewName,DbGoal,SQL),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
'$write_or_not'(SQL),
@ -1056,7 +1056,7 @@ db_prolog_select(Connection,LA,DbGoal):-
;
true
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -1084,7 +1084,7 @@ db_prolog_select_multi(Connection,DbGoalsList,ListOfResults) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_command/2
%
%
%
db_command(Connection,SQL):-
'$error_checks'(db_command(Connection,SQL)),
@ -1125,9 +1125,9 @@ db_assert(Connection,PredName):-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_create_table/3
% FieldsList = [field(Name,Type,Null,Key,DefaultValue)]
% FieldsList = [field(Name,Type,Null,Key,DefaultValue)]
% Example [field(campo1,'char(12)',y,y,a),field(campo2,int,y,y,0)]
% TODO Test with ODBC & Type Checks
db_create_table(Connection,TableName,FieldsInf):-
@ -1148,10 +1148,10 @@ db_create_table(Connection,TableName,FieldsInf):-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_export_view/4
% TODO Test with ODBC
%
%
db_export_view(Connection,TableViewName,SQLorDbGoal,FieldsInf):-
'$error_checks'(db_export_view(Connection,TableViewName,SQLorDbGoal,FieldsInf)),
get_value(Connection,Con),
@ -1165,7 +1165,7 @@ db_export_view(Connection,TableViewName,SQLorDbGoal,FieldsInf):-
;
'$process_fields'(FieldsInf,FieldString,KeysSQL),
'$make_atom'(['CREATE TABLE ',TableName,' (',FieldString,KeysSQL,') AS ',SQL],FinalSQL)
),
),
c_db_connection_type(Con,ConType),
'$write_or_not'(FinalSQL),
@ -1187,12 +1187,12 @@ db_update(Connection,WherePred-SetPred):-
%TODO: error_checks
get_value(Connection,Conn),
% Match and Values must be "unifiable"
% Match and Values must be "unifiable"
functor(WherePred,PredName,Arity),
functor(SetPred,PredName,Arity),
functor(NewRelation,PredName,Arity),
'$extract_args'(WherePred,1,Arity,WhereArgs),
'$extract_args'(SetPred,1,Arity,SetArgs),
@ -1201,9 +1201,9 @@ db_update(Connection,WherePred-SetPred):-
translate(NewRelation,NewRelation,Code),
'$get_values_for_update'(Code,SetArgs,SetCondition,WhereCondition),
'$get_table_name'(Code,TableName),
append(SetCondition,WhereCondition,Conditions),
append(SetCondition,WhereCondition,Conditions),
'$make_atom'(['UPDATE `',TableName,'` '|Conditions],SQL),
'$write_or_not'(SQL),
db_my_result_set(Mode),
@ -1265,4 +1265,4 @@ db_multi_queries_number(Connection,Number) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif /*MYDDAS_MYSQL || MYDDAS_ODBC*/
#endif /*MYDDAS_MYSQL || MYDDAS_ODBC*/

View File

@ -1,8 +1,8 @@
/*************************************************************************
* *
* YAP Prolog *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
@ -56,6 +56,11 @@
]).
:- use_module(myddas_sqlite3,[
sqlite3_result_set/1
]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% db_import/3
% db_import/2
@ -64,18 +69,8 @@ db_import(RelationName,PredName):-
db_import(myddas,RelationName,PredName).
db_import(Connection,RelationName,PredName) :-
'$error_checks'(db_import(Connection,RelationName,PredName)),
get_value(Connection,Con),
c_db_connection_type(Con,ConType),
% get relation arity
( ConType == mysql ->
c_db_my_number_of_fields(RelationName,Con,Arity)
;
ConType == odbc ->
c_db_odbc_number_of_fields(RelationName,Con,Arity)
;
c_sqllite3_number_of_fields(RelationName,Con,Arity)
),
get_value(Connection,Con),
table_arity( Con, ConType, RelationName, Arity ),
db_module(Module),
not c_db_check_if_exists_pred(PredName,Arity,Module),
@ -84,18 +79,11 @@ db_import(Connection,RelationName,PredName) :-
assert(myddas_prolog2sql:R),
Size is 2*Arity,
'$make_a_list'(Size,TypesList),
length(TypesList, Size),
% get attributes types in TypesList [field0,type0,field1,type1...]
( ConType == mysql ->
c_db_my_get_attributes_types(RelationName,Con,TypesList)
;
ConType == odbc ->
c_db_odbc_get_attributes_types(RelationName,Con,TypesList)
;
c_sqlite3_get_attributes_types(RelationName,Con,TypesList)
),
table_attributes( ConType, Con, RelationName, TypesList ),
% assert attributes facts
% assert attributes facts
'$assert_attribute_information'(0,Arity,RelationName,TypesList),
% build PredName functor
@ -104,37 +92,7 @@ db_import(Connection,RelationName,PredName) :-
M=myddas_assert_predicates,
%build PredName clause
( ConType == mysql ->
Assert =..[':-',P,','(M:'$copy_term_nv'(P,[],G,_),
','(M:translate(G,G,Code),
','(M:queries_atom(Code,FinalSQL),
','(M:db_my_result_set(Mode),
','(M:'$write_or_not'(FinalSQL),
','(M:c_db_my_query(FinalSQL,ResultSet,Con,Mode,_),
','(!,M:c_db_my_row(ResultSet,Arity,LA))))))))]
;
ConType == sqlit3 ->
Assert =..[':-',P,','(M:'$copy_term_nv'(P,[],G,_),
','(M:translate(G,G,Code),
','(M:queries_atom(Code,FinalSQL),
','(M:db_my_result_set(Mode),
','(M:'$write_or_not'(FinalSQL),
','(M:c_sqlit3_query(FinalSQL,ResultSet,Con,Mode,_),
','(!,M:c_sqlit3_row(ResultSet,Arity,LA))))))))]
;
'$make_a_list'(Arity,BindList),
Assert =..[':-',P,','(M:'$copy_term_nv'(P,[],G,_),
','(M:translate(G,G,Code),
','(M:queries_atom(Code,FinalSQL),
','(M:c_db_odbc_query(FinalSQL,ResultSet,Arity,BindList,Con),
','(M:'$write_or_not'(FinalSQL),
','(!,M:c_db_odbc_row(ResultSet,BindList,LA)))))))]
),
table_access_predicate( ConType, Con, Arity, P, LA, M, Assert ),
assert(Module:Assert),
c_db_add_preds(PredName,Arity,Module,Con).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -166,26 +124,7 @@ db_view(Connection,PredName,DbGoal) :-
c_db_connection_type(Con,ConType),
% build view clause
( ConType == mysql ->
Assert =..[':-',CopyView,
','(M:'$copy_term_nv'(CopyView,[],ProjT,Dic),
','(M:'$copy_term_nv'(CopyGoal,Dic,NG,_),
','(M:translate(ProjT,NG,Code),
','(M:queries_atom(Code,FinalSQL),
','(M:db_my_result_set(Mode),
','(M:'$write_or_not'(FinalSQL),
','(M:c_db_my_query(FinalSQL,ResultSet,Con,Mode,_),
','(!,M:c_db_my_row(ResultSet,Arity,LA)))))))))]
;
% Assert =..[':-',NewName,
% ','(M:translate(CopyView,CopyGoal,Code),
% ','(M:queries_atom(Code,FinalSQL),
% ','(M:'$make_a_list'(Arity,BindList),
% ','(M:'$write_or_not'(FinalSQL),
% ','(M:c_db_odbc_query(FinalSQL,ResultSet,Arity,BindList,Con),
% ','(!,M:c_db_odbc_row(ResultSet,BindList,LA)))))))]
true
),
table_view( ConType, Con, CopyView, CopyGoal, Arity, LA, M, Assert ),
assert(Module:Assert),
c_db_add_preds(ViewName,Arity,Module,Con).
@ -205,11 +144,7 @@ db_insert(Connection,RelationName,PredName) :-
c_db_connection_type(Con,ConType),
% get relation arity
( ConType == mysql ->
c_db_my_number_of_fields(RelationName,Con,Arity)
;
c_db_odbc_number_of_fields(RelationName,Con,Arity)
),
table_arity( Con, ConType, RelationName, Arity ),
db_module(Module),
not c_db_check_if_exists_pred(PredName,Arity,Module),
@ -226,20 +161,7 @@ db_insert(Connection,RelationName,PredName) :-
% get attributes types in TypesList [field0,type0,field1,type1...]
% and build PredName clause
( ConType == mysql ->
c_db_my_get_attributes_types(RelationName,Con,TypesList),
Assert =..[':-',Predicate,','(myddas_assert_predicates:'$get_values_for_insert'(TypesList,LA,ValuesList),
','(myddas_assert_predicates:'$make_atom'(['INSERT INTO `',RelationName,'` VALUES ('|ValuesList],SQL),
','(myddas_assert_predicates:db_my_result_set(Mode),
','(myddas_assert_predicates:'$write_or_not'(SQL),
myddas_assert_predicates:c_db_my_query(SQL,_,Con,Mode,_)))))]
;
c_db_odbc_get_attributes_types(RelationName,Con,TypesList),
Assert =..[':-',Predicate,','(myddas_assert_predicates:'$get_values_for_insert'(TypesList,LA,ValuesList),
','(myddas_assert_predicates:'$make_atom'(['INSERT INTO `',RelationName,'` VALUES ('|ValuesList],SQL),
','(myddas_assert_predicates:'$write_or_not'(SQL),
myddas_assert_predicates:c_db_odbc_query(SQL,_,_,_,Con))))]
),
table_insert( ConType, Con, RelationName, TypesList, Predicate, LA, Assert ),
assert(Module:Assert),
c_db_add_preds(PredName,Arity,Module,Con).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -308,3 +230,124 @@ db_listing(Name):-
listing(Module:Name/Arity).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% table_arity :- number of columns in a relation.
%
table_arity( Con, ConType, RelationName, Arity ) :-
c_db_connection_type(Con,ConType),
writeln( ConType ),
% get relation arity
( ConType == mysql ->
c_db_my_number_of_fields(RelationName,Con,Arity)
;
ConType == odbc ->
c_db_odbc_number_of_fields(RelationName,Con,Arity)
;
c_sqlite3_number_of_fields(RelationName,Con,Arity))
.
% major attributes types.
table_attributes( mysql, Con, RelationName, TypesList ) :-
c_db_my_get_attributes_types(RelationName,Con,TypesList).
table_attributes( odbc, Con, RelationName, TypesList ) :-
c_db_odbc_get_attributes_types(RelationName,Con,TypesList).
table_attributes( sqlite3, Con, RelationName, TypesList ) :-
c_sqlite3_get_attributes_types(RelationName,Con,TypesList).
% predicate for DB-> query
table_access_predicate( mysql, Con, Arity, P, LA, M,
( P :- M:('$copy_term_nv'(P,[],G,_),
translate(G,G,Code),
queries_atom(Code,FinalSQL),
db_my_result_set(Mode),
'$write_or_not'(FinalSQL),
c_db_my_query(FinalSQL,ResultSet,Con,Mode,_),
!,
c_db_my_row(ResultSet,Arity,LA) ))).
table_access_predicate( sqlite3, Con, Arity, P, LA, M,
( P :- M:('$copy_term_nv'(P,[],G,_),
translate(G,G,Code),
queries_atom(Code,FinalSQL),
sqlite3_result_set(Mode),
'$write_or_not'(FinalSQL),
c_sqlite3_query(FinalSQL,ResultSet,Con,Mode,_),
!,
c_sqlite3_row(ResultSet,Arity,LA)
) )).
table_access_predicate( odbc, Con, Arity, P, LA, M,
( P :- M:('$copy_term_nv'(P,[],G,_),
translate(G,G,Code),
queries_atom(Code,FinalSQL),
c_db_odbc_result_set(Mode),
'$write_or_not'(FinalSQL),
c_db_odbc_query(FinalSQL,ResultSet,Con,Mode,_),
!,
c_db_odbc_row(ResultSet,Arity,LA)
) )).
table_insert( mysql, Con, RelationName, TypesList, Predicate, LA,
( Predicate :- myddas_assert_predicates:
( '$get_values_for_insert'(TypesList,LA,ValuesList),
'$make_atom'(['INSERT INTO `',RelationName,'` VALUES ('|ValuesList],SQL),
db_my_result_set(Mode),
'$write_or_not'(SQL),
c_db_my_query(SQL,_,Con,Mode,_)))
).
table_insert( sqlite3, Con, RelationName, TypesList, Predicate, LA,
( Predicate :- myddas_assert_predicates:
( '$get_values_for_insert'(TypesList,LA,ValuesList),
'$make_atom'(['INSERT INTO `',RelationName,'` VALUES ('|ValuesList],SQL),
db_my_result_set(Mode),
'$write_or_not'(SQL),
c_sqlite3_query(SQL,_,Con,Mode,_)))
).
table_insert( odbc, Con, RelationName, TypesList, Predicate, LA,
( Predicate :- myddas_assert_predicates:
( '$get_values_for_insert'(TypesList,LA,ValuesList),
'$make_atom'(['INSERT INTO `',RelationName,'` VALUES ('|ValuesList],SQL),
'$write_or_not'(SQL),
c_odbc_my_query(SQL,_,_,_,Con)))
).
table_view( mysql, Con, CopyView, CopyGoal, Arity, LA, M,
( CopyView :-
M:( '$copy_term_nv'(CopyView,[],ProjT,Dic),
'$copy_term_nv'(CopyGoal,Dic,NG,_),
translate(ProjT,NG,Code),
queries_atom(Code,FinalSQL),
db_my_result_set(Mode),
'$write_or_not'(FinalSQL),
c_db_my_query(FinalSQL,ResultSet,Con,Mode,_),
!,
c_db_my_row(ResultSet,Arity,LA) ))).
table_view( odbc, Con, CopyView, CopyGoal, Arity, LA, M,
( CopyView :-
M:( '$copy_term_nv'(CopyView,[],ProjT,Dic),
'$copy_term_nv'(CopyGoal,Dic,NG,_),
translate(ProjT,NG,Code),
length(BindList, Arity ),
queries_atom(Code,FinalSQL),
'$write_or_not'(FinalSQL),
c_db_odbc_query(FinalSQL,ResultSet,Arity,BindList,Con),
!,
c_db_my_row(ResultSet,Arity,LA) ))).
table_view( sqlite3, Con, CopyView, CopyGoal, Arity, LA, M,
( CopyView :-
M:( '$copy_term_nv'(CopyView,[],ProjT,Dic),
'$copy_term_nv'(CopyGoal,Dic,NG,_),
translate(ProjT,NG,Code),
queries_atom(Code,FinalSQL),
'$write_or_not'(FinalSQL),
c_sqlite3_query(FinalSQL,ResultSet,Con,_,_),
!,
c_db_my_row(ResultSet,Arity,LA) ))).