2013-07-09 77 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 - 但它爲我工作。

相關問題