2013年11月6日水曜日

SQLite(FMDB)

FMDBを使用



#import "FMDatabase.h"

FMDatabase* _db;
NSString* DB_FILE = @"sample.sqlite3";

//DBオープン
if (![self openDatabase]) {
    //失敗
}

//更新
if (![self executeUpdate]) {
    //失敗
}

//参照
[self executeQuery];

//DBクローズ
[self closeDatabase];

- (BOOL)openDatabase {

    //DBファイルへのパスを取得
    //パスは~/Documents/配下に格納される。
    NSString *dbPath = nil;
    NSArray *documentsPath = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    
    //取得データ数を確認
    if ([documentsPath count] >= 1) {
        //固定で0番目を取得でOK
        dbPath = [documentsPath objectAtIndex:0];
        //パスの最後にファイル名をアペンドし、DBファイルへのフルパスを生成。
        dbPath = [dbPath stringByAppendingPathComponent:DB_FILE];
        NSLog(@"db path : %@", dbPath);
    } else {
        //error
        NSLog(@"search Document path error. database file open error.");
        return false;
    }
    
    //DBファイルがDocument配下に存在するか判定
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:dbPath]) {
        //存在しない
        //デフォルトのDBファイルをコピー(初回のみ)
        //ファイルはアプリケーションディレクトリ配下に格納されている。
        NSBundle *bundle = [NSBundle mainBundle];
        NSString *orgPath = [bundle bundlePath];
        //初期ファイルのパス。(~/XXX.app/sample.db)
        orgPath = [orgPath stringByAppendingPathComponent:DB_FILE];
        
        //デフォルトのDBファイルをDocument配下へコピー
        if (![fileManager copyItemAtPath:orgPath toPath:dbPath error:nil]) {
            //error
            NSLog(@"db file copy error. : %@ to %@.", orgPath, dbPath);
            return false;
        }
    }
    
    //open database with FMDB.
    _db = [FMDatabase databaseWithPath:dbPath];
    return [_db open];
}

- (void)executeQuery {
    
    //クエリ実行
    FMResultSet *rs = [_db executeQuery:@"select * from items where word = ? ",@"abc"];
    
    if ([_db hadError]) {
        NSLog(@"Err %d: %@", [_db lastErrorCode], [_db lastErrorMessage]);
    }
    
    //結果の取得(カラム名指定)
    while ([rs next]) {
        //[rs dateForColumn:@"n"];
        //[rs stringForColumn:@"t"];
        //[rs doubleForColumn:@"r"];
        NSLog(@"id->%d", [rs intForColumn:@"item_id"]);
    }
    
    //close ResultSet.
    [rs close];
    
}

- (BOOL)executeUpdate {
    
    BOOL result = TRUE;
    //トランザクション開始(exclusive)
    [_db beginTransaction];
    
    //ステートメントの再利用フラグ
    //おそらくループ内で同一クエリの更新処理を行う場合バインドクエリの準備を何回
    //も実行してしまうのためこのフラグを設定する。
    //このフラグが設定されているとステートメントが再利用される。
    [_db setShouldCacheStatements:YES];
    
    //update
    [_db executeUpdate:@"update items set correct_count = correct_count + ? ", [NSNumber numberWithInt:1]];
    
    //check
    if ([_db hadError]) {
        result = FALSE;
        NSLog(@"Err %d: %@", [_db lastErrorCode], [_db lastErrorMessage]);
    }
    
    //commit
    [_db commit];
    
    return result;
}


- (void)closeDatabase {
    if (_db) {
        [_db close];
    }
}

0 件のコメント:

コメントを投稿