PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.3.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.3.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 5 years ago Sqlsrv 6 years ago Abstract.php 6 years ago Db2.php 6 years ago Exception.php 6 years ago Mysqli.php 6 years ago Oracle.php 6 years ago Sqlsrv.php 6 years ago
Mysqli.php
588 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 } elseif(is_string($option)) {
317 // Suppress warnings here
318 // Ignore it if it's not a valid constant
319 $option = @constant(strtoupper($option));
320 if($option === null)
321 continue;
322 }
323 mysqli_options($this->_connection, $option, $value);
324 }
325 }
326
327
328 if ($enable_ssl) {
329 mysqli_ssl_set(
330 $this->_connection,
331 $ssl_options['ssl_key'],
332 $ssl_options['ssl_cert'],
333 $ssl_options['ssl_ca'],
334 $ssl_options['ssl_ca_path'],
335 $ssl_options['ssl_cipher']
336 );
337 }
338
339 $flags = null;
340 if ($enable_ssl) {
341 $flags = MYSQLI_CLIENT_SSL;
342 if (!empty($this->_config['driver_options']['ssl_no_verify'])
343 && defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')
344 ) {
345 $flags = MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
346 }
347 }
348
349 $socket = !empty($this->_config['unix_socket']) ? $this->_config['unix_socket'] : null;
350
351 // Suppress connection warnings here.
352 // Throw an exception instead.
353 $_isConnected = @mysqli_real_connect(
354 $this->_connection,
355 $this->_config['host'],
356 $this->_config['username'],
357 $this->_config['password'],
358 $this->_config['dbname'],
359 $port,
360 $socket,
361 $enable_ssl ? $flags : null
362 );
363
364 if ($_isConnected === false || mysqli_connect_errno()) {
365
366 $this->closeConnection();
367 /**
368 * @see Zend_Db_Adapter_Mysqli_Exception
369 */
370 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
371 throw new Zend_Db_Adapter_Mysqli_Exception(mysqli_connect_error());
372 }
373
374 if (!empty($this->_config['charset'])) {
375 mysqli_set_charset($this->_connection, $this->_config['charset']);
376 }
377 }
378
379 /**
380 * Test if a connection is active
381 *
382 * @return boolean
383 */
384 public function isConnected()
385 {
386 return ((bool) ($this->_connection instanceof mysqli));
387 }
388
389 /**
390 * Force the connection to close.
391 *
392 * @return void
393 */
394 public function closeConnection()
395 {
396 if ($this->isConnected()) {
397 $this->_connection->close();
398 }
399 $this->_connection = null;
400 }
401
402 /**
403 * Prepare a statement and return a PDOStatement-like object.
404 *
405 * @param string $sql SQL query
406 * @return Zend_Db_Statement_Mysqli
407 */
408 public function prepare($sql)
409 {
410 $this->_connect();
411 if ($this->_stmt) {
412 $this->_stmt->close();
413 }
414 $stmtClass = $this->_defaultStmtClass;
415 if (!class_exists($stmtClass)) {
416 // require_once 'Zend/Loader.php';
417 Zend_Loader::loadClass($stmtClass);
418 }
419 $stmt = new $stmtClass($this, $sql);
420 if ($stmt === false) {
421 return false;
422 }
423 $stmt->setFetchMode($this->_fetchMode);
424 $this->_stmt = $stmt;
425 return $stmt;
426 }
427
428 /**
429 * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
430 *
431 * As a convention, on RDBMS brands that support sequences
432 * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
433 * from the arguments and returns the last id generated by that sequence.
434 * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
435 * returns the last value generated for such a column, and the table name
436 * argument is disregarded.
437 *
438 * MySQL does not support sequences, so $tableName and $primaryKey are ignored.
439 *
440 * @param string $tableName OPTIONAL Name of table.
441 * @param string $primaryKey OPTIONAL Name of primary key column.
442 * @return string
443 * @todo Return value should be int?
444 */
445 public function lastInsertId($tableName = null, $primaryKey = null)
446 {
447 $mysqli = $this->_connection;
448 return (string) $mysqli->insert_id;
449 }
450
451 /**
452 * Begin a transaction.
453 *
454 * @return void
455 */
456 protected function _beginTransaction()
457 {
458 $this->_connect();
459 $this->_connection->autocommit(false);
460 }
461
462 /**
463 * Commit a transaction.
464 *
465 * @return void
466 */
467 protected function _commit()
468 {
469 $this->_connect();
470 $this->_connection->commit();
471 $this->_connection->autocommit(true);
472 }
473
474 /**
475 * Roll-back a transaction.
476 *
477 * @return void
478 */
479 protected function _rollBack()
480 {
481 $this->_connect();
482 $this->_connection->rollback();
483 $this->_connection->autocommit(true);
484 }
485
486 /**
487 * Set the fetch mode.
488 *
489 * @param int $mode
490 * @return void
491 * @throws Zend_Db_Adapter_Mysqli_Exception
492 */
493 public function setFetchMode($mode)
494 {
495 switch ($mode) {
496 case Zend_Db::FETCH_LAZY:
497 case Zend_Db::FETCH_ASSOC:
498 case Zend_Db::FETCH_NUM:
499 case Zend_Db::FETCH_BOTH:
500 case Zend_Db::FETCH_NAMED:
501 case Zend_Db::FETCH_OBJ:
502 $this->_fetchMode = $mode;
503 break;
504 case Zend_Db::FETCH_BOUND: // bound to PHP variable
505 /**
506 * @see Zend_Db_Adapter_Mysqli_Exception
507 */
508 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
509 throw new Zend_Db_Adapter_Mysqli_Exception('FETCH_BOUND is not supported yet');
510 break;
511 default:
512 /**
513 * @see Zend_Db_Adapter_Mysqli_Exception
514 */
515 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
516 throw new Zend_Db_Adapter_Mysqli_Exception("Invalid fetch mode '$mode' specified");
517 }
518 }
519
520 /**
521 * Adds an adapter-specific LIMIT clause to the SELECT statement.
522 *
523 * @param string $sql
524 * @param int $count
525 * @param int $offset OPTIONAL
526 * @return string
527 */
528 public function limit($sql, $count, $offset = 0)
529 {
530 $count = intval($count);
531 if ($count <= 0) {
532 /**
533 * @see Zend_Db_Adapter_Mysqli_Exception
534 */
535 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
536 throw new Zend_Db_Adapter_Mysqli_Exception("LIMIT argument count=$count is not valid");
537 }
538
539 $offset = intval($offset);
540 if ($offset < 0) {
541 /**
542 * @see Zend_Db_Adapter_Mysqli_Exception
543 */
544 // require_once 'Zend/Db/Adapter/Mysqli/Exception.php';
545 throw new Zend_Db_Adapter_Mysqli_Exception("LIMIT argument offset=$offset is not valid");
546 }
547
548 $sql .= " LIMIT $count";
549 if ($offset > 0) {
550 $sql .= " OFFSET $offset";
551 }
552
553 return $sql;
554 }
555
556 /**
557 * Check if the adapter supports real SQL parameters.
558 *
559 * @param string $type 'positional' or 'named'
560 * @return bool
561 */
562 public function supportsParameters($type)
563 {
564 switch ($type) {
565 case 'positional':
566 return true;
567 case 'named':
568 default:
569 return false;
570 }
571 }
572
573 /**
574 * Retrieve server version in PHP style
575 *
576 *@return string
577 */
578 public function getServerVersion()
579 {
580 $this->_connect();
581 $version = $this->_connection->server_version;
582 $major = (int) ($version / 10000);
583 $minor = (int) ($version % 10000 / 100);
584 $revision = (int) ($version % 100);
585 return $major . '.' . $minor . '.' . $revision;
586 }
587 }
588