DatabaseQuery   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 32.69%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 215
ccs 17
cts 52
cp 0.3269
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A finish() 0 21 3
A getQuery() 0 8 2
A getQueryType() 0 4 1
A getDuration() 0 4 1
A getResults() 0 4 1
A getQueryParts() 0 4 1
A __construct() 0 14 3
A getParams() 0 4 1
A getParameters() 0 4 1
B getResolvedQuery() 0 25 5
1
<?php
2
/**
3
 * This file contains functionality related to MySQL query debugging, logging and timing actions
4
 *
5
 * @package    BZiON
6
 * @license    https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3
7
 */
8
9
namespace BZIon\Debug;
10
11
/**
12
 * A MySQL query that will be profiled on a development environment
13
 */
14
class DatabaseQuery
15
{
16
    /**
17
     * The MySQL query
18
     * @var string
19
     */
20
    private $query;
21
22
    /**
23
     * The first keyword of the query (e.g. SELECT)
24
     * @var string
25
     */
26
    private $queryType;
27
28
    /**
29
     * The parameters of the query
30
     * @var array|null
31
     */
32
    private $params;
33
34
    /**
35
     * The name of the profiler event
36
     * @var string
37
     */
38
    private $eventName;
39
40
    /**
41
     * The starting UNIX timestamp of the query
42
     * @var float
43
     */
44
    private $startTime;
45
46
    /**
47
     * The UNIX timestamp of the time when the query was completed
48
     * @var float
49
     */
50
    private $finishTime;
51
52
    /**
53
     * The duration of the query in microseconds
54
     * @var float
55
     */
56
    private $duration;
57
58
    /**
59
     * The results of the query
60
     * @var mixed
61
     */
62
    private $results;
63
64
    /**
65
     * @var int
66
     */
67
    const MICROSECONDS_IN_SECOND = 1000000;
68
69
    /**
70
     * Debug a database query
71
     *
72
     * @param string     $query  The MySQL query
73
     * @param array|null $params The query parameters
74
     */
75 76
    public function __construct(&$query, &$params)
76
    {
77 76
        $this->query  = $query;
78 76
        $this->params = ($params !== false) ? array_values($params) : null;
79
80 76
        $this->queryType = strtok($query, ' ');
81 76
        $this->eventName = 'database.query.' . $this->queryType;
82
83 76
        Debug::startStopwatch($this->eventName);
84
85 76
        if (\Service::isDebug()) {
86
            $this->startTime = microtime(true);
87
        }
88 76
    }
89
90
    /**
91
     * Mark a query as finished
92
     *
93
     * @param  mixed $return The returned values of the query
94
     * @return void
95
     */
96 76
    public function finish(&$return)
97
    {
98 76
        $duration = Debug::finishStopwatch($this->eventName);
99 76
        Debug::log("Database {$this->queryType} query", array(
100 76
            "query"    => $this->query,
101 76
            "params"   => $this->params,
102 76
            "duration" => "$duration ms"
103 76
        ), 'mysql');
104
105 76
        if (\Service::isDebug()) {
106
            $this->finishTime = microtime(true);
107
            $this->duration = ($this->finishTime - $this->startTime) * self::MICROSECONDS_IN_SECOND;
108
109
            $this->results = $return;
110
111
            $collector = \Service::getContainer()->get('data_collector.bzion_database_collector', null);
112
            if ($collector) {
113
                $collector->logQuery($this);
114
            }
115
        }
116 76
    }
117
118
    /**
119
     * Get the value the MySQL query
120
     *
121
     * @param  bool $highlight Whether HTML should be used to highlight to the query
122
     * @return string
123
     */
124
    public function getQuery($highlight = false)
125
    {
126
        if ($highlight) {
127
            return \SqlFormatter::highlight($this->query);
128
        } else {
129
            return $this->query;
130
        }
131
    }
132
133
    /**
134
     * Get the first keyword of the query (e.g. SELECT)
135
     *
136
     * @return string
137
     */
138
    public function getQueryType()
139
    {
140
        return $this->queryType;
141
    }
142
143
    /**
144
     * Get the parameters of the query
145
     *
146
     * Alias for DatabaseQuery::getParams()
147
     *
148
     * @return array|null
149
     */
150
    public function getParams()
151
    {
152
        return $this->getParameters();
153
    }
154
155
    /**
156
     * Get the parameters of the query
157
     *
158
     * @return array|null
159
     */
160
    public function getParameters()
161
    {
162
        return $this->params;
163
    }
164
165
    /**
166
     * Get the duration of the query in microseconds
167
     *
168
     * @return float
169
     */
170
    public function getDuration()
171
    {
172
        return $this->duration;
173
    }
174
175
    /**
176
     * Get the query results
177
     *
178
     * @return mixed
179
     */
180
    public function getResults()
181
    {
182
        return $this->results;
183
    }
184
185
    /**
186
     * Get the query string parts
187
     *
188
     * @param  bool $highlight Whether HTML should be used to highlight to the query
189
     * @return array
190
     */
191
    public function getQueryParts($highlight = false)
192
    {
193
        return explode("?", $this->getQuery($highlight));
194
    }
195
196
    /**
197
     * Get the resolved query strings (where all `?`s are replaced with the
198
     * actual parameter values)
199
     *
200
     * @param  bool $highlight Whether HTML should be used to highlight to the query
201
     * @return string
202
     */
203
    public function getResolvedQuery($highlight = false)
204
    {
205
        $query = '';
206
207
        foreach ($this->getQueryParts($highlight) as $i => $part) {
208
            $query .= $part;
209
210
            if (array_key_exists($i, $this->params)) {
211
                // We are not going to execute the query, so there is no need
212
                // to use anything safe
213
                $param = addslashes($this->params[$i]);
214
215
                if ($param === null) {
216
                    $query .= 'null';
217
                } elseif (is_string($param)) {
218
                    // Strings will be quoted
219
                    $query .= '"' . $param . '"';
220
                } else {
221
                    $query .= $param;
222
                }
223
            }
224
        }
225
226
        return $query;
227
    }
228
}
229