CodeIgniter でデータベースクエリの記述を簡易化する Active Record クラスの group_by メソッドが使いにくい件について。

まず最初に、Active Record クラスの select メソッドはSQL文のSELECTを指定できるメソッドですが、select メソッドでは第一引数に選択したいレコード、第二引数にレコード名をエスケープするか(boolean)を指定できます。

なぜ第二引数が用意されているかというと、CodeIgniterのエスケープ機能は、MAX()やMIN()、SUM()、CONCAT()などの関数の併用に対応していないからです。

次に、Active Record クラスの group_by メソッドはSQL文のGROUP BYを指定できるメソッドですが、group_byメソッドでは第二引数を指定することができません。

なぜでしょうか?私にも分かりません。GROUP BYと集計関数を併用することはよくあることです。

例えば

$this->db->group_by('LEFT(name, 2)');

と指定するとSQL文では

GROUP BY LEFT(name, `2)`

となってしまい、SQL syntac error となってしまいます。

そこで、本来はあまりやるべきではありませんが、group_by メソッドでもエスケープ処理を拒否するための第二引数の指定を行えるように、COREファイルを編集してみました。

編集したファイルは

system/database/DB_active_rec.php

で、700行目あたりで定義されている group_by メソッドを次のように書き換えました。

public function group_by($by,$escape=TRUE)
{
    if (is_string($by))
    {
        $by = explode(',', $by);
    }

    foreach ($by as $val)
    {
        $val = trim($val);

        if ($val != '')
        {
            if($escape)
            {
                $this->ar_groupby[] = $this->_protect_identifiers($val);
            }
            else
            {
                $this->ar_groupby[] = $val;
            }

            if ($this->ar_caching === TRUE)
            {
                if($escape)
                {
                    $this->ar_cache_groupby[] = $this->_protect_identifiers($val);
                }
                else
                {
                    $this->ar_cache_groupby[] = $val;
                }
                $this->ar_cache_exists[] = 'groupby';
            }
        }
    }
    return $this;
}
 

以上です。

PR