Ugly patch to maintain old DB handle code working quietly

We have to replace this database engine with a modern one
This commit is contained in:
Diogo Cordeiro 2019-04-27 18:21:14 +01:00
parent d75b5d2f4a
commit daa5f87fd4
21 changed files with 7017 additions and 7099 deletions

File diff suppressed because it is too large Load Diff

View File

@ -83,8 +83,15 @@ class DB_DataObject_Cast
*/
public $value;
/**
* Data For time representation ** does not handle timezones!!
*
* @var int hour/minute/second
* @access public
*/
public $hour;
public $minute;
public $second;
/**
* Blob consructor
@ -106,7 +113,6 @@ class DB_DataObject_Cast
return $r;
}
/**
* String consructor (actually use if for ints and everything else!!!
*
@ -146,6 +152,67 @@ class DB_DataObject_Cast
return $r;
}
/**
* DateTime Constructor
*
* create a Cast object from a Date/Time
* Maybe should accept a Date object.!
* NO VALIDATION DONE, although some crappy re-calcing done!
*
* @param vargs... accepts
* noargs (now)
* yyyy-mm-dd HH:MM:SS (Iso)
* array(yyyy,mm,dd,HH,MM,SS)
*
*
* @return bool|object
* @access public
* @author therion 5 at hotmail
*/
public function dateTime()
{
$args = func_get_args();
switch (count($args)) {
case 0: // no args = now!
$datetime = date('Y-m-d G:i:s', mktime());
// no break
case 1:
// continue on from 0 args.
if (!isset($datetime)) {
$datetime = $args[0];
}
$parts = explode(' ', $datetime);
$bits = explode('-', $parts[0]);
$bits = array_merge($bits, explode(':', $parts[1]));
break;
default: // 2 or more..
$bits = $args;
}
if (count($bits) != 6) {
// PEAR ERROR?
return false;
}
$r = DB_DataObject_Cast::date($bits[0], $bits[1], $bits[2]);
if (!$r) {
return $r; // pass thru error (False) - doesnt happen at present!
}
// change the type!
$r->type = 'datetime';
// should we mathematically sort this out..
// (or just assume that no-one's dumb enough to enter 26:90:90 as a time!
$r->hour = $bits[3];
$r->minute = $bits[4];
$r->second = $bits[5];
return $r;
}
/**
* Date Constructor
@ -211,83 +278,6 @@ class DB_DataObject_Cast
return $r;
}
/**
* Data For time representation ** does not handle timezones!!
*
* @var int hour/minute/second
* @access public
*/
public $hour;
public $minute;
public $second;
/**
* DateTime Constructor
*
* create a Cast object from a Date/Time
* Maybe should accept a Date object.!
* NO VALIDATION DONE, although some crappy re-calcing done!
*
* @param vargs... accepts
* noargs (now)
* yyyy-mm-dd HH:MM:SS (Iso)
* array(yyyy,mm,dd,HH,MM,SS)
*
*
* @return object DB_DataObject_Cast
* @access public
* @author therion 5 at hotmail
*/
public function dateTime()
{
$args = func_get_args();
switch (count($args)) {
case 0: // no args = now!
$datetime = date('Y-m-d G:i:s', mktime());
// no break
case 1:
// continue on from 0 args.
if (!isset($datetime)) {
$datetime = $args[0];
}
$parts = explode(' ', $datetime);
$bits = explode('-', $parts[0]);
$bits = array_merge($bits, explode(':', $parts[1]));
break;
default: // 2 or more..
$bits = $args;
}
if (count($bits) != 6) {
// PEAR ERROR?
return false;
}
$r = DB_DataObject_Cast::date($bits[0], $bits[1], $bits[2]);
if (!$r) {
return $r; // pass thru error (False) - doesnt happen at present!
}
// change the type!
$r->type = 'datetime';
// should we mathematically sort this out..
// (or just assume that no-one's dumb enough to enter 26:90:90 as a time!
$r->hour = $bits[3];
$r->minute = $bits[4];
$r->second = $bits[5];
return $r;
}
/**
* time Constructor
*
@ -301,7 +291,7 @@ class DB_DataObject_Cast
* array(HH,MM,SS)
*
*
* @return object DB_DataObject_Cast
* @return bool|object
* @access public
* @author therion 5 at hotmail
*/
@ -340,12 +330,11 @@ class DB_DataObject_Cast
}
/**
* get the string to use in the SQL statement for this...
*
*
* @param int $to Type (DB_DATAOBJECT_*
* @param bool $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
@ -380,7 +369,7 @@ class DB_DataObject_Cast
// perhaps we should support TEXT fields???
if (!($to & DB_DATAOBJECT_BLOB)) {
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::blob to something other than a blob!');
return (new PEAR)->raiseError('Invalid Cast from a DB_DataObject_Cast::blob to something other than a blob!');
}
switch ($db->dsn["phptype"]) {
@ -407,9 +396,8 @@ class DB_DataObject_Cast
return '0x' . $unpacked['hex'];
default:
return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
return (new PEAR)->raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
}
}
@ -459,7 +447,7 @@ class DB_DataObject_Cast
default:
return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
return (new PEAR)->raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
}
}
@ -484,7 +472,7 @@ class DB_DataObject_Cast
//
if (($to !== false) && !($to & DB_DATAOBJECT_DATE)) {
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a date!'.
return (new PEAR)->raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a date!' .
' (why not just use native features)');
}
return "'{$this->year}-{$this->month}-{$this->day}'";
@ -511,7 +499,7 @@ class DB_DataObject_Cast
// perhaps we should support TEXT fields???
if (($to !== false) &&
!($to & (DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME))) {
return PEAR::raiseError('Invalid Cast from a ' .
return (new PEAR)->raiseError('Invalid Cast from a ' .
' DB_DataObject_Cast::dateTime to something other than a datetime!' .
' (try using native features)');
}
@ -538,7 +526,7 @@ class DB_DataObject_Cast
// in blobs can only be cast to blobs.!
// perhaps we should support TEXT fields???
if (($to !== false) && !($to & DB_DATAOBJECT_TIME)) {
return PEAR::raiseError('Invalid Cast from a' .
return (new PEAR)->raiseError('Invalid Cast from a' .
' DB_DataObject_Cast::time to something other than a time!' .
' (try using native features)');
}

View File

@ -29,21 +29,21 @@ class DB_DataObject_Error extends PEAR_Error
/**
* DB_DataObject_Error constructor.
*
* @param string $message
* @param mixed $code DB error code, or string with error message.
* @param integer $mode what "error mode" to operate in
* @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER
* @param mixed $debuginfo additional debug info, such as the last query
*
* @access public
*
* @see PEAR_Error
*/
public function DB_DataObject_Error(
public function __construct(
$message = '',
$code = DB_ERROR,
$mode = PEAR_ERROR_RETURN,
$level = E_USER_NOTICE
) {
)
{
$this->PEAR_Error('DB_DataObject Error: ' . $message, $code, $mode, $level);
}

File diff suppressed because it is too large Load Diff

View File

@ -80,10 +80,10 @@ class DB_DataObject_Links
* Constructor
* -- good ole style..
* @param {DB_DataObject} do DataObject to apply to.
* @param {Array} cfg Configuration (basically properties of this object)
* @param array $cfg
*/
public function DB_DataObject_Links($do, $cfg= array())
public function __construct($do, $cfg = array())
{
// check if do is set!!!?
$this->do = $do;
@ -93,154 +93,6 @@ class DB_DataObject_Links
}
}
/**
* return name from related object
*
* The relies on a <dbname>.links.ini file, unless you specify the arguments.
*
* you can also use $this->getLink('thisColumnName','otherTable','otherTableColumnName')
*
*
* @param string $field|array either row or row.xxxxx or links spec.
* @param string|DB_DataObject $table (optional) name of table to look up value in
* @param string $link (optional) name of column in other table to match
* @author Tim White <tim@cyface.com>
* @access public
* @return mixed object on success false on failure or '0' when not linked
*/
public function getLink($field, $table= false, $link='')
{
static $cache = array();
// GUESS THE LINKED TABLE.. (if found - recursevly call self)
if ($table == false) {
$info = $this->linkInfo($field);
if ($info) {
return $this->getLink($field, $info[0], $link === false ? $info[1] : $link);
}
// no links defined.. - use borked BC method...
// use the old _ method - this shouldnt happen if called via getLinks()
if (!($p = strpos($field, '_'))) {
return false;
}
$table = substr($field, 0, $p);
return $this->getLink($field, $table);
}
$tn = is_string($table) ? $table : $table->tableName();
if (!isset($this->do->$field)) {
$this->do->raiseError("getLink: row not set $field", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
// check to see if we know anything about this table..
if (empty($this->do->$field) || $this->do->$field < 0) {
return 0; // no record.
}
if ($this->cached && isset($cache[$tn.':'. $link .':'. $this->do->$field])) {
return $cache[$tn.':'. $link .':'. $this->do->$field];
}
$obj = is_string($table) ? $this->do->factory($tn) : $table;
;
if (!is_a($obj, 'DB_DataObject')) {
$this->do->raiseError(
"getLink:Could not find class for row $field, table $tn",
DB_DATAOBJECT_ERROR_INVALIDCONFIG
);
return false;
}
// -1 or 0 -- no referenced record..
$ret = false;
if ($link) {
if ($obj->get($link, $this->do->$field)) {
$ret = $obj;
}
// this really only happens when no link config is set (old BC stuff)
} elseif ($obj->get($this->do->$field)) {
$ret= $obj;
}
if ($this->cached) {
$cache[$tn.':'. $link .':'. $this->do->$field] = $ret;
}
return $ret;
}
/**
* get link information for a field or field specification
*
* alll link (and join methods accept the 'link' info ) in various ways
* string : 'field' = which field to get (uses ???.links.ini to work out what)
* array(2) : 'field', 'table:remote_col' << just like the links.ini def.
* array(3) : 'field', $dataobject, 'remote_col' (handy for joinAdd to do nested joins.)
*
* @param string|array $field or link spec to use.
* @return (false|array) array of dataobject and linked field or false.
*
*
*/
public function linkInfo($field)
{
if (is_array($field)) {
if (count($field) == 3) {
// array with 3 args:
// local_col , dataobject, remote_col
return array(
$field[1],
$field[2],
$field[0]
);
}
list($table, $link) = explode(':', $field[1]);
return array(
$this->do->factory($table),
$link,
$field[0]
);
}
// work out the link.. (classic way)
$links = $this->do->links();
if (empty($links) || !is_array($links)) {
return false;
}
if (!isset($links[$field])) {
return false;
}
list($table, $link) = explode(':', $links[$field]);
//??? needed???
if ($p = strpos($field, ".")) {
$field = substr($field, 0, $p);
}
return array(
$this->do->factory($table),
$link,
$field
);
}
/**
* a generic geter/setter provider..
*
@ -255,9 +107,9 @@ class DB_DataObject_Links
*
*
* @param string|array $field the field to fetch or link spec.
* @params array $args the arguments sent to the getter setter
* @param array $args
* @return mixed true of false on set, the object on getter.
*
* @params array $args the arguments sent to the getter setter
*/
public function link($field, $args = array())
{
@ -310,6 +162,151 @@ class DB_DataObject_Links
$this->do->$field = $assign->{$info[1]};
return true;
}
/**
* get link information for a field or field specification
*
* alll link (and join methods accept the 'link' info ) in various ways
* string : 'field' = which field to get (uses ???.links.ini to work out what)
* array(2) : 'field', 'table:remote_col' << just like the links.ini def.
* array(3) : 'field', $dataobject, 'remote_col' (handy for joinAdd to do nested joins.)
*
* @param string|array $field or link spec to use.
* @return array|bool (false|array) array of dataobject and linked field or false.
*
*/
public function linkInfo($field)
{
if (is_array($field)) {
if (count($field) == 3) {
// array with 3 args:
// local_col , dataobject, remote_col
return array(
$field[1],
$field[2],
$field[0]
);
}
list($table, $link) = explode(':', $field[1]);
return array(
$this->do->factory($table),
$link,
$field[0]
);
}
// work out the link.. (classic way)
$links = $this->do->links();
if (empty($links) || !is_array($links)) {
return false;
}
if (!isset($links[$field])) {
return false;
}
list($table, $link) = explode(':', $links[$field]);
//??? needed???
if ($p = strpos($field, ".")) {
$field = substr($field, 0, $p);
}
return array(
$this->do->factory($table),
$link,
$field
);
}
/**
* return name from related object
*
* The relies on a <dbname>.links.ini file, unless you specify the arguments.
*
* you can also use $this->getLink('thisColumnName','otherTable','otherTableColumnName')
*
*
* @param string $field |array either row or row.xxxxx or links spec.
* @param bool $table (optional) name of table to look up value in
* @param string $link (optional) name of column in other table to match
* @return mixed object on success false on failure or '0' when not linked
* @author Tim White <tim@cyface.com>
* @access public
*/
public function getLink($field, $table = false, $link = '')
{
static $cache = array();
// GUESS THE LINKED TABLE.. (if found - recursevly call self)
if ($table == false) {
$info = $this->linkInfo($field);
if ($info) {
return $this->getLink($field, $info[0], $link === false ? $info[1] : $link);
}
// no links defined.. - use borked BC method...
// use the old _ method - this shouldnt happen if called via getLinks()
if (!($p = strpos($field, '_'))) {
return false;
}
$table = substr($field, 0, $p);
return $this->getLink($field, $table);
}
$tn = is_string($table) ? $table : $table->tableName();
if (!isset($this->do->$field)) {
$this->do->raiseError("getLink: row not set $field", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
// check to see if we know anything about this table..
if (empty($this->do->$field) || $this->do->$field < 0) {
return 0; // no record.
}
if ($this->cached && isset($cache[$tn . ':' . $link . ':' . $this->do->$field])) {
return $cache[$tn . ':' . $link . ':' . $this->do->$field];
}
$obj = is_string($table) ? $this->do->factory($tn) : $table;;
if (!is_a($obj, 'DB_DataObject')) {
$this->do->raiseError(
"getLink:Could not find class for row $field, table $tn",
DB_DATAOBJECT_ERROR_INVALIDCONFIG
);
return false;
}
// -1 or 0 -- no referenced record..
$ret = false;
if ($link) {
if ($obj->get($link, $this->do->$field)) {
$ret = $obj;
}
// this really only happens when no link config is set (old BC stuff)
} elseif ($obj->get($this->do->$field)) {
$ret = $obj;
}
if ($this->cached) {
$cache[$tn . ':' . $link . ':' . $this->do->$field] = $ret;
}
return $ret;
}
/**
* load related objects
*
@ -323,9 +320,9 @@ class DB_DataObject_Links
*
*
* @param string format (default _%s) where %s is the table name.
* @return boolean , true on success
* @author Tim White <tim@cyface.com>
* @access public
* @return boolean , true on success
*/
public function applyLinks($format = '_%s')
@ -394,9 +391,9 @@ class DB_DataObject_Links
* @access public
* @param string $field - either column or column.xxxxx
* @param string $table (optional) name of table to look up value in
* @param string $fkey (optional) fetchall key see DB_DataObject::fetchAll()
* @param string $fval (optional)fetchall val DB_DataObject::fetchAll()
* @param string $fval (optional) fetchall method DB_DataObject::fetchAll()
* @param bool $fkey (optional) fetchall key see DB_DataObject::fetchAll()
* @param bool $fval (optional) fetchall method DB_DataObject::fetchAll()
* @param bool $fmethod
* @return array - array of results (empty array on failure)
*
* Example - Getting the related objects
@ -409,7 +406,6 @@ class DB_DataObject_Links
* foreach ($children as $child) {
* echo $child->name, '<br />';
* }
*
*/
public function getLinkArray($field, $table = null, $fkey = false, $fval = false, $fmethod = false)
{

View File

@ -25,32 +25,32 @@
define('DB_DATAOBJECT_NO_OVERLOAD', 1);
//require_once 'DB/DataObject/Generator.php';
require_once 'DB/DataObject/Generator.php';
require_once 'Generator.php';
if (php_sapi_name() != 'cli') {
PEAR::raiseError("\nERROR: You must turn use the cli sapi to run this", null, PEAR_ERROR_DIE);
(new PEAR)->raiseError("\nERROR: You must turn use the cli sapi to run this", null, PEAR_ERROR_DIE);
}
if (!ini_get('register_argc_argv')) {
PEAR::raiseError("\nERROR: You must turn register_argc_argv On in you php.ini file for this to work\neg.\n\nregister_argc_argv = On\n\n", null, PEAR_ERROR_DIE);
(new PEAR)->raiseError("\nERROR: You must turn register_argc_argv On in you php.ini file for this to work\neg.\n\nregister_argc_argv = On\n\n", null, PEAR_ERROR_DIE);
exit;
}
if (!@$_SERVER['argv'][1]) {
PEAR::raiseError("\nERROR: createTable.php usage:\n\n" .$_SERVER['argv'][0] . " example.ini\n\n", null, PEAR_ERROR_DIE);
(new PEAR)->raiseError("\nERROR: createTable.php usage:\n\n" . $_SERVER['argv'][0] . " example.ini\n\n", null, PEAR_ERROR_DIE);
exit;
}
$config = parse_ini_file($_SERVER['argv'][1], true);
foreach ($config as $class => $values) {
$options = &PEAR::getStaticProperty($class, 'options');
$options = &(new PEAR)->getStaticProperty($class, 'options');
$options = $values;
}
$options = &PEAR::getStaticProperty('DB_DataObject', 'options');
$options = &(new PEAR)->getStaticProperty('DB_DataObject', 'options');
if (empty($options)) {
PEAR::raiseError("\nERROR: could not read ini file\n\n", null, PEAR_ERROR_DIE);
(new PEAR)->raiseError("\nERROR: could not read ini file\n\n", null, PEAR_ERROR_DIE);
exit;
}
set_time_limit(0);

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's dbase extension
@ -87,8 +88,7 @@ class DB_dbase extends DB_common
* A mapping of native error codes to DB error codes
* @var array
*/
public $errorcode_map = array(
);
public $errorcode_map = array();
/**
* The raw database connection created by PHP
@ -189,7 +189,7 @@ class DB_dbase extends DB_common
* );
*
* $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* if ((new PEAR)->isError($db)) {
* die($db->getMessage());
* }
* </code>
@ -197,7 +197,7 @@ class DB_dbase extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -371,8 +371,7 @@ class DB_dbase extends DB_common
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @param $foo
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
@ -392,8 +391,7 @@ class DB_dbase extends DB_common
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @param $foo
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
@ -430,7 +428,7 @@ class DB_dbase extends DB_common
* is examined regardless of what is provided here.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's fbsql extension
@ -144,7 +145,7 @@ class DB_fbsql extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -203,6 +204,35 @@ class DB_fbsql extends DB_common
// }}}
// {{{ disconnect()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_fbsql::errorNative(), DB_common::errorCode()
*/
public function fbsqlRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(fbsql_errno($this->connection));
}
return $this->raiseError(
$errno,
null,
null,
null,
@fbsql_error($this->connection)
);
}
// }}}
// {{{ simpleQuery()
/**
* Disconnects from the database server
*
@ -216,7 +246,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ simpleQuery()
// {{{ nextResult()
/**
* Sends a query to the database server
@ -244,7 +274,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ nextResult()
// {{{ fetchInto()
/**
* Move the internal fbsql result pointer to the next available result
@ -261,7 +291,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ freeResult()
/**
* Places a row from the result set into the given array
@ -311,7 +341,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ autoCommit()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -332,7 +362,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ autoCommit()
// {{{ commit()
/**
* Enables or disables automatic commits
@ -349,10 +379,11 @@ class DB_fbsql extends DB_common
} else {
$this->query("SET COMMIT FALSE");
}
return null;
}
// }}}
// {{{ commit()
// {{{ rollback()
/**
* Commits the current transaction
@ -362,10 +393,11 @@ class DB_fbsql extends DB_common
public function commit()
{
@fbsql_commit($this->connection);
return 0;
}
// }}}
// {{{ rollback()
// {{{ numCols()
/**
* Reverts the current transaction
@ -375,10 +407,11 @@ class DB_fbsql extends DB_common
public function rollback()
{
@fbsql_rollback($this->connection);
return 0;
}
// }}}
// {{{ numCols()
// {{{ numRows()
/**
* Gets the number of columns in a result set
@ -389,7 +422,7 @@ class DB_fbsql extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -403,7 +436,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ numRows()
// {{{ affectedRows()
/**
* Gets the number of rows in a result set
@ -414,7 +447,7 @@ class DB_fbsql extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numRows()
*/
@ -428,7 +461,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ affectedRows()
// {{{ nextId()
/**
* Determines the number of rows affected by a data maniuplation query
@ -447,9 +480,6 @@ class DB_fbsql extends DB_common
return $result;
}
// }}}
// {{{ nextId()
/**
* Returns the next free id in a sequence
*
@ -457,7 +487,7 @@ class DB_fbsql extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -489,6 +519,9 @@ class DB_fbsql extends DB_common
return $tmp[0];
}
// }}}
// {{{ dropSequence()
/**
* Creates a new sequence
*
@ -512,7 +545,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ dropSequence()
// {{{ modifyLimitQuery()
/**
* Deletes a sequence
@ -531,7 +564,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ modifyLimitQuery()
// {{{ quoteBoolean()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
@ -567,7 +600,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ quoteBoolean()
// {{{ quoteFloat()
/**
* Formats a boolean value for use within a query in a locale-independent
@ -584,7 +617,7 @@ class DB_fbsql extends DB_common
}
// }}}
// {{{ quoteFloat()
// {{{ fbsqlRaiseError()
/**
* Formats a float value for use within a query in a locale-independent
@ -600,35 +633,6 @@ class DB_fbsql extends DB_common
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ fbsqlRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_fbsql::errorNative(), DB_common::errorCode()
*/
public function fbsqlRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(fbsql_errno($this->connection));
}
return $this->raiseError(
$errno,
null,
null,
null,
@fbsql_error($this->connection)
);
}
// }}}
// {{{ errorNative()
@ -655,7 +659,7 @@ class DB_fbsql extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()

View File

@ -30,7 +30,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's interbase extension
@ -210,7 +211,7 @@ class DB_ibase extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -250,6 +251,112 @@ class DB_ibase extends DB_common
// }}}
// {{{ disconnect()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_ibase::errorNative(), DB_ibase::errorCode()
*/
public function &ibaseRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode($this->errorNative());
}
$tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg());
return $tmp;
}
// }}}
// {{{ simpleQuery()
/**
* Maps native error codes to DB's portable ones
*
* @param int $nativecode the error code returned by the DBMS
*
* @return int the portable DB error code. Return DB_ERROR if the
* current driver doesn't have a mapping for the
* $nativecode submitted.
*
* @since Method available since Release 1.7.0
*/
public function errorCode($nativecode = null)
{
if (isset($this->errorcode_map[$nativecode])) {
return $this->errorcode_map[$nativecode];
}
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/generator .* is not defined/'
=> DB_ERROR_SYNTAX, // for compat. w ibase_errcode()
'/violation of [\w ]+ constraint/i'
=> DB_ERROR_CONSTRAINT,
'/table.*(not exist|not found|unknown)/i'
=> DB_ERROR_NOSUCHTABLE,
'/table .* already exists/i'
=> DB_ERROR_ALREADY_EXISTS,
'/unsuccessful metadata update .* failed attempt to store duplicate value/i'
=> DB_ERROR_ALREADY_EXISTS,
'/unsuccessful metadata update .* not found/i'
=> DB_ERROR_NOT_FOUND,
'/validation error for column .* value "\*\*\* null/i'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/conversion error from string/i'
=> DB_ERROR_INVALID_NUMBER,
'/no permission for/i'
=> DB_ERROR_ACCESS_VIOLATION,
'/arithmetic exception, numeric overflow, or string truncation/i'
=> DB_ERROR_INVALID,
'/feature is not supported/i'
=> DB_ERROR_NOT_CAPABLE,
);
}
$errormsg = @ibase_errmsg();
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
return DB_ERROR;
}
// }}}
// {{{ modifyLimitQuery()
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code. NULL if there is no error code.
*
* @since Method available since Release 1.7.0
*/
public function errorNative()
{
if (function_exists('ibase_errcode')) {
return @ibase_errcode();
}
if (preg_match(
'/^Dynamic SQL Error SQL error code = ([0-9-]+)/i',
@ibase_errmsg(),
$m
)) {
return (int)$m[1];
}
return null;
}
// }}}
// {{{ nextResult()
/**
* Disconnects from the database server
*
@ -263,7 +370,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ simpleQuery()
// {{{ fetchInto()
/**
* Sends a query to the database server
@ -297,7 +404,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ modifyLimitQuery()
// {{{ freeResult()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
@ -330,7 +437,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ nextResult()
// {{{ freeQuery()
/**
* Move the internal ibase result pointer to the next available result
@ -347,7 +454,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ affectedRows()
/**
* Places a row from the result set into the given array
@ -399,7 +506,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ numCols()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -420,7 +527,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ freeQuery()
// {{{ prepare()
public function freeQuery($query)
{
@ -428,14 +535,14 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ affectedRows()
// {{{ execute()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*/
public function affectedRows()
{
@ -445,9 +552,6 @@ class DB_ibase extends DB_common
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE);
}
// }}}
// {{{ numCols()
/**
* Gets the number of columns in a result set
*
@ -457,7 +561,7 @@ class DB_ibase extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -471,7 +575,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ prepare()
// {{{ autoCommit()
/**
* Prepares a query for multiple execution with execute().
@ -527,7 +631,7 @@ class DB_ibase extends DB_common
$newquery = substr($newquery, 0, -1);
$this->last_query = $query;
$newquery = $this->modifyQuery($newquery);
$stmt = @ibase_prepare($this->connection, $newquery);
$stmt = @ibase_prepare(/*$this->connection,*/ $newquery);
if ($stmt === false) {
$stmt = $this->ibaseRaiseError();
@ -540,7 +644,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ execute()
// {{{ commit()
/**
* Executes a DB statement prepared with prepare().
@ -613,6 +717,9 @@ class DB_ibase extends DB_common
return $tmp;
}
// }}}
// {{{ rollback()
/**
* Frees the internal resources associated with a prepared query
*
@ -640,7 +747,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ autoCommit()
// {{{ transactionInit()
/**
* Enables or disables automatic commits
@ -657,7 +764,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ commit()
// {{{ nextId()
/**
* Commits the current transaction
@ -670,7 +777,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ rollback()
// {{{ createSequence()
/**
* Reverts the current transaction
@ -683,7 +790,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ transactionInit()
// {{{ dropSequence()
public function transactionInit($trans_args = 0)
{
@ -693,7 +800,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ nextId()
// {{{ _ibaseFieldFlags()
/**
* Returns the next free id in a sequence
@ -702,7 +809,7 @@ class DB_ibase extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -737,7 +844,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ createSequence()
// {{{ ibaseRaiseError()
/**
* Creates a new sequence
@ -760,7 +867,7 @@ class DB_ibase extends DB_common
}
// }}}
// {{{ dropSequence()
// {{{ errorNative()
/**
* Deletes a sequence
@ -780,187 +887,9 @@ class DB_ibase extends DB_common
. "'");
}
// }}}
// {{{ _ibaseFieldFlags()
/**
* Get the column's flags
*
* Supports "primary_key", "unique_key", "not_null", "default",
* "computed" and "blob".
*
* @param string $field_name the name of the field
* @param string $table_name the name of the table
*
* @return string the flags
*
* @access private
*/
public function _ibaseFieldFlags($field_name, $table_name)
{
$sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE'
.' FROM RDB$INDEX_SEGMENTS I'
.' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME'
.' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\''
.' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'';
$result = @ibase_query($this->connection, $sql);
if (!$result) {
return $this->ibaseRaiseError();
}
$flags = '';
if ($obj = @ibase_fetch_object($result)) {
@ibase_free_result($result);
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') {
$flags .= 'primary_key ';
}
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') {
$flags .= 'unique_key ';
}
}
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,'
.' R.RDB$DEFAULT_SOURCE AS DSOURCE,'
.' F.RDB$FIELD_TYPE AS FTYPE,'
.' F.RDB$COMPUTED_SOURCE AS CSOURCE'
.' FROM RDB$RELATION_FIELDS R '
.' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME'
.' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''
.' AND R.RDB$FIELD_NAME=\'' . $field_name . '\'';
$result = @ibase_query($this->connection, $sql);
if (!$result) {
return $this->ibaseRaiseError();
}
if ($obj = @ibase_fetch_object($result)) {
@ibase_free_result($result);
if (isset($obj->NFLAG)) {
$flags .= 'not_null ';
}
if (isset($obj->DSOURCE)) {
$flags .= 'default ';
}
if (isset($obj->CSOURCE)) {
$flags .= 'computed ';
}
if (isset($obj->FTYPE) && $obj->FTYPE == 261) {
$flags .= 'blob ';
}
}
return trim($flags);
}
// }}}
// {{{ ibaseRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_ibase::errorNative(), DB_ibase::errorCode()
*/
public function &ibaseRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode($this->errorNative());
}
$tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg());
return $tmp;
}
// }}}
// {{{ errorNative()
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code. NULL if there is no error code.
*
* @since Method available since Release 1.7.0
*/
public function errorNative()
{
if (function_exists('ibase_errcode')) {
return @ibase_errcode();
}
if (preg_match(
'/^Dynamic SQL Error SQL error code = ([0-9-]+)/i',
@ibase_errmsg(),
$m
)) {
return (int)$m[1];
}
return null;
}
// }}}
// {{{ errorCode()
/**
* Maps native error codes to DB's portable ones
*
* @param int $nativecode the error code returned by the DBMS
*
* @return int the portable DB error code. Return DB_ERROR if the
* current driver doesn't have a mapping for the
* $nativecode submitted.
*
* @since Method available since Release 1.7.0
*/
public function errorCode($nativecode = null)
{
if (isset($this->errorcode_map[$nativecode])) {
return $this->errorcode_map[$nativecode];
}
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/generator .* is not defined/'
=> DB_ERROR_SYNTAX, // for compat. w ibase_errcode()
'/violation of [\w ]+ constraint/i'
=> DB_ERROR_CONSTRAINT,
'/table.*(not exist|not found|unknown)/i'
=> DB_ERROR_NOSUCHTABLE,
'/table .* already exists/i'
=> DB_ERROR_ALREADY_EXISTS,
'/unsuccessful metadata update .* failed attempt to store duplicate value/i'
=> DB_ERROR_ALREADY_EXISTS,
'/unsuccessful metadata update .* not found/i'
=> DB_ERROR_NOT_FOUND,
'/validation error for column .* value "\*\*\* null/i'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/conversion error from string/i'
=> DB_ERROR_INVALID_NUMBER,
'/no permission for/i'
=> DB_ERROR_ACCESS_VIOLATION,
'/arithmetic exception, numeric overflow, or string truncation/i'
=> DB_ERROR_INVALID,
'/feature is not supported/i'
=> DB_ERROR_NOT_CAPABLE,
);
}
$errormsg = @ibase_errmsg();
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
return DB_ERROR;
}
// }}}
// {{{ tableInfo()
/**
* Returns information about a table or a result set
*
@ -974,7 +903,7 @@ class DB_ibase extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
@ -1051,6 +980,78 @@ class DB_ibase extends DB_common
return $res;
}
// }}}
// {{{ tableInfo()
/**
* Get the column's flags
*
* Supports "primary_key", "unique_key", "not_null", "default",
* "computed" and "blob".
*
* @param string $field_name the name of the field
* @param string $table_name the name of the table
*
* @return string the flags
*
* @access private
*/
public function _ibaseFieldFlags($field_name, $table_name)
{
$sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE'
. ' FROM RDB$INDEX_SEGMENTS I'
. ' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME'
. ' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\''
. ' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'';
$result = @ibase_query($this->connection, $sql);
if (!$result) {
return $this->ibaseRaiseError();
}
$flags = '';
if ($obj = @ibase_fetch_object($result)) {
@ibase_free_result($result);
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') {
$flags .= 'primary_key ';
}
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') {
$flags .= 'unique_key ';
}
}
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,'
. ' R.RDB$DEFAULT_SOURCE AS DSOURCE,'
. ' F.RDB$FIELD_TYPE AS FTYPE,'
. ' F.RDB$COMPUTED_SOURCE AS CSOURCE'
. ' FROM RDB$RELATION_FIELDS R '
. ' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME'
. ' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''
. ' AND R.RDB$FIELD_NAME=\'' . $field_name . '\'';
$result = @ibase_query($this->connection, $sql);
if (!$result) {
return $this->ibaseRaiseError();
}
if ($obj = @ibase_fetch_object($result)) {
@ibase_free_result($result);
if (isset($obj->NFLAG)) {
$flags .= 'not_null ';
}
if (isset($obj->DSOURCE)) {
$flags .= 'default ';
}
if (isset($obj->CSOURCE)) {
$flags .= 'computed ';
}
if (isset($obj->FTYPE) && $obj->FTYPE == 261) {
$flags .= 'blob ';
}
}
return trim($flags);
}
// }}}
// {{{ getSpecialQuery()

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's ifx extension
@ -187,7 +188,7 @@ class DB_ifx extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -218,6 +219,72 @@ class DB_ifx extends DB_common
// }}}
// {{{ disconnect()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_ifx::errorNative(), DB_ifx::errorCode()
*/
public function ifxRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(ifx_error());
}
return $this->raiseError(
$errno,
null,
null,
null,
$this->errorNative()
);
}
// }}}
// {{{ simpleQuery()
/**
* Maps native error codes to DB's portable ones.
*
* Requires that the DB implementation's constructor fills
* in the <var>$errorcode_map</var> property.
*
* @param string $nativecode error code returned by the database
* @return int a portable DB error code, or DB_ERROR if this DB
* implementation has no mapping for the given error code.
*/
public function errorCode($nativecode)
{
if (preg_match('/SQLCODE=(.*)]/', $nativecode, $match)) {
$code = $match[1];
if (isset($this->errorcode_map[$code])) {
return $this->errorcode_map[$code];
}
}
return DB_ERROR;
}
// }}}
// {{{ nextResult()
/**
* Gets the DBMS' native error code and message produced by the last query
*
* @return string the DBMS' error code and message
*/
public function errorNative()
{
return @ifx_error() . ' ' . @ifx_errormsg();
}
// }}}
// {{{ affectedRows()
/**
* Disconnects from the database server
*
@ -231,7 +298,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ simpleQuery()
// {{{ fetchInto()
/**
* Sends a query to the database server
@ -282,7 +349,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ nextResult()
// {{{ numCols()
/**
* Move the internal ifx result pointer to the next available result
@ -299,7 +366,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ affectedRows()
// {{{ freeResult()
/**
* Determines the number of rows affected by a data maniuplation query
@ -318,7 +385,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ autoCommit()
/**
* Places a row from the result set into the given array
@ -379,7 +446,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ numCols()
// {{{ commit()
/**
* Gets the number of columns in a result set
@ -390,7 +457,7 @@ class DB_ifx extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -403,7 +470,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ rollback()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -424,7 +491,7 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ autoCommit()
// {{{ ifxRaiseError()
/**
* Enables or disables automatic commits
@ -443,12 +510,12 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ commit()
// {{{ errorNative()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function commit()
{
@ -463,12 +530,12 @@ class DB_ifx extends DB_common
}
// }}}
// {{{ rollback()
// {{{ errorCode()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function rollback()
{
@ -482,72 +549,6 @@ class DB_ifx extends DB_common
return DB_OK;
}
// }}}
// {{{ ifxRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_ifx::errorNative(), DB_ifx::errorCode()
*/
public function ifxRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(ifx_error());
}
return $this->raiseError(
$errno,
null,
null,
null,
$this->errorNative()
);
}
// }}}
// {{{ errorNative()
/**
* Gets the DBMS' native error code and message produced by the last query
*
* @return string the DBMS' error code and message
*/
public function errorNative()
{
return @ifx_error() . ' ' . @ifx_errormsg();
}
// }}}
// {{{ errorCode()
/**
* Maps native error codes to DB's portable ones.
*
* Requires that the DB implementation's constructor fills
* in the <var>$errorcode_map</var> property.
*
* @param string $nativecode error code returned by the database
* @return int a portable DB error code, or DB_ERROR if this DB
* implementation has no mapping for the given error code.
*/
public function errorCode($nativecode)
{
if (preg_match('/SQLCODE=(.*)]/', $nativecode, $match)) {
$code = $match[1];
if (isset($this->errorcode_map[$code])) {
return $this->errorcode_map[$code];
}
}
return DB_ERROR;
}
// }}}
// {{{ tableInfo()
@ -567,7 +568,7 @@ class DB_ifx extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()

View File

@ -30,7 +30,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's msql extension
@ -94,8 +95,7 @@ class DB_msql extends DB_common
* A mapping of native error codes to DB error codes
* @var array
*/
public $errorcode_map = array(
);
public $errorcode_map = array();
/**
* The raw database connection created by PHP
@ -154,7 +154,7 @@ class DB_msql extends DB_common
* );
*
* $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* if ((new PEAR)->isError($db)) {
* die($db->getMessage());
* }
* </code>
@ -162,7 +162,7 @@ class DB_msql extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -229,357 +229,6 @@ class DB_msql extends DB_common
// }}}
// {{{ disconnect()
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
public function disconnect()
{
$ret = @msql_close($this->connection);
$this->connection = null;
return $ret;
}
// }}}
// {{{ simpleQuery()
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
public function simpleQuery($query)
{
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @msql_query($query, $this->connection);
if (!$result) {
return $this->msqlRaiseError();
}
// Determine which queries that should return data, and which
// should return an error code only.
if ($this->_checkManip($query)) {
$this->_result = $result;
return DB_OK;
} else {
$this->_result = false;
return $result;
}
}
// }}}
// {{{ nextResult()
/**
* Move the internal msql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return false;
}
// }}}
// {{{ fetchInto()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
* those versions.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@msql_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @msql_fetch_array($result, MSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @msql_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
// }}}
// {{{ freeResult()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
return is_resource($result) ? msql_free_result($result) : false;
}
// }}}
// {{{ numCols()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @msql_num_fields($result);
if (!$cols) {
return $this->msqlRaiseError();
}
return $cols;
}
// }}}
// {{{ numRows()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @msql_num_rows($result);
if ($rows === false) {
return $this->msqlRaiseError();
}
return $rows;
}
// }}}
// {{{ affected()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
if (!$this->_result) {
return 0;
}
return msql_affected_rows($this->_result);
}
// }}}
// {{{ nextId()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_msql::createSequence(), DB_msql::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT _seq FROM ${seqname}");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = true;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
// }}}
// {{{ createSequence()
/**
* Creates a new sequence
*
* Also creates a new table to associate the sequence with. Uses
* a separate table to ensure portability with other drivers.
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_msql::nextID(), DB_msql::dropSequence()
*/
public function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$res = $this->query('CREATE TABLE ' . $seqname
. ' (id INTEGER NOT NULL)');
if (DB::isError($res)) {
return $res;
}
$res = $this->query("CREATE SEQUENCE ON ${seqname}");
return $res;
}
// }}}
// {{{ dropSequence()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_msql::nextID(), DB_msql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ quoteIdentifier()
/**
* mSQL does not support delimited identifiers
*
* @param string $str the identifier name to be quoted
*
* @return object a DB_Error object
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.7.0
*/
public function quoteIdentifier($str)
{
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.
*/
public function quoteFloat($float)
{
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ escapeSimple()
/**
* Escapes a string according to the current DBMS's standards
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.7.0
*/
public function escapeSimple($str)
{
return addslashes($str);
}
// }}}
// {{{ msqlRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
@ -602,7 +251,7 @@ class DB_msql extends DB_common
}
// }}}
// {{{ errorNative()
// {{{ simpleQuery()
/**
* Gets the DBMS' native error message produced by the last query
@ -614,8 +263,9 @@ class DB_msql extends DB_common
return @msql_error();
}
// }}}
// {{{ errorCode()
// {{{ nextResult()
/**
* Determines PEAR::DB error code from the database's text error message
@ -697,6 +347,356 @@ class DB_msql extends DB_common
return DB_ERROR;
}
// }}}
// {{{ fetchInto()
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
public function disconnect()
{
$ret = @msql_close($this->connection);
$this->connection = null;
return $ret;
}
// }}}
// {{{ freeResult()
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
public function simpleQuery($query)
{
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @msql_query($query, $this->connection);
if (!$result) {
return $this->msqlRaiseError();
}
// Determine which queries that should return data, and which
// should return an error code only.
if ($this->_checkManip($query)) {
$this->_result = $result;
return DB_OK;
} else {
$this->_result = false;
return $result;
}
}
// }}}
// {{{ numCols()
/**
* Move the internal msql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return false;
}
// }}}
// {{{ numRows()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
* those versions.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@msql_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @msql_fetch_array($result, MSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @msql_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
// }}}
// {{{ affected()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
return is_resource($result) ? msql_free_result($result) : false;
}
// }}}
// {{{ nextId()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @msql_num_fields($result);
if (!$cols) {
return $this->msqlRaiseError();
}
return $cols;
}
// }}}
// {{{ createSequence()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @msql_num_rows($result);
if ($rows === false) {
return $this->msqlRaiseError();
}
return $rows;
}
// }}}
// {{{ dropSequence()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
if (!$this->_result) {
return 0;
}
return msql_affected_rows($this->_result);
}
// }}}
// {{{ quoteIdentifier()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_msql::createSequence(), DB_msql::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT _seq FROM ${seqname}");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = true;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
// }}}
// {{{ quoteFloat()
/**
* Creates a new sequence
*
* Also creates a new table to associate the sequence with. Uses
* a separate table to ensure portability with other drivers.
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_msql::nextID(), DB_msql::dropSequence()
*/
public function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$res = $this->query('CREATE TABLE ' . $seqname
. ' (id INTEGER NOT NULL)');
if (DB::isError($res)) {
return $res;
}
$res = $this->query("CREATE SEQUENCE ON ${seqname}");
return $res;
}
// }}}
// {{{ escapeSimple()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_msql::nextID(), DB_msql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ msqlRaiseError()
/**
* mSQL does not support delimited identifiers
*
* @param string $str the identifier name to be quoted
*
* @return object a DB_Error object
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.7.0
*/
public function quoteIdentifier($str)
{
return $this->raiseError(DB_ERROR_UNSUPPORTED);
}
// }}}
// {{{ errorNative()
/**
* 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.
*/
public function quoteFloat($float)
{
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ errorCode()
/**
* Escapes a string according to the current DBMS's standards
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.7.0
*/
public function escapeSimple($str)
{
return addslashes($str);
}
// }}}
// {{{ tableInfo()
@ -710,7 +710,7 @@ class DB_msql extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::setOption()
@ -804,7 +804,7 @@ class DB_msql extends DB_common
*
* @param string $type the kind of objects you want to retrieve
*
* @return array the array containing the list of objects requested
* @return array|object
*
* @access protected
* @see DB_common::getListOf()

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's mssql extension
@ -199,7 +200,7 @@ class DB_mssql extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -307,6 +308,80 @@ class DB_mssql extends DB_common
// }}}
// {{{ nextResult()
/**
* Produces a DB_Error object regarding the current problem
*
* @param null $code
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mssql::errorNative(), DB_mssql::errorCode()
*/
public function mssqlRaiseError($code = null)
{
$message = @mssql_get_last_message();
if (!$code) {
$code = $this->errorNative();
}
return $this->raiseError(
$this->errorCode($code, $message),
null,
null,
null,
"$code - $message"
);
}
// }}}
// {{{ fetchInto()
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code
*/
public function errorNative()
{
$res = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
if (!$res) {
return DB_ERROR;
}
$row = @mssql_fetch_row($res);
return $row[0];
}
// }}}
// {{{ freeResult()
/**
* Determines PEAR::DB error code from mssql's native codes.
*
* If <var>$nativecode</var> isn't known yet, it will be looked up.
*
* @param mixed $nativecode mssql error code, if known
* @param string $msg
* @return integer an error number from a DB error constant
* @see errorNative()
*/
public function errorCode($nativecode = null, $msg = '')
{
if (!$nativecode) {
$nativecode = $this->errorNative();
}
if (isset($this->errorcode_map[$nativecode])) {
if ($nativecode == 3701
&& preg_match('/Cannot drop the index/i', $msg)) {
return DB_ERROR_NOT_FOUND;
}
return $this->errorcode_map[$nativecode];
} else {
return DB_ERROR;
}
}
// }}}
// {{{ numCols()
/**
* Move the internal mssql result pointer to the next available result
*
@ -322,7 +397,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ numRows()
/**
* Places a row from the result set into the given array
@ -372,7 +447,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ autoCommit()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -393,7 +468,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ numCols()
// {{{ commit()
/**
* Gets the number of columns in a result set
@ -404,7 +479,7 @@ class DB_mssql extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -418,7 +493,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ numRows()
// {{{ rollback()
/**
* Gets the number of rows in a result set
@ -429,7 +504,7 @@ class DB_mssql extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numRows()
*/
@ -443,7 +518,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ autoCommit()
// {{{ affectedRows()
/**
* Enables or disables automatic commits
@ -462,12 +537,12 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ commit()
// {{{ nextId()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function commit()
{
@ -484,13 +559,10 @@ class DB_mssql extends DB_common
return DB_OK;
}
// }}}
// {{{ rollback()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function rollback()
{
@ -508,14 +580,14 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ affectedRows()
// {{{ dropSequence()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*/
public function affectedRows()
{
@ -538,7 +610,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ nextId()
// {{{ escapeSimple()
/**
* Returns the next free id in a sequence
@ -547,7 +619,7 @@ class DB_mssql extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -593,6 +665,9 @@ class DB_mssql extends DB_common
return $result[0];
}
// }}}
// {{{ quoteIdentifier()
/**
* Creates a new sequence
*
@ -612,7 +687,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ dropSequence()
// {{{ mssqlRaiseError()
/**
* Deletes a sequence
@ -630,7 +705,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ escapeSimple()
// {{{ errorNative()
/**
* Escapes a string in a manner suitable for SQL Server.
@ -651,7 +726,7 @@ class DB_mssql extends DB_common
}
// }}}
// {{{ quoteIdentifier()
// {{{ errorCode()
/**
* Quotes a string so it can be safely used as a table or column name
@ -668,82 +743,6 @@ class DB_mssql extends DB_common
return '[' . str_replace(']', ']]', $str) . ']';
}
// }}}
// {{{ mssqlRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mssql::errorNative(), DB_mssql::errorCode()
*/
public function mssqlRaiseError($code = null)
{
$message = @mssql_get_last_message();
if (!$code) {
$code = $this->errorNative();
}
return $this->raiseError(
$this->errorCode($code, $message),
null,
null,
null,
"$code - $message"
);
}
// }}}
// {{{ errorNative()
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code
*/
public function errorNative()
{
$res = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
if (!$res) {
return DB_ERROR;
}
$row = @mssql_fetch_row($res);
return $row[0];
}
// }}}
// {{{ errorCode()
/**
* Determines PEAR::DB error code from mssql's native codes.
*
* If <var>$nativecode</var> isn't known yet, it will be looked up.
*
* @param mixed $nativecode mssql error code, if known
* @return integer an error number from a DB error constant
* @see errorNative()
*/
public function errorCode($nativecode = null, $msg = '')
{
if (!$nativecode) {
$nativecode = $this->errorNative();
}
if (isset($this->errorcode_map[$nativecode])) {
if ($nativecode == 3701
&& preg_match('/Cannot drop the index/i', $msg)) {
return DB_ERROR_NOT_FOUND;
}
return $this->errorcode_map[$nativecode];
} else {
return DB_ERROR;
}
}
// }}}
// {{{ tableInfo()
@ -760,7 +759,7 @@ class DB_mssql extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
@ -867,7 +866,7 @@ class DB_mssql extends DB_common
* @param string $table the table name
* @param string $column the field name
*
* @return string the flags
* @return array|string
*
* @access private
* @author Joern Barthel <j_barthel@web.de>

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's mysql extension
@ -191,7 +192,7 @@ class DB_mysql extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -281,6 +282,46 @@ class DB_mysql extends DB_common
// }}}
// {{{ disconnect()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mysql::errorNative(), DB_common::errorCode()
*/
public function mysqlRaiseError($errno = null)
{
if ($errno === null) {
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
}
$errno = $this->errorCode(mysql_errno($this->connection));
}
return $this->raiseError(
$errno,
null,
null,
null,
@mysql_errno($this->connection) . ' ** ' .
@mysql_error($this->connection)
);
}
// }}}
// {{{ simpleQuery()
/**
* Disconnects from the database server
*
@ -294,7 +335,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ simpleQuery()
// {{{ nextResult()
/**
* Sends a query to the database server
@ -344,7 +385,40 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ nextResult()
// {{{ fetchInto()
/**
* Changes a query string for various DBMS specific reasons
*
* This little hack lets you know how many rows were deleted
* when running a "DELETE FROM table" query. Only implemented
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_common::setOption()
*/
public function modifyQuery($query)
{
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
// "DELETE FROM table" gives 0 affected rows in MySQL.
// This little hack lets you know how many rows were deleted.
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace(
'/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1',
$query
);
}
}
return $query;
}
// }}}
// {{{ freeResult()
/**
* Move the internal mysql result pointer to the next available result
@ -361,7 +435,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ numCols()
/**
* Places a row from the result set into the given array
@ -416,7 +490,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ numRows()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -437,7 +511,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ numCols()
// {{{ autoCommit()
/**
* Gets the number of columns in a result set
@ -448,7 +522,7 @@ class DB_mysql extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -462,7 +536,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ numRows()
// {{{ commit()
/**
* Gets the number of rows in a result set
@ -473,7 +547,7 @@ class DB_mysql extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numRows()
*/
@ -487,7 +561,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ autoCommit()
// {{{ rollback()
/**
* Enables or disables automatic commits
@ -506,12 +580,12 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ commit()
// {{{ affectedRows()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function commit()
{
@ -532,12 +606,12 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ rollback()
// {{{ nextId()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function rollback()
{
@ -558,7 +632,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ affectedRows()
// {{{ createSequence()
/**
* Determines the number of rows affected by a data maniuplation query
@ -577,7 +651,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ nextId()
// {{{ dropSequence()
/**
* Returns the next free id in a sequence
@ -586,7 +660,7 @@ class DB_mysql extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -658,7 +732,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ createSequence()
// {{{ _BCsequence()
/**
* Creates a new sequence
@ -689,25 +763,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ dropSequence()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ _BCsequence()
// {{{ quoteIdentifier()
/**
* Backwards compatibility with old sequence emulation implementation
@ -715,7 +771,7 @@ class DB_mysql extends DB_common
*
* @param string $seqname the sequence name to clean up
*
* @return bool true on success. A DB_Error object on failure.
* @return bool|object
*
* @access private
*/
@ -758,7 +814,25 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ quoteIdentifier()
// {{{ escapeSimple()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ modifyQuery()
/**
* Quotes a string so it can be safely used as a table or column name
@ -780,7 +854,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ escapeSimple()
// {{{ modifyLimitQuery()
/**
* Escapes a string according to the current DBMS's standards
@ -802,40 +876,7 @@ class DB_mysql extends DB_common
}
// }}}
// {{{ modifyQuery()
/**
* Changes a query string for various DBMS specific reasons
*
* This little hack lets you know how many rows were deleted
* when running a "DELETE FROM table" query. Only implemented
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_common::setOption()
*/
public function modifyQuery($query)
{
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
// "DELETE FROM table" gives 0 affected rows in MySQL.
// This little hack lets you know how many rows were deleted.
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace(
'/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1',
$query
);
}
}
return $query;
}
// }}}
// {{{ modifyLimitQuery()
// {{{ mysqlRaiseError()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
@ -862,46 +903,6 @@ class DB_mysql extends DB_common
}
}
// }}}
// {{{ mysqlRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mysql::errorNative(), DB_common::errorCode()
*/
public function mysqlRaiseError($errno = null)
{
if ($errno === null) {
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
}
$errno = $this->errorCode(mysql_errno($this->connection));
}
return $this->raiseError(
$errno,
null,
null,
null,
@mysql_errno($this->connection) . ' ** ' .
@mysql_error($this->connection)
);
}
// }}}
// {{{ errorNative()
@ -928,7 +929,7 @@ class DB_mysql extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()

View File

@ -26,7 +26,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's mysqli extension
@ -272,7 +273,7 @@ class DB_mysqli extends DB_common
* );
*
* $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* if ((new PEAR)->isError($db)) {
* die($db->getMessage());
* }
* </code>
@ -280,7 +281,7 @@ class DB_mysqli extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -418,6 +419,46 @@ class DB_mysqli extends DB_common
// }}}
// {{{ nextResult()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mysqli::errorNative(), DB_common::errorCode()
*/
public function mysqliRaiseError($errno = null)
{
if ($errno === null) {
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
}
$errno = $this->errorCode(mysqli_errno($this->connection));
}
return $this->raiseError(
$errno,
null,
null,
null,
@mysqli_errno($this->connection) . ' ** ' .
@mysqli_error($this->connection)
);
}
// }}}
// {{{ fetchInto()
/**
* Move the internal mysql result pointer to the next available result.
*
@ -433,7 +474,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ freeResult()
/**
* Places a row from the result set into the given array
@ -488,7 +529,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ numCols()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -513,7 +554,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ numCols()
// {{{ numRows()
/**
* Gets the number of columns in a result set
@ -524,7 +565,7 @@ class DB_mysqli extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -538,7 +579,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ numRows()
// {{{ autoCommit()
/**
* Gets the number of rows in a result set
@ -549,7 +590,7 @@ class DB_mysqli extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numRows()
*/
@ -563,7 +604,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ autoCommit()
// {{{ commit()
/**
* Enables or disables automatic commits
@ -582,12 +623,12 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ commit()
// {{{ rollback()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function commit()
{
@ -608,12 +649,12 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ rollback()
// {{{ affectedRows()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function rollback()
{
@ -634,7 +675,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ affectedRows()
// {{{ nextId()
/**
* Determines the number of rows affected by a data maniuplation query
@ -652,9 +693,6 @@ class DB_mysqli extends DB_common
}
}
// }}}
// {{{ nextId()
/**
* Returns the next free id in a sequence
*
@ -662,7 +700,7 @@ class DB_mysqli extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -740,6 +778,9 @@ class DB_mysqli extends DB_common
return $this->raiseError($result);
}
// }}}
// {{{ dropSequence()
/**
* Creates a new sequence
*
@ -763,24 +804,6 @@ class DB_mysqli extends DB_common
return $this->query("INSERT INTO ${seqname} (id) VALUES (0)");
}
// }}}
// {{{ dropSequence()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ _BCsequence()
@ -790,7 +813,7 @@ class DB_mysqli extends DB_common
*
* @param string $seqname the sequence name to clean up
*
* @return bool true on success. A DB_Error object on failure.
* @return bool|object
*
* @access private
*/
@ -836,6 +859,24 @@ class DB_mysqli extends DB_common
// }}}
// {{{ quoteIdentifier()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ escapeSimple()
/**
* 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)
@ -856,7 +897,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ escapeSimple()
// {{{ modifyLimitQuery()
/**
* Escapes a string according to the current DBMS's standards
@ -874,7 +915,7 @@ class DB_mysqli extends DB_common
}
// }}}
// {{{ modifyLimitQuery()
// {{{ mysqliRaiseError()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
@ -901,46 +942,6 @@ class DB_mysqli extends DB_common
}
}
// }}}
// {{{ mysqliRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mysqli::errorNative(), DB_common::errorCode()
*/
public function mysqliRaiseError($errno = null)
{
if ($errno === null) {
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
}
$errno = $this->errorCode(mysqli_errno($this->connection));
}
return $this->raiseError(
$errno,
null,
null,
null,
@mysqli_errno($this->connection) . ' ** ' .
@mysqli_error($this->connection)
);
}
// }}}
// {{{ errorNative()
@ -967,7 +968,7 @@ class DB_mysqli extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::setOption()
@ -1097,7 +1098,8 @@ class DB_mysqli extends DB_common
}
}
public function getVersion() {
public function getVersion()
{
return mysqli_get_server_version($this->connection);
}

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's oci8 extension
@ -211,7 +212,7 @@ class DB_oci8 extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -355,6 +356,68 @@ class DB_oci8 extends DB_common
// }}}
// {{{ nextResult()
/**
* Changes a query string for various DBMS specific reasons
*
* "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
*/
public function modifyQuery($query)
{
if (preg_match('/^\s*SELECT/i', $query) &&
!preg_match('/\sFROM\s/i', $query)) {
$query .= ' FROM dual';
}
return $query;
}
// }}}
// {{{ fetchInto()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_oci8::errorNative(), DB_oci8::errorCode()
*/
public function oci8RaiseError($errno = null)
{
if ($errno === null) {
$error = @OCIError($this->connection);
return $this->raiseError(
$this->errorCode($error['code']),
null,
null,
null,
$error['message']
);
} elseif (is_resource($errno)) {
$error = @OCIError($errno);
return $this->raiseError(
$this->errorCode($error['code']),
null,
null,
null,
$error['message']
);
}
return $this->raiseError($this->errorCode($errno));
}
// }}}
// {{{ freeResult()
/**
* Move the internal oracle result pointer to the next available result
*
@ -369,9 +432,6 @@ class DB_oci8 extends DB_common
return false;
}
// }}}
// {{{ fetchInto()
/**
* Places a row from the result set into the given array
*
@ -419,7 +479,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ freeResult()
// {{{ numRows()
/**
* Deletes the result set and frees the memory occupied by the result set
@ -439,6 +499,9 @@ class DB_oci8 extends DB_common
return is_resource($result) ? OCIFreeStatement($result) : false;
}
// }}}
// {{{ numCols()
/**
* Frees the internal resources associated with a prepared query
*
@ -470,7 +533,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ numRows()
// {{{ prepare()
/**
* Gets the number of rows in a result set
@ -484,7 +547,7 @@ class DB_oci8 extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numRows(), DB_common::setOption()
*/
@ -514,7 +577,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ numCols()
// {{{ execute()
/**
* Gets the number of columns in a result set
@ -525,7 +588,7 @@ class DB_oci8 extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -539,7 +602,145 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ prepare()
// {{{ autoCommit()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
$this->autocommit = (bool)$onoff;;
return DB_OK;
}
// }}}
// {{{ commit()
/**
* Commits the current transaction
*
* @return int|object
*/
public function commit()
{
$result = @OCICommit($this->connection);
if (!$result) {
return $this->oci8RaiseError();
}
return DB_OK;
}
// }}}
// {{{ rollback()
/**
* Reverts the current transaction
*
* @return int|object
*/
public function rollback()
{
$result = @OCIRollback($this->connection);
if (!$result) {
return $this->oci8RaiseError();
}
return DB_OK;
}
// }}}
// {{{ affectedRows()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int|object
*/
public function affectedRows()
{
if ($this->last_stmt === false) {
return $this->oci8RaiseError();
}
$result = @OCIRowCount($this->last_stmt);
if ($result === false) {
return $this->oci8RaiseError($this->last_stmt);
}
return $result;
}
// }}}
// {{{ modifyQuery()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
public function modifyLimitQuery($query, $from, $count, $params = array())
{
// Let Oracle return the name of the columns instead of
// coding a "home" SQL parser
if (count($params)) {
$result = $this->prepare("SELECT * FROM ($query) "
. 'WHERE NULL = NULL');
$tmp = $this->execute($result, $params);
} else {
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
if (!$result = @OCIParse($this->connection, $q_fields)) {
$this->last_query = $q_fields;
return $this->oci8RaiseError();
}
if (!@OCIExecute($result, OCI_DEFAULT)) {
$this->last_query = $q_fields;
return $this->oci8RaiseError($result);
}
}
$ncols = OCINumCols($result);
$cols = array();
for ($i = 1; $i <= $ncols; $i++) {
$cols[] = '"' . OCIColumnName($result, $i) . '"';
}
$fields = implode(', ', $cols);
// XXX Test that (tip by John Lim)
//if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
// // Introduce the FIRST_ROWS Oracle query optimizer
// $query = substr($query, strlen($match[0]), strlen($query));
// $query = "SELECT /* +FIRST_ROWS */ " . $query;
//}
// Construct the query
// more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
// Perhaps this could be optimized with the use of Unions
$query = "SELECT $fields FROM" .
" (SELECT rownum as linenum, $fields FROM" .
" ($query)" .
' WHERE rownum <= ' . ($from + $count) .
') WHERE linenum >= ' . ++$from;
return $query;
}
// }}}
// {{{ modifyLimitQuery()
/**
* Prepares a query for multiple execution with execute().
@ -617,7 +818,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ execute()
// {{{ nextId()
/**
* Executes a DB statement prepared with prepare().
@ -713,170 +914,22 @@ class DB_oci8 extends DB_common
return $tmp;
}
// }}}
// {{{ autoCommit()
/**
* Enables or disables automatic commits
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
* @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.
*/
public function autoCommit($onoff = false)
public function quoteFloat($float)
{
$this->autocommit = (bool)$onoff;
;
return DB_OK;
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ commit()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function commit()
{
$result = @OCICommit($this->connection);
if (!$result) {
return $this->oci8RaiseError();
}
return DB_OK;
}
// }}}
// {{{ rollback()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function rollback()
{
$result = @OCIRollback($this->connection);
if (!$result) {
return $this->oci8RaiseError();
}
return DB_OK;
}
// }}}
// {{{ affectedRows()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
if ($this->last_stmt === false) {
return $this->oci8RaiseError();
}
$result = @OCIRowCount($this->last_stmt);
if ($result === false) {
return $this->oci8RaiseError($this->last_stmt);
}
return $result;
}
// }}}
// {{{ modifyQuery()
/**
* Changes a query string for various DBMS specific reasons
*
* "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
*/
public function modifyQuery($query)
{
if (preg_match('/^\s*SELECT/i', $query) &&
!preg_match('/\sFROM\s/i', $query)) {
$query .= ' FROM dual';
}
return $query;
}
// }}}
// {{{ modifyLimitQuery()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
public function modifyLimitQuery($query, $from, $count, $params = array())
{
// Let Oracle return the name of the columns instead of
// coding a "home" SQL parser
if (count($params)) {
$result = $this->prepare("SELECT * FROM ($query) "
. 'WHERE NULL = NULL');
$tmp = $this->execute($result, $params);
} else {
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
if (!$result = @OCIParse($this->connection, $q_fields)) {
$this->last_query = $q_fields;
return $this->oci8RaiseError();
}
if (!@OCIExecute($result, OCI_DEFAULT)) {
$this->last_query = $q_fields;
return $this->oci8RaiseError($result);
}
}
$ncols = OCINumCols($result);
$cols = array();
for ($i = 1; $i <= $ncols; $i++) {
$cols[] = '"' . OCIColumnName($result, $i) . '"';
}
$fields = implode(', ', $cols);
// XXX Test that (tip by John Lim)
//if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
// // Introduce the FIRST_ROWS Oracle query optimizer
// $query = substr($query, strlen($match[0]), strlen($query));
// $query = "SELECT /* +FIRST_ROWS */ " . $query;
//}
// Construct the query
// more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
// Perhaps this could be optimized with the use of Unions
$query = "SELECT $fields FROM".
" (SELECT rownum as linenum, $fields FROM".
" ($query)".
' WHERE rownum <= '. ($from + $count) .
') WHERE linenum >= ' . ++$from;
return $query;
}
// }}}
// {{{ nextId()
// {{{ dropSequence()
/**
* Returns the next free id in a sequence
@ -885,7 +938,7 @@ class DB_oci8 extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -917,6 +970,9 @@ class DB_oci8 extends DB_common
return $arr[0];
}
// }}}
// {{{ oci8RaiseError()
/**
* Creates a new sequence
*
@ -934,7 +990,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ dropSequence()
// {{{ errorNative()
/**
* Deletes a sequence
@ -953,46 +1009,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ oci8RaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_oci8::errorNative(), DB_oci8::errorCode()
*/
public function oci8RaiseError($errno = null)
{
if ($errno === null) {
$error = @OCIError($this->connection);
return $this->raiseError(
$this->errorCode($error['code']),
null,
null,
null,
$error['message']
);
} elseif (is_resource($errno)) {
$error = @OCIError($errno);
return $this->raiseError(
$this->errorCode($error['code']),
null,
null,
null,
$error['message']
);
}
return $this->raiseError($this->errorCode($errno));
}
// }}}
// {{{ errorNative()
// {{{ tableInfo()
/**
* Gets the DBMS' native error code produced by the last query
@ -1014,7 +1031,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ tableInfo()
// {{{ getSpecialQuery()
/**
* Returns information about a table or a result set
@ -1031,7 +1048,7 @@ class DB_oci8 extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
@ -1127,7 +1144,7 @@ class DB_oci8 extends DB_common
}
// }}}
// {{{ getSpecialQuery()
// {{{ quoteFloat()
/**
* Obtains the query string needed for listing a given type of objects
@ -1154,23 +1171,6 @@ class DB_oci8 extends DB_common
}
}
// }}}
// {{{ 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.
*/
public function quoteFloat($float)
{
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
}

View File

@ -27,7 +27,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's odbc extension
@ -176,7 +177,7 @@ class DB_odbc extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -242,10 +243,26 @@ class DB_odbc extends DB_common
// }}}
// {{{ disconnect()
/**
* Gets the DBMS' native error code and message produced by the last query
*
* @return string the DBMS' error code and message
*/
public function errorNative()
{
if (!is_resource($this->connection)) {
return @odbc_error() . ' ' . @odbc_errormsg();
}
return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection);
}
// }}}
// {{{ simpleQuery()
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
* @return bool|void
*/
public function disconnect()
{
@ -255,7 +272,7 @@ class DB_odbc extends DB_common
}
// }}}
// {{{ simpleQuery()
// {{{ nextResult()
/**
* Sends a query to the database server
@ -284,358 +301,9 @@ class DB_odbc extends DB_common
return $result;
}
// }}}
// {{{ nextResult()
/**
* Move the internal odbc result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return @odbc_next_result($result);
}
// }}}
// {{{ fetchInto()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
$arr = array();
if ($rownum !== null) {
$rownum++; // ODBC first row is 1
if (version_compare(phpversion(), '4.2.0', 'ge')) {
$cols = @odbc_fetch_into($result, $arr, $rownum);
} else {
$cols = @odbc_fetch_into($result, $rownum, $arr);
}
} else {
$cols = @odbc_fetch_into($result, $arr);
}
if (!$cols) {
return null;
}
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
for ($i = 0; $i < count($arr); $i++) {
$colName = @odbc_field_name($result, $i+1);
$a[$colName] = $arr[$i];
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$a = array_change_key_case($a, CASE_LOWER);
}
$arr = $a;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
// }}}
// {{{ freeResult()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
return is_resource($result) ? odbc_free_result($result) : false;
}
// }}}
// {{{ numCols()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @odbc_num_fields($result);
if (!$cols) {
return $this->odbcRaiseError();
}
return $cols;
}
// }}}
// {{{ affectedRows()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
if (empty($this->affected)) { // In case of SELECT stms
return 0;
}
$nrows = @odbc_num_rows($this->affected);
if ($nrows == -1) {
return $this->odbcRaiseError();
}
return $nrows;
}
// }}}
// {{{ numRows()
/**
* Gets the number of rows in a result set
*
* Not all ODBC drivers support this functionality. If they don't
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$nrows = @odbc_num_rows($result);
if ($nrows == -1) {
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
}
if ($nrows === false) {
return $this->odbcRaiseError();
}
return $nrows;
}
// }}}
// {{{ quoteIdentifier()
/**
* Quotes a string so it can be safely used as a table or column name
*
* Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked
* "Use ANSI quoted identifiers" when setting up the ODBC data source.
*
* @param string $str identifier name to be quoted
*
* @return string quoted identifier string
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.6.0
*/
public function quoteIdentifier($str)
{
switch ($this->dsn['dbsyntax']) {
case 'access':
return '[' . $str . ']';
case 'mssql':
case 'sybase':
return '[' . str_replace(']', ']]', $str) . ']';
case 'mysql':
case 'mysqli':
return '`' . $str . '`';
default:
return '"' . str_replace('"', '""', $str) . '"';
}
}
// }}}
// {{{ nextId()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_odbc::createSequence(), DB_odbc::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("update ${seqname} set id = id + 1");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = 1;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $this->query("insert into ${seqname} (id) values(0)");
} else {
$repeat = 0;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $this->query("select id from ${seqname}");
if (DB::isError($result)) {
return $result;
}
$row = $result->fetchRow(DB_FETCHMODE_ORDERED);
if (DB::isError($row || !$row)) {
return $row;
}
return $row[0];
}
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_odbc::nextID(), DB_odbc::dropSequence()
*/
public function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' (id integer NOT NULL,'
. ' PRIMARY KEY(id))');
}
// }}}
// {{{ dropSequence()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_odbc::nextID(), DB_odbc::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ autoCommit()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
if (!@odbc_autocommit($this->connection, $onoff)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
// }}}
// {{{ commit()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function commit()
{
if (!@odbc_commit($this->connection)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
// }}}
// {{{ rollback()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function rollback()
{
if (!@odbc_rollback($this->connection)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
// }}}
// {{{ odbcRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
@ -701,20 +369,353 @@ class DB_odbc extends DB_common
);
}
// }}}
// {{{ freeResult()
/**
* Move the internal odbc result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return @odbc_next_result($result);
}
// }}}
// {{{ numCols()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
$arr = array();
if ($rownum !== null) {
$rownum++; // ODBC first row is 1
if (version_compare(phpversion(), '4.2.0', 'ge')) {
$cols = @odbc_fetch_into($result, $arr, $rownum);
} else {
$cols = @odbc_fetch_into($result, $rownum, $arr);
}
} else {
$cols = @odbc_fetch_into($result, $arr);
}
if (!$cols) {
return null;
}
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
for ($i = 0; $i < count($arr); $i++) {
$colName = @odbc_field_name($result, $i + 1);
$a[$colName] = $arr[$i];
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$a = array_change_key_case($a, CASE_LOWER);
}
$arr = $a;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
// }}}
// {{{ affectedRows()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
return is_resource($result) ? odbc_free_result($result) : false;
}
// }}}
// {{{ numRows()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @odbc_num_fields($result);
if (!$cols) {
return $this->odbcRaiseError();
}
return $cols;
}
// }}}
// {{{ quoteIdentifier()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int|object
*/
public function affectedRows()
{
if (empty($this->affected)) { // In case of SELECT stms
return 0;
}
$nrows = @odbc_num_rows($this->affected);
if ($nrows == -1) {
return $this->odbcRaiseError();
}
return $nrows;
}
// }}}
// {{{ nextId()
/**
* Gets the number of rows in a result set
*
* Not all ODBC drivers support this functionality. If they don't
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$nrows = @odbc_num_rows($result);
if ($nrows == -1) {
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
}
if ($nrows === false) {
return $this->odbcRaiseError();
}
return $nrows;
}
/**
* Quotes a string so it can be safely used as a table or column name
*
* Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked
* "Use ANSI quoted identifiers" when setting up the ODBC data source.
*
* @param string $str identifier name to be quoted
*
* @return string quoted identifier string
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.6.0
*/
public function quoteIdentifier($str)
{
switch ($this->dsn['dbsyntax']) {
case 'access':
return '[' . $str . ']';
case 'mssql':
case 'sybase':
return '[' . str_replace(']', ']]', $str) . ']';
case 'mysql':
case 'mysqli':
return '`' . $str . '`';
default:
return '"' . str_replace('"', '""', $str) . '"';
}
}
// }}}
// {{{ dropSequence()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_odbc::createSequence(), DB_odbc::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("update ${seqname} set id = id + 1");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = 1;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $this->query("insert into ${seqname} (id) values(0)");
} else {
$repeat = 0;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $this->query("select id from ${seqname}");
if (DB::isError($result)) {
return $result;
}
$row = $result->fetchRow(DB_FETCHMODE_ORDERED);
if (DB::isError($row || !$row)) {
return $row;
}
return $row[0];
}
// }}}
// {{{ autoCommit()
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_odbc::nextID(), DB_odbc::dropSequence()
*/
public function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' (id integer NOT NULL,'
. ' PRIMARY KEY(id))');
}
// }}}
// {{{ commit()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_odbc::nextID(), DB_odbc::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ rollback()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int|object
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
if (!@odbc_autocommit($this->connection, $onoff)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
// }}}
// {{{ odbcRaiseError()
/**
* Commits the current transaction
*
* @return int|object
*/
public function commit()
{
if (!@odbc_commit($this->connection)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
// }}}
// {{{ errorNative()
/**
* Gets the DBMS' native error code and message produced by the last query
* Reverts the current transaction
*
* @return string the DBMS' error code and message
* @return int|object
*/
public function errorNative()
public function rollback()
{
if (!is_resource($this->connection)) {
return @odbc_error() . ' ' . @odbc_errormsg();
if (!@odbc_rollback($this->connection)) {
return $this->odbcRaiseError();
}
return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection);
return DB_OK;
}
// }}}
@ -730,7 +731,7 @@ class DB_odbc extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
@ -816,7 +817,7 @@ class DB_odbc extends DB_common
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the list of objects requested
* @return array|string
*
* @access protected
* @see DB_common::getListOf()

View File

@ -28,7 +28,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's pgsql extension
@ -89,8 +90,7 @@ class DB_pgsql extends DB_common
* A mapping of native error codes to DB error codes
* @var array
*/
public $errorcode_map = array(
);
public $errorcode_map = array();
/**
* The raw database connection created by PHP
@ -194,7 +194,7 @@ class DB_pgsql extends DB_common
* );
*
* $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* if ((new PEAR)->isError($db)) {
* die($db->getMessage());
* }
* </code>
@ -202,7 +202,7 @@ class DB_pgsql extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*
* @link http://www.postgresql.org/docs/current/static/libpq.html#LIBPQ-CONNECT
*/
@ -382,386 +382,26 @@ class DB_pgsql extends DB_common
// {{{ nextResult()
/**
* Move the internal pgsql result pointer to the next available result
* 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 a valid fbsql result resource
* @param string The query to check.
*
* @access public
* @return boolean true if the query is a manipulation query, false
* otherwise
*
* @return true if a result is available otherwise return false
* @access protected
*/
public function nextResult($result)
public function _checkManip($query)
{
return false;
return (preg_match('/^\s*(SAVEPOINT|RELEASE)\s+/i', $query)
|| parent::_checkManip($query));
}
// }}}
// {{{ fetchInto()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
$result_int = (int)$result;
$rownum = ($rownum !== null) ? $rownum : $this->row[$result_int];
if ($rownum >= $this->_num_rows[$result_int]) {
return null;
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @pg_fetch_row($result, $rownum);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
$this->row[$result_int] = ++$rownum;
return DB_OK;
}
// }}}
// {{{ freeResult()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
if (is_resource($result)) {
unset($this->row[(int)$result]);
unset($this->_num_rows[(int)$result]);
$this->affected = 0;
return @pg_freeresult($result);
}
return false;
}
// }}}
// {{{ 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.
*/
public function quoteBoolean($boolean)
{
return $boolean ? 'TRUE' : 'FALSE';
}
// }}}
// {{{ escapeSimple()
/**
* Escapes a string according to the current DBMS's standards
*
* {@internal PostgreSQL treats a backslash as an escape character,
* so they are escaped as well.
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
public function escapeSimple($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));
}
}
// }}}
// {{{ numCols()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @pg_numfields($result);
if (!$cols) {
return $this->pgsqlRaiseError();
}
return $cols;
}
// }}}
// {{{ numRows()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @pg_numrows($result);
if ($rows === null) {
return $this->pgsqlRaiseError();
}
return $rows;
}
// }}}
// {{{ autoCommit()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
// }}}
// {{{ commit()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function commit()
{
if ($this->transaction_opcount > 0) {
// (disabled) hack to shut up error messages from libpq.a
//@fclose(@fopen("php://stderr", "w"));
$result = @pg_exec($this->connection, 'end;');
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ rollback()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function rollback()
{
if ($this->transaction_opcount > 0) {
$result = @pg_exec($this->connection, 'abort;');
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ affectedRows()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
return $this->affected;
}
// }}}
// {{{ nextId()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_pgsql::createSequence(), DB_pgsql::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT NEXTVAL('${seqname}')");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = true;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
// }}}
// {{{ createSequence()
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_pgsql::nextID(), DB_pgsql::dropSequence()
*/
public function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$result = $this->query("CREATE SEQUENCE ${seqname}");
return $result;
}
// }}}
// {{{ dropSequence()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_pgsql::nextID(), DB_pgsql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP SEQUENCE '
. $this->getSequenceName($seq_name));
}
// }}}
// {{{ modifyLimitQuery()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
public function modifyLimitQuery($query, $from, $count, $params = array())
{
return "$query LIMIT $count OFFSET $from";
}
// }}}
// {{{ pgsqlRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
@ -788,7 +428,7 @@ class DB_pgsql extends DB_common
}
// }}}
// {{{ errorNative()
// {{{ freeResult()
/**
* Gets the DBMS' native error message produced by the last query
@ -804,7 +444,7 @@ class DB_pgsql extends DB_common
}
// }}}
// {{{ errorCode()
// {{{ quoteBoolean()
/**
* Determines PEAR::DB error code from the database's text error message.
@ -868,9 +508,390 @@ class DB_pgsql extends DB_common
return DB_ERROR;
}
// }}}
// {{{ escapeSimple()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @pg_numrows($result);
if ($rows === null) {
return $this->pgsqlRaiseError();
}
return $rows;
}
// }}}
// {{{ numCols()
/**
* Move the internal pgsql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return false;
}
// }}}
// {{{ numRows()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
$result_int = (int)$result;
$rownum = ($rownum !== null) ? $rownum : $this->row[$result_int];
if ($rownum >= $this->_num_rows[$result_int]) {
return null;
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @pg_fetch_row($result, $rownum);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
$this->row[$result_int] = ++$rownum;
return DB_OK;
}
// }}}
// {{{ autoCommit()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
if (is_resource($result)) {
unset($this->row[(int)$result]);
unset($this->_num_rows[(int)$result]);
$this->affected = 0;
return @pg_freeresult($result);
}
return false;
}
// }}}
// {{{ commit()
/**
* 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.
*/
public function quoteBoolean($boolean)
{
return $boolean ? 'TRUE' : 'FALSE';
}
// }}}
// {{{ rollback()
/**
* Escapes a string according to the current DBMS's standards
*
* {@internal PostgreSQL treats a backslash as an escape character,
* so they are escaped as well.
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
public function escapeSimple($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));
}
}
// }}}
// {{{ affectedRows()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @pg_numfields($result);
if (!$cols) {
return $this->pgsqlRaiseError();
}
return $cols;
}
// }}}
// {{{ nextId()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
// }}}
// {{{ createSequence()
/**
* Commits the current transaction
*
* @return int|object
*/
public function commit()
{
if ($this->transaction_opcount > 0) {
// (disabled) hack to shut up error messages from libpq.a
//@fclose(@fopen("php://stderr", "w"));
$result = @pg_exec($this->connection, 'end;');
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ dropSequence()
/**
* Reverts the current transaction
*
* @return int|object
*/
public function rollback()
{
if ($this->transaction_opcount > 0) {
$result = @pg_exec($this->connection, 'abort;');
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ modifyLimitQuery()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
return $this->affected;
}
// }}}
// {{{ pgsqlRaiseError()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_pgsql::createSequence(), DB_pgsql::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT NEXTVAL('${seqname}')");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = true;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
// }}}
// {{{ errorNative()
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_pgsql::nextID(), DB_pgsql::dropSequence()
*/
public function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$result = $this->query("CREATE SEQUENCE ${seqname}");
return $result;
}
// }}}
// {{{ errorCode()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_pgsql::nextID(), DB_pgsql::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP SEQUENCE '
. $this->getSequenceName($seq_name));
}
// }}}
// {{{ tableInfo()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
public function modifyLimitQuery($query, $from, $count, $params = array())
{
return "$query LIMIT $count OFFSET $from";
}
// }}}
// {{{ _pgFieldFlags()
/**
* Returns information about a table or a result set
*
@ -884,7 +905,7 @@ class DB_pgsql extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
@ -958,7 +979,7 @@ class DB_pgsql extends DB_common
}
// }}}
// {{{ _pgFieldFlags()
// {{{ getSpecialQuery()
/**
* Get a column's flags
@ -970,6 +991,7 @@ class DB_pgsql extends DB_common
* @param int $resource the PostgreSQL result identifier
* @param int $num_field the field number
*
* @param $table_name
* @return string the flags
*
* @access private
@ -1038,7 +1060,7 @@ class DB_pgsql extends DB_common
}
// }}}
// {{{ getSpecialQuery()
// {{{ _checkManip()
/**
* Obtains the query string needed for listing a given type of objects
@ -1099,27 +1121,6 @@ class DB_pgsql extends DB_common
return null;
}
}
// }}}
// {{{ _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
*/
public function _checkManip($query)
{
return (preg_match('/^\s*(SAVEPOINT|RELEASE)\s+/i', $query)
|| parent::_checkManip($query));
}
}
/*

View File

@ -28,7 +28,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's sqlite extension
@ -98,8 +99,7 @@ class DB_sqlite extends DB_common
*
* @var array
*/
public $errorcode_map = array(
);
public $errorcode_map = array();
/**
* The raw database connection created by PHP
@ -183,7 +183,7 @@ class DB_sqlite extends DB_common
* );
*
* $db = DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* if ((new PEAR)->isError($db)) {
* die($db->getMessage());
* }
* </code>
@ -191,7 +191,7 @@ class DB_sqlite extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -255,10 +255,98 @@ class DB_sqlite extends DB_common
// }}}
// {{{ disconnect()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_sqlite::errorNative(), DB_sqlite::errorCode()
*/
public function sqliteRaiseError($errno = null)
{
$native = $this->errorNative();
if ($errno === null) {
$errno = $this->errorCode($native);
}
$errorcode = @sqlite_last_error($this->connection);
$userinfo = "$errorcode ** $this->last_query";
return $this->raiseError($errno, null, null, $userinfo, $native);
}
// }}}
// {{{ simpleQuery()
/**
* Gets the DBMS' native error message produced by the last query
*
* {@internal This is used to retrieve more meaningfull error messages
* because sqlite_last_error() does not provide adequate info.}}
*
* @return string the DBMS' error message
*/
public function errorNative()
{
return $this->_lasterror;
}
// }}}
// {{{ nextResult()
/**
* Determines PEAR::DB error code from the database's text error message
*
* @param string $errormsg the error message returned from the database
*
* @return integer the DB error number
*/
public function errorCode($errormsg)
{
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)) {
$error_regexps = array(
'/^no such table:/' => DB_ERROR_NOSUCHTABLE,
'/^no such index:/' => DB_ERROR_NOT_FOUND,
'/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS,
'/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT,
'/is not unique/' => DB_ERROR_CONSTRAINT,
'/columns .* are not unique/i' => DB_ERROR_CONSTRAINT,
'/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
'/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
'/^no such column:/' => DB_ERROR_NOSUCHFIELD,
'/no column named/' => DB_ERROR_NOSUCHFIELD,
'/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD,
'/^near ".*": syntax error$/' => DB_ERROR_SYNTAX,
'/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW,
);
}
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
// }}}
// {{{ fetchInto()
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
* @return bool|void
*/
public function disconnect()
{
@ -268,7 +356,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ simpleQuery()
// {{{ freeResult()
/**
* Sends a query to the database server
@ -313,7 +401,63 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ nextResult()
// {{{ numCols()
/**
* Changes a query string for various DBMS specific reasons
*
* This little hack lets you know how many rows were deleted
* when running a "DELETE FROM table" query. Only implemented
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_common::setOption()
*/
public function modifyQuery($query)
{
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace(
'/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1',
$query
);
}
}
return $query;
}
// }}}
// {{{ numRows()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @sqlite_num_rows($result);
if ($rows === null) {
return $this->sqliteRaiseError();
}
return $rows;
}
// }}}
// {{{ affected()
/**
* Move the internal sqlite result pointer to the next available result
@ -328,7 +472,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ fetchInto()
// {{{ dropSequence()
/**
* Places a row from the result set into the given array
@ -392,9 +536,6 @@ class DB_sqlite extends DB_common
return DB_OK;
}
// }}}
// {{{ freeResult()
/**
* Deletes the result set and frees the memory occupied by the result set
*
@ -419,7 +560,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ numCols()
// {{{ nextId()
/**
* Gets the number of columns in a result set
@ -430,7 +571,7 @@ class DB_sqlite extends DB_common
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
* @return int|object
*
* @see DB_result::numCols()
*/
@ -444,32 +585,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ numRows()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @sqlite_num_rows($result);
if ($rows === null) {
return $this->sqliteRaiseError();
}
return $rows;
}
// }}}
// {{{ affected()
// {{{ getDbFileStats()
/**
* Determines the number of rows affected by a data maniuplation query
@ -484,7 +600,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ dropSequence()
// {{{ escapeSimple()
/**
* Deletes a sequence
@ -501,37 +617,8 @@ class DB_sqlite extends DB_common
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_sqlite::nextID(), DB_sqlite::dropSequence()
*/
public function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$query = 'CREATE TABLE ' . $seqname .
' (id INTEGER UNSIGNED PRIMARY KEY) ';
$result = $this->query($query);
if (DB::isError($result)) {
return($result);
}
$query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname
BEGIN
DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID();
END ";
$result = $this->query($query);
if (DB::isError($result)) {
return($result);
}
}
// }}}
// {{{ nextId()
// {{{ modifyLimitQuery()
/**
* Returns the next free id in a sequence
@ -540,7 +627,7 @@ class DB_sqlite extends DB_common
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
@ -575,7 +662,39 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ getDbFileStats()
// {{{ modifyQuery()
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_sqlite::nextID(), DB_sqlite::dropSequence()
*/
public function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$query = 'CREATE TABLE ' . $seqname .
' (id INTEGER UNSIGNED PRIMARY KEY) ';
$result = $this->query($query);
if (DB::isError($result)) {
return ($result);
}
$query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname
BEGIN
DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID();
END ";
$result = $this->query($query);
//if (DB::isError($result)) {
return ($result);
//}
}
// }}}
// {{{ sqliteRaiseError()
/**
* Get the file stats for the current database
@ -610,7 +729,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ escapeSimple()
// {{{ errorNative()
/**
* Escapes a string according to the current DBMS's standards
@ -633,7 +752,7 @@ class DB_sqlite extends DB_common
}
// }}}
// {{{ modifyLimitQuery()
// {{{ errorCode()
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
@ -656,125 +775,6 @@ class DB_sqlite extends DB_common
return "$query LIMIT $count OFFSET $from";
}
// }}}
// {{{ modifyQuery()
/**
* Changes a query string for various DBMS specific reasons
*
* This little hack lets you know how many rows were deleted
* when running a "DELETE FROM table" query. Only implemented
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_common::setOption()
*/
public function modifyQuery($query)
{
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace(
'/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1',
$query
);
}
}
return $query;
}
// }}}
// {{{ sqliteRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_sqlite::errorNative(), DB_sqlite::errorCode()
*/
public function sqliteRaiseError($errno = null)
{
$native = $this->errorNative();
if ($errno === null) {
$errno = $this->errorCode($native);
}
$errorcode = @sqlite_last_error($this->connection);
$userinfo = "$errorcode ** $this->last_query";
return $this->raiseError($errno, null, null, $userinfo, $native);
}
// }}}
// {{{ errorNative()
/**
* Gets the DBMS' native error message produced by the last query
*
* {@internal This is used to retrieve more meaningfull error messages
* because sqlite_last_error() does not provide adequate info.}}
*
* @return string the DBMS' error message
*/
public function errorNative()
{
return $this->_lasterror;
}
// }}}
// {{{ errorCode()
/**
* Determines PEAR::DB error code from the database's text error message
*
* @param string $errormsg the error message returned from the database
*
* @return integer the DB error number
*/
public function errorCode($errormsg)
{
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)) {
$error_regexps = array(
'/^no such table:/' => DB_ERROR_NOSUCHTABLE,
'/^no such index:/' => DB_ERROR_NOT_FOUND,
'/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS,
'/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT,
'/is not unique/' => DB_ERROR_CONSTRAINT,
'/columns .* are not unique/i' => DB_ERROR_CONSTRAINT,
'/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
'/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
'/^no such column:/' => DB_ERROR_NOSUCHFIELD,
'/no column named/' => DB_ERROR_NOSUCHFIELD,
'/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD,
'/^near ".*": syntax error$/' => DB_ERROR_SYNTAX,
'/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW,
);
}
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
// }}}
// {{{ tableInfo()
@ -784,7 +784,7 @@ class DB_sqlite extends DB_common
* @param string $result a string containing the name of a table
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()

View File

@ -46,33 +46,33 @@ class DB_storage extends PEAR
// {{{ properties
/** the name of the table (or view, if the backend database supports
updates in views) we hold data from */
* updates in views) we hold data from */
public $_table = null;
/** which column(s) in the table contains primary keys, can be a
string for single-column primary keys, or an array of strings
for multiple-column primary keys */
* string for single-column primary keys, or an array of strings
* for multiple-column primary keys */
public $_keycolumn = null;
/** DB connection handle used for all transactions */
public $_dbh = null;
/** an assoc with the names of database fields stored as properties
in this object */
* in this object */
public $_properties = array();
/** an assoc with the names of the properties in this object that
have been changed since they were fetched from the database */
* have been changed since they were fetched from the database */
public $_changes = array();
/** flag that decides if data in this object can be changed.
objects that don't have their table's key column in their
property lists will be flagged as read-only. */
* objects that don't have their table's key column in their
* property lists will be flagged as read-only. */
public $_readonly = false;
/** function or method that implements a validator for fields that
are set, this validator function returns true if the field is
valid, false if not */
* are set, this validator function returns true if the field is
* valid, false if not */
public $_validator = null;
// }}}
@ -107,6 +107,81 @@ class DB_storage extends PEAR
// }}}
// {{{ _makeWhere()
/**
* Create a new (empty) row in the configured table for this
* object.
* @param $newpk
* @return |null
*/
public function insert($newpk)
{
if (is_array($this->_keycolumn)) {
$primarykey = $this->_keycolumn;
} else {
$primarykey = array($this->_keycolumn);
}
settype($newpk, "array");
for ($i = 0; $i < sizeof($primarykey); $i++) {
$pkvals[] = $this->_dbh->quote($newpk[$i]);
}
$sth = $this->_dbh->query("INSERT INTO $this->_table (" .
implode(",", $primarykey) . ") VALUES(" .
implode(",", $pkvals) . ")");
if (DB::isError($sth)) {
return $sth;
}
if (sizeof($newpk) == 1) {
$newpk = $newpk[0];
}
$this->setup($newpk);
return null;
}
// }}}
// {{{ setup()
/**
* Method used to initialize a DB_storage object from the
* configured table.
*
* @param $keyval mixed the key[s] of the row to fetch (string or array)
*
* @return int|object
*/
public function setup($keyval)
{
$whereclause = $this->_makeWhere($keyval);
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
$sth = $this->_dbh->query($query);
if (DB::isError($sth)) {
return $sth;
}
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
if (DB::isError($row)) {
return $row;
}
if (!$row) {
return $this->raiseError(
null,
DB_ERROR_NOT_FOUND,
null,
null,
$query,
null,
true
);
}
foreach ($row as $key => $value) {
$this->_properties[$key] = true;
$this->$key = $value;
}
return DB_OK;
}
// }}}
// {{{ insert()
/**
* Utility method to build a "WHERE" clause to locate ourselves in
* the table.
@ -114,6 +189,8 @@ class DB_storage extends PEAR
* XXX future improvement: use rowids?
*
* @access private
* @param null $keyval
* @return mixed|string|null
*/
public function _makeWhere($keyval = null)
{
@ -153,78 +230,6 @@ class DB_storage extends PEAR
return $whereclause;
}
// }}}
// {{{ setup()
/**
* Method used to initialize a DB_storage object from the
* configured table.
*
* @param $keyval mixed the key[s] of the row to fetch (string or array)
*
* @return int DB_OK on success, a DB error if not
*/
public function setup($keyval)
{
$whereclause = $this->_makeWhere($keyval);
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
$sth = $this->_dbh->query($query);
if (DB::isError($sth)) {
return $sth;
}
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
if (DB::isError($row)) {
return $row;
}
if (!$row) {
return $this->raiseError(
null,
DB_ERROR_NOT_FOUND,
null,
null,
$query,
null,
true
);
}
foreach ($row as $key => $value) {
$this->_properties[$key] = true;
$this->$key = $value;
}
return DB_OK;
}
// }}}
// {{{ insert()
/**
* Create a new (empty) row in the configured table for this
* object.
*/
public function insert($newpk)
{
if (is_array($this->_keycolumn)) {
$primarykey = $this->_keycolumn;
} else {
$primarykey = array($this->_keycolumn);
}
settype($newpk, "array");
for ($i = 0; $i < sizeof($primarykey); $i++) {
$pkvals[] = $this->_dbh->quote($newpk[$i]);
}
$sth = $this->_dbh->query("INSERT INTO $this->_table (" .
implode(",", $primarykey) . ") VALUES(" .
implode(",", $pkvals) . ")");
if (DB::isError($sth)) {
return $sth;
}
if (sizeof($newpk) == 1) {
$newpk = $newpk[0];
}
$this->setup($newpk);
}
// }}}
// {{{ toString()
@ -293,6 +298,7 @@ class DB_storage extends PEAR
/**
* Static method used to create new DB storage objects.
* @param $table
* @param $data assoc. array where the keys are the names
* of properties/columns
* @return object a new instance of DB_storage or a subclass of it
@ -365,6 +371,9 @@ class DB_storage extends PEAR
/**
* Modify an attriute value.
* @param $property
* @param $newvalue
* @return bool|object
*/
public function set($property, $newvalue)
{
@ -469,7 +478,7 @@ class DB_storage extends PEAR
/**
* Stores changes to this object in the database.
*
* @return DB_OK or a DB error
* @return DB_OK|int
*/
public function store()
{

View File

@ -17,7 +17,7 @@
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio nior <floripa@php.net>
* @author Ant<EFBFBD>nio Carlos Ven<EFBFBD>ncio J<EFBFBD>nior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
@ -28,7 +28,8 @@
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
//require_once 'DB/common.php';
require_once 'common.php';
/**
* The methods PEAR DB uses to interact with PHP's sybase extension
@ -42,7 +43,7 @@ require_once 'DB/common.php';
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio nior <floripa@php.net>
* @author Ant<EFBFBD>nio Carlos Ven<EFBFBD>ncio J<EFBFBD>nior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
@ -92,8 +93,7 @@ class DB_sybase extends DB_common
* A mapping of native error codes to DB error codes
* @var array
*/
public $errorcode_map = array(
);
public $errorcode_map = array();
/**
* The raw database connection created by PHP
@ -167,7 +167,7 @@ class DB_sybase extends DB_common
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
* @return int|object
*/
public function connect($dsn, $persistent = false)
{
@ -291,340 +291,6 @@ class DB_sybase extends DB_common
// }}}
// {{{ nextResult()
/**
* Move the internal sybase result pointer to the next available result
*
* @param a valid sybase result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return false;
}
// }}}
// {{{ fetchInto()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@sybase_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
if (function_exists('sybase_fetch_assoc')) {
$arr = @sybase_fetch_assoc($result);
} else {
if ($arr = @sybase_fetch_array($result)) {
foreach ($arr as $key => $value) {
if (is_int($key)) {
unset($arr[$key]);
}
}
}
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @sybase_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
// }}}
// {{{ freeResult()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
return is_resource($result) ? sybase_free_result($result) : false;
}
// }}}
// {{{ numCols()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @sybase_num_fields($result);
if (!$cols) {
return $this->sybaseRaiseError();
}
return $cols;
}
// }}}
// {{{ numRows()
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @sybase_num_rows($result);
if ($rows === false) {
return $this->sybaseRaiseError();
}
return $rows;
}
// }}}
// {{{ affectedRows()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
if ($this->_last_query_manip) {
$result = @sybase_affected_rows($this->connection);
} else {
$result = 0;
}
return $result;
}
// }}}
// {{{ nextId()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_sybase::createSequence(), DB_sybase::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) {
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
}
} elseif (!DB::isError($result)) {
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0;
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
return $result[0];
}
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_sybase::nextID(), DB_sybase::dropSequence()
*/
public function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' (id numeric(10, 0) IDENTITY NOT NULL,'
. ' vapor int NULL)');
}
// }}}
// {{{ dropSequence()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_sybase::nextID(), DB_sybase::createSequence()
*/
public function dropSequence($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.
*/
public function quoteFloat($float)
{
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ autoCommit()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
// }}}
// {{{ commit()
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function commit()
{
if ($this->transaction_opcount > 0) {
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('COMMIT', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->sybaseRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ rollback()
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
public function rollback()
{
if ($this->transaction_opcount > 0) {
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('ROLLBACK', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->sybaseRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ sybaseRaiseError()
/**
* Produces a DB_Error object regarding the current problem
*
@ -647,7 +313,7 @@ class DB_sybase extends DB_common
}
// }}}
// {{{ errorNative()
// {{{ fetchInto()
/**
* Gets the DBMS' native error message produced by the last query
@ -660,7 +326,7 @@ class DB_sybase extends DB_common
}
// }}}
// {{{ errorCode()
// {{{ freeResult()
/**
* Determines PEAR::DB error code from the database's text error message.
@ -721,6 +387,340 @@ class DB_sybase extends DB_common
return DB_ERROR;
}
// }}}
// {{{ numCols()
/**
* Move the internal sybase result pointer to the next available result
*
* @param a valid sybase result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
public function nextResult($result)
{
return false;
}
// }}}
// {{{ numRows()
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
public function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@sybase_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
if (function_exists('sybase_fetch_assoc')) {
$arr = @sybase_fetch_assoc($result);
} else {
if ($arr = @sybase_fetch_array($result)) {
foreach ($arr as $key => $value) {
if (is_int($key)) {
unset($arr[$key]);
}
}
}
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @sybase_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
// }}}
// {{{ affectedRows()
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
public function freeResult($result)
{
return is_resource($result) ? sybase_free_result($result) : false;
}
// }}}
// {{{ nextId()
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numCols()
*/
public function numCols($result)
{
$cols = @sybase_num_fields($result);
if (!$cols) {
return $this->sybaseRaiseError();
}
return $cols;
}
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int|object
*
* @see DB_result::numRows()
*/
public function numRows($result)
{
$rows = @sybase_num_rows($result);
if ($rows === false) {
return $this->sybaseRaiseError();
}
return $rows;
}
// }}}
// {{{ dropSequence()
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
public function affectedRows()
{
if ($this->_last_query_manip) {
$result = @sybase_affected_rows($this->connection);
} else {
$result = 0;
}
return $result;
}
// }}}
// {{{ quoteFloat()
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int|object
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_sybase::createSequence(), DB_sybase::dropSequence()
*/
public function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) {
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
}
} elseif (!DB::isError($result)) {
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0;
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
return $result[0];
}
// }}}
// {{{ autoCommit()
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_sybase::nextID(), DB_sybase::dropSequence()
*/
public function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' (id numeric(10, 0) IDENTITY NOT NULL,'
. ' vapor int NULL)');
}
// }}}
// {{{ commit()
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_sybase::nextID(), DB_sybase::createSequence()
*/
public function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
// }}}
// {{{ rollback()
/**
* 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.
*/
public function quoteFloat($float)
{
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ sybaseRaiseError()
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
public function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
// }}}
// {{{ errorNative()
/**
* Commits the current transaction
*
* @return int|object
*/
public function commit()
{
if ($this->transaction_opcount > 0) {
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('COMMIT', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->sybaseRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ errorCode()
/**
* Reverts the current transaction
*
* @return int|object
*/
public function rollback()
{
if ($this->transaction_opcount > 0) {
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('ROLLBACK', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->sybaseRaiseError();
}
}
return DB_OK;
}
// }}}
// {{{ tableInfo()
@ -737,7 +737,7 @@ class DB_sybase extends DB_common
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* @return array|object
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()