source: branches/version-2_12-dev/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php @ 21544

Revision 21544, 10.7 KB checked in by Seasoft, 12 years ago (diff)

#1656 (カテゴリ登録のロジックを高速化)
#1661 (共通ロジックを利用する)

  • SC_Query#getCol

#1660 (SC_Helper_DB#sfCountCategory メモリ消費が激しい)
#1659 (SC_Helper_DB#sfCountCategory メモリリークが発生する)

  • 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-2011 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 * MySQL 固有の処理をするクラス.
26 *
27 * このクラスを直接インスタンス化しないこと.
28 * 必ず SC_DB_DBFactory クラスを経由してインスタンス化する.
29 * また, SC_DB_DBFactory クラスの関数を必ずオーバーライドしている必要がある.
30 *
31 * @package DB
32 * @author LOCKON CO.,LTD.
33 * @version $Id:SC_DB_DBFactory_MYSQL.php 15267 2007-08-09 12:31:52Z nanasess $
34 */
35class SC_DB_DBFactory_MYSQL extends SC_DB_DBFactory {
36
37    /** SC_Query インスタンス */
38    var $objQuery;
39
40    /**
41     * DBのバージョンを取得する.
42     *
43     * @param string $dsn データソース名
44     * @return string データベースのバージョン
45     */
46    function sfGetDBVersion($dsn = '') {
47        $objQuery =& SC_Query_Ex::getSingletonInstance($dsn);
48        $val = $objQuery->getOne('select version()');
49        return 'MySQL ' . $val;
50    }
51
52    /**
53     * MySQL 用の SQL 文に変更する.
54     *
55     * @access private
56     * @param string $sql SQL 文
57     * @return string MySQL 用に置換した SQL 文
58     */
59    function sfChangeMySQL($sql) {
60        // 改行、タブを1スペースに変換
61        $sql = preg_replace("/[\r\n\t]/"," ",$sql);
62        // ILIKE検索をLIKE検索に変換する
63        $sql = $this->sfChangeILIKE($sql);
64        // RANDOM()をRAND()に変換する
65        $sql = $this->sfChangeRANDOM($sql);
66        // TRUNCをTRUNCATEに変換する
67        $sql = $this->sfChangeTrunc($sql);
68        // ARRAY_TO_STRINGをGROUP_CONCATに変換する
69        $sql = $this->sfChangeArrayToString($sql);
70        return $sql;
71    }
72
73    /**
74     * 文字コード情報を取得する
75     *
76     * @return array 文字コード情報
77     */
78    function getCharSet() {
79        $objQuery =& SC_Query_Ex::getSingletonInstance();
80        $arrRet = $objQuery->getAll("SHOW VARIABLES LIKE 'char%'");
81        return $arrRet;
82    }
83
84    /**
85     * 昨日の売上高・売上件数を算出する SQL を返す.
86     *
87     * @param string $method SUM または COUNT
88     * @return string 昨日の売上高・売上件数を算出する SQL
89     */
90    function getOrderYesterdaySql($method) {
91        return 'SELECT ' . $method . '(total) FROM dtb_order '
92               . 'WHERE del_flg = 0 '
93               . 'AND cast(create_date as date) = DATE_ADD(current_date, interval -1 day) '
94               . 'AND status <> ' . ORDER_CANCEL;
95    }
96
97    /**
98     * 当月の売上高・売上件数を算出する SQL を返す.
99     *
100     * @param string $method SUM または COUNT
101     * @return string 当月の売上高・売上件数を算出する SQL
102     */
103    function getOrderMonthSql($method) {
104        return 'SELECT '.$method.'(total) FROM dtb_order '
105               . 'WHERE del_flg = 0 '
106               . "AND date_format(create_date, '%Y/%m') = ? "
107               . "AND date_format(create_date, '%Y/%m/%d') <> date_format(CURRENT_TIMESTAMP, '%Y/%m/%d') "
108               . 'AND status <> ' . ORDER_CANCEL;
109    }
110
111    /**
112     * 昨日のレビュー書き込み件数を算出する SQL を返す.
113     *
114     * @return string 昨日のレビュー書き込み件数を算出する SQL
115     */
116    function getReviewYesterdaySql() {
117        return 'SELECT COUNT(*) FROM dtb_review AS A '
118               . 'LEFT JOIN dtb_products AS B '
119               . 'ON A.product_id = B.product_id '
120               . 'WHERE A.del_flg = 0 '
121               . 'AND B.del_flg = 0 '
122               . 'AND cast(A.create_date as date) = DATE_ADD(current_date, interval -1 day) '
123               . 'AND cast(A.create_date as date) != current_date';
124    }
125
126    /**
127     * メール送信履歴の start_date の検索条件の SQL を返す.
128     *
129     * @return string 検索条件の SQL
130     */
131    function getSendHistoryWhereStartdateSql() {
132        return 'start_date BETWEEN date_add(CURRENT_TIMESTAMP,INTERVAL -5 minute) AND date_add(CURRENT_TIMESTAMP,INTERVAL 5 minute)';
133    }
134
135    /**
136     * ダウンロード販売の検索条件の SQL を返す.
137     *
138     * @param string $dtb_order_alias
139     * @return string 検索条件の SQL
140     */
141    function getDownloadableDaysWhereSql($dtb_order_alias = 'dtb_order') {
142        return '(SELECT IF((SELECT d1.downloadable_days_unlimited FROM dtb_baseinfo d1)=1, 1, DATE(CURRENT_TIMESTAMP) <= DATE(DATE_ADD(' . $dtb_order_alias . '.payment_date, INTERVAL (SELECT downloadable_days FROM dtb_baseinfo) DAY))))';
143    }
144
145    /**
146     * 売上集計の期間別集計のSQLを返す
147     *
148     * @param mixed $type
149     * @return string 検索条件のSQL
150     */
151    function getOrderTotalDaysWhereSql($type) {
152        switch ($type) {
153            case 'month':
154                $format = '%m';
155                break;
156            case 'year':
157                $format = '%Y';
158                break;
159            case 'wday':
160                $format = '%a';
161                break;
162            case 'hour':
163                $format = '%H';
164                break;
165            default:
166                $format = '%Y-%m-%d';
167                break;
168        }
169
170        return " date_format(create_date, '".$format."') AS str_date,
171            COUNT(order_id) AS total_order,
172            SUM(CASE WHEN order_sex = 1 THEN 1 ELSE 0 END) AS men,
173            SUM(CASE WHEN order_sex = 2 THEN 1 ELSE 0 END) AS women,
174            SUM(CASE WHEN customer_id <> 0 AND order_sex = 1 THEN 1 ELSE 0 END) AS men_member,
175            SUM(CASE WHEN customer_id <> 0 AND order_sex = 2 THEN 1 ELSE 0 END) AS women_member,
176            SUM(CASE WHEN customer_id = 0 AND order_sex = 1 THEN 1 ELSE 0 END) AS men_nonmember,
177            SUM(CASE WHEN customer_id = 0 AND order_sex = 2 THEN 1 ELSE 0 END) AS women_nonmember,
178            SUM(total) AS total,
179            AVG(total) AS total_average";
180    }
181
182    /**
183     * 売上集計の年代別集計の年代抽出部分のSQLを返す
184     *
185     * @return string 年代抽出部分の SQL
186     */
187    function getOrderTotalAgeColSql() {
188        return 'TRUNC((YEAR(create_date) - YEAR(order_birth)) - (RIGHT(create_date, 5) < RIGHT(order_birth, 5)), -1)';
189    }
190
191    /**
192     * 文字列連結を行う.
193     *
194     * @param array $columns 連結を行うカラム名
195     * @return string 連結後の SQL 文
196     */
197    function concatColumn($columns) {
198        $sql = 'concat(';
199        $i = 0;
200        $total = count($columns);
201        foreach ($columns as $column) {
202            $sql .= $column;
203            if ($i < $total -1) {
204                $sql .= ', ';
205            }
206            $i++;
207        }
208        $sql .= ')';
209        return $sql;
210    }
211
212    /**
213     * テーブルを検索する.
214     *
215     * 引数に部分一致するテーブル名を配列で返す.
216     *
217     * @param string $expression 検索文字列
218     * @return array テーブル名の配列
219     */
220    function findTableNames($expression = '') {
221        $objQuery =& SC_Query_Ex::getSingletonInstance();
222        $sql = 'SHOW TABLES LIKE '. $objQuery->quote('%' . $expression . '%');
223        $arrColList = $objQuery->getAll($sql);
224        $arrColList = SC_Utils_Ex::sfSwapArray($arrColList, false);
225        return $arrColList[0];
226    }
227
228    /**
229     * ILIKE句 を LIKE句へ変換する.
230     *
231     * @access private
232     * @param string $sql SQL文
233     * @return string 変換後の SQL 文
234     */
235    function sfChangeILIKE($sql) {
236        $changesql = preg_replace('/(^|[^\w])ILIKE([^\w]|$)/i', '$1LIKE$2', $sql);
237        return $changesql;
238    }
239
240    /**
241     * RANDOM() を RAND() に変換する.
242     *
243     * @access private
244     * @param string $sql SQL文
245     * @return string 変換後の SQL 文
246     */
247    function sfChangeRANDOM($sql) {
248        $changesql = preg_replace('/(^|[^\w])RANDOM\(/i', '$1RAND(', $sql);
249        return $changesql;
250    }
251
252    /**
253     * TRUNC() を TRUNCATE() に変換する.
254     *
255     * @access private
256     * @param string $sql SQL文
257     * @return string 変換後の SQL 文
258     */
259    function sfChangeTrunc($sql) {
260        $changesql = preg_replace('/(^|[^\w])TRUNC([^\w]|$)/i', '$1TRUNCATE$2', $sql);
261        return $changesql;
262    }
263
264    /**
265     * ARRAY_TO_STRING(ARRAY(A),B) を GROUP_CONCAT() に変換する.
266     *
267     * @access private
268     * @param string $sql SQL文
269     * @return string 変換後の SQL 文
270     */
271    function sfChangeArrayToString($sql) {
272        if (strpos(strtoupper($sql), 'ARRAY_TO_STRING') !== FALSE) {
273            preg_match_all('/ARRAY_TO_STRING.*?\(.*?ARRAY\(.*?SELECT (.+?) FROM (.+?) WHERE (.+?)\).*?\,.*?\'(.+?)\'.*?\)/is', $sql, $match, PREG_SET_ORDER);
274
275            foreach ($match as $item) {
276                $replace = 'GROUP_CONCAT(' . $item[1] . ' SEPARATOR \'' . $item[4] . '\') FROM ' . $item[2] . ' WHERE ' . $item[3];
277                $sql = str_replace($item[0], $replace, $sql);
278            }
279        }
280        return $sql;
281    }
282
283    /**
284     * インデックス作成の追加定義を取得する
285     *
286     * 引数に部分一致するテーブル名を配列で返す.
287     *
288     * @param string $table 対象テーブル名
289     * @param string $name 対象カラム名
290     * @return array インデックス設定情報配列
291     */
292    function sfGetCreateIndexDefinition($table, $name, $definition) {
293        $objQuery =& SC_Query_Ex::getSingletonInstance();
294        $arrTblInfo = $objQuery->getTableInfo($table);
295        foreach ($arrTblInfo as $fieldInfo) {
296            if (array_key_exists($fieldInfo['name'], $definition['fields'])) {
297                if ($fieldInfo['nativetype'] == 'text') {
298                    // TODO: text型フィールドの場合に255文字以内決めうちでインデックス列のサイズとして
299                    //       指定して良いか確認は必要。
300                    $definition['fields'][$fieldInfo['name']]['length'] = '255';
301                }
302            }
303        }
304        return $definition;
305    }
306
307    /**
308     * 擬似表を表すSQL文(FROM 句)を取得する
309     *
310     * @return string
311     */
312    function getDummyFromClauseSql() {
313        return 'FROM DUAL';
314    }
315}
Note: See TracBrowser for help on using the repository browser.