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

Revision 23230, 11.5 KB checked in by m_uehara, 7 years ago (diff)

#2363 r23177, r23181 - r23186, r23188 - r23191, r23194, r23197, r23199 - r23218, r23220, r23223 - r23225 をマージ

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