Mise jour de Pear MDB2

This commit is contained in:
Regis Houssin
2007-08-17 08:24:13 +00:00
parent 275121d719
commit 1e99ea3005
30 changed files with 2417 additions and 632 deletions

View File

@@ -122,8 +122,8 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
$native_code = @mysqli_errno($this->connection);
$native_msg = @mysqli_error($this->connection);
} else {
$native_code = @mysqli_errno();
$native_msg = @mysqli_error();
$native_code = @mysqli_connect_errno();
$native_msg = @mysqli_connect_error();
}
if (is_null($error)) {
static $ecode_map;
@@ -152,6 +152,9 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
1146 => MDB2_ERROR_NOSUCHTABLE,
1216 => MDB2_ERROR_CONSTRAINT,
1217 => MDB2_ERROR_CONSTRAINT,
1356 => MDB2_ERROR_DIVZERO,
1451 => MDB2_ERROR_CONSTRAINT,
1452 => MDB2_ERROR_CONSTRAINT,
);
}
if ($this->options['portability'] & MDB2_PORTABILITY_ERRORS) {
@@ -212,6 +215,7 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
function beginTransaction($savepoint = null)
{
$this->debug('Starting transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint));
$this->_getServerCapabilities();
if (!is_null($savepoint)) {
if (!$this->supports('savepoints')) {
return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
@@ -429,7 +433,7 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
if (!$connection) {
if (($err = @mysqli_connect_error()) != '') {
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED,
return $this->raiseError(null,
null, null, $err, __FUNCTION__);
} else {
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null,
@@ -469,33 +473,8 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
break;
}
}
$this->supported['sub_selects'] = 'emulated';
$this->supported['prepared_statements'] = 'emulated';
$this->start_transaction = false;
$this->varchar_max_length = 255;
$server_info = $this->getServerVersion();
if (is_array($server_info)) {
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.1.0', '<')) {
$this->supported['sub_selects'] = true;
$this->supported['prepared_statements'] = true;
}
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.0.14', '<')
|| !version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.1.1', '<')
) {
$this->supported['savepoints'] = true;
}
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.0.11', '<')) {
$this->start_transaction = true;
}
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '5.0.3', '<')) {
$this->varchar_max_length = 65532;
}
}
$this->_getServerCapabilities();
return MDB2_OK;
}
@@ -519,19 +498,8 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
return $connection;
}
}
if (function_exists('mysqli_set_charset')) {
$result = @mysqli_set_charset($connection, $charset);
} else {
$query = "SET character_set_client = '".mysqli_real_escape_string($connection, $charset)."'";
$result = @mysqli_query($connection, $query);
}
if (!$result) {
return $this->raiseError(null, null, null,
'Unable to set client charset: '.$charset, __FUNCTION__);
}
return MDB2_OK;
$query = "SET NAMES '".mysqli_real_escape_string($connection, $charset)."'";
return $this->_doQuery($query, true, $connection);
}
// }}}
@@ -694,12 +662,27 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
}
}
if ($limit > 0
&& !preg_match('/LIMIT\s*\d(\s*(,|OFFSET)\s*\d+)?/i', $query)
&& !preg_match('/LIMIT\s*\d(?:\s*(?:,|OFFSET)\s*\d+)?(?:[^\)]*)?$/i', $query)
) {
$query = rtrim($query);
if (substr($query, -1) == ';') {
$query = substr($query, 0, -1);
}
// LIMIT doesn't always come last in the query
// @see http://dev.mysql.com/doc/refman/5.0/en/select.html
$after = '';
if (preg_match('/(\s+INTO\s+(?:OUT|DUMP)FILE\s.*)$/ims', $query, $matches)) {
$after = $matches[0];
$query = preg_replace('/(\s+INTO\s+(?:OUT|DUMP)FILE\s.*)$/ims', '', $query);
} elseif (preg_match('/(\s+FOR\s+UPDATE\s*)$/i', $query, $matches)) {
$after = $matches[0];
$query = preg_replace('/(\s+FOR\s+UPDATE\s*)$/im', '', $query);
} elseif (preg_match('/(\s+LOCK\s+IN\s+SHARE\s+MODE\s*)$/im', $query, $matches)) {
$after = $matches[0];
$query = preg_replace('/(\s+LOCK\s+IN\s+SHARE\s+MODE\s*)$/im', '', $query);
}
if ($is_manip) {
return $query . " LIMIT $limit";
} else {
@@ -715,7 +698,7 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
/**
* return version information about the server
*
* @param string $native determines if the raw version string should be returned
* @param bool $native determines if the raw version string should be returned
* @return mixed array/string with version information or MDB2 error object
* @access public
*/
@@ -755,6 +738,80 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
return $server_info;
}
// }}}
// {{{ _getServerCapabilities()
/**
* Fetch some information about the server capabilities
* (transactions, subselects, prepared statements, etc).
*
* @access private
*/
function _getServerCapabilities()
{
static $already_checked = false;
if (!$already_checked) {
$already_checked = true;
//set defaults
$this->supported['sub_selects'] = 'emulated';
$this->supported['prepared_statements'] = 'emulated';
$this->start_transaction = false;
$this->varchar_max_length = 255;
$server_info = $this->getServerVersion();
if (is_array($server_info)) {
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.1.0', '<')) {
$this->supported['sub_selects'] = true;
$this->supported['prepared_statements'] = true;
}
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.0.14', '<')
|| !version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.1.1', '<')
) {
$this->supported['savepoints'] = true;
}
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '4.0.11', '<')) {
$this->start_transaction = true;
}
if (!version_compare($server_info['major'].'.'.$server_info['minor'].'.'.$server_info['patch'], '5.0.3', '<')) {
$this->varchar_max_length = 65532;
}
}
}
}
// }}}
// {{{ function _skipUserDefinedVariable($query, $position)
/**
* Utility method, used by prepare() to avoid misinterpreting MySQL user
* defined variables (SELECT @x:=5) for placeholders.
* Check if the placeholder is a false positive, i.e. if it is an user defined
* variable instead. If so, skip it and advance the position, otherwise
* return the current position, which is valid
*
* @param string $query
* @param integer $position current string cursor position
* @return integer $new_position
* @access protected
*/
function _skipUserDefinedVariable($query, $position)
{
$found = strpos(strrev(substr($query, 0, $position)), '@');
if ($found === false) {
return $position;
}
$pos = strlen($query) - strlen(substr($query, $position)) - $found - 1;
$substring = substr($query, $pos, $position - $pos + 2);
if (preg_match('/^@\w+:=$/', $substring)) {
return $position + 1; //found an user defined variable: skip it
}
return $position;
}
// }}}
// {{{ prepare()
@@ -834,6 +891,12 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
$question = $colon = $placeholder_type;
}
if ($placeholder_type == ':') {
//make sure this is not part of an user defined variable
$new_pos = $this->_skipUserDefinedVariable($query, $position);
if ($new_pos != $position) {
$position = $new_pos;
continue; //evaluate again starting from the new position
}
$parameter = preg_replace('/^.{'.($position+1).'}([a-z0-9_]+).*$/si', '\\1', $query);
if ($parameter === '') {
$err =& $this->raiseError(MDB2_ERROR_SYNTAX, null, null,
@@ -1208,7 +1271,6 @@ class MDB2_Result_mysqli extends MDB2_Result_Common
/**
* Move the internal result pointer to the next available result
*
* @param a valid result resource
* @return true on success, false if there is no more result set or an error object on failure
* @access public
*/
@@ -1433,7 +1495,11 @@ class MDB2_Statement_mysqli extends MDB2_Statement_Common
$value = $data;
}
}
$param_query = 'SET @'.$parameter.' = '.$this->db->quote($value, $type);
$quoted = $this->db->quote($value, $type);
if (PEAR::isError($quoted)) {
return $quoted;
}
$param_query = 'SET @'.$parameter.' = '.$quoted;
$result = $this->db->_doQuery($param_query, true, $connection);
if (PEAR::isError($result)) {
return $result;