@@ -104,6 +104,11 @@ typedef struct {
104104 int index ;
105105} cloudsync_pk_decode_context ;
106106
107+ typedef struct {
108+ sqlite3_context * context ;
109+ bool skip_int_pk_check ;
110+ } cloudsync_init_all_context ;
111+
107112#define SYNCBIT_SET (_data ) _data->insync = 1
108113#define SYNCBIT_RESET (_data ) _data->insync = 0
109114#define BUMP_SEQ (_data ) ((_data)->seq += 1, (_data)->seq - 1)
@@ -1502,8 +1507,11 @@ void cloudsync_context_free (void *ptr) {
15021507const char * cloudsync_context_init (sqlite3 * db , cloudsync_context * data , sqlite3_context * context ) {
15031508 if (!data && context ) data = (cloudsync_context * )sqlite3_user_data (context );
15041509
1505- // perform init just the first time, if the site_id field is not set
1506- if (data -> site_id [0 ] == 0 ) {
1510+ // perform init just the first time, if the site_id field is not set.
1511+ // The data->site_id value could exists while settings tables don't exists if the
1512+ // cloudsync_context_init was previously called in init transaction that was rolled back
1513+ // because of an error during the init process.
1514+ if (data -> site_id [0 ] == 0 || !dbutils_table_exists (db , CLOUDSYNC_SITEID_NAME )) {
15071515 if (dbutils_settings_init (db , data , context ) != SQLITE_OK ) return NULL ;
15081516 if (stmts_add_tocontext (db , data ) != SQLITE_OK ) return NULL ;
15091517 if (cloudsync_load_siteid (db , data ) != SQLITE_OK ) return NULL ;
@@ -2836,7 +2844,7 @@ int cloudsync_load_siteid (sqlite3 *db, cloudsync_context *data) {
28362844 return SQLITE_OK ;
28372845}
28382846
2839- int cloudsync_init_internal (sqlite3_context * context , const char * table_name , const char * algo_name ) {
2847+ int cloudsync_init_internal (sqlite3_context * context , const char * table_name , const char * algo_name , bool skip_int_pk_check ) {
28402848 DEBUG_FUNCTION ("cloudsync_init_internal" );
28412849
28422850 // get database reference
@@ -2846,7 +2854,7 @@ int cloudsync_init_internal (sqlite3_context *context, const char *table_name, c
28462854 cloudsync_context * data = (cloudsync_context * )sqlite3_user_data (context );
28472855
28482856 // sanity check table and its primary key(s)
2849- if (dbutils_table_sanity_check (db , context , table_name ) == false) {
2857+ if (dbutils_table_sanity_check (db , context , table_name , skip_int_pk_check ) == false) {
28502858 return SQLITE_MISUSE ;
28512859 }
28522860
@@ -2920,13 +2928,15 @@ int cloudsync_init_internal (sqlite3_context *context, const char *table_name, c
29202928}
29212929
29222930int cloudsync_init_all_callback (void * xdata , int ncols , char * * values , char * * names ) {
2923- sqlite3_context * context = (sqlite3_context * )xdata ;
2931+ cloudsync_init_all_context * init_ctx = (cloudsync_init_all_context * )xdata ;
2932+ sqlite3_context * context = init_ctx -> context ;
2933+ bool skip_int_pk_check = init_ctx -> skip_int_pk_check ;
29242934
29252935 for (int i = 0 ; i < ncols ; i += 2 ) {
29262936 const char * table = values [i ];
29272937 const char * algo = values [i + 1 ];
29282938
2929- int rc = cloudsync_init_internal (context , table , algo );
2939+ int rc = cloudsync_init_internal (context , table , algo , skip_int_pk_check );
29302940 if (rc != SQLITE_OK ) {
29312941 cloudsync_cleanup_internal (context , table );
29322942 return rc ;
@@ -2936,37 +2946,33 @@ int cloudsync_init_all_callback (void *xdata, int ncols, char **values, char **n
29362946 return SQLITE_OK ;
29372947}
29382948
2939- int cloudsync_init_all (sqlite3_context * context , const char * algo_name ) {
2949+ int cloudsync_init_all (sqlite3_context * context , const char * algo_name , bool skip_int_pk_check ) {
29402950 char sql [1024 ];
29412951 snprintf (sql , sizeof (sql ), "SELECT name, '%s' FROM sqlite_master WHERE type='table' and name NOT LIKE 'sqlite_%%' AND name NOT LIKE 'cloudsync_%%' AND name NOT LIKE '%%_cloudsync';" , (algo_name ) ? algo_name : CLOUDSYNC_DEFAULT_ALGO );
29422952
29432953 sqlite3 * db = sqlite3_context_db_handle (context );
2944- int rc = sqlite3_exec (db , sql , cloudsync_init_all_callback , context , NULL );
2954+ cloudsync_init_all_context init_ctx = {.context = context , .skip_int_pk_check = skip_int_pk_check };
2955+ int rc = sqlite3_exec (db , sql , cloudsync_init_all_callback , & init_ctx , NULL );
29452956 return rc ;
29462957}
29472958
2948- void cloudsync_init_algo (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
2949- DEBUG_FUNCTION ("cloudsync_init_algo" );
2950-
2951- const char * table = (const char * )sqlite3_value_text (argv [0 ]);
2952- const char * algo = (const char * )sqlite3_value_text (argv [1 ]);
2953-
2959+ void cloudsync_init (sqlite3_context * context , const char * table , const char * algo , bool skip_int_pk_check ) {
29542960 cloudsync_context * data = (cloudsync_context * )sqlite3_user_data (context );
29552961 sqlite3 * db = sqlite3_context_db_handle (context );
2956- int rc = sqlite3_exec (db , "SAVEPOINT cloudsync_init_algo ;" , NULL , NULL , NULL );
2962+ int rc = sqlite3_exec (db , "SAVEPOINT cloudsync_init ;" , NULL , NULL , NULL );
29572963 if (rc != SQLITE_OK ) {
2958- dbutils_context_result_error (context , "Unable to create cloudsync_init_algo savepoint. %s" , sqlite3_errmsg (db ));
2964+ dbutils_context_result_error (context , "Unable to create cloudsync_init savepoint. %s" , sqlite3_errmsg (db ));
29592965 sqlite3_result_error_code (context , rc );
29602966 return ;
29612967 }
29622968
2963- if (dbutils_is_star_table (table )) cloudsync_init_all (context , algo );
2964- else cloudsync_init_internal (context , table , algo );
2969+ if (dbutils_is_star_table (table )) rc = cloudsync_init_all (context , algo , skip_int_pk_check );
2970+ else rc = cloudsync_init_internal (context , table , algo , skip_int_pk_check );
29652971
29662972 if (rc == SQLITE_OK ) {
2967- rc = sqlite3_exec (db , "RELEASE cloudsync_init_algo " , NULL , NULL , NULL );
2973+ rc = sqlite3_exec (db , "RELEASE cloudsync_init " , NULL , NULL , NULL );
29682974 if (rc != SQLITE_OK ) {
2969- dbutils_context_result_error (context , "Unable to release cloudsync_init_algo savepoint. %s" , sqlite3_errmsg (db ));
2975+ dbutils_context_result_error (context , "Unable to release cloudsync_init savepoint. %s" , sqlite3_errmsg (db ));
29702976 sqlite3_result_error_code (context , rc );
29712977 }
29722978 }
@@ -2975,33 +2981,31 @@ void cloudsync_init_algo (sqlite3_context *context, int argc, sqlite3_value **ar
29752981 else sqlite3_exec (db , "ROLLBACK" , NULL , NULL , NULL );
29762982}
29772983
2978- void cloudsync_init (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
2979- DEBUG_FUNCTION ("cloudsync_init " );
2984+ void cloudsync_init3 (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
2985+ DEBUG_FUNCTION ("cloudsync_init2 " );
29802986
29812987 const char * table = (const char * )sqlite3_value_text (argv [0 ]);
2988+ const char * algo = (const char * )sqlite3_value_text (argv [1 ]);
2989+ bool skip_int_pk_check = (bool )sqlite3_value_int (argv [2 ]);
2990+
2991+ cloudsync_init (context , table , algo , skip_int_pk_check );
2992+ }
2993+
2994+ void cloudsync_init2 (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
2995+ DEBUG_FUNCTION ("cloudsync_init2" );
29822996
2983- cloudsync_context * data = (cloudsync_context * )sqlite3_user_data (context );
2984- sqlite3 * db = sqlite3_context_db_handle (context );
2985- int rc = sqlite3_exec (db , "SAVEPOINT cloudsync_init;" , NULL , NULL , NULL );
2986- if (rc != SQLITE_OK ) {
2987- dbutils_context_result_error (context , "Unable to create cloudsync_init savepoint. %s" , sqlite3_errmsg (db ));
2988- sqlite3_result_error_code (context , rc );
2989- return ;
2990- }
2997+ const char * table = (const char * )sqlite3_value_text (argv [0 ]);
2998+ const char * algo = (const char * )sqlite3_value_text (argv [1 ]);
2999+
3000+ cloudsync_init (context , table , algo , false);
3001+ }
29913002
2992- if ( dbutils_is_star_table ( table )) rc = cloudsync_init_all ( context , NULL );
2993- else rc = cloudsync_init_internal ( context , table , NULL );
3003+ void cloudsync_init1 ( sqlite3_context * context , int argc , sqlite3_value * * argv ) {
3004+ DEBUG_FUNCTION ( "cloudsync_init1" );
29943005
2995- if (rc == SQLITE_OK ) {
2996- rc = sqlite3_exec (db , "RELEASE cloudsync_init" , NULL , NULL , NULL );
2997- if (rc != SQLITE_OK ) {
2998- dbutils_context_result_error (context , "Unable to release cloudsync_init savepoint. %s" , sqlite3_errmsg (db ));
2999- sqlite3_result_error_code (context , rc );
3000- }
3001- }
3006+ const char * table = (const char * )sqlite3_value_text (argv [0 ]);
30023007
3003- if (rc == SQLITE_OK ) dbutils_update_schema_hash (db , & data -> schema_hash );
3004- else sqlite3_exec (db , "ROLLBACK" , NULL , NULL , NULL );
3008+ cloudsync_init (context , table , NULL , false);
30053009}
30063010
30073011// MARK: -
@@ -3108,7 +3112,7 @@ void cloudsync_commit_alter (sqlite3_context *context, int argc, sqlite3_value *
31083112 // init again cloudsync for the table
31093113 table_algo algo_current = dbutils_table_settings_get_algo (db , table_name );
31103114 if (algo_current == table_algo_none ) algo_current = dbutils_table_settings_get_algo (db , "*" );
3111- rc = cloudsync_init_internal (context , table_name , crdt_algo_name (algo_current ));
3115+ rc = cloudsync_init_internal (context , table_name , crdt_algo_name (algo_current ), true );
31123116 if (rc != SQLITE_OK ) goto rollback_finalize_alter ;
31133117
31143118 // release savepoint
@@ -3162,12 +3166,16 @@ APIEXPORT int sqlite3_cloudsync_init (sqlite3 *db, char **pzErrMsg, const sqlite
31623166 rc = dbutils_register_function (db , "cloudsync_version" , cloudsync_version , 0 , pzErrMsg , ctx , cloudsync_context_free );
31633167 if (rc != SQLITE_OK ) return rc ;
31643168
3165- rc = dbutils_register_function (db , "cloudsync_init" , cloudsync_init , 1 , pzErrMsg , ctx , NULL );
3169+ rc = dbutils_register_function (db , "cloudsync_init" , cloudsync_init1 , 1 , pzErrMsg , ctx , NULL );
31663170 if (rc != SQLITE_OK ) return rc ;
31673171
3168- rc = dbutils_register_function (db , "cloudsync_init" , cloudsync_init_algo , 2 , pzErrMsg , ctx , NULL );
3172+ rc = dbutils_register_function (db , "cloudsync_init" , cloudsync_init2 , 2 , pzErrMsg , ctx , NULL );
31693173 if (rc != SQLITE_OK ) return rc ;
31703174
3175+ rc = dbutils_register_function (db , "cloudsync_init" , cloudsync_init3 , 3 , pzErrMsg , ctx , NULL );
3176+ if (rc != SQLITE_OK ) return rc ;
3177+
3178+
31713179 rc = dbutils_register_function (db , "cloudsync_enable" , cloudsync_enable , 1 , pzErrMsg , ctx , NULL );
31723180 if (rc != SQLITE_OK ) return rc ;
31733181
0 commit comments