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