summaryrefslogtreecommitdiffstats
path: root/database/sqlite/sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'database/sqlite/sqlite.c')
-rw-r--r--database/sqlite/sqlite.c173
1 files changed, 151 insertions, 22 deletions
diff --git a/database/sqlite/sqlite.c b/database/sqlite/sqlite.c
index 7d240a9..425b128 100644
--- a/database/sqlite/sqlite.c
+++ b/database/sqlite/sqlite.c
@@ -38,6 +38,9 @@
#include <memwatch.h>
#endif
+#define btWHERE 0x001
+#define btINSERT 0x002
+#define btUPDATE 0x004
dbresult *glob_results = NULL;
@@ -240,34 +243,160 @@ dbresult *sqlite_query(eurephiaCTX *ctx, char *fmt, ... ) {
return glob_results;
}
-dbresult *sqlite_query_mapped(eurephiaCTX *ctx, char *sql_start, eDBfieldMap *whmap) {
+inline int SQLreservedWord(char **reserved_words, const char *val) {
+ int i;
+
+ // If we find the word in val defined in the reserved_words array, return 1.
+ for( i = 0; reserved_words[i] != NULL; i++ ) {
+ if( strcmp(val, reserved_words[i]) == 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+char *_build_value_string(eDBfieldMap *ptr) {
+ char *reserved_datetime[] = {"CURRENT_TIMESTAMP", "CURRENT_TIME", "CURRENT_DATE", NULL};
+ char *val = NULL;
+
+ // Format the input value according to the defined data type
+ switch( ptr->field_type ) {
+ case ft_INT:
+ // Format integer values as integers
+ val = sqlite3_mprintf("%i", atoi_nullsafe(ptr->value));
+ break;
+
+ case ft_DATETIME:
+ // If the value is a reserved SQL word, don't encapsulate the value
+ if( SQLreservedWord(reserved_datetime, ptr->value) == 1 ) {
+ val = sqlite3_mprintf("%q", ptr->value);
+ } else {
+ val = sqlite3_mprintf("'%q'", ptr->value);
+ }
+ break;
+
+ case ft_PASSWD:
+ case ft_STRING:
+ default:
+ val = sqlite3_mprintf("'%q'", ptr->value);
+ break;
+ }
+ return val;
+}
+
+#define append_str(dest, src, size) strncat(dest, src, (size - strlen_nullsafe(dest)))
+char *_build_sqlpart(int btyp, eDBfieldMap *map) {
eDBfieldMap *ptr = NULL;
- char where[8195], *sqlp = NULL;
- int first;
-
- assert((ctx != NULL) && (sql_start != NULL) && (whmap != NULL) );
-
- // Prepare where clause
- memset(&where, 0, 8195);
- strcat(where, " (");
- first = 1;
-
- // Loop through all fields in the field map, and add properly
- // formed SQL for a WHERE clause
- for(ptr = whmap; ptr != NULL; ptr = ptr->next) {
- // Only add those fields which is not NULL
- if( (ptr->value != NULL) ) {
- sqlp = sqlite3_mprintf("%s%s='%q'", (first != 1 ? " AND " : ""),
- ptr->field_name, ptr->value);
- strncat(where, sqlp, (8192 - strlen_nullsafe(where)));
- sqlite3_free(sqlp);
+ char *ret = NULL;
+ char *fsep = NULL;
+ char fields[4094], vals[4094];
+ char buf[8196];
+ int first = 1;
+
+ memset(&buf, 0, 8196);
+ switch( btyp ) {
+ case btWHERE:
+ case btUPDATE:
+ fsep = (btyp == btWHERE ? " AND " : ",");
+ append_str(buf, "(", 8192);
+ for( ptr = map; ptr != NULL; ptr = ptr->next ) {
+ char *val = NULL;
+
+ // If the value is NULL, ignore it if we're building up WHERE clause
+ if( (ptr->value == NULL) && (btyp == btWHERE) ) {
+ continue;
+ }
+
+ // Add separator in front of next value
+ if( first != 1 ) {
+ append_str(buf, fsep, 8192);
+ }
+
+ // Put the pieces together and append it to the final result
+ val = _build_value_string(ptr);
+ append_str(buf, ptr->field_name, 8192);
+ append_str(buf, "=", 8192);
+ append_str(buf, val, 8192);
+ sqlite3_free(val);
first = 0;
}
+ append_str(buf, ")", 8192);
+ break;
+
+ case btINSERT: // (field_name, field_name, field_name) VALUES ('val','val','val')
+ memset(&fields, 0, 4090);
+
+ for( ptr = map; ptr != NULL; ptr = ptr->next ) {
+ char *val = NULL;
+
+ // Put separator in front of values and field names
+ if( first != 1 ) {
+ append_str(fields, ",", 8192);
+ append_str(vals, ",", 8192);
+ first = 0;
+ }
+
+ // Append the current field name and value to each string
+ append_str(fields, ptr->field_name, 4092);
+ val = _build_value_string(ptr);
+ append_str(vals, val, 4092);
+ sqlite3_free(val);
+ }
+
+ // Put all the pieces together
+ append_str(buf, "(", 8192);
+ append_str(buf, fields, 8192);
+ append_str(buf, ") VALUES (", 8192);
+ append_str(buf, vals, 8192);
+ append_str(buf, ")", 8192);
+ break;
}
- strcat(where, ")"); // End this where clause
+
+ ret = strdup_nullsafe(buf);
+ return ret;
+}
+
+
+dbresult *sqlite_query_mapped(eurephiaCTX *ctx, SQLqueryType qType, const char *sqlstub,
+ eDBfieldMap *valMap, eDBfieldMap *whereMap)
+{
+ dbresult *res = NULL;
+ char *tmp1 = NULL, *tmp2 = NULL;
+
+ assert((ctx != NULL) && (sqlstub != NULL));
+
+ // Build up SQL clause and send the query
+ switch( qType ) {
+ case SQL_SELECT:
+ case SQL_DELETE:
+ if( whereMap != NULL ) {
+ tmp1 = _build_sqlpart(btWHERE, whereMap);
+ res = sqlite_query(ctx, "%s WHERE %s", sqlstub, tmp1);
+ free_nullsafe(tmp1);
+ }
+ break;
+
+ case SQL_UPDATE:
+ if( (whereMap != NULL) && (valMap != NULL) ) {
+ tmp1 = _build_sqlpart(btUPDATE, valMap);
+ tmp2 = _build_sqlpart(btWHERE, whereMap);
+
+ res = sqlite_query(ctx, "%s SET %s WHERE %s", sqlstub, tmp1, tmp2);
+ free_nullsafe(tmp1);
+ free_nullsafe(tmp2);
+ }
+ break;
+
+ case SQL_INSERT:
+ tmp1 = _build_sqlpart(btINSERT, valMap);
+ res = sqlite_query(ctx, "%s %s", sqlstub, tmp1);
+ free_nullsafe(tmp1);
+ break;
+ }
// Send the SQL query to the database and return the result
- return sqlite_query(ctx, "%s WHERE %s", sql_start, where);
+ return res;
}
// Simple line-by-line result dumper