source: branches/version-2_11-dev/data/class/SC_Query.php @ 21373

Revision 21373, 32.7 KB checked in by Seasoft, 10 years ago (diff)

#1583 (SC_Query#count 実装を単純に)
#1526 (typo修正・ソース整形・ソースコメントの改善)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2011 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24require_once realpath(dirname(__FILE__)) . '/../module/MDB2.php';
25
26/**
27 * SQLの構築・実行を行う
28 *
29 * TODO エラーハンドリング, ロギング方法を見直す
30 *
31 * @author LOCKON CO.,LTD.
32 * @version $Id$
33 */
34class SC_Query {
35
36    var $option = '';
37    var $where = '';
38    var $arrWhereVal = array();
39    var $conn;
40    var $groupby = '';
41    var $order = '';
42    var $force_run;
43
44    /**
45     * コンストラクタ.
46     *
47     * @param string $dsn データソース名
48     * @param boolean $force_run エラーが発生しても処理を続行する場合 true
49     * @param boolean $new 新規に接続を行うかどうか
50     */
51    function SC_Query($dsn = "", $force_run = false, $new = false) {
52
53        if ($dsn == "") {
54            $dsn = DEFAULT_DSN;
55        }
56
57        // Debugモード指定
58        // 常時ONにするとメモリが解放されない。
59        // 連続クエリ実行時に問題が生じる。
60        if(DEBUG_MODE) {
61            $options['debug'] = PEAR_DB_DEBUG;
62        } else {
63            $options['debug'] = 0;
64        }
65
66        // 持続的接続オプション
67        $options['persistent'] = PEAR_DB_PERSISTENT;
68
69        // バッファリング trueにするとメモリが解放されない。
70        // 連続クエリ実行時に問題が生じる。
71        $options['result_buffering'] = false;
72
73        if ($new) {
74            $this->conn = MDB2::connect($dsn, $options);
75        } else {
76            $this->conn = MDB2::singleton($dsn, $options);
77        }
78        if (!PEAR::isError($this->conn)) {
79            $this->conn->setCharset("utf8");
80            $this->conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
81        }
82        $this->dbFactory = SC_DB_DBFactory_Ex::getInstance();
83        $this->force_run = $force_run;
84    }
85
86    /**
87     * シングルトンの SC_Query インスタンスを取得する.
88     *
89     * @param string $dsn データソース名
90     * @param boolean $force_run エラーが発生しても処理を続行する場合 true
91     * @param boolean $new 新規に接続を行うかどうか
92     * @return SC_Query シングルトンの SC_Query インスタンス
93     */
94    function getSingletonInstance($dsn = "", $force_run = false, $new = false) {
95        if (!isset($GLOBALS['_SC_Query_instance'])
96            || is_null($GLOBALS['_SC_Query_instance'])) {
97            $GLOBALS['_SC_Query_instance'] =& new SC_Query_Ex($dsn, $force_run, $new);
98        }
99        $GLOBALS['_SC_Query_instance']->where = '';
100        $GLOBALS['_SC_Query_instance']->arrWhereVal = array();
101        $GLOBALS['_SC_Query_instance']->order = '';
102        $GLOBALS['_SC_Query_instance']->groupby = '';
103        $GLOBALS['_SC_Query_instance']->option = '';
104        return $GLOBALS['_SC_Query_instance'];
105    }
106
107    /**
108     * エラー判定を行う.
109     *
110     * @deprecated PEAR::isError() を使用して下さい
111     * @return boolean
112     */
113    function isError() {
114        if(PEAR::isError($this->conn)) {
115            return true;
116        }
117        return false;
118    }
119
120    /**
121     * COUNT文を実行する.
122     *
123     * @param string $table テーブル名
124     * @param string $where where句
125     * @param array $arrWhereVal プレースホルダ
126     * @return integer 件数
127     */
128    function count($table, $where = '', $arrWhereVal = array()) {
129        return $this->get('COUNT(*)', $table, $where, $arrWhereVal);
130    }
131
132    /**
133     * SELECT文を実行する.
134     *
135     * @param string $col カラム名. 複数カラムの場合はカンマ区切りで書く
136     * @param string $table テーブル名
137     * @param string $where WHERE句
138     * @param array $arrWhereVal プレースホルダ
139     * @param integer $fetchmode 使用するフェッチモード。デフォルトは MDB2_FETCHMODE_ASSOC。
140     * @return array|null
141     */
142    function select($col, $table, $where = "", $arrWhereVal = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
143        $sqlse = $this->getSql($col, $table, $where, $arrWhereVal);
144        return $this->getAll($sqlse, $arrWhereVal, $fetchmode);
145    }
146
147    /**
148     * 直前に実行されたSQL文を取得する.
149     *
150     * @param boolean $disp trueの場合、画面出力を行う.
151     * @return string SQL文
152     */
153    function getLastQuery($disp = true) {
154        $sql = $this->conn->last_query;
155        if ($disp) {
156            echo $sql . ";<br />\n";
157        }
158        return $sql;
159    }
160
161    /**
162     * トランザクションをコミットする.
163     *
164     * @return MDB2_OK 成功した場合は MDB2_OK;
165     *         失敗した場合は PEAR::Error オブジェクト
166     */
167    function commit() {
168        return $this->conn->commit();
169    }
170
171    /**
172     * トランザクションを開始する.
173     *
174     * @return MDB2_OK 成功した場合は MDB2_OK;
175     *         失敗した場合は PEAR::Error オブジェクト
176     */
177    function begin() {
178        return $this->conn->beginTransaction();
179    }
180
181    /**
182     * トランザクションをロールバックする.
183     *
184     * @return MDB2_OK 成功した場合は MDB2_OK;
185     *         失敗した場合は PEAR::Error オブジェクト
186     */
187    function rollback() {
188        return $this->conn->rollback();
189    }
190
191    /**
192     * トランザクションが開始されているかチェックする.
193     *
194     * @return boolean トランザクションが開始されている場合 true
195     */
196    function inTransaction() {
197        return $this->conn->inTransaction();
198    }
199
200    /**
201     * 更新系の SQL を実行する.
202     *
203     * この関数は SC_Query::query() のエイリアスです.
204     *
205     * FIXME MDB2::exec() の実装であるべき
206     */
207    function exec($str, $arrval = array()) {
208        return $this->query($str, $arrval);
209    }
210
211    /**
212     * クエリを実行し、結果行毎にコールバック関数を適用する
213     *
214     * @param callback $function コールバック先
215     * @param string $sql SQL クエリ
216     * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
217     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
218     * @return boolean 結果
219     */
220    function doCallbackAll($cbFunc, $sql, $arrval = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
221
222        $sql = $this->dbFactory->sfChangeMySQL($sql);
223
224        $sth =& $this->prepare($sql);
225        if (PEAR::isError($sth) && $this->force_run) {
226            return;
227        }
228
229        $affected =& $this->execute($sth, $arrval);
230        if (PEAR::isError($affected) && $this->force_run) {
231            return;
232        }
233
234        while($data = $affected->fetchRow($fetchmode)) {
235            $result = call_user_func($cbFunc, $data);
236            if($result === false) {
237                break;
238            }
239        }
240        $sth->free();
241        return $result;
242    }
243
244    /**
245     * クエリを実行し、全ての行を返す
246     *
247     * @param string $sql SQL クエリ
248     * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
249     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
250     * @return array データを含む2次元配列。失敗した場合に 0 または DB_Error オブジェクトを返します。
251     */
252    function getAll($sql, $arrval = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
253
254        $sql = $this->dbFactory->sfChangeMySQL($sql);
255
256        $sth =& $this->prepare($sql);
257        if (PEAR::isError($sth) && $this->force_run) {
258            return;
259        }
260
261        $affected =& $this->execute($sth, $arrval);
262        if (PEAR::isError($affected) && $this->force_run) {
263            return;
264        }
265
266        $sth->free();
267        return $affected->fetchAll($fetchmode);
268    }
269
270    /**
271     * 構築した SELECT 文を取得する.
272     *
273     * クラス変数から WHERE 句を組み立てる場合、$arrWhereVal を経由してプレースホルダもクラス変数のもので上書きする。
274     * @param string $col SELECT 文に含めるカラム名
275     * @param string $table SELECT 文に含めるテーブル名
276     * @param string $where SELECT 文に含める WHERE 句
277     * @param mixed $arrWhereVal プレースホルダ(参照)
278     * @return string 構築済みの SELECT 文
279     */
280    function getSql($col, $table, $where = '', &$arrWhereVal = null) {
281        $sqlse = "SELECT $col FROM $table";
282
283        // 引数の$whereを優先する。
284        if (strlen($where) >= 1) {
285            $sqlse .= " WHERE $where";
286        } elseif (strlen($this->where) >= 1) {
287            $sqlse .= " WHERE " . $this->where;
288            // 実行時と同じくキャストしてから評価する (空文字を要素1の配列と評価させる意図)
289            $arrWhereValForEval = (array)$arrWhereVal;
290            if (empty($arrWhereValForEval)) {
291                $arrWhereVal = $this->arrWhereVal;
292            }
293        }
294
295        $sqlse .= ' ' . $this->groupby . ' ' . $this->order . ' ' . $this->option;
296
297        return $sqlse;
298    }
299
300    /**
301     * SELECT 文の末尾に付与する SQL を設定する.
302     *
303     * この関数で設定した値は SC_Query::getSql() で使用されます.
304     *
305     * @param string $str 付与する SQL 文
306     * @return SC_Query 自分自身のインスタンス
307     */
308    function setOption($str) {
309        $this->option = $str;
310        return $this;
311    }
312
313    /**
314     * SELECT 文に付与する LIMIT, OFFSET 句を設定する.
315     *
316     * この関数で設定した値は SC_Query::getSql() で使用されます.
317     * TODO MDB2::setLimit() を使用する
318     *
319     * @param integer $limit LIMIT 句に付与する値
320     * @param integer $offset OFFSET 句に付与する値
321     * @return SC_Query 自分自身のインスタンス
322     */
323    function setLimitOffset($limit, $offset = 0) {
324        if (is_numeric($limit) && is_numeric($offset)){
325
326            $option = " LIMIT " . $limit;
327            $option.= " OFFSET " . $offset;
328            $this->option .= $option;
329        }
330        return $this;
331    }
332
333    /**
334     * SELECT 文に付与する GROUP BY 句を設定する.
335     *
336     * この関数で設定した値は SC_Query::getSql() で使用されます.
337     *
338     * @param string $str GROUP BY 句に付与する文字列
339     * @return SC_Query 自分自身のインスタンス
340     */
341    function setGroupBy($str) {
342        if (strlen($str) == 0) {
343            $this->groupby = '';
344        } else {
345            $this->groupby = "GROUP BY " . $str;
346        }
347        return $this;
348    }
349
350    /**
351     * SELECT 文の WHERE 句に付与する AND 条件を設定する.
352     *
353     * この関数で設定した値は SC_Query::getSql() で使用されます.
354     *
355     * @param string $str WHERE 句に付与する AND 条件の文字列
356     * @return SC_Query 自分自身のインスタンス
357     */
358    function andWhere($str) {
359        if($this->where != "") {
360            $this->where .= " AND " . $str;
361        } else {
362            $this->where = $str;
363        }
364        return $this;
365    }
366
367    /**
368     * SELECT 文の WHERE 句に付与する OR 条件を設定する.
369     *
370     * この関数で設定した値は SC_Query::getSql() で使用されます.
371     *
372     * @param string $str WHERE 句に付与する OR 条件の文字列
373     * @return SC_Query 自分自身のインスタンス
374     */
375    function orWhere($str) {
376        if($this->where != "") {
377            $this->where .= " OR " . $str;
378        } else {
379            $this->where = $str;
380        }
381        return $this;
382    }
383
384    /**
385     * SELECT 文に付与する WHERE 句を設定する.
386     *
387     * この関数で設定した値は SC_Query::getSql() で使用されます.
388     *
389     * @param string $where WHERE 句に付与する文字列
390     * @param mixed $arrWhereVal プレースホルダ
391     * @return SC_Query 自分自身のインスタンス
392     */
393    function setWhere($where = '', $arrWhereVal = array()) {
394        $this->where = $where;
395        $this->arrWhereVal = $arrWhereVal;
396        return $this;
397    }
398
399    /**
400     * SELECT 文に付与する ORDER BY 句を設定する.
401     *
402     * この関数で設定した値は SC_Query::getSql() で使用されます.
403     *
404     * @param string $str ORDER BY 句に付与する文字列
405     * @return SC_Query 自分自身のインスタンス
406     */
407    function setOrder($str) {
408        if (strlen($str) == 0) {
409            $this->order = '';
410        } else {
411            $this->order = "ORDER BY " . $str;
412        }
413        return $this;
414    }
415
416    /**
417     * SELECT 文に付与する LIMIT 句を設定する.
418     *
419     * この関数で設定した値は SC_Query::getSql() で使用されます.
420     *
421     * @param integer $limit LIMIT 句に設定する値
422     * @return SC_Query 自分自身のインスタンス
423     */
424    function setLimit($limit){
425        if ( is_numeric($limit)){
426            $this->option = " LIMIT " .$limit;
427        }
428        return $this;
429    }
430
431    /**
432     * SELECT 文に付与する OFFSET 句を設定する.
433     *
434     * この関数で設定した値は SC_Query::getSql() で使用されます.
435     *
436     * @param integer $offset LIMIT 句に設定する値
437     * @return SC_Query 自分自身のインスタンス
438     */
439    function setOffset($offset) {
440        if ( is_numeric($offset)){
441            $this->offset = " OFFSET " .$offset;
442        }
443        return $this;
444    }
445
446    /**
447     * INSERT文を実行する.
448     *
449     * @param string $table テーブル名
450     * @param array $sqlval array('カラム名' => '値',...)の連想配列
451     * @param array $arrSql array('カラム名' => 'SQL文',...)の連想配列
452     * @param array $arrSqlVal SQL文の中で使用するプレースホルダ配列
453     * @return
454     */
455    function insert($table, $sqlval, $arrSql = array(), $arrSqlVal = array()) {
456        $strcol = '';
457        $strval = '';
458        $find = false;
459        $arrVal = array();
460
461        if(count($sqlval) <= 0 ) return false;
462        foreach ($sqlval as $key => $val) {
463            $strcol .= $key . ',';
464            if(strcasecmp("Now()", $val) === 0) {
465                $strval .= 'Now(),';
466            } else if(strcasecmp('CURRENT_TIMESTAMP', $val) === 0) {
467                $strval .= 'CURRENT_TIMESTAMP,';
468            } else {
469                $strval .= '?,';
470                $arrVal[] = $val;
471            }
472            $find = true;
473        }
474
475        foreach($arrSql as $key => $val) {
476            $strcol .= $key . ',';
477            $strval .= $val . ',';
478        }
479
480        $arrVal = array_merge($arrVal, $arrSqlVal);
481
482        if(!$find) {
483            return false;
484        }
485        // 文末の","を削除
486        $strcol = preg_replace("/,$/", "", $strcol);
487        $strval = preg_replace("/,$/", "", $strval);
488        $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")";
489        // INSERT文の実行
490        $ret = $this->query($sqlin, $arrVal, false, null, MDB2_PREPARE_MANIP);
491
492        return $ret;
493    }
494
495    /**
496     * UPDATE文を実行する.
497     *
498     * @param string $table テーブル名
499     * @param array $sqlval array('カラム名' => '値',...)の連想配列
500     * @param string $where WHERE句
501     * @param array $arrWhereVal WHERE句用のプレースホルダ配列 (従来は追加カラム用も兼ねていた)
502     * @param array $arrRawSql 追加カラム
503     * @param array $arrRawSqlVal 追加カラム用のプレースホルダ配列
504     * @return
505     */
506    function update($table, $sqlval, $where = "", $arrWhereVal = array(), $arrRawSql = array(), $arrRawSqlVal = array()) {
507        $arrCol = array();
508        $arrVal = array();
509        $find = false;
510
511        foreach ($sqlval as $key => $val) {
512            if (strcasecmp("Now()", $val) === 0) {
513                $arrCol[] = $key . '= Now()';
514            } else if(strcasecmp('CURRENT_TIMESTAMP', $val) === 0) {
515                $arrCol[] = $key . '= CURRENT_TIMESTAMP';
516            } else {
517                $arrCol[] = $key . '= ?';
518                $arrVal[] = $val;
519            }
520            $find = true;
521        }
522
523        if ($arrRawSql != "") {
524            foreach($arrRawSql as $key => $val) {
525                $arrCol[] = "$key = $val";
526            }
527        }
528
529        $arrVal = array_merge($arrVal, $arrRawSqlVal);
530
531        if (empty($arrCol)) {
532            return false;
533        }
534
535        // 文末の","を削除
536        $strcol = implode(', ', $arrCol);
537
538        if (is_array($arrWhereVal)) { // 旧版との互換用
539            // プレースホルダー用に配列を追加
540            $arrVal = array_merge($arrVal, $arrWhereVal);
541        }
542
543        $sqlup = "UPDATE $table SET $strcol";
544        if (strlen($where) >= 1) {
545            $sqlup .= " WHERE $where";
546        }
547
548        // UPDATE文の実行
549        return $this->query($sqlup, $arrVal, false, null, MDB2_PREPARE_MANIP);
550    }
551
552    /**
553     * MAX文を実行する.
554     *
555     * @param string $table テーブル名
556     * @param string $col カラム名
557     * @param string $where 付与する WHERE 句
558     * @param array $arrval プレースホルダに挿入する値
559     * @return integer MAX文の実行結果
560     */
561    function max($col, $table, $where = "", $arrval = array()) {
562        $ret = $this->get("MAX($col)", $table, $where, $arrval);
563        return $ret;
564    }
565
566    /**
567     * MIN文を実行する.
568     *
569     * @param string $table テーブル名
570     * @param string $col カラム名
571     * @param string $where 付与する WHERE 句
572     * @param array $arrval プレースホルダに挿入する値
573     * @return integer MIN文の実行結果
574     */
575    function min($col, $table, $where = "", $arrval = array()) {
576        $ret = $this->get("MIN($col)", $table, $where, $arrval);
577        return $ret;
578    }
579
580    /**
581     * SQL を構築して, 特定のカラムの値を取得する.
582     *
583     * @param string $table テーブル名
584     * @param string $col カラム名
585     * @param string $where 付与する WHERE 句
586     * @param array $arrWhereVal プレースホルダに挿入する値
587     * @return mixed SQL の実行結果
588     */
589    function get($col, $table, $where = "", $arrWhereVal = array()) {
590        $sqlse = $this->getSql($col, $table, $where, $arrWhereVal);
591        // SQL文の実行
592        $ret = $this->getOne($sqlse, $arrWhereVal);
593        return $ret;
594    }
595
596    /**
597     * SQL を指定して, 特定のカラムの値を取得する.
598     *
599     * @param string $sql 実行する SQL
600     * @param array $arrval プレースホルダに挿入する値
601     * @return mixed SQL の実行結果
602     */
603    function getOne($sql, $arrval = array()) {
604
605        $sql = $this->dbFactory->sfChangeMySQL($sql);
606
607        $sth =& $this->prepare($sql);
608        if (PEAR::isError($sth) && $this->force_run) {
609            return;
610        }
611
612        $affected =& $this->execute($sth, $arrval);
613        if (PEAR::isError($affected) && $this->force_run) {
614            return;
615        }
616
617        $sth->free();
618        return $affected->fetchOne();
619    }
620
621    /**
622     * 一行をカラム名をキーとした連想配列として取得
623     *
624     * @param string $table テーブル名
625     * @param string $col カラム名
626     * @param string $where WHERE句
627     * @param array $arrWhereVal プレースホルダ配列
628     * @param integer $fetchmode 使用するフェッチモード。デフォルトは MDB2_FETCHMODE_ASSOC。
629     * @return array array('カラム名' => '値', ...)の連想配列
630     */
631    function getRow($col, $table, $where = "", $arrWhereVal = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
632
633        $sql = $this->getSql($col, $table, $where, $arrWhereVal);
634        $sql = $this->dbFactory->sfChangeMySQL($sql);
635
636        $sth =& $this->prepare($sql);
637        if (PEAR::isError($sth) && $this->force_run) {
638            return;
639        }
640
641        $affected =& $this->execute($sth, $arrWhereVal);
642        if (PEAR::isError($affected) && $this->force_run) {
643            return;
644        }
645
646        $sth->free();
647        return $affected->fetchRow($fetchmode);
648    }
649
650    /**
651     * SELECT 文の実行結果を 1列のみ取得する.
652     *
653     * @param string $table テーブル名
654     * @param string $col カラム名
655     * @param string $where 付与する WHERE 句
656     * @param array $arrWhereVal プレースホルダに挿入する値
657     * @return array SQL の実行結果の配列
658     */
659    function getCol($col, $table, $where = "", $arrWhereVal = array()) {
660        $sql = $this->getSql($col, $table, $where, $arrWhereVal);
661        $sql = $this->dbFactory->sfChangeMySQL($sql);
662
663        $sth =& $this->prepare($sql);
664        if (PEAR::isError($sth) && $this->force_run) {
665            return;
666        }
667
668        $affected =& $this->execute($sth, $arrWhereVal);
669        if (PEAR::isError($affected) && $this->force_run) {
670            return;
671        }
672
673        $sth->free();
674        return $affected->fetchCol();
675    }
676
677    /**
678     * レコードの削除
679     *
680     * @param string $table テーブル名
681     * @param string $where WHERE句
682     * @param array $arrval プレースホルダ
683     * @return
684     */
685    function delete($table, $where = "", $arrval = array()) {
686        if(strlen($where) <= 0) {
687            $sqlde = "DELETE FROM $table";
688        } else {
689            $sqlde = "DELETE FROM $table WHERE $where";
690        }
691        $ret = $this->query($sqlde, $arrval, false, null, MDB2_PREPARE_MANIP);
692        return $ret;
693    }
694
695    /**
696     * 次のシーケンス値を取得する.
697     *
698     * @param string $seq_name 取得するシーケンス名
699     * @param integer 次のシーケンス値
700     */
701    function nextVal($seq_name) {
702        return $this->conn->nextID($seq_name);
703    }
704
705    /**
706     * 現在のシーケンス値を取得する.
707     *
708     * @param string $seq_name 取得するシーケンス名
709     * @return integer 現在のシーケンス値
710     */
711    function currVal($seq_name) {
712        return $this->conn->currID($seq_name);
713    }
714
715    /**
716     * シーケンス値を設定する.
717     *
718     * @param string $seq_name シーケンス名
719     * @param integer $start 設定するシーケンス値
720     * @return MDB2_OK
721     */
722    function setVal($seq_name, $start) {
723        $objManager =& $this->conn->loadModule('Manager');
724        // XXX エラーハンドリングを行う
725        $objManager->dropSequence($seq_name);
726        return $objManager->createSequence($seq_name, $start);
727    }
728
729    /**
730     * SQL を実行する.
731     *
732     * FIXME $ignore_errが無視されるようになっているが互換性として問題が無いか確認が必要
733     *
734     * @param string $n 実行する SQL 文
735     * @param array $arr プレースホルダに挿入する値
736     * @param boolean $ignore_err MDB2切替で無効化されている (エラーが発生しても処理を続行する場合 true)
737     * @param mixed $types プレースホルダの型指定 デフォルトnull = string
738     * @param mixed $result_types 返値の型指定またはDML実行(MDB2_PREPARE_MANIP)
739     * @return array SQL の実行結果の配列
740     */
741    function query($n ,$arr = array(), $ignore_err = false, $types = null, $result_types = MDB2_PREPARE_RESULT ){
742
743        $n = $this->dbFactory->sfChangeMySQL($n);
744
745        $sth =& $this->prepare($n, $types, $result_types);
746        if (PEAR::isError($sth) && $this->force_run) {
747            return $sth;
748        }
749
750        $result = $this->execute($sth, $arr);
751        if (PEAR::isError($result) && $this->force_run) {
752            return $sth;
753        }
754
755        //PREPAREの解放
756        $sth->free();
757
758        return $result;
759    }
760
761    /**
762     * シーケンスの一覧を取得する.
763     *
764     * @return array シーケンス名の配列
765     */
766    function listSequences() {
767        $objManager =& $this->conn->loadModule('Manager');
768        return $objManager->listSequences();
769    }
770
771    /**
772     * テーブル一覧を取得する.
773     *
774     * @return array テーブル名の配列
775     */
776    function listTables() {
777        $objManager =& $this->conn->loadModule('Manager');
778        return $objManager->listTables();
779    }
780
781    /**
782     * テーブルのカラム一覧を取得する.
783     *
784     * @param string $table テーブル名
785     * @return array 指定のテーブルのカラム名の配列
786     */
787    function listTableFields($table) {
788        $objManager =& $this->conn->loadModule('Manager');
789        return $objManager->listTableFields($table);
790    }
791
792    /**
793     * テーブルのインデックス一覧を取得する.
794     *
795     * @param string $table テーブル名
796     * @return array 指定のテーブルのインデックス一覧
797     */
798    function listTableIndexes($table) {
799        $objManager =& $this->conn->loadModule('Manager');
800        return $objManager->listTableIndexes($table);
801    }
802
803    /**
804     * テーブルにインデックスを付与する
805     *
806     * @param string $table テーブル名
807     * @param string $name インデックス名
808     * @param array $definition フィールド名など 通常のフィールド指定時は、$definition=array('fields' => array('フィールド名' => array()));
809     *               MySQLのtext型フィールドを指定する場合は $definition['length'] = 'text_field(NNN)' が必要
810     */
811    function createIndex($table, $name, $definition) {
812        $definition = $this->dbFactory->sfGetCreateIndexDefinition($table, $name, $definition);
813        $objManager =& $this->conn->loadModule('Manager');
814        return $objManager->createIndex($table, $name, $definition);
815    }
816
817    /**
818     * テーブルにインデックスを破棄する
819     *
820     * @param string $table テーブル名
821     * @param string $name インデックス名
822     */
823    function dropIndex($table, $name) {
824        $objManager =& $this->conn->loadModule('Manager');
825        return $objManager->dropIndex($table, $name);
826    }
827
828    /**
829     * テーブルの詳細情報を取得する。
830     *
831     * @param string $table テーブル名
832     * @return array テーブル情報の配列
833     */
834    function getTableInfo($table) {
835        $objManager =& $this->conn->loadModule('Reverse');
836        return $objManager->tableInfo($table, NULL);
837    }
838
839    /**
840     * 値を適切にクォートする.
841     *
842     * TODO MDB2 に対応するための暫定的な措置.
843     *      プレースホルダが使用できない実装があるため.
844     *      本来であれば, MDB2::prepare() を適切に使用するべき
845     *
846     * @see MDB2::quote()
847     * @param string $val クォートを行う文字列
848     * @return string クォートされた文字列
849     */
850    function quote($val) {
851        return $this->conn->quote($val);
852    }
853
854    /**
855     * パラメーターの連想配列から, テーブルに存在する列のみを取得する.
856     *
857     * @param string $table テーブル名
858     * @param array プレースホルダの連想配列
859     * @return array テーブルに存在する列のみ抽出した連想配列
860     */
861    function extractOnlyColsOf($table, $arrParams) {
862        $arrCols = $this->listTableFields($table);
863        $arrResults = array();
864        foreach ($arrParams as $key => $val) {
865            if (in_array($key, $arrCols)) {
866                $arrResults[$key] = $val;
867            }
868        }
869        return $arrResults;
870    }
871
872    /**
873     * プリペアドステートメントを構築する.
874     *
875     * @access private
876     * @param string $sql プリペアドステートメントを構築する SQL
877     * @param mixed $types プレースホルダの型指定 デフォルト null
878     * @param mixed $result_types 返値の型指定またはDML実行(MDB2_PREPARE_MANIP)、nullは指定無し
879     * @return MDB2_Statement_Common プリペアドステートメントインスタンス
880     */
881    function prepare($sql, $types = null, $result_types = MDB2_PREPARE_RESULT) {
882        $sth =& $this->conn->prepare($sql, $types, $result_types);
883        if (PEAR::isError($sth)) {
884            if (!$this->force_run) {
885                trigger_error($this->traceError($sth, $sql), E_USER_ERROR);
886            } else {
887                error_log($this->traceError($sth, $sql), 3, LOG_REALFILE);
888            }
889        }
890        return $sth;
891    }
892
893    /**
894     * プリペアドクエリを実行する.
895     *
896     * @access private
897     * @param MDB2_Statement_Common プリペアドステートメントインスタンス
898     * @param array $arrVal プレースホルダに挿入する配列
899     * @return MDB2_Result 結果セットのインスタンス
900     */
901    function execute(&$sth, $arrVal = array()) {
902        $timeStart = SC_Utils_Ex::sfMicrotimeFloat();
903        $affected =& $sth->execute((array)$arrVal);
904
905        // 一定以上時間かかったSQLの場合、ログ出力する。
906        if(defined('SQL_QUERY_LOG_MODE') && SQL_QUERY_LOG_MODE == true) {
907            $timeEnd = SC_Utils_Ex::sfMicrotimeFloat();;
908            $timeExecTime = $timeEnd - $timeStart;
909            if(defined('SQL_QUERY_LOG_MIN_EXEC_TIME') && $timeExecTime >= (float)SQL_QUERY_LOG_MIN_EXEC_TIME) {
910                $logMsg = sprintf("SQL_LOG [%.2fsec]\n%s", $timeExecTime, $sth->query);
911                error_log($logMsg, 3, LOG_REALFILE);
912            }
913        }
914
915        if (PEAR::isError($affected)) {
916            $sql = isset($sth->query) ? $sth->query : '';
917            if (!$this->force_run) {
918                trigger_error($this->traceError($affected, $sql, $arrVal), E_USER_ERROR);
919            } else {
920                error_log($this->traceError($affected, $sql, $arrVal), 3, LOG_REALFILE);
921            }
922        }
923        $this->conn->last_query = stripslashes($sth->query);
924        return $affected;
925    }
926
927    /**
928     * エラーの内容をトレースする.
929     *
930     * @access private
931     * @param PEAR::Error $error PEAR::Error インスタンス
932     * @param string $sql エラーの発生した SQL 文
933     * @param array $arrVal プレースホルダ
934     * @return string トレースしたエラー文字列
935     */
936    function traceError($error, $sql = "", $arrVal = false) {
937        $scheme = '';
938        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
939            $scheme = "http://";
940        } else {
941            $scheme = "https://";
942        }
943
944        $err = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\n\n"
945            . "SERVER_ADDR: " . $_SERVER['SERVER_ADDR'] . "\n"
946            . "REMOTE_ADDR: " . $_SERVER['REMOTE_ADDR'] . "\n"
947            . "USER_AGENT: " . $_SERVER['HTTP_USER_AGENT'] . "\n\n"
948            . "SQL: " . $sql . "\n\n";
949        if ($arrVal !== false) {
950            $err .= "PlaceHolder: " . var_export($arrVal, true) . "\n\n";
951        }
952        $err .= $error->getMessage() . "\n\n";
953        $err .= $error->getUserInfo() . "\n\n";
954
955        $err .= SC_Utils_Ex::sfBacktraceToString($error->getBackTrace());
956
957        return $err;
958    }
959
960    /**
961     * SQLクエリの結果セットのカラム名だけを取得する
962     *
963     * @param string $n 実行する SQL 文
964     * @param array $arr プレースホルダに挿入する値
965     * @param boolean エラーが発生しても処理を続行する場合 true
966     * @param mixed $types プレースホルダの型指定 デフォルトnull = string
967     * @param mixed $result_types 返値の型指定またはDML実行(MDB2_PREPARE_MANIP)
968     * @return array 実行結果の配列
969     */
970    function getQueryDefsFields($n ,$arr = array(), $ignore_err = false, $types = null, $result_types = MDB2_PREPARE_RESULT ){
971
972        $n = $this->dbFactory->sfChangeMySQL($n);
973
974        $sth =& $this->prepare($n, $types, $result_types);
975        if (PEAR::isError($sth) && ($this->force_run || $ignore_err)) {
976            return;
977        }
978
979        $result = $this->execute($sth, $arr);
980        if (PEAR::isError($result) && ($this->force_run || $ignore_err)) {
981            return;
982        }
983        $arrRet = $result->getColumnNames();
984        //PREPAREの解放
985        $sth->free();
986
987        return $arrRet;
988    }
989
990}
991
992?>
Note: See TracBrowser for help on using the repository browser.