diff options
Diffstat (limited to 'database/sqlite/sqlite.c')
-rw-r--r-- | database/sqlite/sqlite.c | 118 |
1 files changed, 100 insertions, 18 deletions
diff --git a/database/sqlite/sqlite.c b/database/sqlite/sqlite.c index 0303b29..2133df8 100644 --- a/database/sqlite/sqlite.c +++ b/database/sqlite/sqlite.c @@ -54,6 +54,23 @@ * @} */ +/** + * Internal function for setting the error fields. + */ +static void _sqlite_set_error(dbresult *dbres, ErrorSeverity sev, const char *query, const char *fmt, ...) +{ + char errbuf[4098]; + va_list ap; + + va_start(ap, fmt); + memset(&errbuf, 0, 4098); + vsnprintf(errbuf, 4096, fmt, ap); + va_end(ap); + + dbres->errSeverity = sev; + dbres->errMsg = strdup(errbuf); + dbres->query = strdup(query); +} /** * Internal function. Free up a dbresult structure. This function is available via the @@ -102,6 +119,11 @@ void _sqlite_free_results(dbresult *inres) free_nullsafe(NULL, hdr->name); free_nullsafe(NULL, hdr); } + + // Remove error messages and copy of the SQL query + inres->status = dbEMPTY; + free_nullsafe(NULL, inres->errMsg); + free_nullsafe(NULL, inres->query); free_nullsafe(NULL, inres); } @@ -220,6 +242,67 @@ static int _cb_parse_result(void *resultptr, int argc, char **argv, char **colNa return 0; } +/** + * Logs sqlite error messages via the eurephia log interface and returns an XML node with details + * (This function is only included if libxml2 is available) + * + * @param eurephiaCTX* eurephia context pointer, where logging will be performed + * @param dbresult* Pointer to the database result with the error message + * + */ +void sqlite_log_error(eurephiaCTX *ctx, dbresult *dbres) { + if( dbres == NULL ) { + eurephia_log(ctx, LOG_CRITICAL, 2, "Unknown error (NULL result)"); + return; + } + + if( dbres->status != dbSUCCESS ) { + eurephia_log(ctx, LOG_ERROR, 4, "SQL Error: %s", dbres->errMsg); + } + DEBUG(ctx, 33, "SQL Query: %s", dbres->query); +} + + +/** + * Logs sqlite error messages via the eurephia log interface and returns an XML node with details + * (This function is only included if libxml2 is available) + * + * @param eurephiaCTX* eurephia context pointer, where logging will be performed + * @param dbresult* Pointer to the database result with the error message + * + * @return An xmlNode pointer with more details of the error. + */ +#ifdef HAVE_LIBXML2 +xmlNode *sqlite_log_error_xml(eurephiaCTX *ctx, dbresult *dbres ) { + xmlNode *ret = NULL; + + sqlite_log_error(ctx, dbres); + if( dbres == NULL ) { + return NULL; + } + + ret = xmlNewNode(NULL, (xmlChar *) "SQLError"); + if( ret != NULL ) { + xmlNode *err_n = NULL; + xmlChar *errstr = NULL; + const xmlChar *ErrorSeverity_str[] = { + (xmlChar *) "Warning", + (xmlChar *) "Error", + (xmlChar *) "Critical", + (xmlChar *) "PANIC", + NULL + }; + + xmlNewProp(ret, (xmlChar *) "driver", (xmlChar *) "edb-sqlite.so"); + errstr = xmlCharStrdup(dbres->errMsg); + err_n = xmlNewTextChild(ret, NULL, (xmlChar *) "ErrorMessage", errstr); + xmlNewProp(err_n, (xmlChar *) "severity", ErrorSeverity_str[dbres->errSeverity]); + free_nullsafe(NULL, errstr); + } + return ret; +} +#endif + /** * Main function for query a SQLite3 database. @@ -236,35 +319,32 @@ dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) { 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"); - return NULL; - } - - if( ctx->context_type == ECTX_NO_PRIVILEGES ) { - eurephia_log(ctx, LOG_ERROR, 0, "Database query attempted from wrong context"); - return NULL; - } - - // prepare a new (global) result set ... - // do not delete the old ones, since we return this "global" - // result as a new individual result + // prepare a new result set ... dbres = malloc_nullsafe(ctx, sizeof(dbresult)+2); + dbres->status = dbEMPTY; dbres->num_tuples = 0; - + // prepare SQL query va_start(ap, fmt); sql = sqlite3_vmprintf(fmt, ap); va_end(ap); + if( ctx->dbc == NULL ) { + _sqlite_set_error(dbres, sevPANIC, sql, "No open database connection to perfom SQL query to"); + goto exit; + } + + if( ctx->context_type == ECTX_NO_PRIVILEGES ) { + _sqlite_set_error(dbres, sevCRITICAL, sql, "Database query attempted from wrong context"); + goto exit; + } + DEBUG(ctx, 25, "Doing SQL Query: %s", sql); 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; + _sqlite_set_error(dbres, (dbres->num_tuples > 0 ? sevWARNING : sevERROR), sql, "%s", errMsg); sqlite3_free(errMsg); errMsg = NULL; - free_nullsafe(ctx, dbres); - return NULL; + goto exit; } if( strcasestr(sql, "INSERT INTO") != 0) { @@ -275,8 +355,10 @@ dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) { dbres->affected_rows = sqlite3_changes((sqlite3 *) dbc->dbhandle); } + dbres->status = dbSUCCESS; dbres->srch_tuples = dbres->tuples; dbres->srch_headerrec = dbres->headerrec; + exit: sqlite3_free(sql); sql = NULL; return dbres; |