Upload
masayuki-nii
View
460
Download
1
Embed Size (px)
Citation preview
1
第6回> Cocoa 勉強会(2004/7/10)>
SQLite を Cocoa で使う(新居雅行)>
SQLデータベースの SQLite
SQLite の特徴 Public Dmain、オープンソースで、事実上自由に使える SQL データベース
(http://www.sqlite.org/) オリジナルにはC/C++およびTCLのインタフェースだけが用意されている PHP5への標準バンドル、さらにはMac OS X v10.4 へのバンドルが予定されている ネットワークには基本的には非対応のため、組み込み用途が主なものとなる。データベース
は、1つのファイルに保存される 「タイプレス」という独特の考え方。フィールドにはタイプを指定しないでもいい(という
か、指定してもあまり意味はないかも) 数値については「精度」「桁数」的な概念はまったくない。数値は倍精度浮動小数点数(64
ビット)にすべて展開される。 文字も数値もある意味は区別がないためちょっと独特。ただし、そのため BLOB 処理がち
ょっと甘いとも言える SQL の非サポート機能で目につくのは GRANT がないこと。アクセス権はデータベースフ
ァイルに対して設定するというのが基本コンセプト。また、タイプレスのためか CHECK制約は機能しないなどもある
Ver.2.8 系列はUTF-8 対応、Ver.3 よりUTF-8/16の両方に対応。なお、Ver.3 ではタイプの扱いが違ってくる模様。
MySQLよりも速いといったベンチマークテストを掲載している。PostgreSQLよりは 10~20倍、MySQLよりも 2倍速いとしているが、SQLite では 1つのトランザクションで処理する事でそのスピードが出る
SQLite をMac OS X で使うには バイナリとして配布されているのは、LinuxとWindowsのみ。そのため、Mac OS X で使うにはビルドしないといけないが、配布されているソース群にはmake すらない。Mac OS X で手軽に使うには、以下のものが必要。 SQLite のMac OS X 版ビルド http://www.c-command.com/tools/sqlite.shtml QuickLite http://www.webbotech.com/
2
SQLite のコネクティビティ SQLite の接続機能を強化するものとしては以下のものがある。 SQLite 用の ODBCおよび JDBCのドライバ http://www.ch-werner.de/sqliteodbc/ http://www.ch-werner.de/javasqlite/ SQLiteServer 1.0(SQLite をネットワークからアクセス。REALbasic で制作) http://sqlabs.net/
QuickLite について SQLite を使うためのCocoaのクラスをオープンソースで提供しているのがQuickLite 確かに、Xcode で開いてデータベース処理はできるが、事実上、自分で SQL文をテキスト
で作成しなければならない。つまり、データベースの内容をオブジェクト化するものではなく、SQLite へのインタフェースを取るためのCocoaクラス
そのため、以下の 3種類のオブジェクト(クラス)について知るだけで使える(というか、その程度の機能)。以下の表は主なメソッドの紹介で、他にもメソッドがある
NSQuickLiteDatabase データベースファイルの抽象化 databaseWithFile: データベースファイルを指定して初期化 open データベースをオープン close データベースをクローズ performQuery: 文字列で指定した SQL文を発行、NSQuickLinkCursor
を戻す prepareStringForQuery: SQL文をクエリーできるように変換。つまりクォートの
置き換え
encodeDataToBase64: NSData を base64にしてNSString を戻す NSQuickLiteCursor クエリー結果の抽象化クラス
rowCount レコード数 columnCount フィールド数 columnNames フィールド名のNSArray を得る rowAtIndex: レコード番号を指定してNSQuickLinkRow への参照を
得る valuesForColumn: 文字列で指定したフィールドのデータをNSArrayで得る
valuesForRow: レコード番号で指定したレコードのデータをNSDictionary で得る
NSQuickLiteRow クエリー結果の中の 1レコードを抽象化するクラス stringForColumn: フィールド名を指定してそのフィールドのデータを文字
列として得る dataForColumn: andRow: フィールド名とレコード番号指定してそのフィールドの
データをNSData として得る
values レコードのデータをNSDictionary で得る
3
NSString での Unicode でインプット/アプトプットがきちんとできる。もちろん日本語もOK
BLOB 対応のために base64 でエンコードする。挿入するデータについては自分で base64にしないといけないが、メソッドは用意されている。取り出しは NSData として取り出すメソッドで元のバイナリが得られる
SQLite をフレームワークにするというプロジェクトもあるが、激しくバグっており(きっと、プロジェクトを作ったけど、ほんとにフレームワークとして使ってはいないだろう)、それはそのままでは使えない。動くフレームワークは、Cocoa 勉強会のサーバ領域に保存(ファイル名: QuickLite Framework.zip)
テキストファイルのインポート機能があることはあるが、これはちょっと使えない…。まじめにテキストファイルのインポートする人はちゃんと改造するか、自分で作りましょう
QuickLite を使ったサンプルプログラム ファイル名:msykQLsample.zip "SQL1" = "INSERT INTO TEST1(str1,str2) VALUES( '表示', 'aaa strings' );"; "SQL2" = "INSERT INTO TEST1(str1,str2) VALUES( '日本語', 'aaa strings' );"; "SQL3" = "INSERT INTO TEST1(str1,str2) VALUES( '東京特許許可局', 'aaa strings' );"; "SQL4" = "INSERT INTO TEST1(str1,str2) VALUES( '髙島屋', 'aaa strings' );"; "SQL5" = "INSERT INTO TEST1(str1,str2) VALUES( '美しい日本語', 'aaa strings' );"; "SQL6" = "INSERT INTO TEST1(str1,str2) VALUES( '日本語', 'aaa strings' );";
4
#import "DBAccess.h" //フレームワーク化したQuickLiteをインポート #import <QuickLite/QuickLite.h> @implementation DBAccess - (IBAction)testRun:(id)sender { long i; NSString* dbPath = @"~/testdb"; //データベースファイル
QuickLiteDatabase* db = [QuickLiteDatabase databaseWithFile: dbPath]; //データベースファイルをもとにしたデータベースオブジェクトを構築する [db open]; //データベースを開く NSArray* tableArray = [db tables]; //テーブルの個数を参照 for (i = 0; i < [tableArray count]; i++) //とりあえずテーブルをすべて消す [db dropTable: [tableArray objectAtIndex: i]]; [db performQuery: @"CREATE TABLE TEST1(id INTEGER PRIMARY KEY, str1, str2);"]; //テーブルを作成するクエリーを発行する
[db performQuery: NSLocalizedString( @"SQL1", @"" ) ]; //INSERTのクエリーを発行 [db performQuery: NSLocalizedString( @"SQL2", @"" ) ]; : [db performQuery: NSLocalizedString( @"SQL9", @"" ) ]; [db performQuery: NSLocalizedString( @"SQL10", @"" ) ]; QuickLiteCursor* cursor = [db performQuery: @"SELECT * FROM TEST1;"]; //テーブルのレコードをすべて取り出す long rowCount = [cursor rowCount]; //レコード数を求める if (rowCount > 0) { for (i = 0; i < rowCount; i++) { //それぞれのレコードについて QuickLiteRow* row = [cursor rowAtIndex: i]; //行データを参照し
if (row != nil) { //各フィールドの値を取り出す NSLog(@"%@: %@", @"id", [row stringForColumn: @"id"]); NSLog(@"%@: %@", @"str1", [row stringForColumn: @"str1"]); NSLog(@"%@: %@", @"str2", [row stringForColumn: @"str2"]); } } } [db close]; //データベースを閉じる } @end