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

Revision 19805, 29.1 KB checked in by Seasoft, 13 years ago (diff)

#834(パラメータの定数名に「URL」を含むにもかかわらず、パスのみのものがある) 一部実装

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