2
0
forked from Wavyzz/dolibarr

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

@@ -151,6 +151,9 @@ class MDB2_Driver_mysql 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) {
@@ -190,7 +193,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
$text = $this->escapePattern($text);
}
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
$text = @mysql_real_escape_string($text, $connection);
@@ -211,6 +214,7 @@ class MDB2_Driver_mysql 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,
@@ -231,7 +235,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
}
$query = $this->start_transaction ? 'START TRANSACTION' : 'SET AUTOCOMMIT = 1';
$result =& $this->_doQuery($query, true);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
$this->in_transaction = true;
@@ -278,13 +282,13 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
}
$result =& $this->_doQuery('COMMIT', true);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
if (!$this->start_transaction) {
$query = 'SET AUTOCOMMIT = 0';
$result =& $this->_doQuery($query, true);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
}
@@ -324,13 +328,13 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
$query = 'ROLLBACK';
$result =& $this->_doQuery($query, true);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
if (!$this->start_transaction) {
$query = 'SET AUTOCOMMIT = 0';
$result =& $this->_doQuery($query, true);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
}
@@ -389,13 +393,14 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
if (is_resource($this->connection)) {
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
&& $this->opened_persistent == $this->options['persistent']
&& $this->connected_database_name == $this->database_name
) {
return MDB2_OK;
}
$this->disconnect(false);
}
if (!DOLIPEAR::loadExtension($this->phptype)) {
if (!PEAR::loadExtension($this->phptype)) {
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
'extension '.$this->phptype.' is not compiled into PHP', __FUNCTION__);
}
@@ -440,7 +445,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
if (!empty($this->dsn['charset'])) {
$result = $this->setCharset($this->dsn['charset'], $connection);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
}
@@ -482,36 +487,12 @@ class MDB2_Driver_mysql 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;
}
// }}}
// {{{ setCharset()
@@ -527,19 +508,12 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
{
if (is_null($connection)) {
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
}
$query = "SET character_set_client = '".mysql_real_escape_string($charset, $connection)."'";
$result = @mysql_query($query, $connection);
if (!$result) {
return $this->raiseError(null, null, null,
'Unable to set client charset: '.$charset, __FUNCTION__);
}
return MDB2_OK;
$query = "SET NAMES '".mysql_real_escape_string($charset, $connection)."'";
return $this->_doQuery($query, true, $connection);
}
// }}}
@@ -594,7 +568,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
$this->last_query = $query;
$result = $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'pre'));
if ($result) {
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
$query = $result;
@@ -606,7 +580,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
if (is_null($connection)) {
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
}
@@ -653,7 +627,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
{
if (is_null($connection)) {
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
}
@@ -684,16 +658,31 @@ class MDB2_Driver_mysql 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";
return $query . " LIMIT $limit" . $after;
} else {
return $query . " LIMIT $offset, $limit";
return $query . " LIMIT $offset, $limit" . $after;
}
}
return $query;
@@ -705,14 +694,14 @@ class MDB2_Driver_mysql 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
*/
function getServerVersion($native = false)
{
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
if ($this->connected_server_info) {
@@ -745,6 +734,80 @@ class MDB2_Driver_mysql 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()
@@ -783,7 +846,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
$query = $this->_modifyQuery($query, $is_manip, $limit, $offset);
$result = $this->debug($query, __FUNCTION__, array('is_manip' => $is_manip, 'when' => 'pre'));
if ($result) {
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
$query = $result;
@@ -810,7 +873,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
}
$new_pos = $this->_skipDelimitedStrings($query, $position, $p_position);
if (DOLIPEAR::isError($new_pos)) {
if (PEAR::isError($new_pos)) {
return $new_pos;
}
if ($new_pos != $position) {
@@ -824,6 +887,12 @@ class MDB2_Driver_mysql 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,
@@ -841,13 +910,13 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
}
}
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
$statement_name = sprintf($this->options['statement_format'], $this->phptype, md5(time() + rand()));
$query = "PREPARE $statement_name FROM ".$this->quote($query, 'text');
$statement =& $this->_doQuery($query, true, $connection);
if (DOLIPEAR::isError($statement)) {
if (PEAR::isError($statement)) {
return $statement;
}
@@ -957,13 +1026,13 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
}
$connection = $this->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
$query = "REPLACE INTO $table ($query) VALUES ($values)";
$result =& $this->_doQuery($query, true, $connection);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
return $this->_affectedRows($connection, $result);
@@ -991,11 +1060,11 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
$result =& $this->_doQuery($query, true);
$this->popExpect();
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) {
$this->loadModule('Manager', null, true);
$result = $this->manager->createSequence($seq_name);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $this->raiseError($result, null, null,
'on demand sequence '.$seq_name.' could not be created', __FUNCTION__);
} else {
@@ -1008,7 +1077,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common
if (is_numeric($value)) {
$query = "DELETE FROM $sequence_name WHERE $seqcol_name < $value";
$result =& $this->_doQuery($query, true);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
$this->warnings[] = 'nextID: could not delete previous sequence table values from '.$seq_name;
}
}
@@ -1076,7 +1145,7 @@ class MDB2_Result_mysql extends MDB2_Result_Common
{
if (!is_null($rownum)) {
$seek = $this->seek($rownum);
if (DOLIPEAR::isError($seek)) {
if (PEAR::isError($seek)) {
return $seek;
}
}
@@ -1141,7 +1210,7 @@ class MDB2_Result_mysql extends MDB2_Result_Common
{
$columns = array();
$numcols = $this->numCols();
if (DOLIPEAR::isError($numcols)) {
if (PEAR::isError($numcols)) {
return $numcols;
}
for ($column = 0; $column < $numcols; $column++) {
@@ -1250,7 +1319,7 @@ class MDB2_BufferedResult_mysql extends MDB2_Result_mysql
function valid()
{
$numrows = $this->numRows();
if (DOLIPEAR::isError($numrows)) {
if (PEAR::isError($numrows)) {
return $numrows;
}
return $this->rownum < ($numrows - 1);
@@ -1315,7 +1384,7 @@ class MDB2_Statement_mysql extends MDB2_Statement_Common
}
$connection = $this->db->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
@@ -1348,9 +1417,13 @@ class MDB2_Statement_mysql 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 (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
}
@@ -1358,7 +1431,7 @@ class MDB2_Statement_mysql extends MDB2_Statement_Common
}
$result = $this->db->_doQuery($query, $this->is_manip, $connection);
if (DOLIPEAR::isError($result)) {
if (PEAR::isError($result)) {
return $result;
}
@@ -1392,7 +1465,7 @@ class MDB2_Statement_mysql extends MDB2_Statement_Common
if (!is_null($this->statement)) {
$connection = $this->db->getConnection();
if (DOLIPEAR::isError($connection)) {
if (PEAR::isError($connection)) {
return $connection;
}
$query = 'DEALLOCATE PREPARE '.$this->statement;