ChristianKienle / Core-Data-Editor

Core Data Editor lets you easily view, edit and analyze applications‘ data. Core Data Editor is compatible with Mac and iOS applications and supports XML, SQLite and binary stores, visualizes all relationships and is able to edit the data and generate Objective-C code for the data model.
BSD 3-Clause "New" or "Revised" License
2.13k stars 182 forks source link

Logic for Store detection #20

Closed ChristianKienle closed 7 years ago

ChristianKienle commented 10 years ago

I found out that the way Core Data Editor (the project browser) determines if a file is a store file, is wrong.

The logic goes like this: If a file is not a SQLite file (determined by looking at the first couple of bytes of a file) then abort. If a file seems to be a SQLite file then try to load its metadata with NSPersistentStoreCoordinator.

- (NSDictionary *)persistentStoreMetadata {
    BOOL isData = [self isPublicDataFile_cde];
    if(isData == NO) {
        return nil;
    }

    if([self isSQLiteURL_cde] == NO) {
        return nil;
    }
    NSDictionary *metadata;
    @try {
        NSError *error;
        // +metadataForPersistentStoreOfType:URL:error: fails if we have a SQLite file but it is not a Core Data SQLite file...
        metadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:self error:&error];
        if(metadata == nil) {
            return nil;
        }
    }
    @catch (NSException *exception) {

    }
    @finally {

    }
    return metadata;
}

Problems: metadataForPersistentStoreOfType:URL:error: may log and error, throw exceptions or even deadlock if a given URL is not a SQLite, XML or binary store file.

We need a more reliable way to determine if a given file is a SQLite/XML/Binary Core Data store file or something else. One idea which may break in the future: Try to open the file with the raw sqlite C-API and determine if Z_METADATA is present. This may break/change with future versions of Core Data and is not really reliable but more reliable than what is happening now...

Any ideas?

danydev commented 10 years ago

Here another user reporting the same problem with metadataForPersistentStoreOfType:URL:error https://www.mail-archive.com/cocoa-dev@lists.apple.com/msg92594.html

The weird thing is that he said that he is not able to catch the exception! Are you experiencing the same?

ps: maybe would be useful attaching some files that give you this problem, so that others can make some tries.

ChristianKienle commented 10 years ago

Thanks. I am more and more convinced that this method is buggy and that using the SQLite c-API is the way to go.

talzag commented 10 years ago

I don't know if using the SQLite API will work here. From Apple's Core Data documentation at https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdFAQ.html#//apple_ref/doc/uid/TP40001802-CJBDBHCB

Although Core Data supports SQLite as one of its persistent store types, the database format is private. You cannot create a SQLite database using native SQLite API and use it directly with Core Data (nor should you manipulate an existing Core Data SQLite store using native SQLite API).

ChristianKienle commented 10 years ago

What I meant by using the SQLite C-API is this:

We cannot use metadataForPersistentStoreOfType:URL:error: to detect the store type or if it is a SQLite store because it will behave strangely. It also is not good enough to detect if a file is a SQLite file. Because there are SQLite files which are not a Core Data store file - just a random SQLite file.

So we need a way to determine if a file is a Core Data SQLite store file or not. This is what I want to use the SQLite-C API for. Only for the detection. At the moment the detection checks for the existence of a table called Z_PRIMARYKEY. Of such a table exists it is very likely that it is a SQLite store file. I know that this is private but it has not changed since 10.4 and if it ever will change we simply have to adapt.

I think this is the best solution for as long as the offical way is buggy.

Does that make sense to you @talzag ?

talzag commented 10 years ago

Ah, yeah I see what you mean now. Not manipulation of the data, just detection of store type.

ChristianKienle commented 7 years ago

closing because I have removed support for other store types from core data editor. Everyone is using the SQLite store type anyways.