iOS プロジェクトの一部としてスクリプトを実行します。私がこれを行う理由は、データベース スキーマを作成する同じ一連のスクリプトが、データベース スキーマも更新するためです (リリース後、新しいデルタ スクリプトが実行されてスキーマが前進します)。ここで詳しく説明されています:
Android での SQLITE (データベースをセットアップするための最良の方法論)
スクリプトをリソースとしてプロジェクトに追加し、実行します。EXxxx ログ呼び出しがいくつかありますが、それ以外は一般的です。tail の使用に注意してください - sqlite は、スクリプトが終了した場所のマーカーとして tail を使用してループするときにステートメントを実行します。実行に使用する関数は次のとおりです。
- (BOOL)executeScript:(NSString *)contents error:(NSError **)error
{
ENHeading(@"executeScript");
sqlite3_stmt *stmt = NULL;
const char *zTail;
int rc;
zTail = [contents UTF8String];
while(zTail != NULL && 0 < strlen(zTail))
{
ENDebug("zTail: \"%s\"\n", zTail);
NSString *tailStr = [NSString stringWithUTF8String:zTail];
NSString *trimmed = [tailStr stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([trimmed length] == 0)
{
ENInfo("ignoring trailing whitespace");
break;
}
// Temporarily hold this until the end of the loop in case we need to report an error
const char *newzTail;
rc = sqlite3_prepare_v2(_sqlite3, zTail, -1, &stmt, &newzTail);
if(SQLITE_OK != rc)
{
ENError(@"prepare err:%@", [self errorMessage]);
if (error != NULL) {
*error = [[[ENSqliteError alloc] initWithErrorCode:ENSqliteErrorInvalidSql
reason:[self errorMessage]] autorelease];
}
return NO;
}
rc = sqlite3_step(stmt);
ENDebug(@"rc=%d", rc);
switch (rc)
{
case SQLITE_ROW:
ENError(@"statement returns rows, script ignores");
break;
case SQLITE_OK:
case SQLITE_DONE:
break;
default:
ENError(@"error");
ENError(@"prepare err:%@", [self errorMessage]);
if (error != NULL) {
*error = [[[ENSqliteError alloc] initWithErrorCode:ENSqliteErrorReadingRows
reason:[self errorMessage]] autorelease];
}
return NO;
}
// For next time around the loop
zTail = newzTail;
// Clear up since we're about to prepare another
sqlite3_finalize(stmt);
}
return YES;
}