ToddleDatabase

ToddleDatabase という SQLite3 のラッパーライブラリを github に置きました。 iPhone での SQLite3 をつかった開発を多少ラクにするためのものです。 Milpon の beta07 からつかっています

例: SELECT

例として、 (id, name, tag_id) というフィールドからなる table から、指定した tag_id をもつ (id, name) をひっぱってくることを考えます。

ベタに SQLite3 の C API をつかうと以下のようなかんじ。

/*
 * collect (id, name) pairs from 'list' table by tag_id.
 *   table 'list' consits of (id, name, tag_id) 
 */
void select_list(sqlite3 *handle, int tag_id)
{
   // construct query
   sqlite3_stmt *stmt = nil;
   const char *query = "SELECT id,name from list where tag_id=?";
 
   if (sqlite3_prepare_v2(handle, query, -1, &stmt, NULL) != SQLITE_OK) {
      handle_error([NSString stringWithFormat:
        @"Error: failed to prepare statement with message '%s'.",
        sqlite3_errmsg([db handle])]);
      return;
   }
 
   sqlite3_bind_int(stmt, 1, tag_id);
 
   // send query and collect results
   while (sqlite3_step(stmt) == SQLITE_ROW) {
      NSNumber *iD   = [NSNumber numberWithInt:sqlite3_column_int(stmt, 0)];
      NSString *name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 1)];
   }
 
   sqlite3_finalize(stmt);
}

これ1つだけならいいんですが、アプリ内にこれと同じようなコードブロックが散在するのが悩みのタネでした。共通化しようにも、query として渡す引数の数はいくつになるかわからないし、型も不定。query の実行結果についても同様で、うまくまとめられません。

ToddleDatabase をつかうと以下のようになります。

(NSArray *) select_list:(ToddleDB *) db withTag:(NSNumber *)tag_id
{
   NSDictionary *where = [NSDictionary
      dictionaryWithObject:[NSString stringWithFormat:@"id=%d", [tag_id intValue]]
      forKey:@"WHERE"];
 
   NSArray *keys  = [NSArray arrayWithObjects:@"id", @"name", nil];                     // fields of table
   NSArray *types = [NSArray arrayWithObjects:[NSNumber class], [NSString class], nil]; // types of each fields
   NSDictionary *query = [NSDictionary dictionaryWithObjects:types forKeys:keys];       // run SQL SELECT
   return [toddleDB select:query from:@"list" option:where];
}

かんたんですね!


抽象化したことでどれくらいパフォーマンスに影響が出ているかは、まだ計っていません。どうだろうかな。

アプリケーションのプロトタイピングにはこういうラッパーを使ってじゃっかん抽象度の高いレイヤで試行錯誤し、リリースするにあたっては SQLite3 API を直叩きする、というのがベストプラクティスなのかな。

もっとよい抽象あるよ! とか高速化のヒントなどあれば、ぜひぜひ fork するなりコメントなりでお知らせください。

blog comments powered by Disqus