1<?php
2/**
3 * 2007-2016 PrestaShop
4 *
5 * thirty bees is an extension to the PrestaShop e-commerce software developed by PrestaShop SA
6 * Copyright (C) 2017-2018 thirty bees
7 *
8 * NOTICE OF LICENSE
9 *
10 * This source file is subject to the Open Software License (OSL 3.0)
11 * that is bundled with this package in the file LICENSE.txt.
12 * It is also available through the world-wide-web at this URL:
13 * http://opensource.org/licenses/osl-3.0.php
14 * If you did not receive a copy of the license and are unable to
15 * obtain it through the world-wide-web, please send an email
16 * to license@thirtybees.com so we can send you a copy immediately.
17 *
18 * DISCLAIMER
19 *
20 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
21 * versions in the future. If you wish to customize PrestaShop for your
22 * needs please refer to https://www.thirtybees.com for more information.
23 *
24 *  @author    thirty bees <contact@thirtybees.com>
25 *  @author    PrestaShop SA <contact@prestashop.com>
26 *  @copyright 2017-2018 thirty bees
27 *  @copyright 2007-2016 PrestaShop SA
28 *  @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
29 *  PrestaShop is an internationally registered trademark & property of PrestaShop SA
30 */
31
32abstract class Db extends DbCore
33{
34    /**
35     * Add SQL_NO_CACHE in SELECT queries
36     *
37     * @var bool
38     */
39    public $disableCache = true;
40
41    /**
42     * Total of queries
43     *
44     * @var int
45     */
46    public $count = 0;
47
48    /**
49     * List of queries
50     *
51     * @var array
52     */
53    public $queries = array();
54
55    /**
56     * List of uniq queries (replace numbers by XX)
57     *
58     * @var array
59     */
60    public $uniqQueries = array();
61
62    /**
63     * List of tables
64     *
65     * @var array
66     */
67    public $tables = array();
68
69    /**
70     * Execute the query and log some informations
71     *
72     * @see DbCore::query()
73     */
74    public function query($sql)
75    {
76        $explain = false;
77        if (preg_match('/^\s*explain\s+/i', $sql) || strpos($sql, _DB_PREFIX_.'modules_perfs')) {
78            $explain = true;
79        }
80
81        if (!$explain) {
82            $uniqSql = preg_replace('/[\'"][a-f0-9]{32}[\'"]/', '<span style="color:blue">XX</span>', $sql);
83            $uniqSql = preg_replace('/[0-9]+/', '<span style="color:blue">XX</span>', $uniqSql);
84            if (!isset($this->uniqQueries[$uniqSql])) {
85                $this->uniqQueries[$uniqSql] = 0;
86            }
87            $this->uniqQueries[$uniqSql]++;
88
89            // No cache for query
90            if ($this->disableCache && !stripos($sql, 'SQL_NO_CACHE')) {
91                $sql = preg_replace('/^\s*select\s+/i', 'SELECT SQL_NO_CACHE ', trim($sql));
92            }
93
94            // Get tables in query
95            preg_match_all('/(from|join)\s+`?'._DB_PREFIX_.'([a-z0-9_-]+)/ui', $sql, $matches);
96            foreach ($matches[2] as $table) {
97                if (!isset($this->tables[$table])) {
98                    $this->tables[$table] = 0;
99                }
100                $this->tables[$table]++;
101            }
102
103            $start = microtime(true);
104        }
105
106        // Execute query
107        $result = parent::query($sql);
108
109        if (!$explain) {
110            $end = microtime(true);
111
112            $stack = debug_backtrace(false);
113            while (preg_match('@[/\\\\]classes[/\\\\]db[/\\\\]@i', $stack[0]['file'])) {
114                array_shift($stack);
115            }
116            $stack_light = array();
117            foreach ($stack as $call) {
118                $stack_light[] = array('file' => isset($call['file']) ? $call['file'] : 'undefined', 'line' => isset($call['line']) ? $call['line'] : 'undefined');
119            }
120
121            $this->queries[] = array(
122                'query' => $sql,
123                'time' => $end - $start,
124                'stack' => $stack_light
125            );
126        }
127
128        return $result;
129    }
130}
131