diff options
| author | Damien Regad <dregad@mantisbt.org> | 2021-08-17 00:30:04 +0200 |
|---|---|---|
| committer | Damien Regad <dregad@mantisbt.org> | 2021-08-17 00:30:04 +0200 |
| commit | 507466ef798b18a3a8830230cfcd51bb488513cf (patch) | |
| tree | 8b6ddc09e077883e9b0567d9c3b1c5249884ea09 /drivers/adodb-mysqli.inc.php | |
| parent | 20b01e83cb61b6b2460f64c7d1277c5f4cc28574 (diff) | |
| download | adodb-507466ef798b18a3a8830230cfcd51bb488513cf.tar.gz adodb-507466ef798b18a3a8830230cfcd51bb488513cf.tar.bz2 adodb-507466ef798b18a3a8830230cfcd51bb488513cf.zip | |
Revert changes since Standardized file headers merge
The conflicts resolution applied when merging the Standardized file
headers (commit e9dcce3df24912ad869d0193f0b419f2309101fc) was seriously
messed up, actually overwriting a number of changes in the master
branch.
Rather than trying to go and fix things one by one which has a high risk
of messing things further, it's easier to redo the merge from a clean
slate, so this commit reverts the following:
- "Merge branch 'hotfix/5.21' Standardized file headers",
e9dcce3df24912ad869d0193f0b419f2309101fc
- "Merge tag 'v5.21.1'",
5f437df3104159d5d659f60e31bef8d33c34995f
- "Reset version to 5.22.0-dev"
af9234a525c3255af051a330164486d73be4c63a
- "Fix incorrect resolution of merge conflicts"
a6733f61b0165b366c8d2c70d9af82edc3881951.
- "Fix syntax error in toexport.inc.php"
20b01e83cb61b6b2460f64c7d1277c5f4cc28574.
Fixes #751
Diffstat (limited to 'drivers/adodb-mysqli.inc.php')
| -rw-r--r-- | drivers/adodb-mysqli.inc.php | 258 |
1 files changed, 211 insertions, 47 deletions
diff --git a/drivers/adodb-mysqli.inc.php b/drivers/adodb-mysqli.inc.php index 352810cc..1539580a 100644 --- a/drivers/adodb-mysqli.inc.php +++ b/drivers/adodb-mysqli.inc.php @@ -1,28 +1,23 @@ <?php -/** - * MySQL improved driver (mysqli) - * - * This is the preferred driver for MySQL connections. It supports both - * transactional and non-transactional table types. You can use this as a - * drop-in replacement for both the mysql and mysqlt drivers. - * As of ADOdb Version 5.20.0, all other native MySQL drivers are deprecated. - * - * This file is part of ADOdb, a Database Abstraction Layer library for PHP. - * - * @package ADOdb - * @link https://adodb.org Project's web site and documentation - * @link https://github.com/ADOdb/ADOdb Source code and issue tracker - * - * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause - * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, - * any later version. This means you can use it in proprietary products. - * See the LICENSE.md file distributed with this source code for details. - * @license BSD-3-Clause - * @license LGPL-2.1-or-later - * - * @copyright 2000-2013 John Lim - * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community - */ +/* +@version v5.22.0-dev Unreleased +@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved. +@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community + Released under both BSD license and Lesser GPL library license. + Whenever there is any discrepancy between the two licenses, + the BSD license will take precedence. + Set tabs to 8. + + This is the preferred driver for MySQL connections, and supports both transactional + and non-transactional table types. You can use this as a drop-in replacement for both + the mysql and mysqlt drivers. As of ADOdb Version 5.20.0, all other native MySQL drivers + are deprecated + + Requires mysql client. Works on Windows and Unix. + +21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl) +Based on adodb 3.40 +*/ // security - hide paths if (!defined('ADODB_DIR')) { @@ -81,11 +76,8 @@ class ADODB_mysqli extends ADOConnection { */ private $usePreparedStatement = false; private $useLastInsertStatement = false; - - /** - * @var bool True if the last executed statement is a SELECT {@see _query()} - */ - private $isSelectStatement = false; + private $usingBoundVariables = false; + private $statementAffectedRows = -1; /** * Sets the isolation level of a transaction. @@ -189,6 +181,8 @@ class ADODB_mysqli extends ADOConnection { // SSL Connections for MySQLI if ($this->ssl_key || $this->ssl_cert || $this->ssl_ca || $this->ssl_capath || $this->ssl_cipher) { mysqli_ssl_set($this->_connectionID, $this->ssl_key, $this->ssl_cert, $this->ssl_ca, $this->ssl_capath, $this->ssl_cipher); + $this->socket = MYSQLI_CLIENT_SSL; + $this->clientFlags = MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; } #if (!empty($this->port)) $argHostname .= ":".$this->port; @@ -439,12 +433,9 @@ class ADODB_mysqli extends ADOConnection { */ function _affectedrows() { - if ($this->isSelectStatement) { - // Affected rows works fine against selects, returning - // the rowcount, but ADOdb does not do that. - return false; - } - + if ($this->usingBoundVariables) + return $this->statementAffectedRows; + $result = @mysqli_affected_rows($this->_connectionID); if ($result == -1) { if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->errorMsg()); @@ -1039,6 +1030,7 @@ class ADODB_mysqli extends ADOConnection { /** * Prepares an SQL statement and returns a handle to use. + * This is not used by bound parameters anymore * * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:prepare * @todo update this function to handle prepared statements correctly @@ -1067,13 +1059,86 @@ class ADODB_mysqli extends ADOConnection { } /** - * Return the query id. + * Execute SQL * - * @param string|array $sql - * @param array $inputarr + * @param string $sql SQL statement to execute, or possibly an array + * holding prepared statement ($sql[0] will hold sql text) + * @param array|bool $inputarr holds the input data to bind to. + * Null elements will be set to null. * - * @return bool|mysqli_result + * @return ADORecordSet|bool */ + public function execute($sql, $inputarr = false) { + + if ($this->fnExecute) { + $fn = $this->fnExecute; + $ret = $fn($this,$sql,$inputarr); + if (isset($ret)) { + return $ret; + } + } + + if ($inputarr === false) { + return $this->_execute($sql,false); + } + + if (!is_array($inputarr)) { + $inputarr = array($inputarr); + } + + if (!is_array($sql)) { + + + + $typeString = ''; + $typeArray = array(''); //placeholder for type list + + foreach ($inputarr as $v) + { + $typeArray[] = $v; + if (is_integer($v) || is_bool($v)) + $typeString .= 'i'; + + else if (is_float($v)) + $typeString .= 'd'; + + else if(is_object($v)) + /* + * Assume a blob + */ + $typeString .= 'b'; + + else + $typeString .= 's'; + + } + + /* + * Place the field type list at the front of the + * parameter array. This is the mysql specific + * format + */ + $typeArray[0] = $typeString; + + $ret = $this->_execute($sql,$typeArray); + if (!$ret) { + return $ret; + } + + } else { + $ret = $this->_execute($sql,$inputarr); + } + return $ret; + } + + /** + * Return the query id. + * + * @param string|array $sql + * @param array $inputarr + * + * @return bool|mysqli_result + */ function _query($sql, $inputarr) { global $ADODB_COUNTRECS; @@ -1108,6 +1173,90 @@ class ADODB_mysqli extends ADOConnection { $ret = mysqli_stmt_execute($stmt); return $ret; } + else if (is_string($sql) && is_array($inputarr)) + { + /* + * This is support for true prepared queries + * with bound parameters + * + * set prepared statement flags + */ + $this->usePreparedStatement = true; + $this->usingBoundVariables = true; + + /* + * Prepare the statement with the placeholders, + * prepare will fail if the statement is invalid + * so we trap and error if necessary. Note that we + * are calling MySQL prepare here, not ADOdb + */ + $stmt = $this->_connectionID->prepare($sql); + if ($stmt === false) + { + $this->outp_throw( + "SQL Statement failed on preparation: " . htmlspecialchars($sql) . "'", + 'Execute' + ); + return false; + } + /* + * Make sure the number of parameters provided in the input + * array matches what the query expects. We must discount + * the first parameter which contains the data types in + * our inbound parameters + */ + $nparams = $stmt->param_count; + + if ($nparams != count($inputarr) - 1) { + $this->outp_throw( + "Input array has " . count($inputarr) . + " params, does not match query: '" . htmlspecialchars($sql) . "'", + 'Execute' + ); + return false; + } + + /* + * Must pass references into call_user_func_array + */ + $paramsByReference = array(); + foreach($inputarr as $key => $value) + $paramsByReference[$key] = &$inputarr[$key]; + + /* + * Bind the params + */ + call_user_func_array(array($stmt, 'bind_param'), $paramsByReference); + + /* + * Execute + */ + $ret = mysqli_stmt_execute($stmt); + + /* + * Did we throw an error? + */ + if ($ret == false) + return false; + + /* + * Is the statement a non-select + */ + if ($stmt->affected_rows > -1) + { + $this->statementAffectedRows = $stmt->affected_rows; + return true; + } + /* + * Turn the statement into a result set + */ + $result = $stmt->get_result(); + /* + * Return the object for the select + */ + return $result; + + } else { /* @@ -1126,7 +1275,7 @@ class ADODB_mysqli extends ADOConnection { return $mysql_res; */ - + if ($this->multiQuery) { $rs = mysqli_multi_query($this->_connectionID, $sql.';'); if ($rs) { @@ -1135,10 +1284,8 @@ class ADODB_mysqli extends ADOConnection { } } else { $rs = mysqli_query($this->_connectionID, $sql, $ADODB_COUNTRECS ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT); - if ($rs) { - $this->isSelectStatement = is_object($rs); - return $rs; - } + + if ($rs) return $rs; } if($this->debug) @@ -1511,6 +1658,7 @@ class ADORecordSet_mysqli extends ADORecordSet{ 12 = MYSQLI_TYPE_DATETIME 13 = MYSQLI_TYPE_YEAR 14 = MYSQLI_TYPE_NEWDATE +245 = MYSQLI_TYPE_JSON 247 = MYSQLI_TYPE_ENUM 248 = MYSQLI_TYPE_SET 249 = MYSQLI_TYPE_TINY_BLOB @@ -1531,7 +1679,7 @@ class ADORecordSet_mysqli extends ADORecordSet{ * * @return string The MetaType */ - function MetaType($t, $len = -1, $fieldobj = false) + function metaType($t, $len = -1, $fieldobj = false) { if (is_object($t)) { $fieldobj = $t; @@ -1539,8 +1687,16 @@ class ADORecordSet_mysqli extends ADORecordSet{ $len = $fieldobj->max_length; } + $t = strtoupper($t); + /* + * Add support for custom actual types. We do this + * first, that allows us to override existing types + */ + if (array_key_exists($t,$this->connection->customActualTypes)) + return $this->connection->customActualTypes[$t]; + $len = -1; // mysql max_length is not accurate - switch (strtoupper($t)) { + switch ($t) { case 'STRING': case 'CHAR': case 'VARCHAR': @@ -1618,6 +1774,8 @@ class ADORecordSet_mysqli extends ADORecordSet{ case 'DEC': case 'FIXED': default: + + //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; return 'N'; } @@ -1647,9 +1805,15 @@ class ADORecordSet_array_mysqli extends ADORecordSet_array $t = $fieldobj->type; $len = $fieldobj->max_length; } + + $t = strtoupper($t); + + if (array_key_exists($t,$this->connection->customActualTypes)) + return $this->connection->customActualTypes[$t]; $len = -1; // mysql max_length is not accurate - switch (strtoupper($t)) { + + switch ($t) { case 'STRING': case 'CHAR': case 'VARCHAR': |
