@@ -164,10 +164,11 @@ int dbutils_write_simple (sqlite3 *db, const char *sql) {
164164}
165165
166166sqlite3_int64 dbutils_int_select (sqlite3 * db , const char * sql ) {
167+ // used only for cound(*), hash, or 1, so return -1 to signal an error
167168 DATABASE_RESULT results [1 ] = {0 };
168169 int expected_types [1 ] = {SQLITE_INTEGER };
169170 dbutils_exec (NULL , db , sql , NULL , NULL , NULL , 0 , results , expected_types , 1 );
170- return results [0 ].value .intValue ;
171+ return ( results [0 ].rc == SQLITE_OK ) ? results [ 0 ]. value .intValue : -1 ;
171172}
172173
173174char * dbutils_text_select (sqlite3 * db , const char * sql ) {
@@ -177,11 +178,12 @@ char *dbutils_text_select (sqlite3 *db, const char *sql) {
177178 return results [0 ].value .stringValue ;
178179}
179180
180- char * dbutils_blob_select (sqlite3 * db , const char * sql , int * size ) {
181+ char * dbutils_blob_select (sqlite3 * db , const char * sql , int * size , sqlite3_context * context , int * rc ) {
181182 DATABASE_RESULT results [1 ] = {0 };
182183 int expected_types [1 ] = {SQLITE_BLOB };
183- dbutils_exec (NULL , db , sql , NULL , NULL , NULL , 0 , results , expected_types , 1 );
184+ dbutils_exec (context , db , sql , NULL , NULL , NULL , 0 , results , expected_types , 1 );
184185 * size = results [0 ].len ;
186+ * rc = results [0 ].rc ;
185187 return results [0 ].value .stringValue ;
186188}
187189
@@ -197,6 +199,7 @@ int dbutils_blob_int_int_select (sqlite3 *db, const char *sql, char **blob, int
197199}
198200
199201sqlite3_int64 dbutils_select (sqlite3 * db , const char * sql , const char * * values , int types [], int lens [], int count , int expected_type ) {
202+ // used only in unit-test
200203 DATABASE_RESULT results [1 ] = {0 };
201204 int expected_types [1 ] = {expected_type };
202205 dbutils_exec (NULL , db , sql , values , types , lens , count , results , expected_types , 1 );
@@ -396,6 +399,9 @@ bool dbutils_table_sanity_check (sqlite3 *db, sqlite3_context *context, const ch
396399 if (count > 128 ) {
397400 dbutils_context_result_error (context , "No more than 128 columns can be used to form a composite primary key" );
398401 return false;
402+ } else if (count == -1 ) {
403+ dbutils_context_result_error (context , "%s" , sqlite3_errmsg (db ));
404+ return false;
399405 }
400406
401407 #if CLOUDSYNC_DISABLE_ROWIDONLY_TABLES
@@ -417,13 +423,21 @@ bool dbutils_table_sanity_check (sqlite3 *db, sqlite3_context *context, const ch
417423 dbutils_context_result_error (context , "Table %s uses an single-column INTEGER primary key. For CRDT replication, primary keys must be globally unique. Consider using a TEXT primary key with UUIDs or ULID to avoid conflicts across nodes. If you understand the risk and still want to use this INTEGER primary key, set the third argument of the cloudsync_init function to 1 to skip this check." , name );
418424 return false;
419425 }
426+ if (count2 == -1 ) {
427+ dbutils_context_result_error (context , "%s" , sqlite3_errmsg (db ));
428+ return false;
429+ }
420430 }
421431 }
422432
423433 // if user declared explicit primary key(s) then make sure they are all declared as NOT NULL
424434 if (count > 0 ) {
425435 sql = sqlite3_snprintf ((int )blen , buffer , "SELECT count(*) FROM pragma_table_info('%w') WHERE pk>0 AND \"notnull\"=1;" , name );
426436 sqlite3_int64 count2 = dbutils_int_select (db , sql );
437+ if (count2 == -1 ) {
438+ dbutils_context_result_error (context , "%s" , sqlite3_errmsg (db ));
439+ return false;
440+ }
427441 if (count != count2 ) {
428442 dbutils_context_result_error (context , "All primary keys must be explicitly declared as NOT NULL (table %s)" , name );
429443 return false;
@@ -434,6 +448,10 @@ bool dbutils_table_sanity_check (sqlite3 *db, sqlite3_context *context, const ch
434448 // Otherwise, col_merge_stmt would fail if changes to other columns are inserted first.
435449 sql = sqlite3_snprintf ((int )blen , buffer , "SELECT count(*) FROM pragma_table_info('%w') WHERE pk=0 AND \"notnull\"=1 AND \"dflt_value\" IS NULL;" , name );
436450 sqlite3_int64 count3 = dbutils_int_select (db , sql );
451+ if (count3 == -1 ) {
452+ dbutils_context_result_error (context , "%s" , sqlite3_errmsg (db ));
453+ return false;
454+ }
437455 if (count3 > 0 ) {
438456 dbutils_context_result_error (context , "All non-primary key columns declared as NOT NULL must have a DEFAULT value. (table %s)" , name );
439457 return false;
@@ -1026,7 +1044,7 @@ int dbutils_settings_init (sqlite3 *db, void *cloudsync_data, sqlite3_context *c
10261044 // check if some process changed schema outside of the lib
10271045 /*
10281046 if ((settings_exists == true) && (data->schema_version != dbutils_schema_version(db))) {
1029- // TODO: SOMEONE CHANGED SCHEMAs SO WE NEED TO RECHECK AUGMENTED TABLES and RELATED TRIGGERS
1047+ // SOMEONE CHANGED SCHEMAs SO WE NEED TO RECHECK AUGMENTED TABLES and RELATED TRIGGERS
10301048 assert(0);
10311049 }
10321050 */
@@ -1072,7 +1090,7 @@ bool dbutils_check_schema_hash (sqlite3 *db, sqlite3_uint64 hash) {
10721090 char sql [1024 ];
10731091 snprintf (sql , sizeof (sql ), "SELECT 1 FROM cloudsync_schema_versions WHERE hash = (%lld)" , hash );
10741092
1075- return dbutils_int_select (db , sql ) == 1 ;
1093+ return ( dbutils_int_select (db , sql ) == 1 ) ;
10761094}
10771095
10781096
0 commit comments