- Updated PEAR::DB package to version 1.7.13

release-0.6
alecpl 17 years ago
parent a6f90e1b2b
commit e5deaae528

@ -1,6 +1,9 @@
CHANGELOG RoundCube Webmail CHANGELOG RoundCube Webmail
--------------------------- ---------------------------
2008/05/12 (alec)
- Updated PEAR::DB package to version 1.7.13
2008/05/10 (alec) 2008/05/10 (alec)
- Make password input fields of type password in installer (#1484886) - Make password input fields of type password in installer (#1484886)

@ -18,7 +18,7 @@
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -424,9 +424,9 @@ define('DB_PORTABILITY_ALL', 63);
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB class DB
@ -467,7 +467,7 @@ class DB
return $tmp; return $tmp;
} }
@$obj =& new $classname; @$obj = new $classname;
foreach ($options as $option => $value) { foreach ($options as $option => $value) {
$test = $obj->setOption($option, $value); $test = $obj->setOption($option, $value);
@ -544,7 +544,7 @@ class DB
return $tmp; return $tmp;
} }
@$obj =& new $classname; @$obj = new $classname;
foreach ($options as $option => $value) { foreach ($options as $option => $value) {
$test = $obj->setOption($option, $value); $test = $obj->setOption($option, $value);
@ -555,7 +555,11 @@ class DB
$err = $obj->connect($dsninfo, $obj->getOption('persistent')); $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
if (DB::isError($err)) { if (DB::isError($err)) {
$err->addUserInfo($dsn); if (is_array($dsn)) {
$err->addUserInfo(DB::getDSNString($dsn, true));
} else {
$err->addUserInfo($dsn);
}
return $err; return $err;
} }
@ -572,7 +576,7 @@ class DB
*/ */
function apiVersion() function apiVersion()
{ {
return '@package_version@'; return '1.7.13';
} }
// }}} // }}}
@ -625,7 +629,7 @@ class DB
{ {
$manips = 'INSERT|UPDATE|DELETE|REPLACE|' $manips = 'INSERT|UPDATE|DELETE|REPLACE|'
. 'CREATE|DROP|' . 'CREATE|DROP|'
. 'LOAD DATA|SELECT .* INTO|COPY|' . 'LOAD DATA|SELECT .* INTO .* FROM|COPY|'
. 'ALTER|GRANT|REVOKE|' . 'ALTER|GRANT|REVOKE|'
. 'LOCK|UNLOCK'; . 'LOCK|UNLOCK';
if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) {
@ -808,13 +812,11 @@ class DB
// process the different protocol options // process the different protocol options
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
$proto_opts = rawurldecode($proto_opts); $proto_opts = rawurldecode($proto_opts);
if (strpos($proto_opts, ':') !== false) {
list($proto_opts, $parsed['port']) = explode(':', $proto_opts);
}
if ($parsed['protocol'] == 'tcp') { if ($parsed['protocol'] == 'tcp') {
if (strpos($proto_opts, ':') !== false) { $parsed['hostspec'] = $proto_opts;
list($parsed['hostspec'],
$parsed['port']) = explode(':', $proto_opts);
} else {
$parsed['hostspec'] = $proto_opts;
}
} elseif ($parsed['protocol'] == 'unix') { } elseif ($parsed['protocol'] == 'unix') {
$parsed['socket'] = $proto_opts; $parsed['socket'] = $proto_opts;
} }
@ -847,6 +849,82 @@ class DB
return $parsed; return $parsed;
} }
// }}}
// {{{ getDSNString()
/**
* Returns the given DSN in a string format suitable for output.
*
* @param array|string the DSN to parse and format
* @param boolean true to hide the password, false to include it
* @return string
*/
function getDSNString($dsn, $hidePassword) {
/* Calling parseDSN will ensure that we have all the array elements
* defined, and means that we deal with strings and array in the same
* manner. */
$dsnArray = DB::parseDSN($dsn);
if ($hidePassword) {
$dsnArray['password'] = 'PASSWORD';
}
/* Protocol is special-cased, as using the default "tcp" along with an
* Oracle TNS connection string fails. */
if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') {
$dsnArray['protocol'] = false;
}
// Now we just have to construct the actual string. This is ugly.
$dsnString = $dsnArray['phptype'];
if ($dsnArray['dbsyntax']) {
$dsnString .= '('.$dsnArray['dbsyntax'].')';
}
$dsnString .= '://'
.$dsnArray['username']
.':'
.$dsnArray['password']
.'@'
.$dsnArray['protocol'];
if ($dsnArray['socket']) {
$dsnString .= '('.$dsnArray['socket'].')';
}
if ($dsnArray['protocol'] && $dsnArray['hostspec']) {
$dsnString .= '+';
}
$dsnString .= $dsnArray['hostspec'];
if ($dsnArray['port']) {
$dsnString .= ':'.$dsnArray['port'];
}
$dsnString .= '/'.$dsnArray['database'];
/* Option handling. Unfortunately, parseDSN simply places options into
* the top-level array, so we'll first get rid of the fields defined by
* DB and see what's left. */
unset($dsnArray['phptype'],
$dsnArray['dbsyntax'],
$dsnArray['username'],
$dsnArray['password'],
$dsnArray['protocol'],
$dsnArray['socket'],
$dsnArray['hostspec'],
$dsnArray['port'],
$dsnArray['database']
);
if (count($dsnArray) > 0) {
$dsnString .= '?';
$i = 0;
foreach ($dsnArray as $key => $value) {
if (++$i > 1) {
$dsnString .= '&';
}
$dsnString .= $key.'='.$value;
}
}
return $dsnString;
}
// }}} // }}}
} }
@ -860,9 +938,9 @@ class DB
* @category Database * @category Database
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_Error extends PEAR_Error class DB_Error extends PEAR_Error
@ -907,9 +985,9 @@ class DB_Error extends PEAR_Error
* @category Database * @category Database
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_result class DB_result
@ -1089,7 +1167,7 @@ class DB_result
$fetchmode = DB_FETCHMODE_ASSOC; $fetchmode = DB_FETCHMODE_ASSOC;
$object_class = $this->fetchmode_object_class; $object_class = $this->fetchmode_object_class;
} }
if ($this->limit_from !== null) { if (is_null($rownum) && $this->limit_from !== null) {
if ($this->row_counter === null) { if ($this->row_counter === null) {
$this->row_counter = $this->limit_from; $this->row_counter = $this->limit_from;
// Skip rows // Skip rows
@ -1121,7 +1199,7 @@ class DB_result
if ($object_class == 'stdClass') { if ($object_class == 'stdClass') {
$arr = (object) $arr; $arr = (object) $arr;
} else { } else {
$arr = &new $object_class($arr); $arr = new $object_class($arr);
} }
} }
return $arr; return $arr;
@ -1171,7 +1249,7 @@ class DB_result
$fetchmode = DB_FETCHMODE_ASSOC; $fetchmode = DB_FETCHMODE_ASSOC;
$object_class = $this->fetchmode_object_class; $object_class = $this->fetchmode_object_class;
} }
if ($this->limit_from !== null) { if (is_null($rownum) && $this->limit_from !== null) {
if ($this->row_counter === null) { if ($this->row_counter === null) {
$this->row_counter = $this->limit_from; $this->row_counter = $this->limit_from;
// Skip rows // Skip rows
@ -1253,10 +1331,33 @@ class DB_result
while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) { while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) {
$i++; $i++;
} }
return $i; $count = $i;
} else { } else {
return $this->dbh->numRows($this->result); $count = $this->dbh->numRows($this->result);
}
/* fbsql is checked for here because limit queries are implemented
* using a TOP() function, which results in fbsql_num_rows still
* returning the total number of rows that would have been returned,
* rather than the real number. As a result, we'll just do the limit
* calculations for fbsql in the same way as a database with emulated
* limits. Unfortunately, we can't just do this in DB_fbsql::numRows()
* because that only gets the result resource, rather than the full
* DB_Result object. */
if (($this->dbh->features['limit'] === 'emulate'
&& $this->limit_from !== null)
|| $this->dbh->phptype == 'fbsql') {
$limit_count = is_null($this->limit_count) ? $count : $this->limit_count;
if ($count < $this->limit_from) {
$count = 0;
} elseif ($count < ($this->limit_from + $limit_count)) {
$count -= $this->limit_from;
} else {
$count = $limit_count;
}
} }
return $count;
} }
// }}} // }}}
@ -1349,9 +1450,9 @@ class DB_result
* @category Database * @category Database
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
* @see DB_common::setFetchMode() * @see DB_common::setFetchMode()
*/ */

@ -18,7 +18,7 @@
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com> * @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -40,9 +40,9 @@ require_once 'PEAR.php';
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com> * @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_common extends PEAR class DB_common extends PEAR
@ -121,6 +121,21 @@ class DB_common extends PEAR
*/ */
var $prepared_queries = array(); var $prepared_queries = array();
/**
* Flag indicating that the last query was a manipulation query.
* @access protected
* @var boolean
*/
var $_last_query_manip = false;
/**
* Flag indicating that the next query <em>must</em> be a manipulation
* query.
* @access protected
* @var boolean
*/
var $_next_query_manip = false;
// }}} // }}}
// {{{ DB_common // {{{ DB_common
@ -424,17 +439,56 @@ class DB_common extends PEAR
*/ */
function quoteSmart($in) function quoteSmart($in)
{ {
if (is_int($in) || is_double($in)) { if (is_int($in)) {
return $in; return $in;
} elseif (is_float($in)) {
return $this->quoteFloat($in);
} elseif (is_bool($in)) { } elseif (is_bool($in)) {
return $in ? 1 : 0; return $this->quoteBoolean($in);
} elseif (is_null($in)) { } elseif (is_null($in)) {
return 'NULL'; return 'NULL';
} else { } else {
if ($this->dbsyntax == 'access'
&& preg_match('/^#.+#$/', $in))
{
return $this->escapeSimple($in);
}
return "'" . $this->escapeSimple($in) . "'"; return "'" . $this->escapeSimple($in) . "'";
} }
} }
// }}}
// {{{ quoteBoolean()
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteBoolean($boolean) {
return $boolean ? '1' : '0';
}
// }}}
// {{{ quoteFloat()
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'";
}
// }}} // }}}
// {{{ escapeSimple() // {{{ escapeSimple()
@ -837,7 +891,7 @@ class DB_common extends PEAR
if (DB::isError($sth)) { if (DB::isError($sth)) {
return $sth; return $sth;
} }
$ret =& $this->execute($sth, array_values($fields_values)); $ret = $this->execute($sth, array_values($fields_values));
$this->freePrepared($sth); $this->freePrepared($sth);
return $ret; return $ret;
@ -931,7 +985,7 @@ class DB_common extends PEAR
* "'it''s good'", * "'it''s good'",
* 'filename.txt' * 'filename.txt'
* ); * );
* $res =& $db->execute($sth, $data); * $res = $db->execute($sth, $data);
* </code> * </code>
* *
* @param resource $stmt a DB statement resource returned from prepare() * @param resource $stmt a DB statement resource returned from prepare()
@ -960,7 +1014,7 @@ class DB_common extends PEAR
if ($result === DB_OK || DB::isError($result)) { if ($result === DB_OK || DB::isError($result)) {
return $result; return $result;
} else { } else {
$tmp =& new DB_result($this, $result); $tmp = new DB_result($this, $result);
return $tmp; return $tmp;
} }
} }
@ -1041,7 +1095,7 @@ class DB_common extends PEAR
function executeMultiple($stmt, $data) function executeMultiple($stmt, $data)
{ {
foreach ($data as $value) { foreach ($data as $value) {
$res =& $this->execute($stmt, $value); $res = $this->execute($stmt, $value);
if (DB::isError($res)) { if (DB::isError($res)) {
return $res; return $res;
} }
@ -1154,7 +1208,7 @@ class DB_common extends PEAR
if (DB::isError($sth)) { if (DB::isError($sth)) {
return $sth; return $sth;
} }
$ret =& $this->execute($sth, $params); $ret = $this->execute($sth, $params);
$this->freePrepared($sth, false); $this->freePrepared($sth, false);
return $ret; return $ret;
} else { } else {
@ -1163,7 +1217,7 @@ class DB_common extends PEAR
if ($result === DB_OK || DB::isError($result)) { if ($result === DB_OK || DB::isError($result)) {
return $result; return $result;
} else { } else {
$tmp =& new DB_result($this, $result); $tmp = new DB_result($this, $result);
return $tmp; return $tmp;
} }
} }
@ -1194,7 +1248,7 @@ class DB_common extends PEAR
if (DB::isError($query)){ if (DB::isError($query)){
return $query; return $query;
} }
$result =& $this->query($query, $params); $result = $this->query($query, $params);
if (is_a($result, 'DB_result')) { if (is_a($result, 'DB_result')) {
$result->setOption('limit_from', $from); $result->setOption('limit_from', $from);
$result->setOption('limit_count', $count); $result->setOption('limit_count', $count);
@ -1229,10 +1283,10 @@ class DB_common extends PEAR
if (DB::isError($sth)) { if (DB::isError($sth)) {
return $sth; return $sth;
} }
$res =& $this->execute($sth, $params); $res = $this->execute($sth, $params);
$this->freePrepared($sth); $this->freePrepared($sth);
} else { } else {
$res =& $this->query($query); $res = $this->query($query);
} }
if (DB::isError($res)) { if (DB::isError($res)) {
@ -1293,10 +1347,10 @@ class DB_common extends PEAR
if (DB::isError($sth)) { if (DB::isError($sth)) {
return $sth; return $sth;
} }
$res =& $this->execute($sth, $params); $res = $this->execute($sth, $params);
$this->freePrepared($sth); $this->freePrepared($sth);
} else { } else {
$res =& $this->query($query); $res = $this->query($query);
} }
if (DB::isError($res)) { if (DB::isError($res)) {
@ -1344,10 +1398,10 @@ class DB_common extends PEAR
return $sth; return $sth;
} }
$res =& $this->execute($sth, $params); $res = $this->execute($sth, $params);
$this->freePrepared($sth); $this->freePrepared($sth);
} else { } else {
$res =& $this->query($query); $res = $this->query($query);
} }
if (DB::isError($res)) { if (DB::isError($res)) {
@ -1360,7 +1414,7 @@ class DB_common extends PEAR
$ret = array(); $ret = array();
} else { } else {
if (!array_key_exists($col, $row)) { if (!array_key_exists($col, $row)) {
$ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD); $ret = $this->raiseError(DB_ERROR_NOSUCHFIELD);
} else { } else {
$ret = array($row[$col]); $ret = array($row[$col]);
while (is_array($row = $res->fetchRow($fetchmode))) { while (is_array($row = $res->fetchRow($fetchmode))) {
@ -1476,10 +1530,10 @@ class DB_common extends PEAR
return $sth; return $sth;
} }
$res =& $this->execute($sth, $params); $res = $this->execute($sth, $params);
$this->freePrepared($sth); $this->freePrepared($sth);
} else { } else {
$res =& $this->query($query); $res = $this->query($query);
} }
if (DB::isError($res)) { if (DB::isError($res)) {
@ -1491,7 +1545,7 @@ class DB_common extends PEAR
$cols = $res->numCols(); $cols = $res->numCols();
if ($cols < 2) { if ($cols < 2) {
$tmp =& $this->raiseError(DB_ERROR_TRUNCATED); $tmp = $this->raiseError(DB_ERROR_TRUNCATED);
return $tmp; return $tmp;
} }
@ -1603,10 +1657,10 @@ class DB_common extends PEAR
return $sth; return $sth;
} }
$res =& $this->execute($sth, $params); $res = $this->execute($sth, $params);
$this->freePrepared($sth); $this->freePrepared($sth);
} else { } else {
$res =& $this->query($query); $res = $this->query($query);
} }
if ($res === DB_OK || DB::isError($res)) { if ($res === DB_OK || DB::isError($res)) {
@ -1627,7 +1681,7 @@ class DB_common extends PEAR
$res->free(); $res->free();
if (DB::isError($row)) { if (DB::isError($row)) {
$tmp =& $this->raiseError($row); $tmp = $this->raiseError($row);
return $tmp; return $tmp;
} }
return $results; return $results;
@ -2102,6 +2156,52 @@ class DB_common extends PEAR
return $this->raiseError(DB_ERROR_UNSUPPORTED); return $this->raiseError(DB_ERROR_UNSUPPORTED);
} }
// }}}
// {{{ nextQueryIsManip()
/**
* Sets (or unsets) a flag indicating that the next query will be a
* manipulation query, regardless of the usual DB::isManip() heuristics.
*
* @param boolean true to set the flag overriding the isManip() behaviour,
* false to clear it and fall back onto isManip()
*
* @return void
*
* @access public
*/
function nextQueryIsManip($manip)
{
$this->_next_query_manip = $manip;
}
// }}}
// {{{ _checkManip()
/**
* Checks if the given query is a manipulation query. This also takes into
* account the _next_query_manip flag and sets the _last_query_manip flag
* (and resets _next_query_manip) according to the result.
*
* @param string The query to check.
*
* @return boolean true if the query is a manipulation query, false
* otherwise
*
* @access protected
*/
function _checkManip($query)
{
if ($this->_next_query_manip || DB::isManip($query)) {
$this->_last_query_manip = true;
} else {
$this->_last_query_manip = false;
}
$this->_next_query_manip = false;
return $this->_last_query_manip;
$manip = $this->_next_query_manip;
}
// }}} // }}}
// {{{ _rtrimArrayValues() // {{{ _rtrimArrayValues()

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author Tomas V.V. Cox <cox@idecnet.com> * @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -39,9 +39,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author Tomas V.V. Cox <cox@idecnet.com> * @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_dbase extends DB_common class DB_dbase extends DB_common
@ -188,7 +188,7 @@ class DB_dbase extends DB_common
* 'portability' => DB_PORTABILITY_ALL, * 'portability' => DB_PORTABILITY_ALL,
* ); * );
* *
* $db =& DB::connect($dsn, $options); * $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) { * if (PEAR::isError($db)) {
* die($db->getMessage()); * die($db->getMessage());
* } * }
@ -214,7 +214,7 @@ class DB_dbase extends DB_common
* Turn track_errors on for entire script since $php_errormsg * Turn track_errors on for entire script since $php_errormsg
* is the only way to find errors from the dbase extension. * is the only way to find errors from the dbase extension.
*/ */
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$php_errormsg = ''; $php_errormsg = '';
if (!file_exists($dsn['database'])) { if (!file_exists($dsn['database'])) {
@ -273,7 +273,7 @@ class DB_dbase extends DB_common
{ {
// emulate result resources // emulate result resources
$this->res_row[(int)$this->result] = 0; $this->res_row[(int)$this->result] = 0;
$tmp =& new DB_result($this, $this->result++); $tmp = new DB_result($this, $this->result++);
return $tmp; return $tmp;
} }
@ -325,6 +325,26 @@ class DB_dbase extends DB_common
return DB_OK; return DB_OK;
} }
// }}}
// {{{ freeResult()
/**
* Deletes the result set and frees the memory occupied by the result set.
*
* This method is a no-op for dbase, as there aren't result resources in
* the same sense as most other database backends.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return true;
}
// }}} // }}}
// {{{ numCols() // {{{ numCols()
@ -368,39 +388,19 @@ class DB_dbase extends DB_common
} }
// }}} // }}}
// {{{ quoteSmart() // {{{ quoteBoolean()
/** /**
* Formats input so it can be safely used in a query * Formats a boolean value for use within a query in a locale-independent
* * manner.
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = <samp>T</samp> if true or
* <samp>F</samp> if false. Use the <kbd>Logical</kbd>
* data type.
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data with single quotes escaped by preceeding
* single quotes then the whole string is encapsulated
* between single quotes
* *
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart() * @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0 * @since Method available since release 1.7.8.
*/ */
function quoteSmart($in) function quoteBoolean($boolean) {
{ return $boolean ? 'T' : 'F';
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'T' : 'F';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
} }
// }}} // }}}

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author Frank M. Kromann <frank@frontbase.com> * @author Frank M. Kromann <frank@frontbase.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -39,9 +39,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author Frank M. Kromann <frank@frontbase.com> * @author Frank M. Kromann <frank@frontbase.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
* @since Class functional since Release 1.7.0 * @since Class functional since Release 1.7.0
*/ */
@ -171,10 +171,10 @@ class DB_fbsql extends DB_common
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
} else { } else {
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
ini_set('track_errors', $ini); @ini_set('track_errors', $ini);
} }
if (!$this->connection) { if (!$this->connection) {
@ -229,7 +229,7 @@ class DB_fbsql extends DB_common
} }
// Determine which queries that should return data, and which // Determine which queries that should return data, and which
// should return an error code only. // should return an error code only.
if (DB::isManip($query)) { if ($this->_checkManip($query)) {
return DB_OK; return DB_OK;
} }
return $result; return $result;
@ -320,7 +320,7 @@ class DB_fbsql extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @fbsql_free_result($result); return is_resource($result) ? fbsql_free_result($result) : false;
} }
// }}} // }}}
@ -353,7 +353,7 @@ class DB_fbsql extends DB_common
*/ */
function commit() function commit()
{ {
@fbsql_commit(); @fbsql_commit($this->connection);
} }
// }}} // }}}
@ -366,7 +366,7 @@ class DB_fbsql extends DB_common
*/ */
function rollback() function rollback()
{ {
@fbsql_rollback(); @fbsql_rollback($this->connection);
} }
// }}} // }}}
@ -431,7 +431,7 @@ class DB_fbsql extends DB_common
*/ */
function affectedRows() function affectedRows()
{ {
if (DB::isManip($this->last_query)) { if ($this->_last_query_manip) {
$result = @fbsql_affected_rows($this->connection); $result = @fbsql_affected_rows($this->connection);
} else { } else {
$result = 0; $result = 0;
@ -543,7 +543,7 @@ class DB_fbsql extends DB_common
*/ */
function modifyLimitQuery($query, $from, $count, $params = array()) function modifyLimitQuery($query, $from, $count, $params = array())
{ {
if (DB::isManip($query)) { if (DB::isManip($query) || $this->_next_query_manip) {
return preg_replace('/^([\s(])*SELECT/i', return preg_replace('/^([\s(])*SELECT/i',
"\\1SELECT TOP($count)", $query); "\\1SELECT TOP($count)", $query);
} else { } else {
@ -553,36 +553,35 @@ class DB_fbsql extends DB_common
} }
// }}} // }}}
// {{{ quoteSmart() // {{{ quoteBoolean()
/** /**
* Formats input so it can be safely used in a query * Formats a boolean value for use within a query in a locale-independent
* manner.
* *
* @param mixed $in the data to be formatted * @param boolean the boolean value to be quoted.
* * @return string the quoted string.
* @return mixed the formatted data. The format depends on the input's * @see DB_common::quoteSmart()
* PHP type: * @since Method available since release 1.7.8.
* + null = the string <samp>NULL</samp> */
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp> function quoteBoolean($boolean) {
* + integer or double = the unquoted number return $boolean ? 'TRUE' : 'FALSE';
* + other (including strings and numeric strings) = }
* the data escaped according to FrontBase's settings
* then encapsulated between single quotes // }}}
// {{{ quoteFloat()
/**
* Formats a float value for use within a query in a locale-independent
* manner.
* *
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart() * @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0 * @since Method available since release 1.7.8.
*/ */
function quoteSmart($in) function quoteFloat($float) {
{ return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'TRUE' : 'FALSE';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
} }
// }}} // }}}

@ -21,7 +21,7 @@
* @package DB * @package DB
* @author Sterling Hughes <sterling@php.net> * @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -47,9 +47,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author Sterling Hughes <sterling@php.net> * @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
* @since Class became stable in Release 1.7.0 * @since Class became stable in Release 1.7.0
*/ */
@ -123,6 +123,7 @@ class DB_ibase extends DB_common
-625 => DB_ERROR_CONSTRAINT_NOT_NULL, -625 => DB_ERROR_CONSTRAINT_NOT_NULL,
-803 => DB_ERROR_CONSTRAINT, -803 => DB_ERROR_CONSTRAINT,
-804 => DB_ERROR_VALUE_COUNT_ON_ROW, -804 => DB_ERROR_VALUE_COUNT_ON_ROW,
// -902 => // Covers too many errors, need to use regex on msg
-904 => DB_ERROR_CONNECT_FAILED, -904 => DB_ERROR_CONNECT_FAILED,
-922 => DB_ERROR_NOSUCHDB, -922 => DB_ERROR_NOSUCHDB,
-923 => DB_ERROR_CONNECT_FAILED, -923 => DB_ERROR_CONNECT_FAILED,
@ -275,7 +276,7 @@ class DB_ibase extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
$query = $this->modifyQuery($query); $query = $this->modifyQuery($query);
$result = @ibase_query($this->connection, $query); $result = @ibase_query($this->connection, $query);
@ -412,7 +413,7 @@ class DB_ibase extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @ibase_free_result($result); return is_resource($result) ? ibase_free_result($result) : false;
} }
// }}} // }}}
@ -420,8 +421,7 @@ class DB_ibase extends DB_common
function freeQuery($query) function freeQuery($query)
{ {
@ibase_free_query($query); return is_resource($query) ? ibase_free_query($query) : false;
return true;
} }
// }}} // }}}
@ -521,8 +521,14 @@ class DB_ibase extends DB_common
$this->last_query = $query; $this->last_query = $query;
$newquery = $this->modifyQuery($newquery); $newquery = $this->modifyQuery($newquery);
$stmt = @ibase_prepare($this->connection, $newquery); $stmt = @ibase_prepare($this->connection, $newquery);
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query); if ($stmt === false) {
$stmt = $this->ibaseRaiseError();
} else {
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query);
}
return $stmt; return $stmt;
} }
@ -547,9 +553,9 @@ class DB_ibase extends DB_common
$data = (array)$data; $data = (array)$data;
$this->last_parameters = $data; $this->last_parameters = $data;
$types =& $this->prepare_types[(int)$stmt]; $types = $this->prepare_types[(int)$stmt];
if (count($types) != count($data)) { if (count($types) != count($data)) {
$tmp =& $this->raiseError(DB_ERROR_MISMATCH); $tmp = $this->raiseError(DB_ERROR_MISMATCH);
return $tmp; return $tmp;
} }
@ -568,7 +574,7 @@ class DB_ibase extends DB_common
} elseif ($types[$i] == DB_PARAM_OPAQUE) { } elseif ($types[$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($data[$key], 'rb'); $fp = @fopen($data[$key], 'rb');
if (!$fp) { if (!$fp) {
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
return $tmp; return $tmp;
} }
$data[$key] = fread($fp, filesize($data[$key])); $data[$key] = fread($fp, filesize($data[$key]));
@ -581,7 +587,7 @@ class DB_ibase extends DB_common
$res = call_user_func_array('ibase_execute', $data); $res = call_user_func_array('ibase_execute', $data);
if (!$res) { if (!$res) {
$tmp =& $this->ibaseRaiseError(); $tmp = $this->ibaseRaiseError();
return $tmp; return $tmp;
} }
/* XXX need this? /* XXX need this?
@ -589,10 +595,13 @@ class DB_ibase extends DB_common
@ibase_commit($this->connection); @ibase_commit($this->connection);
}*/ }*/
$this->last_stmt = $stmt; $this->last_stmt = $stmt;
if ($this->manip_query[(int)$stmt]) { if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) {
$this->_last_query_manip = true;
$this->_next_query_manip = false;
$tmp = DB_OK; $tmp = DB_OK;
} else { } else {
$tmp =& new DB_result($this, $res); $this->_last_query_manip = false;
$tmp = new DB_result($this, $res);
} }
return $tmp; return $tmp;
} }
@ -698,7 +707,7 @@ class DB_ibase extends DB_common
$repeat = 0; $repeat = 0;
do { do {
$this->pushErrorHandling(PEAR_ERROR_RETURN); $this->pushErrorHandling(PEAR_ERROR_RETURN);
$result =& $this->query("SELECT GEN_ID(${sqn}, 1) " $result = $this->query("SELECT GEN_ID(${sqn}, 1) "
. 'FROM RDB$GENERATORS ' . 'FROM RDB$GENERATORS '
. "WHERE RDB\$GENERATOR_NAME='${sqn}'"); . "WHERE RDB\$GENERATOR_NAME='${sqn}'");
$this->popErrorHandling(); $this->popErrorHandling();
@ -856,7 +865,7 @@ class DB_ibase extends DB_common
if ($errno === null) { if ($errno === null) {
$errno = $this->errorCode($this->errorNative()); $errno = $this->errorCode($this->errorNative());
} }
$tmp =& $this->raiseError($errno, null, null, null, @ibase_errmsg()); $tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg());
return $tmp; return $tmp;
} }
@ -925,6 +934,8 @@ class DB_ibase extends DB_common
=> DB_ERROR_ACCESS_VIOLATION, => DB_ERROR_ACCESS_VIOLATION,
'/arithmetic exception, numeric overflow, or string truncation/i' '/arithmetic exception, numeric overflow, or string truncation/i'
=> DB_ERROR_INVALID, => DB_ERROR_INVALID,
'/feature is not supported/i'
=> DB_ERROR_NOT_CAPABLE,
); );
} }

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -46,9 +46,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_ifx extends DB_common class DB_ifx extends DB_common
@ -101,6 +101,7 @@ class DB_ifx extends DB_common
'-236' => DB_ERROR_VALUE_COUNT_ON_ROW, '-236' => DB_ERROR_VALUE_COUNT_ON_ROW,
'-239' => DB_ERROR_CONSTRAINT, '-239' => DB_ERROR_CONSTRAINT,
'-253' => DB_ERROR_SYNTAX, '-253' => DB_ERROR_SYNTAX,
'-268' => DB_ERROR_CONSTRAINT,
'-292' => DB_ERROR_CONSTRAINT_NOT_NULL, '-292' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-310' => DB_ERROR_ALREADY_EXISTS, '-310' => DB_ERROR_ALREADY_EXISTS,
'-316' => DB_ERROR_ALREADY_EXISTS, '-316' => DB_ERROR_ALREADY_EXISTS,
@ -113,6 +114,7 @@ class DB_ifx extends DB_common
'-691' => DB_ERROR_CONSTRAINT, '-691' => DB_ERROR_CONSTRAINT,
'-692' => DB_ERROR_CONSTRAINT, '-692' => DB_ERROR_CONSTRAINT,
'-703' => DB_ERROR_CONSTRAINT_NOT_NULL, '-703' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-1202' => DB_ERROR_DIVZERO,
'-1204' => DB_ERROR_INVALID_DATE, '-1204' => DB_ERROR_INVALID_DATE,
'-1205' => DB_ERROR_INVALID_DATE, '-1205' => DB_ERROR_INVALID_DATE,
'-1206' => DB_ERROR_INVALID_DATE, '-1206' => DB_ERROR_INVALID_DATE,
@ -243,10 +245,10 @@ class DB_ifx extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
$this->affected = null; $this->affected = null;
if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()? if (preg_match('/(SELECT|EXECUTE)/i', $query)) { //TESTME: Use !DB::isManip()?
// the scroll is needed for fetching absolute row numbers // the scroll is needed for fetching absolute row numbers
// in a select query result // in a select query result
$result = @ifx_query($query, $this->connection, IFX_SCROLL); $result = @ifx_query($query, $this->connection, IFX_SCROLL);
@ -268,7 +270,7 @@ class DB_ifx extends DB_common
$this->affected = @ifx_affected_rows($result); $this->affected = @ifx_affected_rows($result);
// Determine which queries should return data, and which // Determine which queries should return data, and which
// should return an error code only. // should return an error code only.
if (preg_match('/(SELECT)/i', $query)) { if (preg_match('/(SELECT|EXECUTE)/i', $query)) {
return $result; return $result;
} }
// XXX Testme: free results inside a transaction // XXX Testme: free results inside a transaction
@ -309,7 +311,7 @@ class DB_ifx extends DB_common
*/ */
function affectedRows() function affectedRows()
{ {
if (DB::isManip($this->last_query)) { if ($this->_last_query_manip) {
return $this->affected; return $this->affected;
} else { } else {
return 0; return 0;
@ -420,7 +422,7 @@ class DB_ifx extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @ifx_free_result($result); return is_resource($result) ? ifx_free_result($result) : false;
} }
// }}} // }}}

@ -21,7 +21,7 @@
* @category Database * @category Database
* @package DB * @package DB
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -45,9 +45,9 @@ require_once 'DB/common.php';
* @category Database * @category Database
* @package DB * @package DB
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
* @since Class not functional until Release 1.7.0 * @since Class not functional until Release 1.7.0
*/ */
@ -153,7 +153,7 @@ class DB_msql extends DB_common
* 'portability' => DB_PORTABILITY_ALL, * 'portability' => DB_PORTABILITY_ALL,
* ); * );
* *
* $db =& DB::connect($dsn, $options); * $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) { * if (PEAR::isError($db)) {
* die($db->getMessage()); * die($db->getMessage());
* } * }
@ -190,10 +190,10 @@ class DB_msql extends DB_common
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
} else { } else {
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
ini_set('track_errors', $ini); @ini_set('track_errors', $ini);
} }
if (!$this->connection) { if (!$this->connection) {
@ -251,7 +251,7 @@ class DB_msql extends DB_common
} }
// Determine which queries that should return data, and which // Determine which queries that should return data, and which
// should return an error code only. // should return an error code only.
if (DB::isManip($query)) { if ($this->_checkManip($query)) {
$this->_result = $result; $this->_result = $result;
return DB_OK; return DB_OK;
} else { } else {
@ -350,7 +350,7 @@ class DB_msql extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @msql_free_result($result); return is_resource($result) ? msql_free_result($result) : false;
} }
// }}} // }}}
@ -443,7 +443,7 @@ class DB_msql extends DB_common
$repeat = false; $repeat = false;
do { do {
$this->pushErrorHandling(PEAR_ERROR_RETURN); $this->pushErrorHandling(PEAR_ERROR_RETURN);
$result =& $this->query("SELECT _seq FROM ${seqname}"); $result = $this->query("SELECT _seq FROM ${seqname}");
$this->popErrorHandling(); $this->popErrorHandling();
if ($ondemand && DB::isError($result) && if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) { $result->getCode() == DB_ERROR_NOSUCHTABLE) {
@ -530,6 +530,22 @@ class DB_msql extends DB_common
return $this->raiseError(DB_ERROR_UNSUPPORTED); return $this->raiseError(DB_ERROR_UNSUPPORTED);
} }
// }}}
// {{{ quoteFloat()
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}} // }}}
// {{{ escapeSimple() // {{{ escapeSimple()
@ -598,6 +614,11 @@ class DB_msql extends DB_common
function errorCode($errormsg) function errorCode($errormsg)
{ {
static $error_regexps; static $error_regexps;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^msql[a-z_]+\(\): /', '', $errormsg);
if (!isset($error_regexps)) { if (!isset($error_regexps)) {
$error_regexps = array( $error_regexps = array(
'/^Access to database denied/i' '/^Access to database denied/i'

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author Sterling Hughes <sterling@php.net> * @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -35,13 +35,21 @@ require_once 'DB/common.php';
* *
* These methods overload the ones declared in DB_common. * These methods overload the ones declared in DB_common.
* *
* DB's mssql driver is only for Microsfoft SQL Server databases.
*
* If you're connecting to a Sybase database, you MUST specify "sybase"
* as the "phptype" in the DSN.
*
* This class only works correctly if you have compiled PHP using
* --with-mssql=[dir_to_FreeTDS].
*
* @category Database * @category Database
* @package DB * @package DB
* @author Sterling Hughes <sterling@php.net> * @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_mssql extends DB_common class DB_mssql extends DB_common
@ -89,19 +97,40 @@ class DB_mssql extends DB_common
*/ */
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX // XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
var $errorcode_map = array( var $errorcode_map = array(
102 => DB_ERROR_SYNTAX,
110 => DB_ERROR_VALUE_COUNT_ON_ROW, 110 => DB_ERROR_VALUE_COUNT_ON_ROW,
155 => DB_ERROR_NOSUCHFIELD, 155 => DB_ERROR_NOSUCHFIELD,
156 => DB_ERROR_SYNTAX,
170 => DB_ERROR_SYNTAX, 170 => DB_ERROR_SYNTAX,
207 => DB_ERROR_NOSUCHFIELD, 207 => DB_ERROR_NOSUCHFIELD,
208 => DB_ERROR_NOSUCHTABLE, 208 => DB_ERROR_NOSUCHTABLE,
245 => DB_ERROR_INVALID_NUMBER, 245 => DB_ERROR_INVALID_NUMBER,
319 => DB_ERROR_SYNTAX,
321 => DB_ERROR_NOSUCHFIELD,
325 => DB_ERROR_SYNTAX,
336 => DB_ERROR_SYNTAX,
515 => DB_ERROR_CONSTRAINT_NOT_NULL, 515 => DB_ERROR_CONSTRAINT_NOT_NULL,
547 => DB_ERROR_CONSTRAINT, 547 => DB_ERROR_CONSTRAINT,
1018 => DB_ERROR_SYNTAX,
1035 => DB_ERROR_SYNTAX,
1913 => DB_ERROR_ALREADY_EXISTS, 1913 => DB_ERROR_ALREADY_EXISTS,
2209 => DB_ERROR_SYNTAX,
2223 => DB_ERROR_SYNTAX,
2248 => DB_ERROR_SYNTAX,
2256 => DB_ERROR_SYNTAX,
2257 => DB_ERROR_SYNTAX,
2627 => DB_ERROR_CONSTRAINT, 2627 => DB_ERROR_CONSTRAINT,
2714 => DB_ERROR_ALREADY_EXISTS, 2714 => DB_ERROR_ALREADY_EXISTS,
3607 => DB_ERROR_DIVZERO,
3701 => DB_ERROR_NOSUCHTABLE, 3701 => DB_ERROR_NOSUCHTABLE,
7630 => DB_ERROR_SYNTAX,
8134 => DB_ERROR_DIVZERO, 8134 => DB_ERROR_DIVZERO,
9303 => DB_ERROR_SYNTAX,
9317 => DB_ERROR_SYNTAX,
9318 => DB_ERROR_SYNTAX,
9331 => DB_ERROR_SYNTAX,
9332 => DB_ERROR_SYNTAX,
15253 => DB_ERROR_SYNTAX,
); );
/** /**
@ -244,7 +273,7 @@ class DB_mssql extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
if (!@mssql_select_db($this->_db, $this->connection)) { if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
@ -316,7 +345,7 @@ class DB_mssql extends DB_common
} }
} }
if ($fetchmode & DB_FETCHMODE_ASSOC) { if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @mssql_fetch_array($result, MSSQL_ASSOC); $arr = @mssql_fetch_assoc($result);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER); $arr = array_change_key_case($arr, CASE_LOWER);
} }
@ -353,7 +382,7 @@ class DB_mssql extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @mssql_free_result($result); return is_resource($result) ? mssql_free_result($result) : false;
} }
// }}} // }}}
@ -483,7 +512,7 @@ class DB_mssql extends DB_common
*/ */
function affectedRows() function affectedRows()
{ {
if (DB::isManip($this->last_query)) { if ($this->_last_query_manip) {
$res = @mssql_query('select @@rowcount', $this->connection); $res = @mssql_query('select @@rowcount', $this->connection);
if (!$res) { if (!$res) {
return $this->mssqlRaiseError(); return $this->mssqlRaiseError();
@ -537,7 +566,15 @@ class DB_mssql extends DB_common
return $this->raiseError($result); return $this->raiseError($result);
} }
} elseif (!DB::isError($result)) { } elseif (!DB::isError($result)) {
$result =& $this->query("SELECT @@IDENTITY FROM $seqname"); $result = $this->query("SELECT IDENT_CURRENT('$seqname')");
if (DB::isError($result)) {
/* Fallback code for MS SQL Server 7.0, which doesn't have
* IDENT_CURRENT. This is *not* safe for concurrent
* requests, and really, if you're using it, you're in a
* world of hurt. Nevertheless, it's here to ensure BC. See
* bug #181 for the gory details.*/
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
}
$repeat = 0; $repeat = 0;
} else { } else {
$repeat = false; $repeat = false;
@ -745,16 +782,22 @@ class DB_mssql extends DB_common
} }
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
if ($got_string) {
$flags = $this->_mssql_field_flags($result,
@mssql_field_name($id, $i));
if (DB::isError($flags)) {
return $flags;
}
} else {
$flags = '';
}
$res[$i] = array( $res[$i] = array(
'table' => $got_string ? $case_func($result) : '', 'table' => $got_string ? $case_func($result) : '',
'name' => $case_func(@mssql_field_name($id, $i)), 'name' => $case_func(@mssql_field_name($id, $i)),
'type' => @mssql_field_type($id, $i), 'type' => @mssql_field_type($id, $i),
'len' => @mssql_field_length($id, $i), 'len' => @mssql_field_length($id, $i),
// We only support flags for table 'flags' => $flags,
'flags' => $got_string
? $this->_mssql_field_flags($result,
@mssql_field_name($id, $i))
: '',
); );
if ($mode & DB_TABLEINFO_ORDER) { if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i; $res['order'][$res[$i]['name']] = $i;
@ -805,7 +848,10 @@ class DB_mssql extends DB_common
$tableName = $table; $tableName = $table;
// get unique and primary keys // get unique and primary keys
$res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC); $res = $this->getAll("EXEC SP_HELPINDEX $table", DB_FETCHMODE_ASSOC);
if (DB::isError($res)) {
return $res;
}
foreach ($res as $val) { foreach ($res as $val) {
$keys = explode(', ', $val['index_keys']); $keys = explode(', ', $val['index_keys']);
@ -828,7 +874,10 @@ class DB_mssql extends DB_common
} }
// get auto_increment, not_null and timestamp // get auto_increment, not_null and timestamp
$res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC); $res = $this->getAll("EXEC SP_COLUMNS $table", DB_FETCHMODE_ASSOC);
if (DB::isError($res)) {
return $res;
}
foreach ($res as $val) { foreach ($res as $val) {
$val = array_change_key_case($val, CASE_LOWER); $val = array_change_key_case($val, CASE_LOWER);

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -39,9 +39,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_mysql extends DB_common class DB_mysql extends DB_common
@ -111,6 +111,9 @@ class DB_mysql extends DB_common
1146 => DB_ERROR_NOSUCHTABLE, 1146 => DB_ERROR_NOSUCHTABLE,
1216 => DB_ERROR_CONSTRAINT, 1216 => DB_ERROR_CONSTRAINT,
1217 => DB_ERROR_CONSTRAINT, 1217 => DB_ERROR_CONSTRAINT,
1356 => DB_ERROR_DIVZERO,
1451 => DB_ERROR_CONSTRAINT,
1452 => DB_ERROR_CONSTRAINT,
); );
/** /**
@ -236,10 +239,10 @@ class DB_mysql extends DB_common
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
} else { } else {
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
ini_set('track_errors', $ini); @ini_set('track_errors', $ini);
} }
if (!$this->connection) { if (!$this->connection) {
@ -297,7 +300,7 @@ class DB_mysql extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
$query = $this->modifyQuery($query); $query = $this->modifyQuery($query);
if ($this->_db) { if ($this->_db) {
@ -419,7 +422,7 @@ class DB_mysql extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @mysql_free_result($result); return is_resource($result) ? mysql_free_result($result) : false;
} }
// }}} // }}}
@ -555,7 +558,7 @@ class DB_mysql extends DB_common
*/ */
function affectedRows() function affectedRows()
{ {
if (DB::isManip($this->last_query)) { if ($this->_last_query_manip) {
return @mysql_affected_rows($this->connection); return @mysql_affected_rows($this->connection);
} else { } else {
return 0; return 0;
@ -752,9 +755,10 @@ class DB_mysql extends DB_common
/** /**
* Quotes a string so it can be safely used as a table or column name * Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
* *
* MySQL can't handle the backtick character (<kbd>`</kbd>) in * WARNING: Older versions of MySQL can't handle the backtick
* table or column names. * character (<kbd>`</kbd>) in table or column names.
* *
* @param string $str identifier name to be quoted * @param string $str identifier name to be quoted
* *
@ -765,7 +769,7 @@ class DB_mysql extends DB_common
*/ */
function quoteIdentifier($str) function quoteIdentifier($str)
{ {
return '`' . $str . '`'; return '`' . str_replace('`', '``', $str) . '`';
} }
// }}} // }}}
@ -852,7 +856,7 @@ class DB_mysql extends DB_common
*/ */
function modifyLimitQuery($query, $from, $count, $params = array()) function modifyLimitQuery($query, $from, $count, $params = array())
{ {
if (DB::isManip($query)) { if (DB::isManip($query) || $this->_next_query_manip) {
return $query . " LIMIT $count"; return $query . " LIMIT $count";
} else { } else {
return $query . " LIMIT $from, $count"; return $query . " LIMIT $from, $count";
@ -928,12 +932,19 @@ class DB_mysql extends DB_common
function tableInfo($result, $mode = null) function tableInfo($result, $mode = null)
{ {
if (is_string($result)) { if (is_string($result)) {
// Fix for bug #11580.
if ($this->_db) {
if (!@mysql_select_db($this->_db, $this->connection)) {
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
}
}
/* /*
* Probably received a table name. * Probably received a table name.
* Create a result resource identifier. * Create a result resource identifier.
*/ */
$id = @mysql_list_fields($this->dsn['database'], $id = @mysql_query("SELECT * FROM $result LIMIT 0",
$result, $this->connection); $this->connection);
$got_string = true; $got_string = true;
} elseif (isset($result->result)) { } elseif (isset($result->result)) {
/* /*

@ -17,7 +17,7 @@
* @category Database * @category Database
* @package DB * @package DB
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -41,9 +41,9 @@ require_once 'DB/common.php';
* @category Database * @category Database
* @package DB * @package DB
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
* @since Class functional since Release 1.6.3 * @since Class functional since Release 1.6.3
*/ */
@ -114,6 +114,9 @@ class DB_mysqli extends DB_common
1146 => DB_ERROR_NOSUCHTABLE, 1146 => DB_ERROR_NOSUCHTABLE,
1216 => DB_ERROR_CONSTRAINT, 1216 => DB_ERROR_CONSTRAINT,
1217 => DB_ERROR_CONSTRAINT, 1217 => DB_ERROR_CONSTRAINT,
1356 => DB_ERROR_DIVZERO,
1451 => DB_ERROR_CONSTRAINT,
1452 => DB_ERROR_CONSTRAINT,
); );
/** /**
@ -210,6 +213,10 @@ class DB_mysqli extends DB_common
MYSQLI_TYPE_VAR_STRING => 'varchar', MYSQLI_TYPE_VAR_STRING => 'varchar',
MYSQLI_TYPE_STRING => 'char', MYSQLI_TYPE_STRING => 'char',
MYSQLI_TYPE_GEOMETRY => 'geometry', MYSQLI_TYPE_GEOMETRY => 'geometry',
/* These constants are conditionally compiled in ext/mysqli, so we'll
* define them by number rather than constant. */
16 => 'bit',
246 => 'decimal',
); );
@ -264,7 +271,7 @@ class DB_mysqli extends DB_common
* 'ssl' => true, * 'ssl' => true,
* ); * );
* *
* $db =& DB::connect($dsn, $options); * $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) { * if (PEAR::isError($db)) {
* die($db->getMessage()); * die($db->getMessage());
* } * }
@ -287,10 +294,10 @@ class DB_mysqli extends DB_common
} }
$ini = ini_get('track_errors'); $ini = ini_get('track_errors');
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$php_errormsg = ''; $php_errormsg = '';
if ($this->getOption('ssl') === true) { if (((int) $this->getOption('ssl')) === 1) {
$init = mysqli_init(); $init = mysqli_init();
mysqli_ssl_set( mysqli_ssl_set(
$init, $init,
@ -322,7 +329,7 @@ class DB_mysqli extends DB_common
); );
} }
ini_set('track_errors', $ini); @ini_set('track_errors', $ini);
if (!$this->connection) { if (!$this->connection) {
if (($err = @mysqli_connect_error()) != '') { if (($err = @mysqli_connect_error()) != '') {
@ -372,7 +379,7 @@ class DB_mysqli extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
$query = $this->modifyQuery($query); $query = $this->modifyQuery($query);
if ($this->_db) { if ($this->_db) {
@ -490,7 +497,7 @@ class DB_mysqli extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @mysqli_free_result($result); return is_resource($result) ? mysqli_free_result($result) : false;
} }
// }}} // }}}
@ -626,7 +633,7 @@ class DB_mysqli extends DB_common
*/ */
function affectedRows() function affectedRows()
{ {
if (DB::isManip($this->last_query)) { if ($this->_last_query_manip) {
return @mysqli_affected_rows($this->connection); return @mysqli_affected_rows($this->connection);
} else { } else {
return 0; return 0;
@ -823,9 +830,10 @@ class DB_mysqli extends DB_common
/** /**
* Quotes a string so it can be safely used as a table or column name * Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
* *
* MySQL can't handle the backtick character (<kbd>`</kbd>) in * WARNING: Older versions of MySQL can't handle the backtick
* table or column names. * character (<kbd>`</kbd>) in table or column names.
* *
* @param string $str identifier name to be quoted * @param string $str identifier name to be quoted
* *
@ -836,7 +844,7 @@ class DB_mysqli extends DB_common
*/ */
function quoteIdentifier($str) function quoteIdentifier($str)
{ {
return '`' . $str . '`'; return '`' . str_replace('`', '``', $str) . '`';
} }
// }}} // }}}
@ -878,7 +886,7 @@ class DB_mysqli extends DB_common
*/ */
function modifyLimitQuery($query, $from, $count, $params = array()) function modifyLimitQuery($query, $from, $count, $params = array())
{ {
if (DB::isManip($query)) { if (DB::isManip($query) || $this->_next_query_manip) {
return $query . " LIMIT $count"; return $query . " LIMIT $count";
} else { } else {
return $query . " LIMIT $from, $count"; return $query . " LIMIT $from, $count";
@ -954,6 +962,13 @@ class DB_mysqli extends DB_common
function tableInfo($result, $mode = null) function tableInfo($result, $mode = null)
{ {
if (is_string($result)) { if (is_string($result)) {
// Fix for bug #11580.
if ($this->_db) {
if (!@mysqli_select_db($this->connection, $this->_db)) {
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
}
}
/* /*
* Probably received a table name. * Probably received a table name.
* Create a result resource identifier. * Create a result resource identifier.
@ -1015,7 +1030,8 @@ class DB_mysqli extends DB_common
'type' => isset($this->mysqli_types[$tmp->type]) 'type' => isset($this->mysqli_types[$tmp->type])
? $this->mysqli_types[$tmp->type] ? $this->mysqli_types[$tmp->type]
: 'unknown', : 'unknown',
'len' => $tmp->max_length, // http://bugs.php.net/?id=36579
'len' => $tmp->length,
'flags' => $flags, 'flags' => $flags,
); );

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author James L. Pine <jlp@valinux.com> * @author James L. Pine <jlp@valinux.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -45,9 +45,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author James L. Pine <jlp@valinux.com> * @author James L. Pine <jlp@valinux.com>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_oci8 extends DB_common class DB_oci8 extends DB_common
@ -94,24 +94,25 @@ class DB_oci8 extends DB_common
* @var array * @var array
*/ */
var $errorcode_map = array( var $errorcode_map = array(
1 => DB_ERROR_CONSTRAINT, 1 => DB_ERROR_CONSTRAINT,
900 => DB_ERROR_SYNTAX, 900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD, 904 => DB_ERROR_NOSUCHFIELD,
913 => DB_ERROR_VALUE_COUNT_ON_ROW, 913 => DB_ERROR_VALUE_COUNT_ON_ROW,
921 => DB_ERROR_SYNTAX, 921 => DB_ERROR_SYNTAX,
923 => DB_ERROR_SYNTAX, 923 => DB_ERROR_SYNTAX,
942 => DB_ERROR_NOSUCHTABLE, 942 => DB_ERROR_NOSUCHTABLE,
955 => DB_ERROR_ALREADY_EXISTS, 955 => DB_ERROR_ALREADY_EXISTS,
1400 => DB_ERROR_CONSTRAINT_NOT_NULL, 1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
1401 => DB_ERROR_INVALID, 1401 => DB_ERROR_INVALID,
1407 => DB_ERROR_CONSTRAINT_NOT_NULL, 1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
1418 => DB_ERROR_NOT_FOUND, 1418 => DB_ERROR_NOT_FOUND,
1476 => DB_ERROR_DIVZERO, 1476 => DB_ERROR_DIVZERO,
1722 => DB_ERROR_INVALID_NUMBER, 1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE, 2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT, 2291 => DB_ERROR_CONSTRAINT,
2292 => DB_ERROR_CONSTRAINT, 2292 => DB_ERROR_CONSTRAINT,
2449 => DB_ERROR_CONSTRAINT, 2449 => DB_ERROR_CONSTRAINT,
12899 => DB_ERROR_INVALID,
); );
/** /**
@ -160,6 +161,13 @@ class DB_oci8 extends DB_common
*/ */
var $manip_query = array(); var $manip_query = array();
/**
* Store of prepared SQL queries.
* @var array
* @access private
*/
var $_prepared_queries = array();
// }}} // }}}
// {{{ constructor // {{{ constructor
@ -216,6 +224,13 @@ class DB_oci8 extends DB_common
$this->dbsyntax = $dsn['dbsyntax']; $this->dbsyntax = $dsn['dbsyntax'];
} }
// Backwards compatibility with DB < 1.7.0
if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
$db = $dsn['hostspec'];
} else {
$db = $dsn['database'];
}
if (function_exists('oci_connect')) { if (function_exists('oci_connect')) {
if (isset($dsn['new_link']) if (isset($dsn['new_link'])
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true)) && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
@ -225,12 +240,8 @@ class DB_oci8 extends DB_common
$connect_function = $persistent ? 'oci_pconnect' $connect_function = $persistent ? 'oci_pconnect'
: 'oci_connect'; : 'oci_connect';
} }
if (isset($this->dsn['port']) && $this->dsn['port']) {
// Backwards compatibility with DB < 1.7.0 $db = '//'.$db.':'.$this->dsn['port'];
if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
$db = $dsn['hostspec'];
} else {
$db = $dsn['database'];
} }
$char = empty($dsn['charset']) ? null : $dsn['charset']; $char = empty($dsn['charset']) ? null : $dsn['charset'];
@ -248,10 +259,10 @@ class DB_oci8 extends DB_common
} }
} else { } else {
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
if ($dsn['hostspec']) { if ($db) {
$this->connection = @$connect_function($dsn['username'], $this->connection = @$connect_function($dsn['username'],
$dsn['password'], $dsn['password'],
$dsn['hostspec']); $db);
} elseif ($dsn['username'] || $dsn['password']) { } elseif ($dsn['username'] || $dsn['password']) {
$this->connection = @$connect_function($dsn['username'], $this->connection = @$connect_function($dsn['username'],
$dsn['password']); $dsn['password']);
@ -322,7 +333,7 @@ class DB_oci8 extends DB_common
return $this->oci8RaiseError($result); return $this->oci8RaiseError($result);
} }
$this->last_stmt = $result; $this->last_stmt = $result;
if (DB::isManip($query)) { if ($this->_checkManip($query)) {
return DB_OK; return DB_OK;
} else { } else {
@ocisetprefetch($result, $this->options['result_buffering']); @ocisetprefetch($result, $this->options['result_buffering']);
@ -415,7 +426,7 @@ class DB_oci8 extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @OCIFreeStatement($result); return is_resource($result) ? OCIFreeStatement($result) : false;
} }
/** /**
@ -476,20 +487,18 @@ class DB_oci8 extends DB_common
$save_query = $this->last_query; $save_query = $this->last_query;
$save_stmt = $this->last_stmt; $save_stmt = $this->last_stmt;
if (count($this->_data)) { $count = $this->query($countquery);
$smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
$count = $this->execute($smt, $this->_data); // Restore the last query and statement.
} else { $this->last_query = $save_query;
$count =& $this->query($countquery); $this->last_stmt = $save_stmt;
}
if (DB::isError($count) || if (DB::isError($count) ||
DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
{ {
$this->last_query = $save_query;
$this->last_stmt = $save_stmt;
return $this->raiseError(DB_ERROR_NOT_CAPABLE); return $this->raiseError(DB_ERROR_NOT_CAPABLE);
} }
return $row[0]; return $row[0];
} }
return $this->raiseError(DB_ERROR_NOT_CAPABLE); return $this->raiseError(DB_ERROR_NOT_CAPABLE);
@ -590,6 +599,7 @@ class DB_oci8 extends DB_common
} }
$this->prepare_types[(int)$stmt] = $types; $this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query); $this->manip_query[(int)$stmt] = DB::isManip($query);
$this->_prepared_queries[(int)$stmt] = $newquery;
return $stmt; return $stmt;
} }
@ -620,11 +630,12 @@ class DB_oci8 extends DB_common
{ {
$data = (array)$data; $data = (array)$data;
$this->last_parameters = $data; $this->last_parameters = $data;
$this->last_query = $this->_prepared_queries[(int)$stmt];
$this->_data = $data; $this->_data = $data;
$types =& $this->prepare_types[(int)$stmt]; $types = $this->prepare_types[(int)$stmt];
if (count($types) != count($data)) { if (count($types) != count($data)) {
$tmp =& $this->raiseError(DB_ERROR_MISMATCH); $tmp = $this->raiseError(DB_ERROR_MISMATCH);
return $tmp; return $tmp;
} }
@ -643,16 +654,23 @@ class DB_oci8 extends DB_common
} elseif ($types[$i] == DB_PARAM_OPAQUE) { } elseif ($types[$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($data[$key], 'rb'); $fp = @fopen($data[$key], 'rb');
if (!$fp) { if (!$fp) {
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); $tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
return $tmp; return $tmp;
} }
$data[$key] = fread($fp, filesize($data[$key])); $data[$key] = fread($fp, filesize($data[$key]));
fclose($fp); fclose($fp);
} elseif ($types[$i] == DB_PARAM_SCALAR) {
// Floats have to be converted to a locale-neutral
// representation.
if (is_float($data[$key])) {
$data[$key] = $this->quoteFloat($data[$key]);
}
} }
if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
$tmp = $this->oci8RaiseError($stmt); $tmp = $this->oci8RaiseError($stmt);
return $tmp; return $tmp;
} }
$this->last_query = str_replace(':bind'.$i, $this->quoteSmart($data[$key]), $this->last_query);
$i++; $i++;
} }
if ($this->autocommit) { if ($this->autocommit) {
@ -665,11 +683,14 @@ class DB_oci8 extends DB_common
return $tmp; return $tmp;
} }
$this->last_stmt = $stmt; $this->last_stmt = $stmt;
if ($this->manip_query[(int)$stmt]) { if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) {
$this->_last_query_manip = true;
$this->_next_query_manip = false;
$tmp = DB_OK; $tmp = DB_OK;
} else { } else {
$this->_last_query_manip = false;
@ocisetprefetch($stmt, $this->options['result_buffering']); @ocisetprefetch($stmt, $this->options['result_buffering']);
$tmp =& new DB_result($this, $stmt); $tmp = new DB_result($this, $stmt);
} }
return $tmp; return $tmp;
} }
@ -797,7 +818,7 @@ class DB_oci8 extends DB_common
if (count($params)) { if (count($params)) {
$result = $this->prepare("SELECT * FROM ($query) " $result = $this->prepare("SELECT * FROM ($query) "
. 'WHERE NULL = NULL'); . 'WHERE NULL = NULL');
$tmp =& $this->execute($result, $params); $tmp = $this->execute($result, $params);
} else { } else {
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
@ -857,7 +878,7 @@ class DB_oci8 extends DB_common
$repeat = 0; $repeat = 0;
do { do {
$this->expectError(DB_ERROR_NOSUCHTABLE); $this->expectError(DB_ERROR_NOSUCHTABLE);
$result =& $this->query("SELECT ${seqname}.nextval FROM dual"); $result = $this->query("SELECT ${seqname}.nextval FROM dual");
$this->popExpect(); $this->popExpect();
if ($ondemand && DB::isError($result) && if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) { $result->getCode() == DB_ERROR_NOSUCHTABLE) {
@ -1098,12 +1119,30 @@ class DB_oci8 extends DB_common
return 'SELECT table_name FROM user_tables'; return 'SELECT table_name FROM user_tables';
case 'synonyms': case 'synonyms':
return 'SELECT synonym_name FROM user_synonyms'; return 'SELECT synonym_name FROM user_synonyms';
case 'views':
return 'SELECT view_name FROM user_views';
default: default:
return null; return null;
} }
} }
// }}} // }}}
// {{{ quoteFloat()
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
} }

@ -18,7 +18,7 @@
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -42,9 +42,9 @@ require_once 'DB/common.php';
* @package DB * @package DB
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_odbc extends DB_common class DB_odbc extends DB_common
@ -266,7 +266,7 @@ class DB_odbc extends DB_common
} }
// Determine which queries that should return data, and which // Determine which queries that should return data, and which
// should return an error code only. // should return an error code only.
if (DB::isManip($query)) { if ($this->_checkManip($query)) {
$this->affected = $result; // For affectedRows() $this->affected = $result; // For affectedRows()
return DB_OK; return DB_OK;
} }
@ -367,7 +367,7 @@ class DB_odbc extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @odbc_free_result($result); return is_resource($result) ? odbc_free_result($result) : false;
} }
// }}} // }}}

@ -19,7 +19,7 @@
* @author Rui Hirokawa <hirokawa@php.net> * @author Rui Hirokawa <hirokawa@php.net>
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -41,9 +41,9 @@ require_once 'DB/common.php';
* @author Rui Hirokawa <hirokawa@php.net> * @author Rui Hirokawa <hirokawa@php.net>
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_pgsql extends DB_common class DB_pgsql extends DB_common
@ -193,7 +193,7 @@ class DB_pgsql extends DB_common
* 'portability' => DB_PORTABILITY_ALL, * 'portability' => DB_PORTABILITY_ALL,
* ); * );
* *
* $db =& DB::connect($dsn, $options); * $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) { * if (PEAR::isError($db)) {
* die($db->getMessage()); * die($db->getMessage());
* } * }
@ -277,10 +277,10 @@ class DB_pgsql extends DB_common
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
} else { } else {
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function, $this->connection = @call_user_func_array($connect_function,
$params); $params);
ini_set('track_errors', $ini); @ini_set('track_errors', $ini);
} }
if (!$this->connection) { if (!$this->connection) {
@ -320,7 +320,7 @@ class DB_pgsql extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
$query = $this->modifyQuery($query); $query = $this->modifyQuery($query);
if (!$this->autocommit && $ismanip) { if (!$this->autocommit && $ismanip) {
@ -336,19 +336,26 @@ class DB_pgsql extends DB_common
if (!$result) { if (!$result) {
return $this->pgsqlRaiseError(); return $this->pgsqlRaiseError();
} }
// Determine which queries that should return data, and which
// should return an error code only. /*
* Determine whether queries produce affected rows, result or nothing.
*
* This logic was introduced in version 1.1 of the file by ssb,
* though the regex has been modified slightly since then.
*
* PostgreSQL commands:
* ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
* CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
* GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
* REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
* UNLISTEN, UPDATE, VACUUM
*/
if ($ismanip) { if ($ismanip) {
$this->affected = @pg_affected_rows($result); $this->affected = @pg_affected_rows($result);
return DB_OK; return DB_OK;
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|SHOW)\s/si', $query)) { } elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW)\s/si',
/* PostgreSQL commands: $query))
ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY, {
CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
UNLISTEN, UPDATE, VACUUM
*/
$this->row[(int)$result] = 0; // reset the row counter. $this->row[(int)$result] = 0; // reset the row counter.
$numrows = $this->numRows($result); $numrows = $this->numRows($result);
if (is_object($numrows)) { if (is_object($numrows)) {
@ -471,36 +478,19 @@ class DB_pgsql extends DB_common
} }
// }}} // }}}
// {{{ quoteSmart() // {{{ quoteBoolean()
/** /**
* Formats input so it can be safely used in a query * Formats a boolean value for use within a query in a locale-independent
* * manner.
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data escaped according to MySQL's settings
* then encapsulated between single quotes
* *
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart() * @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0 * @since Method available since release 1.7.8.
*/ */
function quoteSmart($in) function quoteBoolean($boolean) {
{ return $boolean ? 'TRUE' : 'FALSE';
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'TRUE' : 'FALSE';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
} }
// }}} // }}}
@ -512,9 +502,6 @@ class DB_pgsql extends DB_common
* {@internal PostgreSQL treats a backslash as an escape character, * {@internal PostgreSQL treats a backslash as an escape character,
* so they are escaped as well. * so they are escaped as well.
* *
* Not using pg_escape_string() yet because it requires PostgreSQL
* to be at version 7.2 or greater.}}
*
* @param string $str the string to be escaped * @param string $str the string to be escaped
* *
* @return string the escaped string * @return string the escaped string
@ -524,7 +511,21 @@ class DB_pgsql extends DB_common
*/ */
function escapeSimple($str) function escapeSimple($str)
{ {
return str_replace("'", "''", str_replace('\\', '\\\\', $str)); if (function_exists('pg_escape_string')) {
/* This fixes an undocumented BC break in PHP 5.2.0 which changed
* the prototype of pg_escape_string. I'm not thrilled about having
* to sniff the PHP version, quite frankly, but it's the only way
* to deal with the problem. Revision 1.331.2.13.2.10 on
* php-src/ext/pgsql/pgsql.c (PHP_5_2 branch) is to blame, for the
* record. */
if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
return pg_escape_string($this->connection, $str);
} else {
return pg_escape_string($str);
}
} else {
return str_replace("'", "''", str_replace('\\', '\\\\', $str));
}
} }
// }}} // }}}
@ -675,7 +676,7 @@ class DB_pgsql extends DB_common
$repeat = false; $repeat = false;
do { do {
$this->pushErrorHandling(PEAR_ERROR_RETURN); $this->pushErrorHandling(PEAR_ERROR_RETURN);
$result =& $this->query("SELECT NEXTVAL('${seqname}')"); $result = $this->query("SELECT NEXTVAL('${seqname}')");
$this->popErrorHandling(); $this->popErrorHandling();
if ($ondemand && DB::isError($result) && if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) { $result->getCode() == DB_ERROR_NOSUCHTABLE) {
@ -779,6 +780,10 @@ class DB_pgsql extends DB_common
function pgsqlRaiseError($errno = null) function pgsqlRaiseError($errno = null)
{ {
$native = $this->errorNative(); $native = $this->errorNative();
if (!$native) {
$native = 'Database connection has been lost.';
$errno = DB_ERROR_CONNECT_FAILED;
}
if ($errno === null) { if ($errno === null) {
$errno = $this->errorCode($native); $errno = $this->errorCode($native);
} }
@ -815,12 +820,12 @@ class DB_pgsql extends DB_common
static $error_regexps; static $error_regexps;
if (!isset($error_regexps)) { if (!isset($error_regexps)) {
$error_regexps = array( $error_regexps = array(
'/column .* (of relation .*)?does not exist/i'
=> DB_ERROR_NOSUCHFIELD,
'/(relation|sequence|table).*does not exist|class .* not found/i' '/(relation|sequence|table).*does not exist|class .* not found/i'
=> DB_ERROR_NOSUCHTABLE, => DB_ERROR_NOSUCHTABLE,
'/index .* does not exist/' '/index .* does not exist/'
=> DB_ERROR_NOT_FOUND, => DB_ERROR_NOT_FOUND,
'/column .* does not exist/i'
=> DB_ERROR_NOSUCHFIELD,
'/relation .* already exists/i' '/relation .* already exists/i'
=> DB_ERROR_ALREADY_EXISTS, => DB_ERROR_ALREADY_EXISTS,
'/(divide|division) by zero$/i' '/(divide|division) by zero$/i'
@ -976,22 +981,33 @@ class DB_pgsql extends DB_common
{ {
$field_name = @pg_fieldname($resource, $num_field); $field_name = @pg_fieldname($resource, $num_field);
// Check if there's a schema in $table_name and update things
// accordingly.
$from = 'pg_attribute f, pg_class tab, pg_type typ';
if (strpos($table_name, '.') !== false) {
$from .= ', pg_namespace nsp';
list($schema, $table) = explode('.', $table_name);
$tableWhere = "tab.relname = '$table' AND tab.relnamespace = nsp.oid AND nsp.nspname = '$schema'";
} else {
$tableWhere = "tab.relname = '$table_name'";
}
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef $result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
FROM pg_attribute f, pg_class tab, pg_type typ FROM $from
WHERE tab.relname = typ.typname WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid AND typ.typrelid = f.attrelid
AND f.attname = '$field_name' AND f.attname = '$field_name'
AND tab.relname = '$table_name'"); AND $tableWhere");
if (@pg_numrows($result) > 0) { if (@pg_numrows($result) > 0) {
$row = @pg_fetch_row($result, 0); $row = @pg_fetch_row($result, 0);
$flags = ($row[0] == 't') ? 'not_null ' : ''; $flags = ($row[0] == 't') ? 'not_null ' : '';
if ($row[1] == 't') { if ($row[1] == 't') {
$result = @pg_exec($this->connection, "SELECT a.adsrc $result = @pg_exec($this->connection, "SELECT a.adsrc
FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a FROM $from, pg_attrdef a
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
AND f.attrelid = a.adrelid AND f.attname = '$field_name' AND f.attrelid = a.adrelid AND f.attname = '$field_name'
AND tab.relname = '$table_name' AND f.attnum = a.adnum"); AND $tableWhere AND f.attnum = a.adnum");
$row = @pg_fetch_row($result, 0); $row = @pg_fetch_row($result, 0);
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); $num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]);
$flags .= 'default_' . rawurlencode($num) . ' '; $flags .= 'default_' . rawurlencode($num) . ' ';
@ -1000,12 +1016,12 @@ class DB_pgsql extends DB_common
$flags = ''; $flags = '';
} }
$result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey $result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i FROM $from, pg_index i
WHERE tab.relname = typ.typname WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid AND typ.typrelid = f.attrelid
AND f.attrelid = i.indrelid AND f.attrelid = i.indrelid
AND f.attname = '$field_name' AND f.attname = '$field_name'
AND tab.relname = '$table_name'"); AND $tableWhere");
$count = @pg_numrows($result); $count = @pg_numrows($result);
for ($i = 0; $i < $count ; $i++) { for ($i = 0; $i < $count ; $i++) {
@ -1066,6 +1082,9 @@ class DB_pgsql extends DB_common
. ' FROM pg_catalog.pg_tables' . ' FROM pg_catalog.pg_tables'
. ' WHERE schemaname NOT IN' . ' WHERE schemaname NOT IN'
. " ('pg_catalog', 'information_schema', 'pg_toast')"; . " ('pg_catalog', 'information_schema', 'pg_toast')";
case 'schema.views':
return "SELECT schemaname || '.' || viewname from pg_views WHERE schemaname"
. " NOT IN ('information_schema', 'pg_catalog')";
case 'views': case 'views':
// Table cols: viewname | viewowner | definition // Table cols: viewname | viewowner | definition
return 'SELECT viewname from pg_views WHERE schemaname' return 'SELECT viewname from pg_views WHERE schemaname'

@ -19,7 +19,7 @@
* @author Urs Gehrig <urs@circle.ch> * @author Urs Gehrig <urs@circle.ch>
* @author Mika Tuupola <tuupola@appelsiini.net> * @author Mika Tuupola <tuupola@appelsiini.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -45,9 +45,9 @@ require_once 'DB/common.php';
* @author Urs Gehrig <urs@circle.ch> * @author Urs Gehrig <urs@circle.ch>
* @author Mika Tuupola <tuupola@appelsiini.net> * @author Mika Tuupola <tuupola@appelsiini.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_sqlite extends DB_common class DB_sqlite extends DB_common
@ -182,7 +182,7 @@ class DB_sqlite extends DB_common
* 'portability' => DB_PORTABILITY_ALL, * 'portability' => DB_PORTABILITY_ALL,
* ); * );
* *
* $db =& DB::connect($dsn, $options); * $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) { * if (PEAR::isError($db)) {
* die($db->getMessage()); * die($db->getMessage());
* } * }
@ -204,7 +204,11 @@ class DB_sqlite extends DB_common
$this->dbsyntax = $dsn['dbsyntax']; $this->dbsyntax = $dsn['dbsyntax'];
} }
if ($dsn['database']) { if (!$dsn['database']) {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
if ($dsn['database'] !== ':memory:') {
if (!file_exists($dsn['database'])) { if (!file_exists($dsn['database'])) {
if (!touch($dsn['database'])) { if (!touch($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
@ -229,14 +233,12 @@ class DB_sqlite extends DB_common
if (!is_readable($dsn['database'])) { if (!is_readable($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
} }
} else {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
} }
$connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
// track_errors must remain on for simpleQuery() // track_errors must remain on for simpleQuery()
ini_set('track_errors', 1); @ini_set('track_errors', 1);
$php_errormsg = ''; $php_errormsg = '';
if (!$this->connection = @$connect_function($dsn['database'])) { if (!$this->connection = @$connect_function($dsn['database'])) {
@ -280,7 +282,7 @@ class DB_sqlite extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
$query = $this->modifyQuery($query); $query = $this->modifyQuery($query);
@ -357,6 +359,16 @@ class DB_sqlite extends DB_common
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER); $arr = array_change_key_case($arr, CASE_LOWER);
} }
/* Remove extraneous " characters from the fields in the result.
* Fixes bug #11716. */
if (is_array($arr) && count($arr) > 0) {
$strippedArr = array();
foreach ($arr as $field => $value) {
$strippedArr[trim($field, '"')] = $value;
}
$arr = $strippedArr;
}
} else { } else {
$arr = @sqlite_fetch_array($result, SQLITE_NUM); $arr = @sqlite_fetch_array($result, SQLITE_NUM);
} }
@ -727,6 +739,11 @@ class DB_sqlite extends DB_common
function errorCode($errormsg) function errorCode($errormsg)
{ {
static $error_regexps; static $error_regexps;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg);
if (!isset($error_regexps)) { if (!isset($error_regexps)) {
$error_regexps = array( $error_regexps = array(
'/^no such table:/' => DB_ERROR_NOSUCHTABLE, '/^no such table:/' => DB_ERROR_NOSUCHTABLE,

@ -16,7 +16,7 @@
* @category Database * @category Database
* @package DB * @package DB
* @author Stig Bakken <stig@php.net> * @author Stig Bakken <stig@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -36,9 +36,9 @@ require_once 'DB.php';
* @category Database * @category Database
* @package DB * @package DB
* @author Stig Bakken <stig@php.net> * @author Stig Bakken <stig@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_storage extends PEAR class DB_storage extends PEAR
@ -293,7 +293,7 @@ class DB_storage extends PEAR
function &create($table, &$data) function &create($table, &$data)
{ {
$classname = strtolower(get_class($this)); $classname = strtolower(get_class($this));
$obj =& new $classname($table); $obj = new $classname($table);
foreach ($data as $name => $value) { foreach ($data as $name => $value) {
$obj->_properties[$name] = true; $obj->_properties[$name] = true;
$obj->$name = &$value; $obj->$name = &$value;
@ -445,6 +445,8 @@ class DB_storage extends PEAR
*/ */
function store() function store()
{ {
$params = array();
$vars = array();
foreach ($this->_changes as $name => $foo) { foreach ($this->_changes as $name => $foo) {
$params[] = &$this->$name; $params[] = &$this->$name;
$vars[] = $name . ' = ?'; $vars[] = $name . ' = ?';

@ -19,7 +19,7 @@
* @author Sterling Hughes <sterling@php.net> * @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio Júnior <floripa@php.net> * @author Antônio Carlos Venâncio Júnior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$ * @version CVS: $Id$
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
@ -44,9 +44,9 @@ require_once 'DB/common.php';
* @author Sterling Hughes <sterling@php.net> * @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio Júnior <floripa@php.net> * @author Antônio Carlos Venâncio Júnior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net> * @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group * @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 * @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@ * @version Release: 1.7.13
* @link http://pear.php.net/package/DB * @link http://pear.php.net/package/DB
*/ */
class DB_sybase extends DB_common class DB_sybase extends DB_common
@ -248,9 +248,9 @@ class DB_sybase extends DB_common
*/ */
function simpleQuery($query) function simpleQuery($query)
{ {
$ismanip = DB::isManip($query); $ismanip = $this->_checkManip($query);
$this->last_query = $query; $this->last_query = $query;
if (!@sybase_select_db($this->_db, $this->connection)) { if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
} }
$query = $this->modifyQuery($query); $query = $this->modifyQuery($query);
@ -370,7 +370,7 @@ class DB_sybase extends DB_common
*/ */
function freeResult($result) function freeResult($result)
{ {
return @sybase_free_result($result); return is_resource($result) ? sybase_free_result($result) : false;
} }
// }}} // }}}
@ -435,7 +435,7 @@ class DB_sybase extends DB_common
*/ */
function affectedRows() function affectedRows()
{ {
if (DB::isManip($this->last_query)) { if ($this->_last_query_manip) {
$result = @sybase_affected_rows($this->connection); $result = @sybase_affected_rows($this->connection);
} else { } else {
$result = 0; $result = 0;
@ -462,7 +462,7 @@ class DB_sybase extends DB_common
function nextId($seq_name, $ondemand = true) function nextId($seq_name, $ondemand = true)
{ {
$seqname = $this->getSequenceName($seq_name); $seqname = $this->getSequenceName($seq_name);
if (!@sybase_select_db($this->_db, $this->connection)) { if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
} }
$repeat = 0; $repeat = 0;
@ -479,7 +479,7 @@ class DB_sybase extends DB_common
return $this->raiseError($result); return $this->raiseError($result);
} }
} elseif (!DB::isError($result)) { } elseif (!DB::isError($result)) {
$result =& $this->query("SELECT @@IDENTITY FROM $seqname"); $result = $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0; $repeat = 0;
} else { } else {
$repeat = false; $repeat = false;
@ -528,6 +528,22 @@ class DB_sybase extends DB_common
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
} }
// }}}
// {{{ quoteFloat()
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}} // }}}
// {{{ autoCommit() // {{{ autoCommit()
@ -558,7 +574,7 @@ class DB_sybase extends DB_common
function commit() function commit()
{ {
if ($this->transaction_opcount > 0) { if ($this->transaction_opcount > 0) {
if (!@sybase_select_db($this->_db, $this->connection)) { if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
} }
$result = @sybase_query('COMMIT', $this->connection); $result = @sybase_query('COMMIT', $this->connection);
@ -581,7 +597,7 @@ class DB_sybase extends DB_common
function rollback() function rollback()
{ {
if ($this->transaction_opcount > 0) { if ($this->transaction_opcount > 0) {
if (!@sybase_select_db($this->_db, $this->connection)) { if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
} }
$result = @sybase_query('ROLLBACK', $this->connection); $result = @sybase_query('ROLLBACK', $this->connection);
@ -642,6 +658,11 @@ class DB_sybase extends DB_common
function errorCode($errormsg) function errorCode($errormsg)
{ {
static $error_regexps; static $error_regexps;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^sybase[a-z_]+\(\): /', '', $errormsg);
if (!isset($error_regexps)) { if (!isset($error_regexps)) {
$error_regexps = array( $error_regexps = array(
'/Incorrect syntax near/' '/Incorrect syntax near/'
@ -674,6 +695,8 @@ class DB_sybase extends DB_common
=> DB_ERROR_ALREADY_EXISTS, => DB_ERROR_ALREADY_EXISTS,
'/^There are fewer columns in the INSERT statement than values specified/i' '/^There are fewer columns in the INSERT statement than values specified/i'
=> DB_ERROR_VALUE_COUNT_ON_ROW, => DB_ERROR_VALUE_COUNT_ON_ROW,
'/Divide by zero/i'
=> DB_ERROR_DIVZERO,
); );
} }
@ -714,7 +737,7 @@ class DB_sybase extends DB_common
* Probably received a table name. * Probably received a table name.
* Create a result resource identifier. * Create a result resource identifier.
*/ */
if (!@sybase_select_db($this->_db, $this->connection)) { if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
} }
$id = @sybase_query("SELECT * FROM $result WHERE 1=0", $id = @sybase_query("SELECT * FROM $result WHERE 1=0",
@ -811,14 +834,24 @@ class DB_sybase extends DB_common
$flags = array(); $flags = array();
$tableName = $table; $tableName = $table;
// get unique/primary keys /* We're running sp_helpindex directly because it doesn't exist in
$res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC); * older versions of ASE -- unfortunately, we can't just use
* DB::isError() because the user may be using callback error
* handling. */
$res = @sybase_query("sp_helpindex $table", $this->connection);
if (!isset($res[0]['index_description'])) { if ($res === false || $res === true) {
// Fake a valid response for BC reasons.
return ''; return '';
} }
foreach ($res as $val) { while (($val = sybase_fetch_assoc($res)) !== false) {
if (!isset($val['index_keys'])) {
/* No useful information returned. Break and be done with
* it, which preserves the pre-1.7.9 behaviour. */
break;
}
$keys = explode(', ', trim($val['index_keys'])); $keys = explode(', ', trim($val['index_keys']));
if (sizeof($keys) > 1) { if (sizeof($keys) > 1) {
@ -834,6 +867,8 @@ class DB_sybase extends DB_common
} }
} }
sybase_free_result($res);
} }
if (array_key_exists($column, $flags)) { if (array_key_exists($column, $flags)) {

Loading…
Cancel
Save