Search code examples
iosdatabasesqliteicloudxmppframework

Could not modify sqlite file after copying it to new path in ios


In my app I have sqlite file & I want to copy that file to another path. I have the following code. but when I copy it I found that all data is not copied to the new file. If I have new File then next time before copying I have to delete file(Replacement of file with new data) & copy the new file at same path. If again I copied the data to new path & if all data is copied to new path that time I can not modify the old sqlite file. I don't understand why I can't modify database after all data is copied. & how do I come to that all data is successfully copied? what are the ways to achieve this. If anyone want any extra information I will provide you.

NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,
                                    NSUserDomainMask, YES);
NSString *applicationSupportDirectory = [paths firstObject];
NSString *str=[NSString stringWithFormat:@"%@/XMPPMessageArchiving.sqlite",applicationSupportDirectory];//copy this file

NSString *fileName = [NSString stringWithFormat:@"XMPPMessageArchiving.sqlite"];
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];


NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];

NSURL *fromURL = [NSURL fileURLWithPath:str];
NSURL *toURL = [[ubiq URLByAppendingPathComponent:@"Documents"]
                URLByAppendingPathComponent:fileName]; 

[coordinator coordinateReadingItemAtURL:fromURL options:NSFileCoordinatorReadingForUploading writingItemAtURL:toURL options:0 error:nil byAccessor:^(NSURL *newReadingURL, NSURL *newWritingURL)
 {

     NSFileManager* fileManager = [[NSFileManager alloc] init];
     BOOL fileExists = [fileManager fileExistsAtPath:newWritingURL.path];
     if (fileExists)
     {
         [fileManager removeItemAtURL:toURL error:nil];
     }

     NSError *error=nil;
     [fileManager copyItemAtURL:newReadingURL toURL:newWritingURL error:&error];

 }];

Solution

  • All the problem is because of .sqlite-wal File. In my case the data is first inserted into wal(write ahead logging) file & then that data is committed into original sqlite file. & when I was trying to copy that original sqlite file that time I don't have newest data in file & I am trying to copy that file... All data (which present in original file) get properly copied. Now the data in wal file is not in original file thats why I couldn't get that data while copying. & I was thinking like data loss is happing...After so much struggle I found the solution. I changed the sqlite journal mode to delete using the following line of code.

    NSDictionary *options = @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};
    
    [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                            configuration:nil
                                            URL:storeURL
                                            options:options
                                            error:&error]