PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.7
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.7
5.13.0 5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / libs / Zend / Db / Adapter / Mysqli.php
matomo / app / libs / Zend / Db / Adapter Last commit date
Db2 2 years ago Mysqli 2 years ago Oracle 2 years ago Pdo 2 years ago Sqlsrv 2 years ago Abstract.php 2 years ago Db2.php 2 years ago Exception.php 2 years ago Mysqli.php 2 years ago Oracle.php 2 years ago Sqlsrv.php 2 years ago
Mysqli.php
510 lines
1 <?php
2
3 namespace {
4 /**
5 * Zend Framework
6 *
7 * LICENSE
8 *
9 * This source file is subject to the new BSD license that is bundled
10 * with this package in the file LICENSE.txt.
11 * It is also available through the world-wide-web at this URL:
12 * http://framework.zend.com/license/new-bsd
13 * If you did not receive a copy of the license and are unable to
14 * obtain it through the world-wide-web, please send an email
15 * to license@zend.com so we can send you a copy immediately.
16 *
17 * @category Zend
18 * @package Zend_Db
19 * @subpackage Adapter
20 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
21 * @license http://framework.zend.com/license/new-bsd New BSD License
22 * @version $Id: Mysqli.php 23775 2011-03-01 17:25:24Z ralph $
23 */
24 /**
25 * @see Zend_Db_Adapter_Abstract
26 */
27 // require_once 'Zend/Db/Adapter/Abstract.php';
28 /**
29 * @see Zend_Db_Profiler
30 */
31 // require_once 'Zend/Db/Profiler.php';
32 /**
33 * @see Zend_Db_Select
34 */
35 // require_once 'Zend/Db/Select.php';
36 /**
37 * @see Zend_Db_Statement_Mysqli
38 */
39 // require_once 'Zend/Db/Statement/Mysqli.php';
40 /**
41 * @category Zend
42 * @package Zend_Db
43 * @subpackage Adapter
44 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
45 * @license http://framework.zend.com/license/new-bsd New BSD License
46 */
47 class Zend_Db_Adapter_Mysqli extends \Zend_Db_Adapter_Abstract
48 {
49 /**
50 * Keys are UPPERCASE SQL datatypes or the constants
51 * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
52 *
53 * Values are:
54 * 0 = 32-bit integer
55 * 1 = 64-bit integer
56 * 2 = float or decimal
57 *
58 * @var array Associative array of datatypes to values 0, 1, or 2.
59 */
60 protected $_numericDataTypes = array(\Zend_Db::INT_TYPE => \Zend_Db::INT_TYPE, \Zend_Db::BIGINT_TYPE => \Zend_Db::BIGINT_TYPE, \Zend_Db::FLOAT_TYPE => \Zend_Db::FLOAT_TYPE, 'INT' => \Zend_Db::INT_TYPE, 'INTEGER' => \Zend_Db::INT_TYPE, 'MEDIUMINT' => \Zend_Db::INT_TYPE, 'SMALLINT' => \Zend_Db::INT_TYPE, 'TINYINT' => \Zend_Db::INT_TYPE, 'BIGINT' => \Zend_Db::BIGINT_TYPE, 'SERIAL' => \Zend_Db::BIGINT_TYPE, 'DEC' => \Zend_Db::FLOAT_TYPE, 'DECIMAL' => \Zend_Db::FLOAT_TYPE, 'DOUBLE' => \Zend_Db::FLOAT_TYPE, 'DOUBLE PRECISION' => \Zend_Db::FLOAT_TYPE, 'FIXED' => \Zend_Db::FLOAT_TYPE, 'FLOAT' => \Zend_Db::FLOAT_TYPE);
61 /**
62 * @var Zend_Db_Statement_Mysqli
63 */
64 protected $_stmt = null;
65 /**
66 * Default class name for a DB statement.
67 *
68 * @var string
69 */
70 protected $_defaultStmtClass = 'Zend_Db_Statement_Mysqli';
71 /**
72 * Quote a raw string.
73 *
74 * @param mixed $value Raw string
75 *
76 * @return string Quoted string
77 */
78 protected function _quote($value)
79 {
80 if (\is_int($value) || \is_float($value)) {
81 return $value;
82 }
83 $this->_connect();
84 return "'" . $this->_connection->real_escape_string($value) . "'";
85 }
86 /**
87 * Returns the symbol the adapter uses for delimiting identifiers.
88 *
89 * @return string
90 */
91 public function getQuoteIdentifierSymbol()
92 {
93 return "`";
94 }
95 /**
96 * Returns a list of the tables in the database.
97 *
98 * @return array
99 */
100 public function listTables()
101 {
102 $result = array();
103 // Use mysqli extension API, because SHOW doesn't work
104 // well as a prepared statement on MySQL 4.1.
105 $sql = 'SHOW TABLES';
106 if ($queryResult = $this->getConnection()->query($sql)) {
107 while ($row = $queryResult->fetch_row()) {
108 $result[] = $row[0];
109 }
110 $queryResult->close();
111 } else {
112 /**
113 * @see Zend_Db_Adapter_Mysqli_Exception
114 */
115 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
116 throw new \Zend_Db_Adapter_Mysqli_Exception($this->getConnection()->error);
117 }
118 return $result;
119 }
120 /**
121 * Returns the column descriptions for a table.
122 *
123 * The return value is an associative array keyed by the column name,
124 * as returned by the RDBMS.
125 *
126 * The value of each array element is an associative array
127 * with the following keys:
128 *
129 * SCHEMA_NAME => string; name of database or schema
130 * TABLE_NAME => string;
131 * COLUMN_NAME => string; column name
132 * COLUMN_POSITION => number; ordinal position of column in table
133 * DATA_TYPE => string; SQL datatype name of column
134 * DEFAULT => string; default expression of column, null if none
135 * NULLABLE => boolean; true if column can have nulls
136 * LENGTH => number; length of CHAR/VARCHAR
137 * SCALE => number; scale of NUMERIC/DECIMAL
138 * PRECISION => number; precision of NUMERIC/DECIMAL
139 * UNSIGNED => boolean; unsigned property of an integer type
140 * PRIMARY => boolean; true if column is part of the primary key
141 * PRIMARY_POSITION => integer; position of column in primary key
142 * IDENTITY => integer; true if column is auto-generated with unique values
143 *
144 * @param string $tableName
145 * @param string $schemaName OPTIONAL
146 * @return array
147 */
148 public function describeTable($tableName, $schemaName = null)
149 {
150 /**
151 * @todo use INFORMATION_SCHEMA someday when
152 * MySQL's implementation isn't too slow.
153 */
154 if ($schemaName) {
155 $sql = 'DESCRIBE ' . $this->quoteIdentifier("{$schemaName}.{$tableName}", \true);
156 } else {
157 $sql = 'DESCRIBE ' . $this->quoteIdentifier($tableName, \true);
158 }
159 /**
160 * Use mysqli extension API, because DESCRIBE doesn't work
161 * well as a prepared statement on MySQL 4.1.
162 */
163 if ($queryResult = $this->getConnection()->query($sql)) {
164 while ($row = $queryResult->fetch_assoc()) {
165 $result[] = $row;
166 }
167 $queryResult->close();
168 } else {
169 /**
170 * @see Zend_Db_Adapter_Mysqli_Exception
171 */
172 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
173 throw new \Zend_Db_Adapter_Mysqli_Exception($this->getConnection()->error);
174 }
175 $desc = array();
176 $row_defaults = array('Length' => null, 'Scale' => null, 'Precision' => null, 'Unsigned' => null, 'Primary' => \false, 'PrimaryPosition' => null, 'Identity' => \false);
177 $i = 1;
178 $p = 1;
179 foreach ($result as $key => $row) {
180 $row = \array_merge($row_defaults, $row);
181 if (\preg_match('/unsigned/', $row['Type'])) {
182 $row['Unsigned'] = \true;
183 }
184 if (\preg_match('/^((?:var)?char)\\((\\d+)\\)/', $row['Type'], $matches)) {
185 $row['Type'] = $matches[1];
186 $row['Length'] = $matches[2];
187 } else {
188 if (\preg_match('/^decimal\\((\\d+),(\\d+)\\)/', $row['Type'], $matches)) {
189 $row['Type'] = 'decimal';
190 $row['Precision'] = $matches[1];
191 $row['Scale'] = $matches[2];
192 } else {
193 if (\preg_match('/^float\\((\\d+),(\\d+)\\)/', $row['Type'], $matches)) {
194 $row['Type'] = 'float';
195 $row['Precision'] = $matches[1];
196 $row['Scale'] = $matches[2];
197 } else {
198 if (\preg_match('/^((?:big|medium|small|tiny)?int)\\((\\d+)\\)/', $row['Type'], $matches)) {
199 $row['Type'] = $matches[1];
200 /**
201 * The optional argument of a MySQL int type is not precision
202 * or length; it is only a hint for display width.
203 */
204 }
205 }
206 }
207 }
208 if (\strtoupper($row['Key']) == 'PRI') {
209 $row['Primary'] = \true;
210 $row['PrimaryPosition'] = $p;
211 if ($row['Extra'] == 'auto_increment') {
212 $row['Identity'] = \true;
213 } else {
214 $row['Identity'] = \false;
215 }
216 ++$p;
217 }
218 $desc[$this->foldCase($row['Field'])] = array(
219 'SCHEMA_NAME' => null,
220 // @todo
221 'TABLE_NAME' => $this->foldCase($tableName),
222 'COLUMN_NAME' => $this->foldCase($row['Field']),
223 'COLUMN_POSITION' => $i,
224 'DATA_TYPE' => $row['Type'],
225 'DEFAULT' => $row['Default'],
226 'NULLABLE' => (bool) ($row['Null'] == 'YES'),
227 'LENGTH' => $row['Length'],
228 'SCALE' => $row['Scale'],
229 'PRECISION' => $row['Precision'],
230 'UNSIGNED' => $row['Unsigned'],
231 'PRIMARY' => $row['Primary'],
232 'PRIMARY_POSITION' => $row['PrimaryPosition'],
233 'IDENTITY' => $row['Identity'],
234 );
235 ++$i;
236 }
237 return $desc;
238 }
239 /**
240 * Creates a connection to the database.
241 *
242 * @return void
243 * @throws Zend_Db_Adapter_Mysqli_Exception
244 */
245 protected function _connect()
246 {
247 if ($this->_connection) {
248 return;
249 }
250 if (!\extension_loaded('mysqli')) {
251 /**
252 * @see Zend_Db_Adapter_Mysqli_Exception
253 */
254 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
255 throw new \Zend_Db_Adapter_Mysqli_Exception('The Mysqli extension is required for this adapter but the extension is not loaded');
256 }
257 if (isset($this->_config['port'])) {
258 $port = (int) $this->_config['port'];
259 } else {
260 $port = null;
261 }
262 $this->_connection = \mysqli_init();
263 $enable_ssl = \false;
264 $ssl_options = array('ssl_ca' => null, 'ssl_ca_path' => null, 'ssl_cert' => null, 'ssl_cipher' => null, 'ssl_key' => null);
265 if (!empty($this->_config['driver_options'])) {
266 foreach ($this->_config['driver_options'] as $option => $value) {
267 if (\array_key_exists($option, $ssl_options)) {
268 $ssl_options[$option] = $value;
269 $enable_ssl = \true;
270 continue;
271 // these options are set below in mysqli_ssl_set
272 } elseif (\is_string($option)) {
273 // Suppress warnings here
274 // Ignore it if it's not a valid constant
275 if (!\defined(\strtoupper($option))) {
276 continue;
277 }
278 $option = @\constant(\strtoupper($option));
279 if ($option === null) {
280 continue;
281 }
282 }
283 \mysqli_options($this->_connection, $option, $value);
284 }
285 }
286 if ($enable_ssl) {
287 \mysqli_ssl_set($this->_connection, $ssl_options['ssl_key'], $ssl_options['ssl_cert'], $ssl_options['ssl_ca'], $ssl_options['ssl_ca_path'], $ssl_options['ssl_cipher']);
288 }
289 $flags = null;
290 if ($enable_ssl) {
291 $flags = \MYSQLI_CLIENT_SSL;
292 if (!empty($this->_config['driver_options']['ssl_no_verify']) && \defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) {
293 $flags = \MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
294 }
295 }
296 $socket = !empty($this->_config['unix_socket']) ? $this->_config['unix_socket'] : null;
297 // Suppress connection warnings here.
298 // Throw an exception instead.
299 $_isConnected = @\mysqli_real_connect($this->_connection, $this->_config['host'], $this->_config['username'], $this->_config['password'], $this->_config['dbname'], $port, $socket, $enable_ssl ? $flags : null);
300 if ($_isConnected === \false || \mysqli_connect_errno()) {
301 $this->closeConnection();
302 /**
303 * @see Zend_Db_Adapter_Mysqli_Exception
304 */
305 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
306 throw new \Zend_Db_Adapter_Mysqli_Exception(\mysqli_connect_error());
307 }
308 if (!empty($this->_config['charset'])) {
309 \mysqli_set_charset($this->_connection, $this->_config['charset']);
310 }
311 }
312 /**
313 * Test if a connection is active
314 *
315 * @return boolean
316 */
317 public function isConnected()
318 {
319 return (bool) ($this->_connection instanceof \mysqli);
320 }
321 /**
322 * Force the connection to close.
323 *
324 * @return void
325 */
326 public function closeConnection()
327 {
328 if ($this->isConnected()) {
329 $this->_connection->close();
330 }
331 $this->_connection = null;
332 }
333 /**
334 * Prepare a statement and return a PDOStatement-like object.
335 *
336 * @param string $sql SQL query
337 * @return Zend_Db_Statement_Mysqli
338 */
339 public function prepare($sql)
340 {
341 $this->_connect();
342 if ($this->_stmt) {
343 $this->_stmt->close();
344 }
345 $stmtClass = $this->_defaultStmtClass;
346 if (!\class_exists($stmtClass)) {
347 // require_once 'Zend/Loader.php';
348 \Zend_Loader::loadClass($stmtClass);
349 }
350 $stmt = new $stmtClass($this, $sql);
351 if ($stmt === \false) {
352 return \false;
353 }
354 $stmt->setFetchMode($this->_fetchMode);
355 $this->_stmt = $stmt;
356 return $stmt;
357 }
358 /**
359 * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
360 *
361 * As a convention, on RDBMS brands that support sequences
362 * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
363 * from the arguments and returns the last id generated by that sequence.
364 * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
365 * returns the last value generated for such a column, and the table name
366 * argument is disregarded.
367 *
368 * MySQL does not support sequences, so $tableName and $primaryKey are ignored.
369 *
370 * @param string $tableName OPTIONAL Name of table.
371 * @param string $primaryKey OPTIONAL Name of primary key column.
372 * @return string
373 * @todo Return value should be int?
374 */
375 public function lastInsertId($tableName = null, $primaryKey = null)
376 {
377 $mysqli = $this->_connection;
378 return (string) $mysqli->insert_id;
379 }
380 /**
381 * Begin a transaction.
382 *
383 * @return void
384 */
385 protected function _beginTransaction()
386 {
387 $this->_connect();
388 $this->_connection->autocommit(\false);
389 }
390 /**
391 * Commit a transaction.
392 *
393 * @return void
394 */
395 protected function _commit()
396 {
397 $this->_connect();
398 $this->_connection->commit();
399 $this->_connection->autocommit(\true);
400 }
401 /**
402 * Roll-back a transaction.
403 *
404 * @return void
405 */
406 protected function _rollBack()
407 {
408 $this->_connect();
409 $this->_connection->rollback();
410 $this->_connection->autocommit(\true);
411 }
412 /**
413 * Set the fetch mode.
414 *
415 * @param int $mode
416 * @return void
417 * @throws Zend_Db_Adapter_Mysqli_Exception
418 */
419 public function setFetchMode($mode)
420 {
421 switch ($mode) {
422 case \Zend_Db::FETCH_LAZY:
423 case \Zend_Db::FETCH_ASSOC:
424 case \Zend_Db::FETCH_NUM:
425 case \Zend_Db::FETCH_BOTH:
426 case \Zend_Db::FETCH_NAMED:
427 case \Zend_Db::FETCH_OBJ:
428 $this->_fetchMode = $mode;
429 break;
430 case \Zend_Db::FETCH_BOUND:
431 // bound to PHP variable
432 /**
433 * @see Zend_Db_Adapter_Mysqli_Exception
434 */
435 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
436 throw new \Zend_Db_Adapter_Mysqli_Exception('FETCH_BOUND is not supported yet');
437 break;
438 default:
439 /**
440 * @see Zend_Db_Adapter_Mysqli_Exception
441 */
442 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
443 throw new \Zend_Db_Adapter_Mysqli_Exception("Invalid fetch mode '{$mode}' specified");
444 }
445 }
446 /**
447 * Adds an adapter-specific LIMIT clause to the SELECT statement.
448 *
449 * @param string $sql
450 * @param int $count
451 * @param int $offset OPTIONAL
452 * @return string
453 */
454 public function limit($sql, $count, $offset = 0)
455 {
456 $count = \intval($count);
457 if ($count <= 0) {
458 /**
459 * @see Zend_Db_Adapter_Mysqli_Exception
460 */
461 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
462 throw new \Zend_Db_Adapter_Mysqli_Exception("LIMIT argument count={$count} is not valid");
463 }
464 $offset = \intval($offset);
465 if ($offset < 0) {
466 /**
467 * @see Zend_Db_Adapter_Mysqli_Exception
468 */
469 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
470 throw new \Zend_Db_Adapter_Mysqli_Exception("LIMIT argument offset={$offset} is not valid");
471 }
472 $sql .= " LIMIT {$count}";
473 if ($offset > 0) {
474 $sql .= " OFFSET {$offset}";
475 }
476 return $sql;
477 }
478 /**
479 * Check if the adapter supports real SQL parameters.
480 *
481 * @param string $type 'positional' or 'named'
482 * @return bool
483 */
484 public function supportsParameters($type)
485 {
486 switch ($type) {
487 case 'positional':
488 return \true;
489 case 'named':
490 default:
491 return \false;
492 }
493 }
494 /**
495 * Retrieve server version in PHP style
496 *
497 *@return string
498 */
499 public function getServerVersion()
500 {
501 $this->_connect();
502 $version = $this->_connection->server_version;
503 $major = (int) ($version / 10000);
504 $minor = (int) ($version % 10000 / 100);
505 $revision = (int) ($version % 100);
506 return $major . '.' . $minor . '.' . $revision;
507 }
508 }
509 }
510