source: branches/version-2_5-dev/data/class/SC_Query.php @ 19670

Revision 19670, 26.3 KB checked in by nanasess, 13 years ago (diff)

スマートフォン対応(#787)

  • r19668 の差し戻し
  • SC_Helper_Session::getToken() 内の SC_Helper_Session::createToken() を static に変更
  • 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-2010 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 $instance;
37    var $option;
38    var $where;
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        $options['debug'] = PEAR_DB_DEBUG;
59        // 持続的接続オプション
60        $options['persistent'] = PEAR_DB_PERSISTENT;
61
62        if ($new) {
63            $this->conn = MDB2::connect($dsn, $options);
64        } else {
65            $this->conn = MDB2::singleton($dsn, $options);
66        }
67        if (!PEAR::isError($this->conn)) {
68            $this->conn->setCharset(CHAR_CODE);
69            $this->conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
70        }
71        $this->dbFactory = SC_DB_DBFactory_Ex::getInstance();
72        $this->force_run = $force_run;
73        $this->where = "";
74        $this->order = "";
75        $this->groupby = "";
76        $this->option = "";
77    }
78
79    /**
80     * シングルトンの SC_Query インスタンスを取得する.
81     *
82     * @param string $dsn データソース名
83     * @param boolean $force_run エラーが発生しても処理を続行する場合 true
84     * @param boolean $new 新規に接続を行うかどうか
85     * @return SC_Query シングルトンの SC_Query インスタンス
86     */
87    function getSingletonInstance($dsn = "", $force_run = false, $new = false) {
88        if (is_null($this->instance)) {
89            $this->instance =& new SC_Query($dsn, $force_run, $new);
90        }
91        $this->instance->where = "";
92        $this->instance->order = "";
93        $this->instance->groupby = "";
94        $this->instance->option = "";
95        return $this->instance;
96    }
97
98    /**
99     *  エラー判定を行う.
100     *
101     * @deprecated PEAR::isError() を使用して下さい
102     * @return boolean
103     */
104    function isError() {
105        if(PEAR::isError($this->conn)) {
106            return true;
107        }
108        return false;
109    }
110
111    /**
112     * COUNT文を実行する.
113     *
114     * @param string $table テーブル名
115     * @param string $where where句
116     * @param array $arrval プレースホルダ
117     * @return integer 件数
118     */
119    function count($table, $where = "", $arrval = array()) {
120        if(strlen($where) <= 0) {
121            $sqlse = "SELECT COUNT(*) FROM $table";
122        } else {
123            $sqlse = "SELECT COUNT(*) FROM $table WHERE $where";
124        }
125        $sqlse = $this->dbFactory->sfChangeMySQL($sqlse);
126        return $this->getOne($sqlse, $arrval);
127    }
128
129    /**
130     * SELECT文を実行する.
131     *
132     * @param string $col カラム名. 複数カラムの場合はカンマ区切りで書く
133     * @param string $table テーブル名
134     * @param string $where WHERE句
135     * @param array $arrval プレースホルダ
136     * @param integer $fetchmode 使用するフェッチモード。デフォルトは MDB2_FETCHMODE_ASSOC。
137     * @return array|null
138     */
139    function select($col, $table, $where = "", $arrval = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
140        $sqlse = $this->getSql($col, $table, $where);
141        return $this->getAll($sqlse, $arrval, $fetchmode);
142    }
143
144    /**
145     * 直前に実行されたSQL文を取得する.
146     *
147     * @param boolean $disp trueの場合、画面出力を行う.
148     * @return string SQL文
149     */
150    function getLastQuery($disp = true) {
151        $sql = $this->conn->last_query;
152        if($disp) {
153            print($sql.";<br />\n");
154        }
155        return $sql;
156    }
157
158    /**
159     * トランザクションをコミットする.
160     *
161     * @return MDB2_OK 成功した場合は MDB2_OK;
162     *         失敗した場合は PEAR::Error オブジェクト
163     */
164    function commit() {
165        return $this->conn->commit();
166    }
167
168    /**
169     * トランザクションを開始する.
170     *
171     * @return MDB2_OK 成功した場合は MDB2_OK;
172     *         失敗した場合は PEAR::Error オブジェクト
173     */
174    function begin() {
175        return $this->conn->beginTransaction();
176    }
177
178    /**
179     * トランザクションをロールバックする.
180     *
181     * @return MDB2_OK 成功した場合は MDB2_OK;
182     *         失敗した場合は PEAR::Error オブジェクト
183     */
184    function rollback() {
185        return $this->conn->rollback();
186    }
187
188    /**
189     * トランザクションが開始されているかチェックする.
190     *
191     * @return boolean トランザクションが開始されている場合 true
192     */
193    function inTransaction() {
194        return $this->conn->inTransaction();
195    }
196
197    /**
198     * 更新系の SQL を実行する.
199     *
200     * この関数は SC_Query::query() のエイリアスです.
201     *
202     * FIXME MDB2::exec() の実装であるべき
203     */
204    function exec($str, $arrval = array()) {
205        return $this->query($str, $arrval);
206    }
207
208    /**
209     * クエリを実行し、全ての行を返す
210     *
211     * @param string $sql SQL クエリ
212     * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
213     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
214     * @return array データを含む2次元配列。失敗した場合に 0 または DB_Error オブジェクトを返します。
215     */
216    function getAll($sql, $arrval = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
217
218        $sql = $this->dbFactory->sfChangeMySQL($sql);
219
220        $sth =& $this->prepare($sql);
221        if (PEAR::isError($sth) && $this->force_run) {
222            return;
223        }
224
225        $affected =& $this->execute($sth, $arrval);
226        if (PEAR::isError($affected) && $this->force_run) {
227            return;
228        }
229
230        return $affected->fetchAll($fetchmode);
231    }
232
233    /**
234     * 構築した SELECT 文を取得する.
235     *
236     * @param string $col SELECT 文に含めるカラム名
237     * @param string $table SELECT 文に含めるテーブル名
238     * @param string $where SELECT 文に含める WHERE 句
239     * @return string 構築済みの SELECT 文
240     */
241    function getSql($col, $table, $where = '') {
242        $sqlse = "SELECT $col FROM $table";
243
244        // 引数の$whereを優先する。
245        if (strlen($where) >= 1) {
246            $sqlse .= " WHERE $where";
247        } elseif (strlen($this->where) >= 1) {
248            $sqlse .= " WHERE " . $this->where;
249        }
250
251        $sqlse .= ' ' . $this->groupby . ' ' . $this->order . ' ' . $this->option;
252
253        return $sqlse;
254    }
255
256    /**
257     * SELECT 文の末尾に付与する SQL を設定する.
258     *
259     * この関数で設定した値は SC_Query::getSql() で使用されます.
260     *
261     * @param string $str 付与する SQL 文
262     * @return SC_Query 自分自身のインスタンス
263     */
264    function setOption($str) {
265        $this->option = $str;
266        return $this;
267    }
268
269    /**
270     * SELECT 文に付与する LIMIT, OFFSET 句を設定する.
271     *
272     * この関数で設定した値は SC_Query::getSql() で使用されます.
273     * TODO MDB2::setLimit() を使用する
274     *
275     * @param integer $limit LIMIT 句に付与する値
276     * @param integer $offset OFFSET 句に付与する値
277     * @return SC_Query 自分自身のインスタンス
278     */
279    function setLimitOffset($limit, $offset = 0) {
280        if (is_numeric($limit) && is_numeric($offset)){
281
282            $option = " LIMIT " . $limit;
283            $option.= " OFFSET " . $offset;
284            $this->option .= $option;
285        }
286        return $this;
287    }
288
289    /**
290     * SELECT 文に付与する GROUP BY 句を設定する.
291     *
292     * この関数で設定した値は SC_Query::getSql() で使用されます.
293     *
294     * @param string $str GROUP BY 句に付与する文字列
295     * @return SC_Query 自分自身のインスタンス
296     */
297    function setGroupBy($str) {
298        if (strlen($str) == 0) {
299            $this->groupby = '';
300        } else {
301            $this->groupby = "GROUP BY " . $str;
302        }
303        return $this;
304    }
305
306    /**
307     * SELECT 文の WHERE 句に付与する AND 条件を設定する.
308     *
309     * この関数で設定した値は SC_Query::getSql() で使用されます.
310     *
311     * @param string $str WHERE 句に付与する AND 条件の文字列
312     * @return SC_Query 自分自身のインスタンス
313     */
314    function andWhere($str) {
315        if($this->where != "") {
316            $this->where .= " AND " . $str;
317        } else {
318            $this->where = $str;
319        }
320        return $this;
321    }
322
323    /**
324     * SELECT 文の WHERE 句に付与する OR 条件を設定する.
325     *
326     * この関数で設定した値は SC_Query::getSql() で使用されます.
327     *
328     * @param string $str WHERE 句に付与する OR 条件の文字列
329     * @return SC_Query 自分自身のインスタンス
330     */
331    function orWhere($str) {
332        if($this->where != "") {
333            $this->where .= " OR " . $str;
334        } else {
335            $this->where = $str;
336        }
337        return $this;
338    }
339
340    /**
341     * SELECT 文に付与する WHERE 句を設定する.
342     *
343     * この関数で設定した値は SC_Query::getSql() で使用されます.
344     *
345     * @param string $str WHERE 句に付与する文字列
346     * @return SC_Query 自分自身のインスタンス
347     */
348    function setWhere($str) {
349        $this->where = $str;
350        return $this;
351    }
352
353    /**
354     * SELECT 文に付与する ORDER BY 句を設定する.
355     *
356     * この関数で設定した値は SC_Query::getSql() で使用されます.
357     *
358     * @param string $str ORDER BY 句に付与する文字列
359     * @return SC_Query 自分自身のインスタンス
360     */
361    function setOrder($str) {
362        if (strlen($str) == 0) {
363            $this->order = '';
364        } else {
365            $this->order = "ORDER BY " . $str;
366        }
367        return $this;
368    }
369
370    /**
371     * SELECT 文に付与する LIMIT 句を設定する.
372     *
373     * この関数で設定した値は SC_Query::getSql() で使用されます.
374     *
375     * @param integer $limit LIMIT 句に設定する値
376     * @return SC_Query 自分自身のインスタンス
377     */
378    function setLimit($limit){
379        if ( is_numeric($limit)){
380            $this->option = " LIMIT " .$limit;
381        }
382        return $this;
383    }
384
385    /**
386     * SELECT 文に付与する OFFSET 句を設定する.
387     *
388     * この関数で設定した値は SC_Query::getSql() で使用されます.
389     *
390     * @param integer $offset LIMIT 句に設定する値
391     * @return SC_Query 自分自身のインスタンス
392     */
393    function setOffset($offset) {
394        if ( is_numeric($offset)){
395            $this->offset = " OFFSET " .$offset;
396        }
397        return $this;
398    }
399
400    /**
401     * INSERT文を実行する.
402     *
403     * @param string $table テーブル名
404     * @param array $sqlval array('カラム名' => '値',...)の連想配列
405     * @return
406     */
407    function insert($table, $sqlval) {
408        $strcol = '';
409        $strval = '';
410        $find = false;
411
412        if(count($sqlval) <= 0 ) return false;
413
414        foreach ($sqlval as $key => $val) {
415            $strcol .= $key . ',';
416            if(eregi("^Now\(\)$", $val)) {
417                $strval .= 'Now(),';
418            } else {
419                $strval .= '?,';
420                $arrval[] = $val;
421            }
422            $find = true;
423        }
424        if(!$find) {
425            return false;
426        }
427        // 文末の","を削除
428        $strcol = ereg_replace(",$","",$strcol);
429        // 文末の","を削除
430        $strval = ereg_replace(",$","",$strval);
431        $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")";
432        // INSERT文の実行
433        $ret = $this->query($sqlin, $arrval);
434
435        return $ret;
436    }
437
438    /**
439     * UPDATE文を実行する.
440     *
441     * @param string $table テーブル名
442     * @param array $sqlval array('カラム名' => '値',...)の連想配列
443     * @param string $where WHERE句
444     * @param array $arrValIn WHERE句用のプレースホルダ配列 (従来は追加カラム用も兼ねていた)
445     * @param array $arrRawSql 追加カラム
446     * @param array $arrRawSqlVal 追加カラム用のプレースホルダ配列
447     * @return
448     */
449    function update($table, $sqlval, $where = "", $arrValIn = array(), $arrRawSql = array(), $arrRawSqlVal = array()) {
450        $arrCol = array();
451        $arrVal = array();
452        $find = false;
453        foreach ($sqlval as $key => $val) {
454            if (eregi("^Now\(\)$", $val)) {
455                $arrCol[] = $key . '= Now()';
456            } else {
457                $arrCol[] = $key . '= ?';
458                $arrVal[] = $val;
459            }
460            $find = true;
461        }
462
463        if ($arrRawSql != "") {
464            foreach($arrRawSql as $key => $val) {
465                $arrCol[] = "$key = $val";
466            }
467        }
468       
469        $arrVal = array_merge($arrVal, $arrRawSqlVal);
470       
471        if (empty($arrCol)) {
472            return false;
473        }
474
475        // 文末の","を削除
476        $strcol = implode(', ', $arrCol);
477
478        if (is_array($arrValIn)) { // 旧版との互換用
479            // プレースホルダー用に配列を追加
480            $arrVal = array_merge($arrVal, $arrValIn);
481        }
482
483        $sqlup = "UPDATE $table SET $strcol";
484        if (strlen($where) >= 1) {
485            $sqlup .= " WHERE $where";
486        }
487
488        // UPDATE文の実行
489        return $this->query($sqlup, $arrVal);
490    }
491
492    /**
493     * MAX文を実行する.
494     *
495     * @param string $table テーブル名
496     * @param string $col カラム名
497     * @param string $where 付与する WHERE 句
498     * @param array $arrval ブレースホルダに挿入する値
499     * @return integer MAX文の実行結果
500     */
501    function max($table, $col, $where = "", $arrval = array()) {
502        $ret = $this->get($table, "MAX($col)", $where, $arrval);
503        return $ret;
504    }
505
506    /**
507     * MIN文を実行する.
508     *
509     * @param string $table テーブル名
510     * @param string $col カラム名
511     * @param string $where 付与する WHERE 句
512     * @param array $arrval ブレースホルダに挿入する値
513     * @return integer MIN文の実行結果
514     */
515    function min($table, $col, $where = "", $arrval = array()) {
516        $ret = $this->get($table, "MIN($col)", $where, $arrval);
517        return $ret;
518    }
519
520    /**
521     * SQL を構築して, 特定のカラムの値を取得する.
522     *
523     * @param string $table テーブル名
524     * @param string $col カラム名
525     * @param string $where 付与する WHERE 句
526     * @param array $arrval ブレースホルダに挿入する値
527     * @return mixed SQL の実行結果
528     */
529    function get($table, $col, $where = "", $arrval = array()) {
530        $sqlse = $this->getSql($col, $table, $where);
531        // SQL文の実行
532        $ret = $this->getOne($sqlse, $arrval);
533        return $ret;
534    }
535
536    /**
537     * SQL を指定して, 特定のカラムの値を取得する.
538     *
539     * @param string $sql 実行する SQL
540     * @param array $arrval ブレースホルダに挿入する値
541     * @return mixed SQL の実行結果
542     */
543    function getOne($sql, $arrval = array()) {
544
545        $sql = $this->dbFactory->sfChangeMySQL($sql);
546
547        $sth =& $this->prepare($sql);
548        if (PEAR::isError($sth) && $this->force_run) {
549            return;
550        }
551
552        $affected =& $this->execute($sth, $arrval);
553        if (PEAR::isError($affected) && $this->force_run) {
554            return;
555        }
556
557        return $affected->fetchOne();
558    }
559
560    /**
561     * 一行をカラム名をキーとした連想配列として取得
562     *
563     * @param string $table テーブル名
564     * @param string $col カラム名
565     * @param string $where WHERE句
566     * @param array $arrVal プレースホルダ配列
567     * @param integer $fetchmode 使用するフェッチモード。デフォルトは MDB2_FETCHMODE_ASSOC。
568     * @return array array('カラム名' => '値', ...)の連想配列
569     */
570    function getRow($table, $col, $where = "", $arrVal = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
571
572        $sql = $this->getSql($col, $table, $where);
573        $sql = $this->dbFactory->sfChangeMySQL($sql);
574
575        $sth =& $this->prepare($sql);
576        if (PEAR::isError($sth) && $this->force_run) {
577            return;
578        }
579
580        $affected =& $this->execute($sth, $arrVal);
581        if (PEAR::isError($affected) && $this->force_run) {
582            return;
583        }
584
585        return $affected->fetchRow($fetchmode);
586    }
587
588    /**
589     * SELECT 文の実行結果を 1行のみ取得する.
590     *
591     * @param string $table テーブル名
592     * @param string $col カラム名
593     * @param string $where 付与する WHERE 句
594     * @param array $arrval ブレースホルダに挿入する値
595     * @return array SQL の実行結果の配列
596     */
597    function getCol($table, $col, $where = "", $arrval = array()) {
598        $sql = $this->getSql($col, $table, $where);
599        $sql = $this->dbFactory->sfChangeMySQL($sql);
600
601        $sth =& $this->prepare($sql);
602        if (PEAR::isError($sth) && $this->force_run) {
603            return;
604        }
605
606        $affected =& $this->execute($sth, $arrval);
607        if (PEAR::isError($affected) && $this->force_run) {
608            return;
609        }
610
611        return $affected->fetchCol($col);
612    }
613
614    /**
615     * レコードの削除
616     *
617     * @param string $table テーブル名
618     * @param string $where WHERE句
619     * @param array $arrval プレースホルダ
620     * @return
621     */
622    function delete($table, $where = "", $arrval = array()) {
623        if(strlen($where) <= 0) {
624            $sqlde = "DELETE FROM $table";
625        } else {
626            $sqlde = "DELETE FROM $table WHERE $where";
627        }
628        $ret = $this->query($sqlde, $arrval);
629        return $ret;
630    }
631
632    /**
633     * 次のシーケンス値を取得する.
634     *
635     * @param string $seq_name 取得するシーケンス名
636     * @param integer 次のシーケンス値
637     */
638    function nextVal($seq_name) {
639        return $this->conn->nextID($seq_name);
640    }
641
642    /**
643     * 現在のシーケンス値を取得する.
644     *
645     * @param string $seq_name 取得するシーケンス名
646     * @return integer 現在のシーケンス値
647     */
648    function currVal($seq_name) {
649        return $this->conn->currID($seq_name);
650    }
651
652    /**
653     * シーケンス値を設定する.
654     *
655     * @param string $seq_name シーケンス名
656     * @param integer $start 設定するシーケンス値
657     * @return MDB2_OK
658     */
659    function setVal($seq_name, $start) {
660        $this->conn->loadModule('Manager');
661        // XXX エラーハンドリングを行う
662        $this->conn->dropSequence($seq_name);
663        return $this->conn->createSequence($seq_name, $start);
664    }
665
666    /**
667     * SQL を実行する.
668     *
669     * XXX 更新系には exec() を使用するべき
670     *
671     * @param string $n 実行する SQL 文
672     * @param array $arrval ブレースホルダに挿入する値
673     * @return array SQL の実行結果の配列
674     */
675    function query($n ,$arr = array(), $ignore_err = false){
676
677        $n = $this->dbFactory->sfChangeMySQL($n);
678
679        $sth =& $this->prepare($n);
680        if (PEAR::isError($sth) && $this->force_run) {
681            return;
682        }
683
684        $result = $this->execute($sth, $arr);
685        if (PEAR::isError($result) && $this->force_run) {
686            return;
687        }
688
689        return $result;
690    }
691
692    /**
693     * シーケンスの一覧を取得する.
694     *
695     * @return array シーケンス名の配列
696     */
697    function listSequences() {
698        $this->conn->loadModule('Manager');
699        return $this->conn->listSequences();
700    }
701
702    /**
703     * テーブル一覧を取得する.
704     *
705     * @return array テーブル名の配列
706     */
707    function listTables() {
708        $this->conn->loadModule('Manager');
709        return $this->conn->listTables();
710    }
711
712    /**
713     * テーブルのカラム一覧を取得する.
714     *
715     * @param string $table テーブル名
716     * @return array 指定のテーブルのカラム名の配列
717     */
718    function listTableFields($table) {
719        $this->conn->loadModule('Manager');
720        return $this->conn->listTableFields($table);
721    }
722
723    /**
724     * テーブルのインデックス一覧を取得する.
725     *
726     * @param string $table テーブル名
727     * @return array 指定のテーブルのインデックス一覧
728     */
729    function listTableIndexes($table) {
730        $this->conn->loadModule('Manager');
731        return $this->conn->listTableIndexes($table);
732    }
733   
734    /**
735     * テーブルにインデックスを付与する
736     *
737     * @param string $table テーブル名
738     * @param string $name インデックス名
739     * @param array $definition フィールド名など 通常のフィールド指定時は、$definition=array('fields' => array('フィールド名' => array()));
740     */
741    function createIndex($table, $name, $definition) {
742        $this->conn->loadModule('Manager');
743        return $this->conn->createIndex($table, $name, $definition);
744    }
745
746    /**
747     * テーブルにインデックスを破棄する
748     *
749     * @param string $table テーブル名
750     * @param string $name インデックス名
751     */
752    function dropIndex($table, $name) {
753        $this->conn->loadModule('Manager');
754        return $this->conn->dropIndex($table, $name);
755    }
756   
757    /**
758     * 値を適切にクォートする.
759     *
760     * TODO MDB2 に対応するための暫定的な措置.
761     *      ブレースホルダが使用できない実装があるため.
762     *      本来であれば, MDB2::prepare() を適切に使用するべき
763     *
764     * @see MDB2::quote()
765     * @param string $val クォートを行う文字列
766     * @return string クォートされた文字列
767     */
768    function quote($val) {
769        return $this->conn->quote($val);
770    }
771
772    /**
773     * プリペアドステートメントを構築する.
774     *
775     * @access private
776     * @param string $sql プリペアドステートメントを構築する SQL
777     * @return MDB2_Statement_Common プリペアドステートメントインスタンス
778     */
779    function prepare($sql) {
780        $sth =& $this->conn->prepare($sql);
781        if (PEAR::isError($sth)) {
782            if (!$this->force_run) {
783                trigger_error($this->traceError($sth, $sql), E_USER_ERROR);
784            } else {
785                error_log($this->traceError($sth, $sql), 3, LOG_PATH);
786            }
787        }
788        return $sth;
789    }
790
791    /**
792     * プリペアドクエリを実行する.
793     *
794     * @access private
795     * @param MDB2_Statement_Common プリペアドステートメントインスタンス
796     * @param array $arrVal ブレースホルダに挿入する配列
797     * @return MDB2_Result 結果セットのインスタンス
798     */
799    function execute(&$sth, $arrVal = array()) {
800        $timeStart = SC_Utils_Ex::sfMicrotimeFloat();
801        $affected =& $sth->execute($arrVal);
802
803        // 一定以上時間かかったSQLの場合、ログ出力する。
804        if(defined('SQL_QUERY_LOG_MODE') && SQL_QUERY_LOG_MODE == true) {
805            $timeEnd = SC_Utils_Ex::sfMicrotimeFloat();;
806            $timeExecTime = $timeEnd - $timeStart;
807            if(defined('SQL_QUERY_LOG_MIN_EXEC_TIME') && $timeExecTime >= (float)SQL_QUERY_LOG_MIN_EXEC_TIME) {
808                //$logMsg = sprintf("SQL_LOG [%.2fsec]\n%s", $timeExecTime, $this->getLastQuery(false));
809                $logMsg = sprintf("SQL_LOG [%.2fsec]\n%s", $timeExecTime, $sth->query);
810                GC_Utils_Ex::gfPrintLog($logMsg);
811            }
812        }
813
814        if (PEAR::isError($affected)) {
815            $sql = isset($sth->query) ? $sth->query : '';
816            if (!$this->force_run) {
817                trigger_error($this->traceError($affected, $sql), E_USER_ERROR);
818            } else {
819                error_log($this->traceError($affected, $sql), 3, LOG_PATH);
820            }
821        }
822        return $affected;
823    }
824
825    /**
826     * エラーの内容をトレースする.
827     *
828     * @access private
829     * @param PEAR::Error $error PEAR::Error インスタンス
830     * @param string $sql エラーの発生した SQL 文
831     * @return string トレースしたエラー文字列
832     */
833    function traceError($error, $sql = "") {
834        $scheme = '';
835        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
836            $scheme = "http://";
837        } else {
838            $scheme = "https://";
839        }
840
841        $err = $scheme . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\n\n"
842            . "SERVER_ADDR: " . $_SERVER['SERVER_ADDR'] . "\n"
843            . "REMOTE_ADDR: " . $_SERVER['REMOTE_ADDR'] . "\n"
844            . "USER_AGENT: " . $_SERVER['HTTP_USER_AGENT'] . "\n\n"
845            . "SQL: " . $sql . "\n\n"
846            . $error->getMessage() . "\n\n"
847            . $error->getUserInfo() . "\n\n";
848
849        $err .= SC_Utils_Ex::sfBacktraceToString($error->getBackTrace());
850
851        return $err;
852    }
853}
854
855?>
Note: See TracBrowser for help on using the repository browser.