2013-07-09 71 views
2

我想将预先填充的sqlite数据库集成到phonegap iPhone应用程序中,并且无法使用javascript连接到数据库。如何将prepopulated的sqlite数据库集成到phonegap iPhone应用程序中

该集成的必要步骤是什么?

我使用Phonegap-SQLite插件(https://github.com/davibe/Phonegap-SQLitePlugin/)。单元测试运行正常。 (动态创建一个数据库,从它读取/写入),所以插件的工作。但我无法访问预填充的数据库。

db放在Resources文件夹中。它是根据项目选项列出/构建阶段/复制包资源

我尝试如下分配它在javascript:

var db = window.sqlitePlugin.openDatabase({name: "dbname.db"});

它得到一个数据库对象返回,而不是充满分贝。有趣的是,当我在模拟器中进行新的运行时,会使用相同的数据库。

在日志窗口中,我得到以下信息: 文件:

的成品负载///Users/username/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/33553FCA -3FFA-4BBB-9986-110721148F85/Appname.app/WWW/index.html中

2013年7月9日18:39:14.977 Raumklima [49796:C07]检测到的文档路径: /用户/戴夫/库/ Application Support/iPhone Simulator/5.0/Applications/33553FCA-3FFA-4BBB-9986-110721148F85/Documents

2013-07-09 18:39:14.977 AppName [49796:c07] using db name: /Users/usernam/Library/Application Support/iPhone Simulator/5.0/Applications/33553FCA-3FFA-4BBB-9986-110721148F85 /Documents/dbname.db

我用电话差距2.5.0

有谁知道我有这么寻求一个解决方案?可能是什么问题呢?或者一般来说应该如何处理这个问题。

类似的问题已经问到这个平台上,但目前还没有答案:

Creating a PhoneGap iOS app with a pre-existing database

​​

+0

请参阅我的答案:http://stackoverflow.com/questions/34673365/working-with-prepopulated-sqlite-database-in-phonegap-android/37857340#37857340 – Balflear

回答

3

的SQLitePlugin不给你预填充的数据库作为发货。因此,目前发生的事情是,您打开的数据库不存在,因此SQLite会创建并打开一个空数据库,其中Documents不存在。

如果您希望SQLitePlugin从“资源”部分中的现有SQLite数据库填充数据库,则需要执行一些工作才能达到目标。这是我做过什么:(替换SQLPlugin.mopen法)

/* 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]; 
} 

现在,如果你确保你已经添加了数据库项目的资源节(也加入他们“复制包资源”,在目标的Build Phases部分),数据库将在必要时从Resources复制到Documents。这将返回Documents目录中可写数据库的句柄。

1

我修改了代码http://gauravstomar.blogspot.com/2011/08/prepopulate-sqlite-in-phonegap.html,修改了最后一个,添加了一个检查,看sqlite数据库是否已经存在。

void copy(String file, String folder) throws IOException { 
    File CheckDirectory; 
    CheckDirectory = new File(folder); 
    if (!CheckDirectory.exists()) 
    { 
     CheckDirectory.mkdir(); 
    } 

    File f = new File(folder+file); 
    if(!f.exists()) {  
    InputStream in = getApplicationContext().getAssets().open(file); 
    OutputStream out = new FileOutputStream(folder+file); 

    // Transfer bytes from in to out 
    byte[] buf = new byte[1024]; 
    int len; while ((len = in.read(buf)) > 0) out.write(buf, 0, len); 
    in.close(); out.close(); 
    } 
} 
+0

在哪个文件夹中添加了此代码? – Muhammed

0

我曾在这个问题上很长一段时间 - 问题是要导入一个预填充数据库 - 其中有很多不容易的解决方案。我发现最好的 - 现在只是关于 - 解决方案是LiteHelpers CORDOVA-SQLITE-EXT(https://github.com/litehelpers/cordova-sqlite-ext

我已经将它添加到我的应用程序中,它运行良好。我不得不从PhoneGap切换 - 并使用CORDOVA - 但它为我工作。

相关问题