4
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/

Cocoa勉強会#6-SQLiteをCocoaで使う

Embed Size (px)

Citation preview

Page 1: Cocoa勉強会#6-SQLiteをCocoaで使う

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/

Page 2: Cocoa勉強会#6-SQLiteをCocoaで使う

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 で得る

Page 3: Cocoa勉強会#6-SQLiteをCocoaで使う

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' );";

Page 4: Cocoa勉強会#6-SQLiteをCocoaで使う

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