PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.2.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.2.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 1 year ago Mysqli 2 years ago Oracle 2 years ago Pdo 1 year ago Sqlsrv 2 years ago Abstract.php 2 years ago Db2.php 2 years ago Exception.php 1 year ago Mysqli.php 1 year ago Oracle.php 2 years ago Sqlsrv.php 2 years ago
Mysqli.php
514 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']) && !empty($this->_config['collation'])) {
309 // mysqli_set_charset does not support setting a collation
310 $query = "SET NAMES '" . $this->_config['charset'] . "' COLLATE '" . $this->_config['collation'] . "'";
311 \mysqli_query($this->_connection, $query);
312 } elseif (!empty($this->_config['charset'])) {
313 \mysqli_set_charset($this->_connection, $this->_config['charset']);
314 }
315 }
316 /**
317 * Test if a connection is active
318 *
319 * @return boolean
320 */
321 public function isConnected()
322 {
323 return (bool) ($this->_connection instanceof \mysqli);
324 }
325 /**
326 * Force the connection to close.
327 *
328 * @return void
329 */
330 public function closeConnection()
331 {
332 if ($this->isConnected()) {
333 $this->_connection->close();
334 }
335 $this->_connection = null;
336 }
337 /**
338 * Prepare a statement and return a PDOStatement-like object.
339 *
340 * @param string $sql SQL query
341 * @return Zend_Db_Statement_Mysqli
342 */
343 public function prepare($sql)
344 {
345 $this->_connect();
346 if ($this->_stmt) {
347 $this->_stmt->close();
348 }
349 $stmtClass = $this->_defaultStmtClass;
350 if (!\class_exists($stmtClass)) {
351 // require_once 'Zend/Loader.php';
352 \Zend_Loader::loadClass($stmtClass);
353 }
354 $stmt = new $stmtClass($this, $sql);
355 if ($stmt === \false) {
356 return \false;
357 }
358 $stmt->setFetchMode($this->_fetchMode);
359 $this->_stmt = $stmt;
360 return $stmt;
361 }
362 /**
363 * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
364 *
365 * As a convention, on RDBMS brands that support sequences
366 * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
367 * from the arguments and returns the last id generated by that sequence.
368 * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
369 * returns the last value generated for such a column, and the table name
370 * argument is disregarded.
371 *
372 * MySQL does not support sequences, so $tableName and $primaryKey are ignored.
373 *
374 * @param string $tableName OPTIONAL Name of table.
375 * @param string $primaryKey OPTIONAL Name of primary key column.
376 * @return string
377 * @todo Return value should be int?
378 */
379 public function lastInsertId($tableName = null, $primaryKey = null)
380 {
381 $mysqli = $this->_connection;
382 return (string) $mysqli->insert_id;
383 }
384 /**
385 * Begin a transaction.
386 *
387 * @return void
388 */
389 protected function _beginTransaction()
390 {
391 $this->_connect();
392 $this->_connection->autocommit(\false);
393 }
394 /**
395 * Commit a transaction.
396 *
397 * @return void
398 */
399 protected function _commit()
400 {
401 $this->_connect();
402 $this->_connection->commit();
403 $this->_connection->autocommit(\true);
404 }
405 /**
406 * Roll-back a transaction.
407 *
408 * @return void
409 */
410 protected function _rollBack()
411 {
412 $this->_connect();
413 $this->_connection->rollback();
414 $this->_connection->autocommit(\true);
415 }
416 /**
417 * Set the fetch mode.
418 *
419 * @param int $mode
420 * @return void
421 * @throws Zend_Db_Adapter_Mysqli_Exception
422 */
423 public function setFetchMode($mode)
424 {
425 switch ($mode) {
426 case \Zend_Db::FETCH_LAZY:
427 case \Zend_Db::FETCH_ASSOC:
428 case \Zend_Db::FETCH_NUM:
429 case \Zend_Db::FETCH_BOTH:
430 case \Zend_Db::FETCH_NAMED:
431 case \Zend_Db::FETCH_OBJ:
432 $this->_fetchMode = $mode;
433 break;
434 case \Zend_Db::FETCH_BOUND:
435 // bound to PHP variable
436 /**
437 * @see Zend_Db_Adapter_Mysqli_Exception
438 */
439 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
440 throw new \Zend_Db_Adapter_Mysqli_Exception('FETCH_BOUND is not supported yet');
441 break;
442 default:
443 /**
444 * @see Zend_Db_Adapter_Mysqli_Exception
445 */
446 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
447 throw new \Zend_Db_Adapter_Mysqli_Exception("Invalid fetch mode '{$mode}' specified");
448 }
449 }
450 /**
451 * Adds an adapter-specific LIMIT clause to the SELECT statement.
452 *
453 * @param string $sql
454 * @param int $count
455 * @param int $offset OPTIONAL
456 * @return string
457 */
458 public function limit($sql, $count, $offset = 0)
459 {
460 $count = \intval($count);
461 if ($count <= 0) {
462 /**
463 * @see Zend_Db_Adapter_Mysqli_Exception
464 */
465 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
466 throw new \Zend_Db_Adapter_Mysqli_Exception("LIMIT argument count={$count} is not valid");
467 }
468 $offset = \intval($offset);
469 if ($offset < 0) {
470 /**
471 * @see Zend_Db_Adapter_Mysqli_Exception
472 */
473 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
474 throw new \Zend_Db_Adapter_Mysqli_Exception("LIMIT argument offset={$offset} is not valid");
475 }
476 $sql .= " LIMIT {$count}";
477 if ($offset > 0) {
478 $sql .= " OFFSET {$offset}";
479 }
480 return $sql;
481 }
482 /**
483 * Check if the adapter supports real SQL parameters.
484 *
485 * @param string $type 'positional' or 'named'
486 * @return bool
487 */
488 public function supportsParameters($type)
489 {
490 switch ($type) {
491 case 'positional':
492 return \true;
493 case 'named':
494 default:
495 return \false;
496 }
497 }
498 /**
499 * Retrieve server version in PHP style
500 *
501 *@return string
502 */
503 public function getServerVersion()
504 {
505 $this->_connect();
506 $version = $this->_connection->server_version;
507 $major = (int) ($version / 10000);
508 $minor = (int) ($version % 10000 / 100);
509 $revision = (int) ($version % 100);
510 return $major . '.' . $minor . '.' . $revision;
511 }
512 }
513 }
514