From ada2ad44de5657748de59c82550178054d69e313 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Sat, 14 Feb 2015 11:35:07 +0000 Subject: [PATCH] basic myddas with SQLITE3 --- packages/myddas/MyddasProto.h | 4 +- packages/myddas/myddas.h | 1 + packages/myddas/myddas_initialization.c | 5 +- packages/myddas/myddas_mysql.c | 4 +- packages/myddas/myddas_odbc.c | 2 +- packages/myddas/myddas_shared.c | 28 ++- packages/myddas/myddas_sqlite3.c | 109 +++++---- packages/myddas/myddas_structs.h | 8 + packages/myddas/myddas_util.c | 17 +- packages/myddas/pl/myddas.ypp | 218 ++++++++--------- .../myddas/pl/myddas_assert_predicates.ypp | 231 +++++++++++------- 11 files changed, 346 insertions(+), 281 deletions(-) diff --git a/packages/myddas/MyddasProto.h b/packages/myddas/MyddasProto.h index 96cd1bb67..61f8b5825 100644 --- a/packages/myddas/MyddasProto.h +++ b/packages/myddas/MyddasProto.h @@ -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 *); diff --git a/packages/myddas/myddas.h b/packages/myddas/myddas.h index 619626df9..5585dde19 100644 --- a/packages/myddas/myddas.h +++ b/packages/myddas/myddas.h @@ -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" diff --git a/packages/myddas/myddas_initialization.c b/packages/myddas/myddas_initialization.c index f0b0aee57..3be038f07 100644 --- a/packages/myddas/myddas_initialization.c +++ b/packages/myddas/myddas_initialization.c @@ -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; diff --git a/packages/myddas/myddas_mysql.c b/packages/myddas/myddas_mysql.c index 18f354f43..0416ad076 100644 --- a/packages/myddas/myddas_mysql.c +++ b/packages/myddas/myddas_mysql.c @@ -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�o feitas as convers�es de tipos de dados */ + /* Here we perform data type conversion. */ field = mysql_fetch_field(res_set); head = HeadOfTerm(list); list = TailOfTerm(list); diff --git a/packages/myddas/myddas_odbc.c b/packages/myddas/myddas_odbc.c index 3f8e393bf..5cc8b6557 100644 --- a/packages/myddas/myddas_odbc.c +++ b/packages/myddas/myddas_odbc.c @@ -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; diff --git a/packages/myddas/myddas_shared.c b/packages/myddas/myddas_shared.c index 6d7e8f6e5..ee8d8b8ab 100644 --- a/packages/myddas/myddas_shared.c +++ b/packages/myddas/myddas_shared.c @@ -22,7 +22,6 @@ #include "cut_c.h" #include "myddas.h" #include -#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*/ diff --git a/packages/myddas/myddas_sqlite3.c b/packages/myddas/myddas_sqlite3.c index a02ba9efe..dc9ba8de8 100644 --- a/packages/myddas/myddas_sqlite3.c +++ b/packages/myddas/myddas_sqlite3.c @@ -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;idb; - - 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 diff --git a/packages/myddas/myddas_structs.h b/packages/myddas/myddas_structs.h index 1fc81e2a8..4a48aad29 100644 --- a/packages/myddas/myddas_structs.h +++ b/packages/myddas/myddas_structs.h @@ -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 */ diff --git a/packages/myddas/myddas_util.c b/packages/myddas/myddas_util.c index aadf21ab3..cf2d4aa75 100644 --- a/packages/myddas/myddas_util.c +++ b/packages/myddas/myddas_util.c @@ -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"); diff --git a/packages/myddas/pl/myddas.ypp b/packages/myddas/pl/myddas.ypp index 31c09b05c..153ab53d4 100644 --- a/packages/myddas/pl/myddas.ypp +++ b/packages/myddas/pl/myddas.ypp @@ -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 Hello World is the name of the relation and myddas 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 db_datalog_describe/2, 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*/ diff --git a/packages/myddas/pl/myddas_assert_predicates.ypp b/packages/myddas/pl/myddas_assert_predicates.ypp index 617bef5eb..f7234000a 100644 --- a/packages/myddas/pl/myddas_assert_predicates.ypp +++ b/packages/myddas/pl/myddas_assert_predicates.ypp @@ -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) ))).