link0047
link0047

Reputation: 103

Issue with RestKit and CoreData unable to turn off journal mode

I just started using the RestKit framework v0.20.3 vs using Core Data directly. I'm trying to turn off journal mode to view the DB in a SQLite Database Browser. I set the NSSQLitePragmaOption to @{@"journal_mode":@"delete"} with the following code:

NSDictionary *options = @{ NSMigratePersistentStoresAutomaticallyOption:@YES,
                           NSInferMappingModelAutomaticallyOption:@YES,
                           NSSQLitePragmasOption : @{@"journal_mode": @"delete"}
                         };
NSError *error;
NSPersistentStore *persistentStore = [objectStore addSQLitePersistentStoreAtPath:storePath
                                                          fromSeedDatabaseAtPath:nil
                                                               withConfiguration:nil
                                                                         options:options
                                                                           error:&error];

This however doesn't seem to turn off journal mode and remove the .sqlite-wal file. When I use Core Data directly and add this option it works perfectly. Is there something I'm missing?

Upvotes: 0

Views: 410

Answers (2)

Manu Kanthan
Manu Kanthan

Reputation: 197

I've found that addPersistentStoreWithType is called elsewhere in RestKit and needs to have the same option in order to disable journaling. In my case, I was using RKManagedObjectImporter to create a seed DB as follows:

NSError * error = nil;
NSString * seedFilePath = [[NSBundle mainBundle] pathForResource:@"seed" ofType:@"json"];

NSString * documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString * path = [documentsPath stringByAppendingPathComponent:@"MyDB.sqlite"];

RKManagedObjectImporter * importer = [[RKManagedObjectImporter alloc] initWithManagedObjectModel:_objectManager.managedObjectStore.managedObjectModel storePath:path];
[importer importObjectsFromItemAtPath:seedFilePath withMapping:mapping keyPath:keyPath error:&error];
BOOL success = [importer finishImporting:&error];
if (success) {
    [importer logSeedingInfo];
} else {
    RKLogError(@"Failed to finish import and save seed database due to error: %@", error);
}

I was still seeing the -shm and -wal files here even after making the above change to RKManagedObjectStore. It apparently doesn't care about the options used to create _object_manager.managedObjectStore which is of type RKManagedObjectStore.

I found, in RKManagedObjectImporter.m, the createPersistentStoreCoordinator method adds its own persistent store as well, so I added the options dictionary to that:

NSDictionary * options = @{ NSSQLitePragmasOption : @{ @"journal_mode" : @"DELETE" } };
NSPersistentStore *persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                                              configuration:nil
                                                                                        URL:storeURL
                                                                                    options:options error:error];
if (! persistentStore) {
    return nil;
}

Ended up being ... well, kind of crucial to do it since the seed DB will be missing data without it. Now my -shm and -wal files are gone. Thanks, BTW as the above answer helped me hunt down the other location.

Upvotes: 2

Ratan
Ratan

Reputation: 1757

I was facing same issue. The code which was working in iOS 6 suddenly started showing some bugs (data loss) in iOS 7.

I added NSSQLitePragmasOption: @{ @"journal_mode": @"DELETE"} option RKManagedObjectStore object but still I was facing this issue.

So, while going through

- (NSPersistentStore *)addSQLitePersistentStoreAtPath:(NSString *)storePath fromSeedDatabaseAtPath:(NSString *)seedPath withConfiguration:(NSString *)nilOrConfigurationName options:(NSDictionary *)nilOrOptions error:(NSError **)error

method of RKManagedObjectStore.m class, I found out this comment

/** There seems to be trouble with combining configurations and migration. So do this in two steps: first, attach the store with NO configuration, but WITH migration options; then remove it and reattach WITH configuration, but NOT migration options. **/

Here "persistentStore" is re-initialised with "seedOptions" skipping "options" provided by me. So for my project I don't need any configuration, so I commented below lines and it started working.

    if (! [self.persistentStoreCoordinator removePersistentStore:persistentStore error:error]) return nil;

NSDictionary *seedOptions = @{ RKSQLitePersistentStoreSeedDatabasePathOption: (seedPath ?: [NSNull null]) };
persistentStore = [self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nilOrConfigurationName URL:storeURL options:seedOptions error:error];
if (! persistentStore) return nil;

Now wal and shm files are not getting generated and my code works as expected.

Hope this helps.

Upvotes: 1

Related Questions