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

Revision 18773, 14.6 KB checked in by nanasess, 16 years ago (diff)

SC_DbConn クラスを削除(#565)

  • 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    var $option;
36    var $where;
37    var $conn;
38    var $groupby;
39    var $order;
40
41    /**
42     * コンストラクタ.
43     *
44     * @param $dsn
45     * @param boolean $err_disp エラー表示を行うかどうか
46     * @param boolean $new 新規に接続を行うかどうか
47     * @return SC_Query
48     */
49    function SC_Query($dsn = "", $err_disp = true, $new = false) {
50
51        if ($dsn == "") {
52            $dsn = DEFAULT_DSN;
53        }
54
55        // Debugモード指定
56        $options['debug'] = PEAR_DB_DEBUG;
57        // 持続的接続オプション
58        $options['persistent'] = PEAR_DB_PERSISTENT;
59
60        if ($new) {
61            $this->conn = MDB2::connect($dsn, $options);
62        } else {
63            $this->conn = MDB2::singleton($dsn, $options);
64        }
65
66        $this->conn->setCharset(CHAR_CODE);
67        $this->conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
68        $this->dbFactory = SC_DB_DBFactory_Ex::getInstance();
69        $this->where = "";
70    }
71
72    /**
73     *  エラー判定を行う.
74     *
75     * @return boolean
76     */
77    function isError() {
78        if(PEAR::isError($this->conn)) {
79            return true;
80        }
81        return false;
82    }
83
84    /**
85     * COUNT文を実行する.
86     *
87     * @param string $table テーブル名
88     * @param string $where where句
89     * @param array $arrval プレースホルダ
90     * @return integer 件数
91     */
92    function count($table, $where = "", $arrval = array()) {
93        if(strlen($where) <= 0) {
94            $sqlse = "SELECT COUNT(*) FROM $table";
95        } else {
96            $sqlse = "SELECT COUNT(*) FROM $table WHERE $where";
97        }
98        $sqlse = $this->dbFactory->sfChangeMySQL($sqlse);
99        return $this->getOne($sqlse, $arrval);
100    }
101
102    /**
103     * SELECT文を実行する.
104     *
105     * @param string $col カラム名. 複数カラムの場合はカンマ区切りで書く
106     * @param string $table テーブル名
107     * @param string $where WHERE句
108     * @param array $arrval プレースホルダ
109     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
110     * @return array|null
111     */
112    function select($col, $table, $where = "", $arrval = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
113        $sqlse = $this->getSql($col, $table, $where);
114        return $this->getAll($sqlse, $arrval, $fetchmode);
115    }
116
117    /**
118     * 直前に実行されたSQL文を取得する.
119     *
120     * @param boolean $disp trueの場合、画面出力を行う.
121     * @return string SQL文
122     */
123    function getLastQuery($disp = true) {
124        $sql = $this->conn->last_query;
125        if($disp) {
126            print($sql.";<br />\n");
127        }
128        return $sql;
129    }
130
131    function commit() {
132        $this->conn->commit();
133    }
134
135    function begin() {
136        $this->conn->beginTransaction();
137    }
138
139    function rollback() {
140        $this->conn->rollback();
141    }
142
143    function exec($str, $arrval = array()) {
144        // FIXME MDB2::exec() の実装であるべき
145        $this->query($str, $arrval);
146    }
147
148    /**
149     * クエリを実行し、全ての行を返す
150     *
151     * @param string $sql SQL クエリ
152     * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
153     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
154     * @return array データを含む2次元配列。失敗した場合に 0 または DB_Error オブジェクトを返します。
155     */
156    function getAll($sql, $arrval = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
157
158        $sql = $this->dbFactory->sfChangeMySQL($sql);
159
160        $sth = $this->conn->prepare($sql);
161        $affected = $sth->execute($arrval);
162
163        if (PEAR::isError($affected)) {
164            trigger_error($affected->getMessage(), E_USER_ERROR);
165        }
166
167        return $affected->fetchAll($fetchmode);
168    }
169
170    function getSql($col, $table, $where = '') {
171        $sqlse = "SELECT $col FROM $table";
172
173        // 引数の$whereを優先する。
174        if (strlen($where) >= 1) {
175            $sqlse .= " WHERE $where";
176        } elseif (strlen($this->where) >= 1) {
177            $where = $this->where;
178        }
179
180        $sqlse .= ' ' . $this->groupby . ' ' . $this->order . ' ' . $this->option;
181
182        return $sqlse;
183    }
184
185    function setOption($str) {
186        $this->option = $str;
187    }
188
189    // TODO MDB2::setLimit() を使用する
190    function setLimitOffset($limit, $offset = 0, $return = false) {
191        if (is_numeric($limit) && is_numeric($offset)){
192
193            $option = " LIMIT " . $limit;
194            $option.= " OFFSET " . $offset;
195
196            if($return){
197                return $option;
198            }else{
199                $this->option.= $option;
200            }
201        }
202    }
203
204    function setGroupBy($str) {
205        if (strlen($str) == 0) {
206            $this->groupby = '';
207        } else {
208            $this->groupby = "GROUP BY " . $str;
209        }
210    }
211
212    function andwhere($str) {
213        if($this->where != "") {
214            $this->where .= " AND " . $str;
215        } else {
216            $this->where = $str;
217        }
218    }
219
220    function orWhere($str) {
221        if($this->where != "") {
222            $this->where .= " OR " . $str;
223        } else {
224            $this->where = $str;
225        }
226    }
227
228    function setWhere($str) {
229        $this->where = $str;
230    }
231
232    function setOrder($str) {
233        if (strlen($str) == 0) {
234            $this->order = '';
235        } else {
236            $this->order = "ORDER BY " . $str;
237        }
238    }
239
240
241    function setLimit($limit){
242        if ( is_numeric($limit)){
243            $this->option = " LIMIT " .$limit;
244        }
245    }
246
247    function setOffset($offset) {
248        if ( is_numeric($offset)){
249            $this->offset = " OFFSET " .$offset;
250        }
251    }
252
253    /**
254     * INSERT文を実行する.
255     *
256     * @param string $table テーブル名
257     * @param array $sqlval array('カラム名' => '値',...)の連想配列
258     * @return
259     */
260    function insert($table, $sqlval) {
261        $strcol = '';
262        $strval = '';
263        $find = false;
264
265        if(count($sqlval) <= 0 ) return false;
266
267        foreach ($sqlval as $key => $val) {
268            $strcol .= $key . ',';
269            if(eregi("^Now\(\)$", $val)) {
270                $strval .= 'Now(),';
271            } else {
272                $strval .= '?,';
273                $arrval[] = $val;
274            }
275            $find = true;
276        }
277        if(!$find) {
278            return false;
279        }
280        // 文末の","を削除
281        $strcol = ereg_replace(",$","",$strcol);
282        // 文末の","を削除
283        $strval = ereg_replace(",$","",$strval);
284        $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")";
285        // INSERT文の実行
286        $ret = $this->query($sqlin, $arrval);
287
288        return $ret;
289    }
290
291    /**
292     * UPDATE文を実行する.
293     *
294     * @param string $table テーブル名
295     * @param array $sqlval array('カラム名' => '値',...)の連想配列
296     * @param string $where WHERE句
297     * @param array $arrValIn WHERE句用のプレースホルダ配列 (従来は追加カラム用も兼ねていた)
298     * @param array $arrRawSql 追加カラム
299     * @param array $arrRawSqlVal 追加カラム用のプレースホルダ配列
300     * @return
301     */
302    function update($table, $sqlval, $where = "", $arrValIn = array(), $arrRawSql = array(), $arrRawSqlVal = array()) {
303        $arrCol = array();
304        $arrVal = array();
305        $find = false;
306        foreach ($sqlval as $key => $val) {
307            if (eregi("^Now\(\)$", $val)) {
308                $arrCol[] = $key . '= Now()';
309            } else {
310                $arrCol[] = $key . '= ?';
311                $arrVal[] = $val;
312            }
313            $find = true;
314        }
315
316        if ($arrRawSql != "") {
317            foreach($arrRawSql as $key => $val) {
318                $arrCol[] = "$key = $val";
319            }
320        }
321       
322        $arrVal = array_merge($arrVal, $arrRawSqlVal);
323       
324        if (empty($arrCol)) {
325            return false;
326        }
327
328        // 文末の","を削除
329        $strcol = implode(', ', $arrCol);
330
331        if (is_array($arrValIn)) { // 旧版との互換用
332            // プレースホルダー用に配列を追加
333            $arrVal = array_merge($arrVal, $arrValIn);
334        }
335
336        $sqlup = "UPDATE $table SET $strcol";
337        if (strlen($where) >= 1) {
338            $sqlup .= " WHERE $where";
339        }
340
341        // UPDATE文の実行
342        return $this->query($sqlup, $arrVal);
343    }
344
345    // MAX文の実行
346    function max($table, $col, $where = "", $arrval = array()) {
347        $ret = $this->get($table, "MAX($col)", $where, $arrval);
348        return $ret;
349    }
350
351    // MIN文の実行
352    function min($table, $col, $where = "", $arrval = array()) {
353        $ret = $this->get($table, "MIN($col)", $where, $arrval);
354        return $ret;
355    }
356
357    // 特定のカラムの値を取得
358    function get($table, $col, $where = "", $arrval = array()) {
359        $sqlse = $this->getSql($col, $table, $where);
360        // SQL文の実行
361        $ret = $this->getOne($sqlse, $arrval);
362        return $ret;
363    }
364
365    function getOne($sql, $arrval = array()) {
366
367        $sql = $this->dbFactory->sfChangeMySQL($sql);
368
369        $sth = $this->conn->prepare($sql);
370        $affected = $sth->execute($arrval);
371
372        if (PEAR::isError($affected)) {
373            trigger_error($affected->getMessage(), E_USER_ERROR);
374        }
375
376        return $affected->fetchOne();
377    }
378
379    /**
380     * 一行をカラム名をキーとした連想配列として取得
381     *
382     * @param string $table テーブル名
383     * @param string $col カラム名
384     * @param string $where WHERE句
385     * @param array $arrVal プレースホルダ配列
386     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
387     * @return array array('カラム名' => '値', ...)の連想配列
388     */
389    function getRow($table, $col, $where = "", $arrVal = array(), $fetchmode = MDB2_FETCHMODE_ASSOC) {
390
391        $sql = $this->getSql($col, $table, $where);
392        $sql = $this->dbFactory->sfChangeMySQL($sql);
393
394        $sth = $this->conn->prepare($sql);
395        $affected = $sth->execute($arrVal);
396
397        if (PEAR::isError($affected)) {
398            trigger_error($affected->getMessage(), E_USER_ERROR);
399        }
400
401        return $affected->fetchRow($fetchmode);
402    }
403
404    // 1列取得
405    function getCol($table, $col, $where = "", $arrval = array()) {
406        $sql = $this->getSql($col, $table, $where);
407        $sql = $this->dbFactory->sfChangeMySQL($sql);
408
409        $sth = $this->conn->prepare($sql);
410        $affected = $sth->execute($arrval);
411
412        if (PEAR::isError($affected)) {
413            trigger_error($affected->getMessage(), E_USER_ERROR);
414        }
415
416        return $affected->fetchCol($col);
417    }
418
419    /**
420     * レコードの削除
421     *
422     * @param string $table テーブル名
423     * @param string $where WHERE句
424     * @param array $arrval プレースホルダ
425     * @return
426     */
427    function delete($table, $where = "", $arrval = array()) {
428        if(strlen($where) <= 0) {
429            $sqlde = "DELETE FROM $table";
430        } else {
431            $sqlde = "DELETE FROM $table WHERE $where";
432        }
433        $ret = $this->query($sqlde, $arrval);
434        return $ret;
435    }
436
437    function nextval($table, $colname) {
438        $sql = "";
439        // postgresqlとmysqlとで処理を分ける
440        if (DB_TYPE == "pgsql") {
441            $seqtable = $table . "_" . $colname . "_seq";
442            $sql = "SELECT NEXTVAL('$seqtable')";
443        }else if (DB_TYPE == "mysql") {
444            $sql = "SELECT last_insert_id();";
445        }
446        $ret = $this->getOne($sql);
447
448        return $ret;
449    }
450
451    function currval($table, $colname) {
452        $sql = "";
453        if (DB_TYPE == "pgsql") {
454            $seqtable = $table . "_" . $colname . "_seq";
455            $sql = "SELECT CURRVAL('$seqtable')";
456        }else if (DB_TYPE == "mysql") {
457            $sql = "SELECT last_insert_id();";
458        }
459        $ret = $this->getOne($sql);
460
461        return $ret;
462    }
463
464    function setval($table, $colname, $data) {
465        $sql = "";
466        if (DB_TYPE == "pgsql") {
467            $seqtable = $table . "_" . $colname . "_seq";
468            $sql = "SELECT SETVAL('$seqtable', $data)";
469            $ret = $this->getOne($sql);
470        }else if (DB_TYPE == "mysql") {
471            $sql = "ALTER TABLE $table AUTO_INCREMENT=$data";
472            $ret = $this->query($sql);
473        }
474
475        return $ret;
476    }
477
478    // XXX 更新系には exec() を使用するべき
479    function query($n ,$arr = array(), $ignore_err = false){
480
481        $n = $this->dbFactory->sfChangeMySQL($n);
482
483        $sth = $this->conn->prepare($n);
484        $result = $sth->execute($arr);
485
486        if (PEAR::isError($result)) {
487            trigger_error($result->getMessage(), E_USER_ERROR);
488        }
489
490        return $result;
491    }
492
493    /**
494     * auto_incrementを取得する.
495     *
496     * @param string $table_name テーブル名
497     * @return integer
498     */
499    function get_auto_increment($table_name){
500        // ロックする
501        $this->query("LOCK TABLES $table_name WRITE");
502
503        // 次のIncrementを取得
504        $arrRet = $this->getAll("SHOW TABLE STATUS LIKE ?", array($table_name));
505        $auto_inc_no = $arrRet[0]["Auto_increment"];
506
507        // 値をカウントアップしておく
508        $this->query("ALTER TABLE $table_name AUTO_INCREMENT=?" , $auto_inc_no + 1);
509
510        // 解除する
511        $this->query('UNLOCK TABLES');
512
513        return $auto_inc_no;
514    }
515}
516
517?>
Note: See TracBrowser for help on using the repository browser.