diff options
author | David Sommerseth <dazo@users.sourceforge.net> | 2009-09-17 09:36:51 +0200 |
---|---|---|
committer | David Sommerseth <dazo@users.sourceforge.net> | 2009-09-17 09:36:51 +0200 |
commit | 5ae9320cf84a28b79b0b9406a77ea938ba4d82cd (patch) | |
tree | 9e784ddf2554a3f309a25fe4afd1747815d29118 /database/sqlite/sqlite.c | |
parent | 7bb84e4d9eeaccf292aebe4d349755b87f87a143 (diff) | |
download | eurephia-5ae9320cf84a28b79b0b9406a77ea938ba4d82cd.tar.gz eurephia-5ae9320cf84a28b79b0b9406a77ea938ba4d82cd.tar.xz eurephia-5ae9320cf84a28b79b0b9406a77ea938ba4d82cd.zip |
Removed usage of a global result pointer
The callback function do now get a pointer to the query results directly instead
of using a global result pointer. This makes queries done in parallel a lot safer.
Made the SQLITE_DEBUG main() function more generic and removed memwatch references
which is no longer in use, as valgrind is much better and easier to use.
Diffstat (limited to 'database/sqlite/sqlite.c')
-rw-r--r-- | database/sqlite/sqlite.c | 104 |
1 files changed, 50 insertions, 54 deletions
diff --git a/database/sqlite/sqlite.c b/database/sqlite/sqlite.c index 70ae682..71bd04a 100644 --- a/database/sqlite/sqlite.c +++ b/database/sqlite/sqlite.c @@ -44,10 +44,6 @@ #include "./sqlite.h" -#ifdef MEMWATCH -#include <memwatch.h> -#endif - /** * @{ */ @@ -58,7 +54,6 @@ * @} */ -dbresult *glob_results = NULL; /**< A local pointer needed for the SQLite3 callback function */ /** * Internal function. Free up a dbresult structure. This function is available via the @@ -114,26 +109,27 @@ void _sqlite_free_results(dbresult *inres) * Callback function used by sqlite3_exec - populates a global variable glob_results. * The glob_results structure is allocated with a new address on each sqlite_query call * - * @param NotUsed N/A - * @param argc Number of fields in the result - * @param argv Array pointer to the values of the fields - * @param colName Array pointer to the field names (column names) + * @param resultptr Pointer to a dbresult struct where the query result will be saved + * @param argc Number of fields in the result + * @param argv Array pointer to the values of the fields + * @param colName Array pointer to the field names (column names) * * @return SQLite3 defines 0 for no errors, and 1 for errors. */ -static int _cb_parse_result(void *NotUsed, int argc, char **argv, char **colName) +static int _cb_parse_result(void *resultptr, int argc, char **argv, char **colName) { // This callback function is called for each row returned by the query _sqlite_header *hrec = NULL; _sqlite_tuples *trec = NULL, *new_frec = NULL; int i; + dbresult *dbres = (dbresult *) resultptr; - if( glob_results == NULL ) { + if( dbres == NULL ) { return 1; } // If no header records are found, populate this structure - if( glob_results->headerrec == NULL ) { + if( dbres->headerrec == NULL ) { for( i = 0; i < argc; i++ ) { hrec = (_sqlite_header *) malloc_nullsafe(NULL, sizeof(_sqlite_header)+2); @@ -143,22 +139,22 @@ static int _cb_parse_result(void *NotUsed, int argc, char **argv, char **colName // Append the new record to the "end" of the // circular pointer chain for header info - if( glob_results->headerrec == NULL ) { - glob_results->headerrec = hrec; + if( dbres->headerrec == NULL ) { + dbres->headerrec = hrec; hrec->next = hrec; hrec->prev = hrec; } else { - hrec->next = glob_results->headerrec; - hrec->prev = glob_results->headerrec->prev; - glob_results->headerrec->prev->next = hrec; - glob_results->headerrec->prev = hrec; + hrec->next = dbres->headerrec; + hrec->prev = dbres->headerrec->prev; + dbres->headerrec->prev->next = hrec; + dbres->headerrec->prev = hrec; } } - glob_results->num_fields = argc; + dbres->num_fields = argc; } // Add all data fields for this record into a tuple structure - hrec = glob_results->headerrec; + hrec = dbres->headerrec; for( i = 0; i < argc; i++ ) { new_frec = (_sqlite_tuples *) malloc_nullsafe(NULL, sizeof(_sqlite_tuples)+2); @@ -172,19 +168,19 @@ static int _cb_parse_result(void *NotUsed, int argc, char **argv, char **colName // // These pointers directs you to the next or previous // record set of data fields - if( glob_results->tuples == NULL ) { - glob_results->tuples = trec; + if( dbres->tuples == NULL ) { + dbres->tuples = trec; trec->nexttuple = trec; trec->prevtuple = trec; } else { - trec->nexttuple = glob_results->tuples; - trec->prevtuple = glob_results->tuples->prevtuple; - glob_results->tuples->prevtuple->nexttuple = trec; - glob_results->tuples->prevtuple = trec; + trec->nexttuple = dbres->tuples; + trec->prevtuple = dbres->tuples->prevtuple; + dbres->tuples->prevtuple->nexttuple = trec; + dbres->tuples->prevtuple = trec; } } - new_frec->tupleid = glob_results->num_tuples; + new_frec->tupleid = dbres->num_tuples; new_frec->fieldid = i; new_frec->value = strdup_nullsafe(argv[i]); new_frec->length = strlen_nullsafe(trec->value); @@ -219,7 +215,7 @@ static int _cb_parse_result(void *NotUsed, int argc, char **argv, char **colName hrec = hrec->next; } // Increase the tuple counter - glob_results->num_tuples++; + dbres->num_tuples++; return 0; } @@ -238,6 +234,7 @@ dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) { va_list ap; char *errMsg = NULL, *sql = NULL; eDBconn *dbc = ctx->dbc; + dbresult *dbres = NULL; if( ctx->dbc == NULL ) { eurephia_log(ctx, LOG_PANIC, 0, "No open database connection to perfom SQL query to"); @@ -252,8 +249,8 @@ dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) { // prepare a new (global) result set ... // do not delete the old ones, since we return this "global" // result as a new individual result - glob_results = malloc_nullsafe(ctx, sizeof(dbresult)+2); - glob_results->num_tuples = 0; + dbres = malloc_nullsafe(ctx, sizeof(dbresult)+2); + dbres->num_tuples = 0; // prepare SQL query va_start(ap, fmt); @@ -261,27 +258,27 @@ dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) { va_end(ap); DEBUG(ctx, 25, "Doing SQL Query: %s", sql); - rc = sqlite3_exec( (sqlite3 *) dbc->dbhandle, sql, _cb_parse_result, 0, &errMsg ); + rc = sqlite3_exec( (sqlite3 *) dbc->dbhandle, sql, _cb_parse_result, dbres, &errMsg ); if( rc != SQLITE_OK ) { eurephia_log(ctx, LOG_ERROR, 0, "SQL Error: %s", errMsg); sqlite3_free(sql); sql = NULL; - free_nullsafe(ctx, glob_results); + free_nullsafe(ctx, dbres); return NULL; } - if( strcasestr(sql, "INSERT INTO") != NULL) { - glob_results->last_insert_id = sqlite3_last_insert_rowid((sqlite3 *) dbc->dbhandle); + if( strcasestr(sql, "INSERT INTO") != 0) { + dbres->last_insert_id = sqlite3_last_insert_rowid((sqlite3 *) dbc->dbhandle); }; - if( strcasestr(sql, "SELECT ") == NULL ) { + if( strcasestr(sql, "SELECT ") == 0 ) { // If not a SELECT query, then get the number of affected records - glob_results->affected_rows = sqlite3_changes((sqlite3 *) dbc->dbhandle); + dbres->affected_rows = sqlite3_changes((sqlite3 *) dbc->dbhandle); } - glob_results->srch_tuples = glob_results->tuples; - glob_results->srch_headerrec = glob_results->headerrec; + dbres->srch_tuples = dbres->tuples; + dbres->srch_headerrec = dbres->headerrec; sqlite3_free(sql); sql = NULL; - return glob_results; + return dbres; } /** @@ -679,20 +676,26 @@ int sqlite_get_affected_rows(dbresult *res) { } #ifdef SQLITE_DEBUG -// Just a simple test program ... to debug this sqlite wrapper -int main() { +/* + * Just a simple test program ... to debug this sqlite wrapper + * + * To compile it: + * gcc -o sqlite sqlite.c -lsqlite3 -I ../ -I ../../common/ ../../common/eurephia_log.c ../../common/eurephia_nullsafe.c ../eurephiadb_mapping.c ../../common/eurephia_xml.c `pkg-config libxml-2.0 --cflags --libs` ../../common/passwd.c -DSQLITE_DEBUG ../../common/sha512.c ../../common/eurephia_values.c ../../common/randstr.c `pkg-config openssl --cflags --libs` -Wall -g -DHAVE_LIBXML2 -D_GNU_SOURCE + */ +int main(int argc, char **argv) { int rc; - dbresult *res = NULL, *res2 = NULL; + dbresult *res = NULL; eurephiaCTX *ctx; -#ifdef MEMWATCH - mwStatistics(3); -#endif + if( argc != 3 ) { + fprintf(stderr, "Usage: %s <db file> <sql query>\n", argv[0]); + return 1; + } ctx = malloc_nullsafe(NULL, sizeof(eurephiaCTX)+2); ctx->dbc = malloc_nullsafe(NULL, sizeof(eDBconn)+2); - rc = sqlite3_open("./vpnaccess", (void *) &ctx->dbc->dbhandle); + rc = sqlite3_open(argv[1], (void *) &ctx->dbc->dbhandle); if( rc ) { fprintf(stderr, "Could not open db\n"); return 1; @@ -702,17 +705,10 @@ int main() { ctx->loglevel = 5; - res = sqlite_query(ctx, "SELECT * FROM openvpn_access"); - res2 = sqlite_query(ctx, "SELECT CURRENT_TIMESTAMP"); + res = sqlite_query(ctx, argv[2]); if( res != NULL ) { sqlite_dump_result(stdout, res); - sqlite_dump_result(stdout, res2); - - fprintf(stderr, "--> %s - %s\n", sqlite_get_value(res, 3, 2), sqlite_get_value(res, 1, 4)); - fprintf(stderr, "--> %s - %s\n", sqlite_get_value(res2, 0, 0), sqlite_get_value(res2, 0, 4)); - sqlite_free_results(res); - sqlite_free_results(res2); } sqlite3_close(ctx->dbc->dbhandle); free(ctx->dbc); |