📄 main.cpp
字号:
} else if ((db_fullpath = FindDatabase(name, (char *)conn->getHostName())) != NULL) { conn->setDatabase(db_fullpath); } else { GB.Error("Unable to locate database: &1", name); return NULL; } GB.FreeString(&name); GB.FreeString(&db_fullpath); if ( conn->connect() != DB_CONNECTION_OK){ GB.Error("Cannot open database: &1", conn->getErrorMsg()); conn->disconnect(); return NULL; } /* Character set cannot be set for sqlite. A sqlite re-compile * is required. */ GB.NewString(charset, strcmp(sqlite_encoding, "iso8859") == 0 ? "ISO-8859-1" : "UTF-8", 0); /* set dbversion */ desc->version = db_version(); return (DB_DATABASE)conn;}/***************************************************************************** close_database() Terminates the database connection. <handle> contains the database handle.*****************************************************************************/static void close_database(DB_DATABASE handle){ SqliteDatabase *conn = (SqliteDatabase *)handle; if (conn) conn->disconnect();}/***************************************************************************** format_value() This function transforms a gambas value into a string value that can be inserted into a SQL query. <arg> points to the value. <add> is a callback called to insert the string into the query. This function must return TRUE if it translates the value, and FALSE if it does not. If the value is not translated, then a default translation is used.*****************************************************************************/static int format_value(GB_VALUE *arg, DB_FORMAT_CALLBACK add){ int l; GB_DATE_SERIAL *date; switch (arg->type) { case GB_T_BOOLEAN:/*Note this is likely to go to a tinyint */ if (VALUE((GB_BOOLEAN *)arg)) add("'1'", 3); else add("'0'", 3); return TRUE; case GB_T_STRING: case GB_T_CSTRING: return FALSE; case GB_T_DATE: date = GB.SplitDate((GB_DATE *)arg); l = sprintf(_buffer, "'%04d-%02d-%02d %02d:%02d:%02d", date->year, date->month, date->day, date->hour, date->min, date->sec); add(_buffer, l); if (date->msec) { l = sprintf(_buffer, ".%03d", date->msec); add(_buffer, l); } add("'", 1); return TRUE; default: return FALSE; }}/***************************************************************************** exec_query() Send a query to the server and gets the result. <handle> is the database handle, as returned by open_database() <query> is the query string. <result> will receive the result handle of the query. <err> is an error message used when the query failed. <result> can be NULL, when we don't care getting the result.*****************************************************************************/static int exec_query(DB_DATABASE handle, char *query, DB_RESULT *result, char *err){ return do_query((SqliteDatabase *)handle, err, (Dataset **)result, query, 0);}/***************************************************************************** query_init() Initialize an info structure from a query result. <result> is the handle of the query result. <info> points to the info structure. <count> will receive the number of records returned by the query. This function must initialize the info->nfield field with the number of field in the query result.*****************************************************************************/static void query_init(DB_RESULT result, DB_INFO *info, int *count){ Dataset *res = (Dataset *)result; if(res) { *count = res->num_rows(); info->nfield = res->fieldCount(); } else { *count = 0; info->nfield = 0; }}/***************************************************************************** query_release() Free the info structure filled by query_init() and the result handle. <result> is the handle of the query result. <info> points to the info structure.*****************************************************************************/static void query_release(DB_RESULT result, DB_INFO *info){ ((Dataset *)result)->close();}/***************************************************************************** query_fill() Fill a result buffer with the value of each field of a record. <result> is the handle of the result. <pos> is the index of the record in the result. <buffer> points to an array having one element for each field in the result. <next> is a boolean telling if we want the next row. This function must use GB.StoreVariant() to store the value in the buffer.*****************************************************************************/static void query_fill(DB_RESULT result, int pos, GB_VARIANT_VALUE *buffer, int next){ Dataset *res = (Dataset *)result; int i; char *data; GB_VARIANT value; if (!next) res->seek(pos);/* move to record */ else res->next(); for ( i=0; i < res->fieldCount(); i++) { GB.NewString( &data, res->fv(res->fieldName(i)).get_asString().data(),0); value.type = GB_T_VARIANT; value.value._object.type = GB_T_NULL; //if (field->type != FIELD_TYPE_NULL) if (data){ conv_data(data, &value.value, (fType) res->fieldType(i)); } GB.FreeString(&data); GB.StoreVariant(&value, &buffer[i]); }}/***************************************************************************** field_name() Return the name of a field in a result from its index. <result> is the result handle. <field> is the field index.*****************************************************************************/static char *field_name(DB_RESULT result, int field){ return (char *)(((Dataset *)result)->fieldName(field));}/***************************************************************************** field_index() Return the index of a field in a result from its name. <Result> is the result handle. <name> is the field name. <handle> can be ignored by this driver.*****************************************************************************/static int field_index(DB_RESULT result, char *name, DB_DATABASE handle, long version){ char *fld; fld = strchr(name, (int)FLD_SEP); if (fld){ //Includes table identity fld[0] = '.'; } return (((Dataset *)result)->fieldIndex(name));}/***************************************************************************** field_type() Return the Gambas type of a field in a result from its index. <result> is the result handle. <field> is the field index.*****************************************************************************/static GB_TYPE field_type(DB_RESULT result, int field){ return conv_type(((Dataset *)result)->fieldType(field));}/***************************************************************************** field_length() Return the length of a field in a result from its index. <result> is the result handle. <field> is the field index.*****************************************************************************/static int field_length(DB_RESULT result, int field){ int len; len = ((Dataset *)result)->fieldSize(field); GB_TYPE type = conv_type(((Dataset *)result)->fieldType(field)); if (type != GB_T_STRING) return 0; else return len;}/***************************************************************************** begin_transaction() Begin a transaction. <handle> is the database handle. This function returns TRUE if the command has failed, and FALSE if everything was OK. In mysql commit/rollback can only be used with transaction safe tables (BDB, or InnoDB tables) ISAM, MyISAM and HEAP tables will commit straight away. The transaction methods are therefore ignored.*****************************************************************************/static int begin_transaction(DB_DATABASE handle){ return do_query((SqliteDatabase *)handle, "Unable to begin transaction: &1", NULL, "BEGIN", 0);}/***************************************************************************** commit_transaction() Commit a transaction. <handle> is the database handle. This function returns TRUE if the command has failed, and FALSE if everything was OK.*****************************************************************************/static int commit_transaction(DB_DATABASE handle){ return do_query((SqliteDatabase *)handle, "Unable to commit transaction: &1", NULL, "COMMIT", 0);}/***************************************************************************** rollback_transaction() Rolllback a transaction. <handle> is the database handle. This function returns TRUE if the command has failed, and FALSE if everything was OK.*****************************************************************************/static int rollback_transaction(DB_DATABASE handle){ return do_query((SqliteDatabase *)handle, "Unable to rollback transaction: &1", NULL, "ROLLBACK", 0);}/***************************************************************************** table_init() Initialize an info structure from table fields. <handle> is the database handle. <table> is the table name. <info> points at the info structure. This function must initialize the following info fields: - info->nfield must contain the number of fields in the table. - info->fields is a char*[] pointing at the name of each field. - info->types is a GB_TYPE[] giving the gambas type of each field. This function returns TRUE if the command has failed, and FALSE if everything was OK.*****************************************************************************/static int table_init(DB_DATABASE db, char *table, DB_INFO *info){ char *qfield = "PRAGMA table_info('&1')"; SqliteDatabase *conn = (SqliteDatabase *)db; Dataset *res; int i, n; DB_FIELD *f; /* Nom de la table */ GB.NewString(&info->table, table, 0); /* Liste des champs */ if (do_query(conn, "Unable to get table fields: &1", &res, qfield, 1, table)) return TRUE; result_set* r = (result_set*) res->getExecRes(); info->nfield = n = r->records.size(); if (n == 0){ res->close(); return TRUE; } GB.Alloc((void **)&info->field, sizeof(DB_FIELD) * n); for (i = 0; i < n; i++) { f = &info->field[i]; GB.NewString(&f->name, r->records[i][1].get_asString().data(), 0); f->length = 0; f->type = conv_type(GetFieldType((char *) r->records[i][2].get_asString().data(), (unsigned int *) &f->length)); } res->close(); return FALSE;}/***************************************************************************** table_index() Initialize an info structure from table primary index. <handle> is the database handle. <table> is the table name. <info> points at the info structure. This function must initialize the following info fields: - info->nindex must contain the number of fields in the primary index. - info->index is a int[] giving the index of each index field in info->fields. This function must be called after table_init(). This function returns TRUE if the command has failed, and FALSE if everything was OK.*****************************************************************************/static int table_index(DB_DATABASE db, char *table, DB_INFO *info){ char *qindex1 = "PRAGMA index_list('&1')"; char *qindex2 = "PRAGMA index_info('&1')"; SqliteDatabase *conn = (SqliteDatabase *)db; Dataset *res; char *sql = NULL; int n = 0; /* Index primaire */ if (do_query(conn, "Unable to get primary index: &1", &res, qindex1, 1, table)) return TRUE; result_set* r = (result_set*) res->getExecRes(); if (( n = r->records.size()) <= 0){ /* no indexes returned */ /* sqlite will use a PRIMARY INDEX on ROWID */ /* BM: without a true primary index, Edit() does not work */ GB.Error("Table '&1' has no primary index", table); res->close(); return TRUE; } for (int i = 0; i < n; i++) { if (strstr(r->records[i][1].get_asString().data(), "autoindex") != NULL){ GB.NewString( &sql, r->records[i][1].get_asString().data(), 0); res->close(); if (do_query(conn, "Unable to get information on primary index: &1", &res, qindex2, 1, sql)){ res->close(); GB.FreeString(&sql); return TRUE; } GB.FreeString(&sql); r = (result_set*) res->getExecRes(); info->nindex = r->records.size(); GB.Alloc((void **)&info->index, sizeof(int) * info->nindex); for (i = 0; i < info->nindex; i++){ info->index[i] = r->records[i][1].get_asShort(); } break; } } res->close(); return FALSE;}/***************************************************************************** table_release() Free the info structure filled by table_init() and/or table_index() <handle> is the database handle. <info> points at the info structure.*****************************************************************************/static void table_release(DB_DATABASE db, DB_INFO *info){ /* All is done outside the driver */}/***************************************************************************** table_exist() Returns if a table exists <handle> is the database handle. <table> is the table name. This function returns TRUE if the table exists, and FALSE if not.*****************************************************************************/static int table_exist(DB_DATABASE handle, char *table, long version){ const char *query = "select tbl_name from " "( select tbl_name from sqlite_master where type = 'table' union " "select tbl_name from sqlite_temp_master where type = 'table' ) " "where tbl_name = '&1'"; if ( strcmp(table,"sqlite_master") == 0 || strcmp(table,"sqlite_temp_master") == 0){ return TRUE; } SqliteDatabase *conn = (SqliteDatabase *)handle; Dataset *res; int exist; if (do_query(conn, "Unable to check table: &1", &res, query, 1, table)) return FALSE; exist = res->num_rows(); res->close(); return exist;}/***************************************************************************** table_list() Returns an array containing the name of each table in the database <handle> is the database handle. <tables> points to a variable that will receive the char* array. This function returns the number of tables, or -1 if the command has failed. Be careful: <tables> can be NULL, so that just the count is returned.*****************************************************************************/static long table_list(DB_DATABASE handle, char ***tables, long version){ const char *query = "select tbl_name from " "( select tbl_name from sqlite_master where type = 'table' union " " select tbl_name from sqlite_temp_master where type = 'table')"; SqliteDatabase *conn = (SqliteDatabase *)handle; Dataset *res; long rows; int i = 0; if (do_query(conn, "Unable to get tables: &1", &res, query, 0)) return -1; rows = res->num_rows(); GB.NewArray(tables, sizeof(char *), rows + 2);//sqlite_master and sqlite_temp_master need to be //added to the list while ( !res->eof()){ GB.NewString(&(*tables)[i], res->fv("tbl_name").get_asString().data(), 0); res->next(); i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -