source: branches/comu-ver2/data/class/SC_Query.php @ 18590

Revision 18590, 12.9 KB checked in by Seasoft, 11 years ago (diff)
  • #615(SQL文生成時にパラメータが無視されるケースがある)改修
  • 分散しているSQL文生成ロジックを集約
  • SQL文生成ロジックを整理
  • 未参照メソッドの削除
  • 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-2007 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
24/**
25 * SQLの構築・実行を行う
26 *
27 * @author LOCKON CO.,LTD.
28 * @version $Id$
29 */
30class SC_Query {
31    var $option;
32    var $where;
33    var $conn;
34    var $groupby;
35    var $order;
36
37    /**
38     * コンストラクタ.
39     *
40     * @param $dsn
41     * @param boolean $err_disp エラー表示を行うかどうか
42     * @param boolean $new 新規に接続を行うかどうか
43     * @return SC_Query
44     */
45    function SC_Query($dsn = "", $err_disp = true, $new = false) {
46        $this->conn = new SC_DBconn($dsn, $err_disp, $new);
47        $this->where = "";
48    }
49
50    /**
51     *  エラー判定を行う.
52     *
53     * @return boolean
54     */
55    function isError() {
56        if(PEAR::isError($this->conn->conn)) {
57            return true;
58        }
59        return false;
60    }
61
62    /**
63     * COUNT文を実行する.
64     *
65     * @param string $table テーブル名
66     * @param string $where where句
67     * @param array $arrval プレースホルダ
68     * @return integer 件数
69     */
70    function count($table, $where = "", $arrval = array()) {
71        if(strlen($where) <= 0) {
72            $sqlse = "SELECT COUNT(*) FROM $table";
73        } else {
74            $sqlse = "SELECT COUNT(*) FROM $table WHERE $where";
75        }
76        // カウント文の実行
77        $ret = $this->conn->getOne($sqlse, $arrval);
78        return $ret;
79    }
80
81    /**
82     * SELECT文を実行する.
83     *
84     * @param string $col カラム名. 複数カラムの場合はカンマ区切りで書く
85     * @param string $table テーブル名
86     * @param string $where WHERE句
87     * @param array $arrval プレースホルダ
88     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
89     * @return array|null
90     */
91    function select($col, $table, $where = "", $arrval = array(), $fetchmode = DB_FETCHMODE_ASSOC) {
92        $sqlse = $this->getsql($col, $table, $where);
93        $ret = $this->conn->getAll($sqlse, $arrval, $fetchmode);
94        return $ret;
95    }
96
97    /**
98     * 直前に実行されたSQL文を取得する.
99     * SC_DBconn::getLastQuery() を利用.
100     *
101     * @param boolean $disp trueの場合、画面出力を行う.
102     * @return string SQL文
103     */
104    function getLastQuery($disp = true) {
105        return $this->conn->getLastQuery($disp);
106    }
107
108    function commit() {
109        $this->conn->query("COMMIT");
110    }
111
112    function begin() {
113        $this->conn->query("BEGIN");
114    }
115
116    function rollback() {
117        $this->conn->query("ROLLBACK");
118    }
119
120    function exec($str, $arrval = array()) {
121        $this->conn->query($str, $arrval);
122    }
123
124    /**
125     * クエリを実行し、全ての行を返す
126     *
127     * @param string $sql SQL クエリ
128     * @param array $arrVal プリペアドステートメントの実行時に使用される配列。配列の要素数は、クエリ内のプレースホルダの数と同じでなければなりません。
129     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
130     * @return array データを含む2次元配列。失敗した場合に 0 または DB_Error オブジェクトを返します。
131     */
132    function getall($sql, $arrval = array(), $fetchmode = DB_FETCHMODE_ASSOC) {
133        $ret = $this->conn->getAll($sql, $arrval, $fetchmode);
134        return $ret;
135    }
136
137    function getsql($col, $table, $where = '') {
138        $sqlse = "SELECT $col FROM $table";
139
140        // 引数の$whereを優先する。
141        if (strlen($where) >= 1) {
142            $sqlse .= " WHERE $where";
143        } elseif (strlen($this->where) >= 1) {
144            $where = $this->where;
145        }
146
147        $sqlse .= ' ' . $this->groupby . ' ' . $this->order . ' ' . $this->option;
148
149        return $sqlse;
150    }
151
152    function setoption($str) {
153        $this->option = $str;
154    }
155
156    function setlimitoffset($limit, $offset = 0, $return = false) {
157        if (is_numeric($limit) && is_numeric($offset)){
158
159            $option = " LIMIT " . $limit;
160            $option.= " OFFSET " . $offset;
161
162            if($return){
163                return $option;
164            }else{
165                $this->option.= $option;
166            }
167        }
168    }
169
170    function setgroupby($str) {
171        if (strlen($str) == 0) {
172            $this->groupby = '';
173        } else {
174            $this->groupby = "GROUP BY " . $str;
175        }
176    }
177
178    function andwhere($str) {
179        if($this->where != "") {
180            $this->where .= " AND " . $str;
181        } else {
182            $this->where = $str;
183        }
184    }
185
186    function orwhere($str) {
187        if($this->where != "") {
188            $this->where .= " OR " . $str;
189        } else {
190            $this->where = $str;
191        }
192    }
193
194    function setwhere($str) {
195        $this->where = $str;
196    }
197
198    function setorder($str) {
199        if (strlen($str) == 0) {
200            $this->order = '';
201        } else {
202            $this->order = "ORDER BY " . $str;
203        }
204    }
205
206
207    function setlimit($limit){
208        if ( is_numeric($limit)){
209            $this->option = " LIMIT " .$limit;
210        }
211    }
212
213    function setoffset($offset) {
214        if ( is_numeric($offset)){
215            $this->offset = " OFFSET " .$offset;
216        }
217    }
218
219    /**
220     * INSERT文を実行する.
221     *
222     * @param string $table テーブル名
223     * @param array $sqlval array('カラム名' => '値',...)の連想配列
224     * @return
225     */
226    function insert($table, $sqlval) {
227        $strcol = '';
228        $strval = '';
229        $find = false;
230
231        if(count($sqlval) <= 0 ) return false;
232
233        foreach ($sqlval as $key => $val) {
234            $strcol .= $key . ',';
235            if(eregi("^Now\(\)$", $val)) {
236                $strval .= 'Now(),';
237            } else {
238                $strval .= '?,';
239                $arrval[] = $val;
240            }
241            $find = true;
242        }
243        if(!$find) {
244            return false;
245        }
246        // 文末の","を削除
247        $strcol = ereg_replace(",$","",$strcol);
248        // 文末の","を削除
249        $strval = ereg_replace(",$","",$strval);
250        $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")";
251        // INSERT文の実行
252        $ret = $this->conn->query($sqlin, $arrval);
253
254        return $ret;
255    }
256
257    /**
258     * UPDATE文を実行する.
259     *
260     * @param string $table テーブル名
261     * @param array $sqlval array('カラム名' => '値',...)の連想配列
262     * @param string $where WHERE句
263     * @param array $arrValIn WHERE句用のプレースホルダ配列 (従来は追加カラム用も兼ねていた)
264     * @param array $arrRawSql 追加カラム
265     * @param array $arrRawSqlVal 追加カラム用のプレースホルダ配列
266     * @return
267     */
268    function update($table, $sqlval, $where = "", $arrValIn = array(), $arrRawSql = array(), $arrRawSqlVal = array()) {
269        $arrCol = array();
270        $arrVal = array();
271        $find = false;
272        foreach ($sqlval as $key => $val) {
273            if (eregi("^Now\(\)$", $val)) {
274                $arrCol[] = $key . '= Now()';
275            } else {
276                $arrCol[] = $key . '= ?';
277                $arrVal[] = $val;
278            }
279            $find = true;
280        }
281
282        if ($arrRawSql != "") {
283            foreach($arrRawSql as $key => $val) {
284                $arrCol[] = "$key = $val";
285            }
286        }
287       
288        $arrVal = array_merge($arrVal, $arrRawSqlVal);
289       
290        if (empty($arrCol)) {
291            return false;
292        }
293
294        // 文末の","を削除
295        $strcol = implode(', ', $arrCol);
296
297        if (is_array($arrValIn)) { // 旧版との互換用
298            // プレースホルダー用に配列を追加
299            $arrVal = array_merge($arrVal, $arrValIn);
300        }
301
302        $sqlup = "UPDATE $table SET $strcol";
303        if (strlen($where) >= 1) {
304            $sqlup .= " WHERE $where";
305        }
306
307        // UPDATE文の実行
308        return $this->conn->query($sqlup, $arrVal);
309    }
310
311    // MAX文の実行
312    function max($table, $col, $where = "", $arrval = array()) {
313        $ret = $this->get($table, "MAX($col)", $where);
314        return $ret;
315    }
316
317    // MIN文の実行
318    function min($table, $col, $where = "", $arrval = array()) {
319        $ret = $this->get($table, "MIN($col)", $where);
320        return $ret;
321    }
322
323    // 特定のカラムの値を取得
324    function get($table, $col, $where = "", $arrval = array()) {
325        $sqlse = $this->getsql($col, $table, $where);
326        // SQL文の実行
327        $ret = $this->getone($sqlse, $arrval);
328        return $ret;
329    }
330
331    function getone($sql, $arrval = array()) {
332        // SQL文の実行
333        $ret = $this->conn->getOne($sql, $arrval);
334        return $ret;
335    }
336
337    /**
338     * 一行をカラム名をキーとした連想配列として取得
339     *
340     * @param string $table テーブル名
341     * @param string $col カラム名
342     * @param string $where WHERE句
343     * @param array $arrVal プレースホルダ配列
344     * @param integer $fetchmode 使用するフェッチモード。デフォルトは DB_FETCHMODE_ASSOC。
345     * @return array array('カラム名' => '値', ...)の連想配列
346     */
347    function getRow($table, $col, $where = "", $arrVal = array(), $fetchmode = DB_FETCHMODE_ASSOC) {
348        $sqlse = $this->getsql($col, $table, $where);
349        // SQL文の実行
350        return $this->conn->getRow($sqlse, $arrVal ,$fetchmode);
351    }
352
353    // 1列取得
354    function getCol($table, $col, $where = "", $arrval = array()) {
355        $sqlse = $this->getsql($col, $table, $where);
356        // SQL文の実行
357        return $this->conn->getCol($sqlse, 0, $arrval);
358    }
359
360    /**
361     * レコードの削除
362     *
363     * @param string $table テーブル名
364     * @param string $where WHERE句
365     * @param array $arrval プレースホルダ
366     * @return
367     */
368    function delete($table, $where = "", $arrval = array()) {
369        if(strlen($where) <= 0) {
370            $sqlde = "DELETE FROM $table";
371        } else {
372            $sqlde = "DELETE FROM $table WHERE $where";
373        }
374        $ret = $this->conn->query($sqlde, $arrval);
375        return $ret;
376    }
377
378    function nextval($table, $colname) {
379        $sql = "";
380        // postgresqlとmysqlとで処理を分ける
381        if (DB_TYPE == "pgsql") {
382            $seqtable = $table . "_" . $colname . "_seq";
383            $sql = "SELECT NEXTVAL('$seqtable')";
384        }else if (DB_TYPE == "mysql") {
385            $sql = "SELECT last_insert_id();";
386        }
387        $ret = $this->conn->getOne($sql);
388
389        return $ret;
390    }
391
392    function currval($table, $colname) {
393        $sql = "";
394        if (DB_TYPE == "pgsql") {
395            $seqtable = $table . "_" . $colname . "_seq";
396            $sql = "SELECT CURRVAL('$seqtable')";
397        }else if (DB_TYPE == "mysql") {
398            $sql = "SELECT last_insert_id();";
399        }
400        $ret = $this->conn->getOne($sql);
401
402        return $ret;
403    }
404
405    function setval($table, $colname, $data) {
406        $sql = "";
407        if (DB_TYPE == "pgsql") {
408            $seqtable = $table . "_" . $colname . "_seq";
409            $sql = "SELECT SETVAL('$seqtable', $data)";
410            $ret = $this->conn->getOne($sql);
411        }else if (DB_TYPE == "mysql") {
412            $sql = "ALTER TABLE $table AUTO_INCREMENT=$data";
413            $ret = $this->conn->query($sql);
414        }
415
416        return $ret;
417    }
418
419    function query($n ,$arr = "", $ignore_err = false){
420        $result = $this->conn->query($n, $arr, $ignore_err);
421        return $result;
422    }
423
424    /**
425     * auto_incrementを取得する.
426     *
427     * @param string $table_name テーブル名
428     * @return integer
429     */
430    function get_auto_increment($table_name){
431        // ロックする
432        $this->query("LOCK TABLES $table_name WRITE");
433
434        // 次のIncrementを取得
435        $arrRet = $this->getAll("SHOW TABLE STATUS LIKE ?", array($table_name));
436        $auto_inc_no = $arrRet[0]["Auto_increment"];
437
438        // 値をカウントアップしておく
439        $this->conn->query("ALTER TABLE $table_name AUTO_INCREMENT=?" , $auto_inc_no + 1);
440
441        // 解除する
442        $this->query('UNLOCK TABLES');
443
444        return $auto_inc_no;
445    }
446}
447
448?>
Note: See TracBrowser for help on using the repository browser.