MonoTouch で使えるSQLiteラッパーのまとめ

2009-11-22 追記

sqlite-net なのですがiPhoneシミュレータで走らせるとデータの保存/読み込みができていませんでした.データベースにアクセスすると,コンソールにエラー:
"SmileDays(293,0xa01fa500) malloc: *** error for object 0x70d3b18: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug"
が表示されています.XCodeなどで追いかけていかなければ原因をつかむのは難しそうです.このためにMono.Data.Sqlite が無難な選択と思います.

はじめに

MonoTouchメーリングリストに登録しました.
Mac OS 10.6では問題ないが,Mac OS 10.5 では iPhone simulatorでSQLiteを使うプログラムを動かそうとするとSQLiteのバージョンが古いという警告が出て動かないなど,いろいろ苦労されていることが生で伝わってきます.

MonoTouchのデータ保存方法にはファイル保存(XML (LINQ), テキスト),SQLiteがあります.MonoTouchにはObjective-Cにあるオブジェクトの永続化は(今は)ありません. 今回はSQLiteのラッパーをまとめます.

SQLiteはアプリケーションに組み込んで使用できるリレーショナルデータベースです.C言語で書かれているために,C#から呼び出すにはなんらかのラッパーが必要となります.ラッパーには,Mono.Data.Sqlite およびsqlite-netがあります.この2つはいずれも外部のsqlite3を呼び出します.またSQliteC#に移植したcsharp-sqlite があります.

Mono.Data.Sqlite はMonoTouch 1.2から提供されます.ざっと見たところSystem.Data.SQLiteと同じようなメソッドが並んでいます.なぜ名前空間がMonoTouchになのかとは疑問に思います.このアセンブリは外部のsqlite3を呼び出します.

sqlite-netsqliteの薄いラッパーです.簡単なO/Rマッピング機能があり,プリミティブ型に限定されますが,型のプロパティ属性情報からのSQLのテーブル作成,テーブルの列情報からインスタンスオブジェクトを作成できます.

csharp-sqliteSQLiteC#に移植したものだそうです.オリジナルのSQLiteとのベンチマークでは,Insert/Deleteこそ処理時間が2~3倍かかりますが,その他はほぼ同等の速度を出しています.私はMonoTouchでの動作確認をしていませんが,おそらく動くでしょう.

私の勝手な評価ですが表にまとめてみます:

項目 お勧め度 使いやすさ 過去の資産活用度 プラットホーム非依存
Mono.Data.Sqlite
sqlite-net ×
csharp-sqlite
System.Data

後者2つはラッパーではありませんがMonoTouchでSQLを利用するときに検討されるだろうと考えて掲載しました.また,私の開発環境が,IDEVisual Studioを使い,UIが絡まないユニットテストNUnitを使いWindows環境で実行する変わったものですから,プラットホーム依存度という項目を付け足しています.

Mono.Data.Sqliteは,Sqliteを使って開発した資産の再利用などになんら問題ないのですが,名前空間をすげ替える手間が出るだろうと考えて,あえて△をつけています.

iPhoneのアプリケーションをゼロから開発するならば,sqlite-netが一番のお勧めです.O/Rマッピング機能は,簡単なものであっても,コーディング量を相当に削減してくれます.(注意: sqllite 3.6.19 と組み合わせて使うと,SQLiteがサポートしないSQL文を構築するためにUpdateで例外が発生します.修正はIssueに投げました.品質確保のためには,テストケースがないソースは避けるべきなのかもしれません.)

過去の資産を再利用するならばSystem.Dataが使えます.しかしVisual Studioではない開発環境ではDataSetやDataTableなどを自分でコーディングすることになりますし,LINQ to SQLがある現在では,(私個人としては)新規開発に使うことはどうだろうかと考えます.

全てが.netで動かせる csharp-sqlite では,環境ごとにsqlite3のライブラリを用意する必要が無くなりますから,開発だけではなくてテストの可搬性が高くなります.ただし,開発ではSQLを生で扱うことはほとんどなくSQL to LINQなどを利用することになると思います.それらにこのcsharp-sqliteを接続する方法を押さえておかないと不便な思いをするかもしれません.

ベストな解決方法はDb4Objectsが動くことなのでしょうが,中間言語をばしばし使うものがすんなりMonoTouchで動いてくれるものかどうかと考えると,検討にはまとまった時間が必要かなと思います.これから検討したいなとは思います.