ようこそゲストさん

CPA-LABテクニカル

メッセージ欄

分類 【sqlite】 で検索

一覧で表示する

2008/02/17(日) CakePHP1.2をSQLite3で動かしてみた。&ダウンロード

はてブ情報 はてブに登録 はてブ数 sqlitespok

dbo_sqlite3_spok とは

CakePHP1.2b用 SQLite3データベースオブジェクトです。CakePHPでは、SQLiteは、バージョン2までしか対応していませんが、PHP5の機能(PDO)を使って対応させてみました。
私はSQLite2でなく、SQLite3が好きなので。。。
以前はSQLite2で動いていたサイトをCakePHPでSQLite3を対応させてみました。
本を買う前にこの書評を読め!
PaginatorでPaginateしてみた。
は、CakePHP version 1.2.0.6311 beta, SQLite 3 で動いています。(最近レンタルサーバーが重いことが多いので、ご容赦を。CakePHPやSQLiteが重いのでなくてサーバー自体の問題です。)
サイトがしょぼいのどうのはともかく、一応、まともに動いています。

私はこれまでに、CakePHPがSQLite3に対応しにくい理由と偉そうなことを書いたり、SQLite2より3の方が断然いい理由SQLiteを使うべき10の理由と5つのデメリットと、SQLiteマンセーの記事を書いたりしてきたけど、やっぱり自分でやってみたくなってやってみた、ということです。


CakePHPはMITライセンスとのことなので、改造、再配布は問題ないと思うのだけれど。。。

注意


PHP5限定です。PHP4では動きません。(そうかこれがSQLite3にCakePHPが正式対応しない理由かもね)
数少ない状況でしかテストしておりません。複雑なクエリのテストはしておりません。
人柱として理解のある方のみお試し下さい。

制限事項  (追記の追記)

fields = array( '*' )
を指定すると、得られるモデル名がすべて「0」になるようです。
直接 * を指定されると、確かにテーブル名とフィールド名の事前マッピングが不可能になるので、今回のやり方の限界となります。

「*」については、すべてのフィールド名を展開してSELECT文を発行することで対処しました。


その他、ご自分で独自SQL文を発行している方については不具合がでるかもしれません。
複雑なSQLは、私自身思いつかないので、テストにも限界があるのが実情です。
うまく動かすコツは、取得するフィールド名については、フィールド名だけでなく、必ずモデル名も指定しておけばいいと思います。

つまり
SELECT  id,content FROM ....
ではなく
SELECT  Hoge.id,Hoge.content FROM ....
ということです。


del:また、テーブルをジョインするときは、大文字で「JOIN」として
......JOIN  hoge_model_name as "HogeModelName"
と、CakePHPが自動作成するSQL文に準じた形で書いていただくとうまくいくかと思います。
ポイントは、「JOIN」は大文字、実テーブル名の後のモデル名(エイリアス)は、”(ダブルクオーテーション)で囲む。


JOIN でなく ,カンマ区切りで結合&「*」とすると、たぶんマッピングがうまく動かないので、取得したデータのモデル名はゼロになるかと思います。
バージョン1.0.5bで対応しました。


とにかく
SELECT  Hoge.id,Hoge.content FROM ....
を守っていれば、かなり大丈夫と思います。

ダウンロード

1 下記zipファイルをダウンロード
  • 最新バージョン
SQLite3_spok1.0.7beta.ZIP
(1.07にバージョンアップしました。フィールド名に「name」が使われているとエラーがでる現象に対処しました。)


以前のバージョン
SQLite3_spok1.0.6beta.ZIP
(1.0.6にバージョンアップしました。LEFT JOIN などという形のJOIN形式にも対応しました。以前は、取得フィールド* で JOIN句を使うとエラーでした。)


(1.0.5Bにバージョンアップしました。独自sqlで、JOINするときにカンマ区切りでも大丈夫なようにしてみました。また複雑な副問い合わせの場合にも対処しました(つもり)。その他マッピングの不具合を修正。)
SQLite3_spok1.0.5beta.ZIP

(1.0.4bにバージョンアップしました。独自SQLをfunciton query( 'SELECT .......' );と発行した場合に対処しました。
SQLite3_spok1.0.4beta.ZIP
以前のバージョン
(1.03bにバージョンアップしました。取得フィールドが、「*」 の時にテーブル名(モデル名)が、ゼロになってしまっていたのを修正しました。
SQLite3_spok1.0.3beta.ZIP
以前のバージョン
(1.0.2bにバージョンアップしました。一部、insertでエラーが出たのを修正。アソシエーションで同じフィールド名を持っている場合のマッピングの不具合修正。)
SQLite3_spok1.0.2beta.ZIP


2 解凍した2つのファイルを以下にコピー
  • dbo_sqlite3_spok.php は、 app/models/datasources/dbo/ にコピー
(フォルダがない場合は作ってください)
  • dbo_source.php は、app/models/datasources/ にコピー

3 現在のキャッシュをすべて消去 (意外に重要)


4 config/database.phpの中身の例
var $default = array(
    'driver' => 'sqlite3_spok',
    'connect' => 'PDO',
    'host' => '',
    'port' => '',
    'login' => '',
    'password' => '',
    'database' => "sqlite:/home/hoge/hogehoge/filename.sqlite3",
    'schema' => '',
    'prefix' => '',
    'encoding' => ''
    );
config の注意点
'database' の sqlite:/home/hoge/hogehoge/name.sqlite3
と、「sqlite:」を最初につけるのを忘れないでください。PDOの仕様です。ちなみに、「sqlite2:」とすると、SQLite2にも繋げられます。
ウィンドウズ(Windows)の場合は、「sqlite:c:¥hoge¥hogehoge¥filename.sqlite3」のようになります*1
ファイル名は、なんだって大丈夫。拡張子はsqlite3である必要もないし、拡張子なしでも大丈夫。
'login' => '','password' => '',は、例のように'' か null に設定してください。

留意点


PDOやSQLite3の特性を生かし切ったコードにはなっていません。SQLite2用のコードを流用させていただいたので、あくまでも、とりあえず動くようにしたレベルです。

不具合?

  • 不具合などあれば、ご報告しただければ直せるかも知れないし、直せないかも知れません。
  • 考えられる不具合
    • カラム名の大文字小文字でトラブルがあり得るかも。
    • CakePHPでSQLite3を使う(覚書編) のようなやり方なので、ダブルクオーテーションや、ドットが通常ではない形式でフィールド名にまざると誤動作するかもしれません。
    • テーブル名を事前マッピングします。as 句 を使った場合に意図しないテーブル名(モデル名)にデータがセットされるかも知れません。(そうならないように工夫したつもりですが)

SQLiteの管理ツール


SQLite管理ツールをご参考に。

*1 : ¥は半角

1: 名無しさん 『SQLite3_spok1.0.7beta.ZIPの公開ありがとうございます。 
私の環境でいくつか問題があったため報告です。 ...』 (2009/03/30 27:33)

2: べり 『ソースを使わせてもらってます。ありがとうございます。 セッションの保存先をDBにすると、下記のエラーが出力されてしまい困ってい...』 (2009/05/09 17:42)

  • CakePHPでSQLite3を使う(覚書編) CPA-LABテクニカル spok
    CakePHP1.2で、SQLite2を動かすには、CakePHP1.2をSQLite3で動かしてみた。&ダウンロードをご覧下さい。これは自分のための覚書。背景CakePHPでは、データベースからのfetchでarray( 'テーブル名.フィールド名'...
  • [CakePHP] SQLite3を使えるようにする【してやんよ♪】 Rain or Shine
    現在リリースされているCakePHPはSQLite2にしか対応しておらず、SQLite3はそのままでは使えないので、使えるようにしてみました。なのでちょっとメモ。CakePHP 1.2.3.8166 Stableにで確認。以前からCPA-LABに独自で作ら...

2008/02/15(金) CakePHPでSQLite3を使う(覚書編)

はてブ情報 はてブに登録 はてブ数 sqlitespok
CakePHP1.2で、SQLite3を動かすには、CakePHP1.2をSQLite3で動かしてみた。&ダウンロードをご覧下さい。
これは自分のための覚書。

背景

CakePHPでは、データベースからのfetchで


array( 'テーブル名.フィールド名' => value )


という形を期待して、結果をfetchしている。

しかし、PHP5のPDOのSQLite3用のデバイスは、テーブル名を省略して、結果を返してくる。テーブル名が上記の形になるのは、複数のテーブルを連結した場合&取得するフィールド名が、重なった場合だけである。
(テーブル名を常につけるオプションは、現段階ではサポートされていない)


CakePHPは、この結果から、 $find で返す配列に


array ( 'テーブル名(正しくはモデル名)' => value )


とセットしている。

実現方法


これをPDO,SQLite3でも実現するため、SELECT文を発行する時に、テーブル名とカラム名の組み合わせを覚えておき、結果セット取得時に、それと照合する、というやり方にする。
幸い、CakePHPは、ユーザーがテーブル名を省略して、取得フィールドを設定しても、必ず、
 ”テーブル名(モデル名)”.”フィールド名”

という形にするので、それを横取りして、この組み合わせをメンバ変数に覚えておかせることにした。
$spok_map_table,$spok_map_col

そして、フィールド名は次のようにしておく。
 ”テーブル名(モデル名)”.”フィールド名” as  ”テーブル名(モデル名).フィールド名”
(微妙な違いがわかりますでしょうか)

ただし、問題となるのは、ユーザーが as  によって別名をつけた場合や、max( field ) などとした場合である。
この点は、 as があったら、as 以降を カラム名として扱うこととした。
関数を使った場合は、テーブル名を ゼロ とした。
(たぶん、他のDBOも、この仕様になっているはず)

事前の横取りマッピング


事前に横取りして、テーブル名とカラム名の組み合わせを覚えておくのは
dbo_source.php の function renderStatement の select文発行のところ。
そこに、 $this->spok_sqlite3_maps($data['fields']) と、return直前に、横取りした。
function spok_sqlite3_maps($fields) は、同じファイルの最後に追加した。

事後のマッピング利用

dbo_sqliteをベースに改造した。
sqlite固有の関数は、すべてPDO用に置き換えた。(たぶん問題ないと思う)

function resultSet は、そもそもその結果を使っていなかったので、すぐにreturnするようにしておいた。
function fetchResult() において、事前マッピングしたものを、ここで利用した。
ダブルクオーテーションを抜くことを忘れずに。


データベースconfig

login,paswordは設定しても無駄である。
	var $default = array(
		'driver' => 'sqlite3_spok',
		'connect' => 'PDO',
		'host' => '',
		'port' => '',
		'login' => '',
		'password' => '',
		'database' => 'sqlite:c:\hogehoge\hogehoge\hoge.sqlite3',
		'schema' => '',
		'prefix' => '',
		'encoding' => ''
	);

「*」 の問題

SELECT * FROM.....となった場合、事前マッピングが不可能になる。
実現するには
  1. *をすべて個別のフィールドに展開してしまう
  2. フィールドの個数とテーブル名(モデル名)を対応させておく
というあたりが考えられるが、1の方法をとった。

1: Carlos 『Hello, posted the spanish translation of this article at: http:/...』 (2009/11/15 28:25)

2008/02/02(土) SQLite2より3の方が断然いい理由

はてブ情報 はてブに登録 はてブ数 sqlitespok
cakephpを触っていて、cakeさんがSQLite3でうまく動かないものだから、ダウングレードしてSQLite2でちょっといじってみた。以下はその感想。

バージョン3の方が、、、、
  1. 他で書込中でも、素直にselectを受け付けてくれる。
  2. 断然早い
CakePHPよ。早くSQLite3に対応してたもうなかれ。

(追記)CakePHP1.2をSQLite3で動かしてみた。&ダウンロード
  • CakePHP1.2をSQLite3で動かしてみた。&ダウンロード CPA-LABテクニカル spok
    私はSQLite2でなく、SQLite3が好きだ。だから、以前はSQLite2で動いていたサイトをCakePHPでSQLite3を対応させてみた。本を買う前にこの書評を読め!PaginatorでPaginateしてみた。は、CakePHP version ...