SQLitePlugin は、出荷時に事前設定されたデータベースを提供しません。したがって、現在起こっていることは、Documents
まだ存在していない でデータベースを開こうとしているということです。そのため、SQLite は空のデータベースを作成して開きます。
SQLitePlugin で、リソース セクションの既存の SQLite DB からデータベースにデータを入力する場合は、そこに到達するために少し作業を行う必要があります。これは私がしたことです: (open
メソッドを に置き換えますSQLPlugin.m
)
/* This is a hacked version which will copy the file from the Resources path
if it does not exist in the Documents path or if it is newer. */
-(void)open: (CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSMutableDictionary *options = [command.arguments objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dbname = [self getDBPath:[options objectForKey:@"name"]];
NSValue *dbPointer;
if (dbname == NULL) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"You must specify database name"];
}
else {
dbPointer = [openDBs objectForKey:dbname];
if (dbPointer != NULL) {
// NSLog(@"Reusing existing database connection");
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Database opened"];
}
else {
//NSLog(@"Opening %@", dbname );
NSError *error;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[options objectForKey:@"name"]];
//NSLog(@"Date in app was %@", [[[fileManager attributesOfItemAtPath:databasePathFromApp error:NULL] fileModificationDate] description]);
//NSLog(@"Local date was %@", [[[fileManager attributesOfItemAtPath:dbname error:NULL] fileModificationDate] description]);
if (![fileManager fileExistsAtPath:dbname]) {
BOOL success = [fileManager copyItemAtPath:databasePathFromApp toPath:dbname error:&error] ;
if (!success) {
NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
}
NSLog(@"Database didn't exist in %@, copying it from %@", dbname, databasePathFromApp);
} else if ([[[fileManager attributesOfItemAtPath:databasePathFromApp error:NULL] fileModificationDate] compare:[[fileManager attributesOfItemAtPath:dbname error:NULL] fileModificationDate]] == NSOrderedDescending) {
[fileManager removeItemAtPath:dbname error:NULL];
BOOL success = [fileManager copyItemAtPath:databasePathFromApp toPath:dbname error:&error];
if (!success) {
NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
}
NSLog(@"Database in app was newer, copying it from %@", databasePathFromApp);
[[NSURL fileURLWithPath:dbname] setResourceValue: [NSNumber numberWithBool: YES]
forKey: NSURLIsExcludedFromBackupKey error: NULL];
}
const char *name = [dbname UTF8String];
// NSLog(@"using db name: %@", dbname);
sqlite3 *db;
if (sqlite3_open(name, &db) != SQLITE_OK) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Unable to open DB"];
return;
}
else {
// Extra for SQLCipher:
// const char *key = [[options objectForKey:@"key"] UTF8String];
// if(key != NULL) sqlite3_key(db, key, strlen(key));
// Attempt to read the SQLite master table (test for SQLCipher version):
if(sqlite3_exec(db, (const char*)"SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
dbPointer = [NSValue valueWithPointer:db];
[openDBs setObject: dbPointer forKey: dbname];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Database opened"];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Unable to encrypt DB"];
}
}
}
}
if (sqlite3_threadsafe()) {
NSLog(@"Good news: SQLite is thread safe!");
}
else {
NSLog(@"Warning: SQLite is not thread safe.");
}
[self.commandDelegate sendPluginResult:pluginResult callbackId: command.callbackId];
}
プロジェクトの Resources セクションにデータベースを追加した (さらに、ターゲットの Build Phases セクションの "Copy Bundle Resources" にも追加した) ことを確認すると、データベースは必要に応じて から にコピーされResources
ますDocuments
。これにより、Documents ディレクトリ内の書き込み可能なデータベースへのハンドルが返されます。