/************************************************************************* * * * 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 * * * *************************************************************************/ #if defined MYDDAS_sqlite3 #include #include #include #include #include "Yap.h" #include "Yatom.h" #include "YapText.h" #include "cut_c.h" #include "myddas.h" #ifdef MYDDAS_STATS #include "myddas_structs.h" #include "myddas_statistics.h" #endif #include "myddas_wkb2prolog.h" #define CALL_SQLITE(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); \ } \ } \ #define CALL_SQLITE_EXPECT(f,x) \ { \ int i; \ i = sqlite3_ ## f; \ if (i != SQLITE_ ## x) { \ fprintf (stderr, "%s failed with status %d: %s\n", \ #f, i, sqlite3_errmsg (db)); \ exit (1); \ } \ } \ #define IS_SQL_INT(FIELD) FIELD == FIELD_TYPE_INT24 || \ FIELD == FIELD_TYPE_LONG || \ FIELD == FIELD_TYPE_LONGLONG || \ FIELD == FIELD_TYPE_SHORT || \ FIELD == FIELD_TYPE_TINY #define IS_SQL_FLOAT(FIELD) FIELD == FIELD_TYPE_DECIMAL || \ FIELD == FIELD_TYPE_DOUBLE || \ FIELD == FIELD_TYPE_FLOAT #define IS_SQL_GEOMETRY(FIELD) FIELD == FIELD_TYPE_GEOMETRY static Int null_id = 0; static Int c_db_lite_connect( USES_REGS1 ); static Int c_db_lite_disconnect( USES_REGS1 ); static Int c_db_lite_number_of_fields( USES_REGS1 ); static Int c_db_lite_get_attributes_types( USES_REGS1 ); static Int c_db_lite_query( USES_REGS1 ); static Int c_db_lite_table_write( USES_REGS1 ); static Int c_db_lite_row( USES_REGS1 ); static Int c_db_lite_row_cut( USES_REGS1 ); static Int c_db_lite_get_fields_properties( USES_REGS1 ); static Int c_db_lite_get_next_result_set( USES_REGS1 ); static Int c_db_lite_get_database( USES_REGS1 ); static Int c_db_lite_change_database( USES_REGS1 ); void Yap_InitMYDDAS_SQLitePreds(void) { /* db_dbect: Host x User x Passwd x Database x dbection x ERROR_CODE */ Yap_InitCPred("c_db_lite_connect", 7, c_db_lite_connect, 0); /* db_number_of_fields: Relation x connection x NumberOfFields */ Yap_InitCPred("c_db_lite_number_of_fields",3, c_db_lite_number_of_fields, 0); /* db_get_attributes_types: Relation x TypesList */ Yap_InitCPred("c_db_lite_get_attributes_types", 3, c_db_lite_get_attributes_types, 0); /* db_query: SQLQuery x ResultSet x conection */ Yap_InitCPred("c_db_lite_query", 5, c_db_lite_query, 0); /* db_disconnect: connection */ Yap_InitCPred("c_db_lite_disconnect", 1,c_db_lite_disconnect, 0); /* db_table_write: Result Set */ Yap_InitCPred("c_db_lite_table_write", 1, c_db_lite_table_write, 0); /* db_get_fields_properties: PredName x connection x PropertiesList*/ Yap_InitCPred("c_db_lite_get_fields_properties",3,c_db_lite_get_fields_properties,0); Yap_InitCPred("c_db_lite_get_next_result_set",2,c_db_lite_get_next_result_set,0); /* c_db_lite_get_database: connection x DataBaseName */ Yap_InitCPred("c_db_lite_get_database",2,c_db_lite_get_database,0); /* c_db_lite_change_database: connection x DataBaseName */ Yap_InitCPred("c_db_lite_change_database",2,c_db_lite_change_database,0); } void Yap_InitBackMYDDAS_sqlite3Preds(void) { /* db_row: ResultSet x Arity x ListOfArgs */ Yap_InitCPredBackCut("c_db_lite_row", 3, sizeof(Int), c_db_lite_row, c_db_lite_row, c_db_lite_row_cut, 0); } static Int c_db_lite_connect( USES_REGS1 ) { Term arg_file = Deref(ARG1); Term arg_db = ARG2; MYDDAS_UTIL_CONNECTION new = NULL; sqlite3 *db; char *file = AtomName(AtomOfTerm(arg_file)); rc = CALL_SQLITE(sqlite3_open(argv[1], &db) ); if (!Yap_unify(arg_db, MkIntegerTerm((Int)db))) return FALSE; else { /* Criar um novo no na lista de ligacoes*/ new = myddas_util_add_connection(db,NULL); if (new == NULL){ #ifdef DEBUG fprintf(stderror, "ERROR: ** c_db_my_connect ** Error allocating memory\n"); #endif return FALSE; } return TRUE; } } static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); t0 = tf; for(i=0; ires_set = res_set; rs->nrows = nrows; rs->length = length; if (!Yap_unify(arg_result_set, MkIntegerTerm((Int) rs))) { SQL_LITE (sqlite3_free_table(res_set) ); return FALSE; } } return TRUE; } static Int c_db_lite_number_of_fields( USES_REGS1 ) { Term arg_relation = Deref(ARG1); Term arg_db = Deref(ARG2); Term arg_fields = ARG3; char *relation = AtomName(AtomOfTerm(arg_relation)); sqlite3 *db = (sqlite3 *) (IntegerOfTerm(arg_db)); sqlite3_stmt *pStmt; char sql[256]; sprintf(sql,"SELECT * FROM TABLE `%s`",relation); /* executar a query SQL */ SQL_LITE (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) ); int fields = sqlite3_column_count( stmt ); SQL_LITE (sqlite3_finalize( stmt ) ); return Yap_unify(arg_fields, MkIntegerTerm( fields )); } /* db_get_attributes_types: RelName x connection -> TypesList */ static Int c_db_lite_get_attributes_types( USES_REGS1 ) { Term arg_relation = Deref(ARG1); Term arg_db = Deref(ARG2); Term arg_types_list = Deref(ARG3); char *relation = AtomName(AtomOfTerm(arg_relation)); sqlite3 *db = (sqlite3 *) IntegerOfTerm(arg_db); char sql[256]; sqlite3_stmt *stmt; Int rc = TRUE; char sql[256]; sprintf(sql,"SELECT * FROM TABLE `%s`",relation); /* executar a query SQL */ SQL_LITE (sqlite3_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 &&= Yap_unify(head, MkAtomTerm(Yap_LookupAtom(sqlite3_column_name(stmt, i))) ); list = TailOfTerm(list); head = HeadOfTerm(list); list = TailOfTerm(list); int type = sqlite3_column_type(stmt, i); switch(type) { case SQLITE_INTEGER: tm = "integer"; break; case SQLITE_FLOAT: tm = "real"; break; case SQLITE_TEXT: tm = "string"; break; case SQLITE_BLOB: tm = "blob"; break; case SQLITE_NULL: tm = "null"; break; } if (!Yap_unify(head, MkAtomTerm(Yap_LookupAtom(rc))) ) rc = FALSE; } SQL_LITE (sqlite3_finalize( stmt ) ); return rc; } /* db_disconnect */ static Int c_db_lite_disconnect( USES_REGS1 ) { Term arg_db = Deref(ARG1); sqlite3 *db = (sqlite3 *) IntegerOfTerm(arg_db); if ((myddas_util_search_connection(db)) != NULL) { myddas_util_delete_connection(db); sqlite3_close(db); return TRUE; } else { return FALSE; } } /* db_table_write: Result Set */ static Int c_db_lite_table_write( USES_REGS1 ) { Term arg_res_set = Deref(ARG1); sqlite3_RES *res_set = (sqlite3_RES *) IntegerOfTerm(arg_res_set); myddas_util_table_write(res_set); sqlite3_free_result(res_set); return TRUE; } static Int c_db_lite_row_cut( USES_REGS1 ) { sqlite3_RES *sqlite3_res=NULL; sqlite3_res = (sqlite3_RES *) IntegerOfTerm(EXTRA_CBACK_CUT_ARG(Term,1)); sqlite3_free_result(sqlite3_res); return TRUE; } static Int c_db_lite_get_fields_properties( USES_REGS1 ) { Term nome_relacao = Deref(ARG1); Term arg_db = Deref(ARG2); Term fields_properties_list = Deref(ARG3); Term head, list; char *relacao = AtomName(AtomOfTerm(nome_relacao)); char sql[256]; Int num_fields,i; sqlite3_FIELD *fields; sqlite3 *db = (sqlite3 *) (IntegerOfTerm(arg_db)); sqlite3_stmt *stmt; Int rc = TRUE; sprintf(sql,"SELECT * FROM TABLE `%s`",relation); /* executar a query SQL */ SQL_LITE (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) ); Functor functor = Yap_MkFunctor(Yap_LookupAtom("property"),4); Term properties[4]; list = fields_properties_list; num_fields = sqlite3_column_count( stmt ); for (i=0;idb)))) return FALSE; return TRUE; } static Int c_db_lite_change_database( USES_REGS1 ) { Term arg_con = Deref(ARG1); Term arg_database = Deref(ARG2); sqlite3 *con = (sqlite3 *) (IntegerOfTerm(arg_con)); char *database = AtomName(AtomOfTerm(arg_database)); if (sqlite3_select_db(con,database)!=0) return FALSE; return TRUE; } #endif /* MYDDAS_sqlite3 */