2

事前入力された sqlite データベースを phonegap iPhone アプリに統合したいのですが、javascript を使用してデータベースに接続するのに問題があります。

その統合に必要な手順は何ですか?

Phonegap-SQLite プラグイン ( https://github.com/davibe/Phonegap-SQLitePlugin/ ) を使用します。単体テストは正しく実行されます。(オンザフライでデータベースを作成し、そこから読み取り/書き込み)、プラグインが機能します。しかし、事前入力されたデータベースにアクセスできません。

データベースは Resources フォルダー内に配置されます。プロジェクトオプション/ビルドフェーズ/バンドルリソースのコピーの下にリストされています

次のようにjavascriptで割り当てようとします:

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

db オブジェクトを取得しますが、満たされた db は取得しません。興味深いことに、シミュレーターで新しい実行を行うと、同じデータベースが使用されます。

ログ ウィンドウに次のメッセージが表示されます。

次の読み込みが完了しました: file:///Users/username/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/33553FCA-3FFA-4BBB-9986-110721148F85/Appname.app/www/index.html

2013-07-09 18:39:14.977 Raumklima[49796:c07] 検出されたドキュメント パス: /Users/dave/Library/Application Support/iPhone Simulator/5.0/Applications/33553FCA-3FFA-4BBB-9986-110721148F85/Documents

2013-07-09 18:39:14.977 AppName[49796:c07] データベース名を使用: /Users/usernam/Library/Application Support/iPhone Simulator/5.0/Applications/33553FCA-3FFA-4BBB-9986-110721148F85/Documents/dbname .db

phone gap 2.5.0を使っています

私がどこにいるのか知っている人はいますか?何が問題なのですか?または、一般的に、この問題にどのように取り組むべきか。

このプラットフォームでも同様の質問が寄せられていますが、まだ回答がありません。

既存のデータベースを使用した PhoneGap iOS アプリの作成

PhoneGap / Cordova 2.0 で事前設定された SQLite データベースを使用するにはどうすればよいですか?

4

3 に答える 3

3

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 ディレクトリ内の書き込み可能なデータベースへのハンドルが返されます。

于 2013-08-14T00:40:52.073 に答える
1

http://gauravstomar.blogspot.com/2011/08/prepopulate-sqlite-in-phonegap.htmlのコードを変更し、最後のコードを変更して、sqlite db が既に存在するかどうかのチェックを追加しました。

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();
    }
}
于 2013-08-31T00:08:19.380 に答える