@@ -871,12 +871,23 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
871
871
u32 meta ;
872
872
int rc = 0 ;
873
873
int command_idx = 0 ;
874
+ int saved_flags ;
875
+ int saved_nChange ;
876
+ int saved_nTotalChange ;
877
+ void (* saved_xTrace )(void * ,const char * );
878
+ Db * pDb = 0 ;
874
879
sqlite3 * db = ctx -> pBt -> db ;
875
880
const char * db_filename = sqlite3_db_filename (db , "main" );
876
881
const char * migrated_db_filename = sqlite3_mprintf ("%s-migrated" , db_filename );
877
882
const char * key = ctx -> read_ctx -> pass ;
878
- int db_idx = db -> nDb ;
879
- CODEC_TRACE (("current database count:%d\n" , db_idx ));
883
+ static const unsigned char aCopy [] = {
884
+ BTREE_SCHEMA_VERSION , 1 , /* Add one to the old schema cookie */
885
+ BTREE_DEFAULT_CACHE_SIZE , 0 , /* Preserve the default page cache size */
886
+ BTREE_TEXT_ENCODING , 0 , /* Preserve the text encoding */
887
+ BTREE_USER_VERSION , 0 , /* Preserve the user version */
888
+ BTREE_APPLICATION_ID , 0 , /* Preserve the application id */
889
+ };
890
+
880
891
if (db_filename ){
881
892
char * attach_command = sqlite3_mprintf ("ATTACH DATABASE '%s-migrated' as migrate KEY '%s';" ,
882
893
db_filename , key );
@@ -893,31 +904,39 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
893
904
}
894
905
}
895
906
sqlite3_free (attach_command );
907
+
896
908
if (rc == SQLITE_OK ){
909
+ if ( !db -> autoCommit ){
910
+ CODEC_TRACE (("cannot migrate from within a transaction" ));
911
+ goto handle_error ;
912
+ }
913
+ if ( db -> activeVdbeCnt > 1 ){
914
+ CODEC_TRACE (("cannot migrate - SQL statements in progress" ));
915
+ goto handle_error ;
916
+ }
917
+
918
+ /* Save the current value of the database flags so that it can be
919
+ ** restored before returning. Then set the writable-schema flag, and
920
+ ** disable CHECK and foreign key constraints. */
921
+ saved_flags = db -> flags ;
922
+ saved_nChange = db -> nChange ;
923
+ saved_nTotalChange = db -> nTotalChange ;
924
+ saved_xTrace = db -> xTrace ;
925
+ db -> flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin ;
926
+ db -> flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder );
927
+ db -> xTrace = 0 ;
897
928
898
- static const unsigned char aCopy [] = {
899
- BTREE_SCHEMA_VERSION , 1 , /* Add one to the old schema cookie */
900
- BTREE_DEFAULT_CACHE_SIZE , 0 , /* Preserve the default page cache size */
901
- BTREE_TEXT_ENCODING , 0 , /* Preserve the text encoding */
902
- BTREE_USER_VERSION , 0 , /* Preserve the user version */
903
- BTREE_APPLICATION_ID , 0 , /* Preserve the application id */
904
- };
905
-
906
- CODEC_TRACE (("current database count:%d\n" , db -> nDb ));
907
929
Btree * pDest = db -> aDb [0 ].pBt ;
908
- Btree * pSrc = db -> aDb [db -> nDb - 1 ].pBt ;
909
-
910
- CODEC_TRACE (("pSrc is '%p'\n" , (void * )pSrc ));
911
- CODEC_TRACE (("pDest is '%p'\n" , (void * )pDest ));
930
+ pDb = & (db -> aDb [db -> nDb - 1 ]);
931
+ Btree * pSrc = pDb -> pBt ;
912
932
913
- // rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
933
+ rc = sqlite3_exec (db , "BEGIN;" , NULL , NULL , NULL );
914
934
rc = sqlite3BtreeBeginTrans (pSrc , 2 );
915
- rc = sqlite3BtreeBeginTrans (pDest , 2 );
935
+ // rc = sqlite3BtreeBeginTrans(pDest, 2);
916
936
917
937
assert ( 1 == sqlite3BtreeIsInTrans (pDest ) );
918
938
assert ( 1 == sqlite3BtreeIsInTrans (pSrc ) );
919
939
920
- CODEC_TRACE (("before metadata copy\n" ));
921
940
int i = 0 ;
922
941
for (i = 0 ; i < ArraySize (aCopy ); i += 2 ){
923
942
sqlite3BtreeGetMeta (pSrc , aCopy [i ], & meta );
@@ -927,15 +946,28 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
927
946
rc = sqlite3BtreeCopyFile (pSrc , pDest );
928
947
if ( rc != SQLITE_OK ) goto handle_error ;
929
948
rc = sqlite3BtreeCommit (pDest );
930
- rc = sqlite3_exec (db , "DETACH DATABASE migrate;" , NULL , NULL , NULL );
949
+
950
+ db -> flags = saved_flags ;
951
+ db -> nChange = saved_nChange ;
952
+ db -> nTotalChange = saved_nTotalChange ;
953
+ db -> xTrace = saved_xTrace ;
954
+ sqlite3BtreeSetPageSize (pDest , -1 , -1 , 1 );
955
+ db -> autoCommit = 1 ;
956
+ if ( pDb ){
957
+ sqlite3BtreeClose (pDb -> pBt );
958
+ pDb -> pBt = 0 ;
959
+ pDb -> pSchema = 0 ;
960
+ }
961
+ sqlite3ResetAllSchemasOfConnection (db );
931
962
remove (migrated_db_filename );
963
+ sqlite3_free (migrated_db_filename );
932
964
}
933
- sqlite3_free (migrated_db_filename );
934
965
}
935
966
goto exit ;
936
967
937
968
handle_error :
938
- CODEC_TRACE (("An error occurred\n" ));
969
+ CODEC_TRACE (("an error occurred\n" ));
970
+ rc = SQLITE_ERROR ;
939
971
940
972
exit :
941
973
return rc ;
0 commit comments