今さらながら Ethna-2.5.0 で データベース MySQL から SQLite に切り替えてみる。
SQLite と言っても互換性が無くなってしまった SQLite2 。ここまでの環境
CentOS release 6.4 (Final)
PHP Version 5.3.3
DB 1.7.14 stable
PEAR 1.9.4 stable
sqlite 2.8.17
sqlite3 3.6.20
で、Ethna-2.5.0 + MySQL5 前提Webアプリのデータベースを SQLite2 に切り替え。
極力 SQLベタ書きをさける為の Ethna_AppObject は、そのままではNG。
原因は PEAR:DB::fetchRow(DB_FETCHMODE_ASSOC) の結果セット各列のキーが
mysql だと
最小限の修正手順... ▼
SQLite と言っても互換性が無くなってしまった SQLite2 。ここまでの環境
CentOS release 6.4 (Final)
PHP Version 5.3.3
DB 1.7.14 stable
PEAR 1.9.4 stable
sqlite 2.8.17
sqlite3 3.6.20
で、Ethna-2.5.0 + MySQL5 前提Webアプリのデータベースを SQLite2 に切り替え。
極力 SQLベタ書きをさける為の Ethna_AppObject は、そのままではNG。
原因は PEAR:DB::fetchRow(DB_FETCHMODE_ASSOC) の結果セット各列のキーが
mysql だと
fieldSQLite2 だと
tables"."fieldで異なる為。 ※ DBを切り替えたらキャッシュを削除しないと混乱する。
最小限の修正手順... ▼
●APPID-ini.php のdsnを変更。
/// 'dsn' => 'mysql://id:pw@localhost/database', 'dsn' => 'sqlite:///'.BASE.'/schema/database.sqlite2',ここでは、SQLite2 データファイル database.sqlite2 は、APPID/schema に。
●APPID_Controller.php に下記を追加
require_once 'Ethna_AppObject2.php';●Ethna_AppObject を継承し searchProp() だけをオーバーライドした Ethna_AppObject2.php を APPID/lib に。
<?php class Ethna_AppObject2 extends Ethna_AppObject{ function searchProp($keys = null, $filter = null, $order = null, $offset = null, $count = null ){ // プライマリーキー件数検索 if (is_null($offset) == false || is_null($count) == false) { $sql = $this->_getSQL_SearchLength($filter); $r =& $this->my_db_ro->query($sql); if (Ethna::isError($r)) { return $r; } /// $row = $this->my_db_ro->fetchRow($r, DB_FETCHMODE_ASSOC); /// ▼▼▼▼▼▼▼▼▼▼ $row = $r->fetchRow( DB_FETCHMODE_ASSOC ); /// ▲▲▲▲▲▲▲▲▲▲ $length = $row['id_count']; } else { $length = null; } $prop_list = array(); $sql = $this->_getSQL_SearchProp($keys, $filter, $order, $offset, $count); $r =& $this->my_db_ro->query($sql); if (Ethna::isError($r)) { return $r; } $n = $r->numRows(); for ($i = 0; $i < $n; $i++) { /// $row = $this->my_db_ro->fetchRow($r, DB_FETCHMODE_ASSOC); /// ▼▼▼▼▼▼▼▼▼▼ $row = $r->fetchRow( DB_FETCHMODE_ASSOC ); if( $this->my_db_rw->getType() == 'sqlite' ){ /// 『tables"."field』 → 『field』 foreach( $row as $k=>$v ){ $kk = substr( $k, 1+strrpos( $k, '"') ); $row[$kk] = $v ; unset( $row[$k] ); } } /// ▲▲▲▲▲▲▲▲▲▲ $prop_list[] = $row; } if (is_null($length)) { $length = count($prop_list); } return array($length, $prop_list); } } ⁄>●各テーブルの AppObject の継承元を
class APPID_Tables extends Ethna_AppObjectから
class APPID_Tables extends Ethna_AppObject2に変更。
これだけで、Webアプリのロジックを変更することなく互換性を保って MySql と SQLite2 の切り替え完了。少なくとも、SELECT、INSERT、UPDATE、JOIN で正常。
それにしても、
$this->my_db_ro->fetchRow($r, DB_FETCHMODE_ASSOC);は、バグでは???