source: branches/version-2/data/class/SC_Query.php @ 17564

Revision 17564, 14.9 KB checked in by nakanishi, 16 years ago (diff)

INSERTでプレースホルダを除外する時にDBエラーになる問題を修正。
#342

  • 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     * @return array|null
89     */
90    function select($col, $table, $where = "", $arrval = array()){
91        $sqlse = $this->getsql($col, $table, $where);
92        // DBに依存した SQL へ変換
93        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
94        $sqlse = $dbFactory->sfChangeMySQL($sqlse);
95        $ret = $this->conn->getAll($sqlse, $arrval);
96        return $ret;
97    }
98
99    /**
100     * 直前に実行されたSQL文を取得する.
101     *
102     * @param boolean $disp trueの場合、画面出力を行う.
103     * @return string SQL文
104     */
105    function getLastQuery($disp = true) {
106        $sql = $this->conn->conn->last_query;
107        if($disp) {
108            print($sql.";<br />\n");
109        }
110        return $sql;
111    }
112
113    function commit() {
114        $this->conn->query("COMMIT");
115    }
116
117    function begin() {
118        $this->conn->query("BEGIN");
119    }
120
121    function rollback() {
122        $this->conn->query("ROLLBACK");
123    }
124
125    function exec($str, $arrval = array()) {
126        $this->conn->query($str, $arrval);
127    }
128
129    function autoselect($col, $table, $arrwhere = array(), $arrcon = array()) {
130        $strw = "";
131        $find = false;
132        foreach ($arrwhere as $key => $val) {
133            if(strlen($val) > 0) {
134                if(strlen($strw) <= 0) {
135                    $strw .= $key ." LIKE ?";
136                } else if(strlen($arrcon[$key]) > 0) {
137                    $strw .= " ". $arrcon[$key]. " " . $key ." LIKE ?";
138                } else {
139                    $strw .= " AND " . $key ." LIKE ?";
140                }
141
142                $arrval[] = $val;
143            }
144        }
145
146        if(strlen($strw) > 0) {
147            $sqlse = "SELECT $col FROM $table WHERE $strw ".$this->option;
148        } else {
149            $sqlse = "SELECT $col FROM $table ".$this->option;
150        }
151        $ret = $this->conn->getAll($sqlse, $arrval);
152        return $ret;
153    }
154
155    function getall($sql, $arrval = array()) {
156        $ret = $this->conn->getAll($sql, $arrval);
157        return $ret;
158    }
159
160    function getsql($col, $table, $where) {
161        if($where != "") {
162            // 引数の$whereを優先して実行する。
163            $sqlse = "SELECT $col FROM $table WHERE $where " . $this->groupby . " " . $this->order . " " . $this->option;
164        } else {
165            if($this->where != "") {
166                    $sqlse = "SELECT $col FROM $table WHERE $this->where " . $this->groupby . " " . $this->order . " " . $this->option;
167                } else {
168                    $sqlse = "SELECT $col FROM $table " . $this->groupby . " " . $this->order . " " . $this->option;
169            }
170        }
171        return $sqlse;
172    }
173
174    function setoption($str) {
175        $this->option = $str;
176    }
177
178    function setlimitoffset($limit, $offset = 0, $return = false) {
179        if (is_numeric($limit) && is_numeric($offset)){
180
181            $option = " LIMIT " . $limit;
182            $option.= " OFFSET " . $offset;
183
184            if($return){
185                return $option;
186            }else{
187                $this->option.= $option;
188            }
189        }
190    }
191
192    function setgroupby($str) {
193        $this->groupby = "GROUP BY " . $str;
194    }
195
196    function andwhere($str) {
197        if($this->where != "") {
198            $this->where .= " AND " . $str;
199        } else {
200            $this->where = $str;
201        }
202    }
203
204    function orwhere($str) {
205        if($this->where != "") {
206            $this->where .= " OR " . $str;
207        } else {
208            $this->where = $str;
209        }
210    }
211
212    function setwhere($str) {
213        $this->where = $str;
214    }
215
216    function setorder($str) {
217        $this->order = "ORDER BY " . $str;
218    }
219
220
221    function setlimit($limit){
222        if ( is_numeric($limit)){
223            $this->option = " LIMIT " .$limit;
224        }
225    }
226
227    function setoffset($offset) {
228        if ( is_numeric($offset)){
229            $this->offset = " OFFSET " .$offset;
230        }
231    }
232
233    /**
234     * INSERT文を実行する.
235     *
236     * @param string $table テーブル名
237     * @param array $sqlval array('カラム名' => '値',...)の連想配列
238     * @return
239     */
240    function insert($table, $sqlval) {
241        $strcol = '';
242        $strval = '';
243        $find = false;
244
245        if(count($sqlval) <= 0 ) return false;
246
247        foreach ($sqlval as $key => $val) {
248            $strcol .= $key . ',';
249            if(eregi("^Now\(\)$", $val)) {
250                $strval .= 'Now(),';
251            // 先頭に~があるとプレースホルダーしない。
252            } else if(ereg("^~", $val)) {
253                $strval .= ereg_replace("^~", "", $val).",";
254            } else {
255                $strval .= '?,';
256                if($val != ""){
257                    $arrval[] = $val;
258                } else {
259                    $arrval[] = NULL;
260                }
261            }
262            $find = true;
263        }
264        if(!$find) {
265            return false;
266        }
267        // 文末の","を削除
268        $strcol = ereg_replace(",$","",$strcol);
269        // 文末の","を削除
270        $strval = ereg_replace(",$","",$strval);
271        $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")";
272        echo $sqlin;exit;
273        // INSERT文の実行
274        $ret = $this->conn->query($sqlin, $arrval);
275
276        return $ret;
277    }
278
279    // INSERT文の生成・実行
280    // $table   :テーブル名
281    // $sqlval  :列名 => 値の格納されたハッシュ配列
282    function fast_insert($table, $sqlval) {
283        $strcol = '';
284        $strval = '';
285        $find = false;
286
287        foreach ($sqlval as $key => $val) {
288                $strcol .= $key . ',';
289                if($val != ""){
290                    $eval = pg_escape_string($val);
291                    $strval .= "'$eval',";
292                } else {
293                    $strval .= "NULL,";
294                }
295                $find = true;
296        }
297        if(!$find) {
298            return false;
299        }
300        // 文末の","を削除
301        $strcol = ereg_replace(",$","",$strcol);
302        // 文末の","を削除
303        $strval = ereg_replace(",$","",$strval);
304        $sqlin = "INSERT INTO $table(" . $strcol. ") VALUES (" . $strval . ")";
305
306        // INSERT文の実行
307        $ret = $this->conn->query($sqlin);
308
309        return $ret;
310    }
311
312    /**
313     * UPDATE文を実行する.
314     *
315     * @param string $table テーブル名
316     * @param array $sqlval array('カラム名' => '値',...)の連想配列
317     * @param string $where WHERE句
318     * @param array $arradd $addcol用のプレースホルダ配列
319     * @param string $addcol 追加カラム
320     * @return
321     */
322    function update($table, $sqlval, $where = "", $arradd = "", $addcol = "") {
323        $strcol = '';
324        $strval = '';
325        $find = false;
326        foreach ($sqlval as $key => $val) {
327            if(eregi("^Now\(\)$", $val)) {
328                $strcol .= $key . '= Now(),';
329            // 先頭に~があるとプレースホルダーしない。
330            } else if(ereg("^~", $val)) {
331                $strcol .= $key . "=" . ereg_replace("^~", "", $val) . ",";
332            } else {
333                $strcol .= $key . '= ?,';
334                if($val != ""){
335                    $arrval[] = $val;
336                } else {
337                    $arrval[] = NULL;
338                }
339            }
340            $find = true;
341        }
342        if(!$find) {
343            return false;
344        }
345
346        if($addcol != "") {
347            foreach($addcol as $key => $val) {
348                $strcol .= "$key = $val,";
349            }
350        }
351
352        // 文末の","を削除
353        $strcol = ereg_replace(",$","",$strcol);
354        // 文末の","を削除
355        $strval = ereg_replace(",$","",$strval);
356
357        if($where != "") {
358            $sqlup = "UPDATE $table SET $strcol WHERE $where";
359        } else {
360            $sqlup = "UPDATE $table SET $strcol";
361        }
362
363        if(is_array($arradd)) {
364            // プレースホルダー用に配列を追加
365            foreach($arradd as $val) {
366                $arrval[] = $val;
367            }
368        }
369
370        // INSERT文の実行
371        $ret = $this->conn->query($sqlup, $arrval);
372        return $ret;
373    }
374
375    // MAX文の実行
376    function max($table, $col, $where = "", $arrval = array()) {
377        if(strlen($where) <= 0) {
378            $sqlse = "SELECT MAX($col) FROM $table";
379        } else {
380            $sqlse = "SELECT MAX($col) FROM $table WHERE $where";
381        }
382        // MAX文の実行
383        $ret = $this->conn->getOne($sqlse, $arrval);
384        return $ret;
385    }
386
387    // MIN文の実行
388    function min($table, $col, $where = "", $arrval = array()) {
389        if(strlen($where) <= 0) {
390            $sqlse = "SELECT MIN($col) FROM $table";
391        } else {
392            $sqlse = "SELECT MIN($col) FROM $table WHERE $where";
393        }
394        // MIN文の実行
395        $ret = $this->conn->getOne($sqlse, $arrval);
396        return $ret;
397    }
398
399    // 特定のカラムの値を取得
400    function get($table, $col, $where = "", $arrval = array()) {
401        if(strlen($where) <= 0) {
402            $sqlse = "SELECT $col FROM $table";
403        } else {
404            $sqlse = "SELECT $col FROM $table WHERE $where";
405        }
406        // SQL文の実行
407        $ret = $this->conn->getOne($sqlse, $arrval);
408        return $ret;
409    }
410
411    function getone($sql, $arrval = array()) {
412        // SQL文の実行
413        $ret = $this->conn->getOne($sql, $arrval);
414        return $ret;
415
416    }
417
418    // 一行を取得
419    function getrow($table, $col, $where = "", $arrval = array()) {
420        if(strlen($where) <= 0) {
421            $sqlse = "SELECT $col FROM $table";
422        } else {
423            $sqlse = "SELECT $col FROM $table WHERE $where";
424        }
425        // SQL文の実行
426        $ret = $this->conn->getRow($sqlse, $arrval);
427
428        return $ret;
429    }
430
431    // 1列取得
432    function getCol($table, $col, $where = "", $arrval = array()) {
433        if (strlen($where) <= 0) {
434            $sqlse = "SELECT $col FROM $table";
435        } else {
436            $sqlse = "SELECT $col FROM $table WHERE $where";
437        }
438        // SQL文の実行
439        return $this->conn->getCol($sqlse, $col, $arrval);
440    }
441
442    /**
443     * レコードの削除
444     *
445     * @param string $table テーブル名
446     * @param string $where WHERE句
447     * @param array $arrval プレースホルダ
448     * @return
449     */
450    function delete($table, $where = "", $arrval = array()) {
451        if(strlen($where) <= 0) {
452            $sqlde = "DELETE FROM $table";
453        } else {
454            $sqlde = "DELETE FROM $table WHERE $where";
455        }
456        $ret = $this->conn->query($sqlde, $arrval);
457        return $ret;
458    }
459
460    function nextval($table, $colname) {
461        $sql = "";
462        // postgresqlとmysqlとで処理を分ける
463        if (DB_TYPE == "pgsql") {
464            $seqtable = $table . "_" . $colname . "_seq";
465            $sql = "SELECT NEXTVAL('$seqtable')";
466        }else if (DB_TYPE == "mysql") {
467            $sql = "SELECT last_insert_id();";
468        }
469        $ret = $this->conn->getOne($sql);
470
471        return $ret;
472    }
473
474    function currval($table, $colname) {
475        $sql = "";
476        if (DB_TYPE == "pgsql") {
477            $seqtable = $table . "_" . $colname . "_seq";
478            $sql = "SELECT CURRVAL('$seqtable')";
479        }else if (DB_TYPE == "mysql") {
480            $sql = "SELECT last_insert_id();";
481        }
482        $ret = $this->conn->getOne($sql);
483
484        return $ret;
485    }
486
487    function setval($table, $colname, $data) {
488        $sql = "";
489        if (DB_TYPE == "pgsql") {
490            $seqtable = $table . "_" . $colname . "_seq";
491            $sql = "SELECT SETVAL('$seqtable', $data)";
492            $ret = $this->conn->getOne($sql);
493        }else if (DB_TYPE == "mysql") {
494            $sql = "ALTER TABLE $table AUTO_INCREMENT=$data";
495            $ret = $this->conn->query($sql);
496        }
497
498        return $ret;
499    }
500
501    function query($n ,$arr = "", $ignore_err = false){
502        $result = $this->conn->query($n, $arr, $ignore_err);
503        return $result;
504    }
505
506    /**
507     * auto_incrementを取得する.
508     *
509     * @param string $table_name テーブル名
510     * @return integer
511     */
512    function get_auto_increment($table_name){
513        // ロックする
514        $this->query("LOCK TABLES $table_name WRITE");
515
516        // 次のIncrementを取得
517        $arrRet = $this->getAll("SHOW TABLE STATUS LIKE ?", array($table_name));
518        $auto_inc_no = $arrRet[0]["Auto_increment"];
519
520        // 値をカウントアップしておく
521        $this->conn->query("ALTER TABLE $table_name AUTO_INCREMENT=?" , $auto_inc_no + 1);
522
523        // 解除する
524        $this->query('UNLOCK TABLES');
525
526        return $auto_inc_no;
527    }
528}
529
530?>
Note: See TracBrowser for help on using the repository browser.