Archive for the ‘Uncategorized’ Category

CakePHPでレコード直読み

CakePHPのmodelでは、データベースから読み込んだものをいったん配列に「全部」入れています。
これだと、諸事情でものすごい量のデータを読み込むけど配列には入れたくないケース(集計等)では、確実にメモリ不足でこけます。

だから、直接レコードを読み取れないかなー、ということで。
わかりやすく言うと、フレームワーク使わずにMySQL等を直接さわる関数(mysql_query,mysql_fetch_array)を使う気分で使いたいときです。
そんなわけで、調べてました。

・・・ちょっと大変なことをする必要があります。割とハイレベル。
データソースの rawQuery , fetchRow を呼ぶ必要があります。
こんなかんじです。

class Hoge extends AppModel {
    var $name  = "Hoge" ;
    var $useTable = "table_hoge" ; 

    private $dbob ;
    private $sqlrsrc ;  
  
    function __construct() {
        parent::__construct() ;
        $this->dbob = &ConnectionManager::getDataSource($this->useDbConfig);
    }

    function executeQuery( $arg_query ) {
        $this->sqlrsrc = $this->dbob->rawQuery( $arg_query ) ;
        return $this->sqlrsrc ;
    }

    function fetchRow2( $arg_arg = null ) {
        $this->dbob->results = $this->mysqlrsrc ;
        $__result = $this->dbob->fetchRow() ; 
        return $__result ;
    }

}

※注:private の宣言は意味ないです(笑) ぶっちゃけ var でいいですが、自分の好みでこうやってます。

executeQuery でクエリ実行、fetchRow2 でレコード1つ取得、です。
fetchRow2 で戻ってくるのは、CakePHPのモデルで戻ってくるのと同じ様式の配列です。
ですから、以前

$__rows = $this->Hoge->query( $__query ) ; // とりあえず全部読み
foreach( $__rows as $__r ) {
//以下略

と書いていたのを、

$__rows = $this->Hoge->executeQuery( $__query ) ; // とりあえず全部読み
while( $__r = $this->Hoge->fetchRow2() ) {
//以下略

と2行書き換えるだけでそのまま動きます。

ちなみにこのへんについて知りたければ、
CORE/cake/libs/model/model.php
CORE/cake/libs/model/datasources/datasource.php
CORE/cake/libs/model/datasources/dbo_source.php
CORE/cake/libs/model/datasources/dbo/dbp_mysql.php
あたりを読めばいいんじゃないかなと。