« PHP5.3.3 から sqlite2 をアクセス | メイン | Ethna_AppObjectのバグ??? »

database , ethna , php

Ethna で SQLite の試み

今さらながら 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 だと
	field
SQLite2 だと
	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);
は、バグでは???

トラックバック

このエントリーのトラックバックURL:
https://www.remix.asia/cgi/mt/mt-tb.cgi/7013

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)