- <?php
- /**
- * File for mock DB class
- *
- * This file has the same name as the file holding the {@link }
- * http://pear.php.net/package/DB PEAR DB class}.
- * To use the mock DB, put this file in the PHP include path ahead of
- * the PEAR library, so that any class which requires DB.php will
- * load this version.
- *
- * (PHP 5)
- *
- * @package PHPonTraxTest
- * @license http://opensource.org/licenses/gpl-license.php GNU Public License
- * @copyright (c) Walter O. Haas 2006
- * @version $Id: DB.php 198 2006-04-20 16:20:30Z haas $
- * @author Walt Haas <haas@xmission.com>
- */
-
- require_once 'PEAR.php';
- require_once 'PHPUnit2/Framework/Assert.php';
-
- /**
- * The code returned by many methods upon success
- */
- define('DB_OK', 1);
-
- /**
- * Unkown error
- */
- define('DB_ERROR', -1);
-
- /**
- * Syntax error
- */
- define('DB_ERROR_SYNTAX', -2);
-
- /**
- * Tried to insert a duplicate value into a primary or unique index
- */
- define('DB_ERROR_CONSTRAINT', -3);
-
- /**
- * An identifier in the query refers to a non-existant object
- */
- define('DB_ERROR_NOT_FOUND', -4);
-
- /**
- * Tried to create a duplicate object
- */
- define('DB_ERROR_ALREADY_EXISTS', -5);
-
- /**
- * The current driver does not support the action you attempted
- */
- define('DB_ERROR_UNSUPPORTED', -6);
-
- /**
- * The number of parameters does not match the number of placeholders
- */
- define('DB_ERROR_MISMATCH', -7);
-
- /**
- * A literal submitted did not match the data type expected
- */
- define('DB_ERROR_INVALID', -8);
-
- /**
- * The current DBMS does not support the action you attempted
- */
- define('DB_ERROR_NOT_CAPABLE', -9);
-
- /**
- * A literal submitted was too long so the end of it was removed
- */
- define('DB_ERROR_TRUNCATED', -10);
-
- /**
- * A literal number submitted did not match the data type expected
- */
- define('DB_ERROR_INVALID_NUMBER', -11);
-
- /**
- * A literal date submitted did not match the data type expected
- */
- define('DB_ERROR_INVALID_DATE', -12);
-
- /**
- * Attempt to divide something by zero
- */
- define('DB_ERROR_DIVZERO', -13);
-
- /**
- * A database needs to be selected
- */
- define('DB_ERROR_NODBSELECTED', -14);
-
- /**
- * Could not create the object requested
- */
- define('DB_ERROR_CANNOT_CREATE', -15);
-
- /**
- * Could not drop the database requested because it does not exist
- */
- define('DB_ERROR_CANNOT_DROP', -17);
-
- /**
- * An identifier in the query refers to a non-existant table
- */
- define('DB_ERROR_NOSUCHTABLE', -18);
-
- /**
- * An identifier in the query refers to a non-existant column
- */
- define('DB_ERROR_NOSUCHFIELD', -19);
-
- /**
- * The data submitted to the method was inappropriate
- */
- define('DB_ERROR_NEED_MORE_DATA', -20);
-
- /**
- * The attempt to lock the table failed
- */
- define('DB_ERROR_NOT_LOCKED', -21);
-
- /**
- * The number of columns doesn't match the number of values
- */
- define('DB_ERROR_VALUE_COUNT_ON_ROW', -22);
-
- /**
- * The DSN submitted has problems
- */
- define('DB_ERROR_INVALID_DSN', -23);
-
- /**
- * Could not connect to the database
- */
- define('DB_ERROR_CONNECT_FAILED', -24);
-
- /**
- * The PHP extension needed for this DBMS could not be found
- */
- define('DB_ERROR_EXTENSION_NOT_FOUND',-25);
-
- /**
- * The present user has inadequate permissions to perform the task requestd
- */
- define('DB_ERROR_ACCESS_VIOLATION', -26);
-
- /**
- * The database requested does not exist
- */
- define('DB_ERROR_NOSUCHDB', -27);
-
- /**
- * Tried to insert a null value into a column that doesn't allow nulls
- */
- define('DB_ERROR_CONSTRAINT_NOT_NULL',-29);
-
- /**
- * Identifiers for the placeholders used in prepared statements.
- * @see prepare()
- */
-
- /**
- * Indicates a scalar (<kbd>?</kbd>) placeholder was used
- *
- * Quote and escape the value as necessary.
- */
- define('DB_PARAM_SCALAR', 1);
-
- /**
- * Indicates an opaque (<kbd>&</kbd>) placeholder was used
- *
- * The value presented is a file name. Extract the contents of that file
- * and place them in this column.
- */
- define('DB_PARAM_OPAQUE', 2);
-
- /**
- * Indicates a misc (<kbd>!</kbd>) placeholder was used
- *
- * The value should not be quoted or escaped.
- */
- define('DB_PARAM_MISC', 3);
-
- /**
- * The different ways of returning binary data from queries.
- */
-
- /**
- * Sends the fetched data straight through to output
- */
- define('DB_BINMODE_PASSTHRU', 1);
-
- /**
- * Lets you return data as usual
- */
- define('DB_BINMODE_RETURN', 2);
-
- /**
- * Converts the data to hex format before returning it
- *
- * For example the string "123" would become "313233".
- */
- define('DB_BINMODE_CONVERT', 3);
-
- /**
- * Fetchmode constants
- */
- define('DB_FETCHMODE_DEFAULT', 0);
- define('DB_FETCHMODE_ORDERED', 1);
- define('DB_FETCHMODE_ASSOC', 2);
- define('DB_FETCHMODE_OBJECT', 3);
-
- /**
- * For multi-dimensional results, make the column name the first level
- * of the array and put the row number in the second level of the array
- *
- * This is flipped from the normal behavior, which puts the row numbers
- * in the first level of the array and the column names in the second level.
- */
- define('DB_FETCHMODE_FLIPPED', 4);
-
- /**
- * Old fetch modes. Left here for compatibility.
- */
- define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
- define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
- define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
-
- /**
- * The type of information to return from the tableInfo() method.
- *
- * Bitwised constants, so they can be combined using <kbd>|</kbd>
- * and removed using <kbd>^</kbd>.
- *
- * @see tableInfo()
- */
- define('DB_TABLEINFO_ORDER', 1);
- define('DB_TABLEINFO_ORDERTABLE', 2);
- define('DB_TABLEINFO_FULL', 3);
-
- /**
- * The type of query to create with the automatic query building methods.
- * @see autoPrepare(), autoExecute()
- */
- define('DB_AUTOQUERY_INSERT', 1);
- define('DB_AUTOQUERY_UPDATE', 2);
-
- /**
- * Portability Modes.
- *
- * Bitwised constants, so they can be combined using <kbd>|</kbd>
- * and removed using <kbd>^</kbd>.
- *
- * @see setOption()
- */
-
- /**
- * Turn off all portability features
- */
- define('DB_PORTABILITY_NONE', 0);
-
- /**
- * Convert names of tables and fields to lower case
- * when using the get*(), fetch*() and tableInfo() methods
- */
- define('DB_PORTABILITY_LOWERCASE', 1);
-
- /**
- * Right trim the data output by get*() and fetch*()
- */
- define('DB_PORTABILITY_RTRIM', 2);
-
- /**
- * Force reporting the number of rows deleted
- */
- define('DB_PORTABILITY_DELETE_COUNT', 4);
-
- /**
- * Enable hack that makes numRows() work in Oracle
- */
- define('DB_PORTABILITY_NUMROWS', 8);
-
- /**
- * Makes certain error messages in certain drivers compatible
- * with those from other DBMS's
- *
- * + mysql, mysqli: change unique/primary key constraints
- * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
- *
- * + odbc(access): MS's ODBC driver reports 'no such field' as code
- * 07001, which means 'too few parameters.' When this option is on
- * that code gets mapped to DB_ERROR_NOSUCHFIELD.
- */
- define('DB_PORTABILITY_ERRORS', 16);
-
- /**
- * Convert null values to empty strings in data output by
- * get*() and fetch*()
- */
- define('DB_PORTABILITY_NULL_TO_EMPTY', 32);
-
- /**
- * Turn on all portability features
- */
- define('DB_PORTABILITY_ALL', 63);
-
- /**
- * Mock DB class for testing
- *
- * This class is a mock version of the
- * {@link http://pear.php.net/package/DB PEAR DB class}. It is
- * intended to provide the same interface as the real DB class, plus
- * a small database sufficient to test software.
- */
-
- class DB {
-
- /**
- * Create a new DB object for the specified database type but don't
- * connect to the database
- *
- * @param string $type the database type (eg "mysql")
- * @param array $options an associative array of option names and values
- * @return object a new DB object. A DB_Error object on failure.
- * @see DB_common::setOption()
- * @todo Implement mock DB::factory
- */
- public function &factory($type, $options = false)
- {
- // if (!is_array($options)) {
- // $options = array('persistent' => $options);
- // }
- //
- // if (isset($options['debug']) && $options['debug'] >= 2) {
- // // expose php errors with sufficient debug level
- // include_once "DB/{$type}.php";
- // } else {
- // @include_once "DB/{$type}.php";
- // }
- //
- // $classname = "DB_${type}";
- //
- // if (!class_exists($classname)) {
- // $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
- // "Unable to include the DB/{$type}.php"
- // . " file for '$dsn'",
- // 'DB_Error', true);
- // return $tmp;
- // }
- //
- // @$obj =& new $classname;
- //
- // foreach ($options as $option => $value) {
- // $test = $obj->setOption($option, $value);
- // if (DB::isError($test)) {
- // return $test;
- // }
- // }
- //
- // return $obj;
- }
-
- /**
- * Create a new DB object including a connection to the specified database
- *
- * @param mixed $dsn the string "data source name" or array in the
- * format returned by DB::parseDSN()
- * @param array $options an associative array of option names and values
- * @return object a new DB object. A DB_Error object on failure.
- * @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError()
- * @todo Implement mock DB::connect
- */
- function &connect($dsn, $options = array())
- {
- $dsninfo = DB::parseDSN($dsn);
- $type = $dsninfo['phptype'];
-
- // only support MySQL at the moment
- PHPUnit2_Framework_Assert::assertEquals($type,'mysql');
- @$obj =& new DB_mysql;
-
- foreach ($options as $option => $value) {
- $test = $obj->setOption($option, $value);
- if (DB::isError($test)) {
- return $test;
- }
- }
-
- // $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
- // if (DB::isError($err)) {
- // $err->addUserInfo($dsn);
- // return $err;
- // }
- //
- return $obj;
- }
-
- /**
- * Return the DB API version
- *
- * @return string the DB API version number
- */
- function apiVersion()
- {
- return '1.7.6';
- }
-
- /**
- * Determines if a variable is a DB_Error object
- *
- * @param mixed $value the variable to check
- * @return bool whether $value is DB_Error object
- */
- function isError($value)
- {
- return is_a($value, 'DB_Error');
- }
-
- /**
- * Determines if a value is a DB_<driver> object
- *
- * @param mixed $value the value to test
- * @return bool whether $value is a DB_<driver> object
- * @todo Implement mock DB::isConnection
- */
- function isConnection($value)
- {
- // return (is_object($value) &&
- // is_subclass_of($value, 'db_common') &&
- // method_exists($value, 'simpleQuery'));
- }
-
- /**
- * Tell whether a query is a data manipulation or data definition query
- *
- * @param string $query the query
- * @return boolean whether $query is a data manipulation query
- */
- function isManip($query)
- {
- $manips = 'INSERT|UPDATE|DELETE|REPLACE|'
- . 'CREATE|DROP|'
- . 'LOAD DATA|SELECT .* INTO|COPY|'
- . 'ALTER|GRANT|REVOKE|'
- . 'LOCK|UNLOCK';
- if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) {
- return true;
- }
- return false;
- }
-
- /**
- * Return a textual error message for a DB error code
- *
- * @param integer $value the DB error code
- * @return string the error message or false if the error code was
- * not recognized
- * @todo Implement mock DB::errorMessage
- */
- public function errorMessage($value)
- {
- static $errorMessages;
- if (!isset($errorMessages)) {
- $errorMessages = array(
- DB_ERROR => 'unknown error',
- DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions',
- DB_ERROR_ALREADY_EXISTS => 'already exists',
- DB_ERROR_CANNOT_CREATE => 'can not create',
- DB_ERROR_CANNOT_DROP => 'can not drop',
- DB_ERROR_CONNECT_FAILED => 'connect failed',
- DB_ERROR_CONSTRAINT => 'constraint violation',
- DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
- DB_ERROR_DIVZERO => 'division by zero',
- DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
- DB_ERROR_INVALID => 'invalid',
- DB_ERROR_INVALID_DATE => 'invalid date or time',
- DB_ERROR_INVALID_DSN => 'invalid DSN',
- DB_ERROR_INVALID_NUMBER => 'invalid number',
- DB_ERROR_MISMATCH => 'mismatch',
- DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
- DB_ERROR_NODBSELECTED => 'no database selected',
- DB_ERROR_NOSUCHDB => 'no such database',
- DB_ERROR_NOSUCHFIELD => 'no such field',
- DB_ERROR_NOSUCHTABLE => 'no such table',
- DB_ERROR_NOT_CAPABLE => 'DB backend not capable',
- DB_ERROR_NOT_FOUND => 'not found',
- DB_ERROR_NOT_LOCKED => 'not locked',
- DB_ERROR_SYNTAX => 'syntax error',
- DB_ERROR_UNSUPPORTED => 'not supported',
- DB_ERROR_TRUNCATED => 'truncated',
- DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
- DB_OK => 'no error',
- );
- }
-
- // if (DB::isError($value)) {
- // $value = $value->getCode();
- // }
- //
- // return isset($errorMessages[$value]) ? $errorMessages[$value]
- // : $errorMessages[DB_ERROR];
- }
-
- /**
- * Parse a data source name
- *
- * @param string $dsn Data Source Name to be parsed
- * @return array an associative array with the following keys:
- * + phptype: Database backend used in PHP (mysql, odbc etc.)
- * + dbsyntax: Database used with regards to SQL syntax etc.
- * + protocol: Communication protocol to use (tcp, unix etc.)
- * + hostspec: Host specification (hostname[:port])
- * + database: Database to use on the DBMS server
- * + username: User name for login
- * + password: Password for login
- * @todo Implement mock DB::parseDSN
- */
- public function parseDSN($dsn)
- {
- $parsed = array(
- 'phptype' => false,
- 'dbsyntax' => false,
- 'username' => false,
- 'password' => false,
- 'protocol' => false,
- 'hostspec' => false,
- 'port' => false,
- 'socket' => false,
- 'database' => false,
- );
-
- if (is_array($dsn)) {
- $dsn = array_merge($parsed, $dsn);
- if (!$dsn['dbsyntax']) {
- $dsn['dbsyntax'] = $dsn['phptype'];
- }
- return $dsn;
- }
-
- // Find phptype and dbsyntax
- if (($pos = strpos($dsn, '://')) !== false) {
- $str = substr($dsn, 0, $pos);
- $dsn = substr($dsn, $pos + 3);
- } else {
- $str = $dsn;
- $dsn = null;
- }
-
- // Get phptype and dbsyntax
- // $str => phptype(dbsyntax)
- if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
- $parsed['phptype'] = $arr[1];
- $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2];
- } else {
- $parsed['phptype'] = $str;
- $parsed['dbsyntax'] = $str;
- }
-
- if (!count($dsn)) {
- return $parsed;
- }
-
- // Get (if found): username and password
- // $dsn => username:password@protocol+hostspec/database
- if (($at = strrpos($dsn,'@')) !== false) {
- $str = substr($dsn, 0, $at);
- $dsn = substr($dsn, $at + 1);
- if (($pos = strpos($str, ':')) !== false) {
- $parsed['username'] = rawurldecode(substr($str, 0, $pos));
- $parsed['password'] = rawurldecode(substr($str, $pos + 1));
- } else {
- $parsed['username'] = rawurldecode($str);
- }
- }
-
- // Find protocol and hostspec
-
- if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
- // $dsn => proto(proto_opts)/database
- $proto = $match[1];
- $proto_opts = $match[2] ? $match[2] : false;
- $dsn = $match[3];
-
- } else {
- // $dsn => protocol+hostspec/database (old format)
- if (strpos($dsn, '+') !== false) {
- list($proto, $dsn) = explode('+', $dsn, 2);
- }
- if (strpos($dsn, '/') !== false) {
- list($proto_opts, $dsn) = explode('/', $dsn, 2);
- } else {
- $proto_opts = $dsn;
- $dsn = null;
- }
- }
-
- // process the different protocol options
- $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
- $proto_opts = rawurldecode($proto_opts);
- if ($parsed['protocol'] == 'tcp') {
- if (strpos($proto_opts, ':') !== false) {
- list($parsed['hostspec'],
- $parsed['port']) = explode(':', $proto_opts);
- } else {
- $parsed['hostspec'] = $proto_opts;
- }
- } elseif ($parsed['protocol'] == 'unix') {
- $parsed['socket'] = $proto_opts;
- }
-
- // Get dabase if any
- // $dsn => database
- if ($dsn) {
- if (($pos = strpos($dsn, '?')) === false) {
- // /database
- $parsed['database'] = rawurldecode($dsn);
- } else {
- // /database?param1=value1¶m2=value2
- $parsed['database'] = rawurldecode(substr($dsn, 0, $pos));
- $dsn = substr($dsn, $pos + 1);
- if (strpos($dsn, '&') !== false) {
- $opts = explode('&', $dsn);
- } else { // database?param1=value1
- $opts = array($dsn);
- }
- foreach ($opts as $opt) {
- list($key, $value) = explode('=', $opt);
- if (!isset($parsed[$key])) {
- // don't allow params overwrite
- $parsed[$key] = rawurldecode($value);
- }
- }
- }
- }
-
- return $parsed;
- }
- }
-
- /**
- * Mock DB_common for testing
- * @todo Implement mock DB_common class
- */
- class DB_common extends PEAR {
-
- /**
- * Mock Database
- */
- protected static $database =
- // Person names table
- array('person_names' =>
- // Description
- array('info' =>
- array(array('table' => 'person_names',
- 'name' => 'id',
- 'type' => 'int',
- 'len' => '11',
- 'flags' => 'primary_key not_null'),
- array('table' => 'person_names',
- 'name' => 'prefix',
- 'type' => 'string',
- 'len' => '20',
- 'flags' => ''),
- array('table' => 'person_names',
- 'name' => 'first_name',
- 'type' => 'string',
- 'len' => '40',
- 'flags' => ''),
- array('table' => 'person_names',
- 'name' => 'mi',
- 'type' => 'string',
- 'len' => '1',
- 'flags' => ''),
- array('table' => 'person_names',
- 'name' => 'last_name',
- 'type' => 'string',
- 'len' => '40',
- 'flags' => ''),
- array('table' => 'person_names',
- 'name' => 'suffix',
- 'type' => 'string',
- 'len' => '20',
- 'flags' => ''),
- ),
- 'data' =>
- array()
- ),
-
- // Data types table
- 'data_types' =>
-
- // Description
- array('info' =>
- array(array("table" => "data_types",
- "name" => "id",
- "type" => "int",
- "len" => '11',
- "flags" => "not_null primary_key auto_increment"),
- array("table" => "data_types",
- "name" => "bit_type",
- "type" => "int",
- "len" => '1',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "tinyint_type",
- "type" => "int",
- "len" => '4',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "bool_type",
- "type" => "int",
- "len" => '1',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "boolean_type",
- "type" => "int",
- "len" => '1',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "smallint_type",
- "type" => "int",
- "len" => '6',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "mediumint_type",
- "type" => "int",
- "len" => '9',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "int_type",
- "type" => "int",
- "len" => '11',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "integer_type",
- "type" => "int",
- "len" => '11',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "bigint_type",
- "type" => "int",
- "len" => '20',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "float_type",
- "type" => "real",
- "len" => '12',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "double_type",
- "type" => "real",
- "len" => '22',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "double_precision_type",
- "type" => "real",
- "len" => '22',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "decimal_type",
- "type" => "real",
- "len" => '11',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "dec_type",
- "type" => "real",
- "len" => '11',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "numeric_type",
- "type" => "real",
- "len" => '11',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "fixed_type",
- "type" => "real",
- "len" => '11',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "date_type",
- "type" => "date",
- "len" => '10',
- "flags" => "binary"),
- array("table" => "data_types",
- "name" => "datetime_type",
- "type" => "datetime",
- "len" => '19',
- "flags" => "binary"),
- array("table" => "data_types",
- "name" => "timestamp_type",
- "type" => "timestamp",
- "len" => '19',
- "flags" => "unsigned zerofill binary"),
- array("table" => "data_types",
- "name" => "time_type",
- "type" => "time",
- "len" => '8',
- "flags" => "binary"),
- array("table" => "data_types",
- "name" => "year_type",
- "type" => "year",
- "len" => '4',
- "flags" => "unsigned zerofill"),
- array("table" => "data_types",
- "name" => "char_type",
- "type" => "string",
- "len" => '20',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "varchar_type",
- "type" => "string",
- "len" => '20',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "nchar_type",
- "type" => "string",
- "len" => '20',
- "flags" => ""),
- array("table" => "data_types",
- "name" => "binary_type",
- "type" => "string",
- "len" => '20',
- "flags" => "binary"),
- array("table" => "data_types",
- "name" => "varbinary_type",
- "type" => "string",
- "len" => '20',
- "flags" => "binary"),
- array("table" => "data_types",
- "name" => "tinyblob_type",
- "type" => "blob",
- "len" => '255',
- "flags" => "blob binary"),
- array("table" => "data_types",
- "name" => "tinytext_type",
- "type" => "blob",
- "len" => '255',
- "flags" => "blob"),
- array("table" => "data_types",
- "name" => "blob_type",
- "type" => "blob",
- "len" => '65535',
- "flags" => "blob binary"),
- array("table" => "data_types",
- "name" => "text_type",
- "type" => "blob",
- "len" => '65535',
- "flags" => "blob"),
- array("table" => "data_types",
- "name" => "mediumblob_type",
- "type" => "blob",
- "len" => '16777215',
- "flags" => "blob binary"),
- array("table" => "data_types",
- "name" => "mediumtext_type",
- "type" => "blob",
- "len" => '16777215',
- "flags" => "blob"),
- array("table" => "data_types",
- "name" => "longblob_type",
- "type" => "blob",
- "len" => '-1',
- "flags" => "blob binary"),
- array("table" => "data_types",
- "name" => "longtext_type",
- "type" => "blob",
- "len" => '-1',
- "flags" => "blob"),
- array("table" => "data_types",
- "name" => "enum_type",
- "type" => "string",
- "len" => '3',
- "flags" => "enum"),
- array("table" => "data_types",
- "name" => "set_type",
- "type" => "string",
- "len" => '7',
- "flags" => "set"),
- ),
- 'data' =>
- array()
- ),
- );
-
- /**
- * Run-time configuration options
- *
- * @var array
- * @see DB_common::setOption()
- */
- var $options = array(
- 'result_buffering' => 500,
- 'persistent' => false,
- 'ssl' => false,
- 'debug' => 0,
- 'seqname_format' => '%s_seq',
- 'autofree' => false,
- 'portability' => DB_PORTABILITY_NONE,
- 'optimize' => 'performance', // Deprecated. Use 'portability'.
- );
-
- /**
- * List of expected queries and returns
- */
- private $expected_list = null;
-
- /**
- * Cursor in list of expected queries and returns
- */
- private $expected_list_cursor = null;
-
- /**
- * Expected query
- * @var string
- */
- private $expected_query = null;
-
- /**
- * Result to be returned from expected query
- * @var string
- */
- private $expected_result = null;
-
- /**
- * This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
- *
- * @return void
- */
- function DB_common()
- {
- $this->PEAR('DB_Error');
- }
-
- /**
- * Automatically indicates which properties should be saved
- * when PHP's serialize() function is called
- *
- * @return array the array of properties names that should be saved
- * @todo Implement mock DB_common::__sleep
- */
- function __sleep()
- {
- // if ($this->connection) {
- // // Don't disconnect(), people use serialize() for many reasons
- // $this->was_connected = true;
- // } else {
- // $this->was_connected = false;
- // }
- // if (isset($this->autocommit)) {
- // return array('autocommit',
- // 'dbsyntax',
- // 'dsn',
- // 'features',
- // 'fetchmode',
- // 'fetchmode_object_class',
- // 'options',
- // 'was_connected',
- // );
- // } else {
- // return array('dbsyntax',
- // 'dsn',
- // 'features',
- // 'fetchmode',
- // 'fetchmode_object_class',
- // 'options',
- // 'was_connected',
- // );
- // }
- }
-
- /**
- * Automatically reconnects to the database when PHP's unserialize()
- * function is called
- *
- * @return void
- * @todo Implement mock DB_common::__wakeup
- */
- function __wakeup()
- {
- // if ($this->was_connected) {
- // $this->connect($this->dsn, $this->options);
- // }
- }
-
- /**
- * Automatic string conversion for PHP 5
- *
- * @return string a string describing the current PEAR DB object
- * @todo Implement mock DB_common::__toString
- */
- public function __toString()
- {
- // $info = strtolower(get_class($this));
- // $info .= ': (phptype=' . $this->phptype .
- // ', dbsyntax=' . $this->dbsyntax .
- // ')';
- // if ($this->connection) {
- // $info .= ' [connected]';
- // }
- // return $info;
- }
-
- /**
- * Quotes a string so it can be safely used as a table or column name
- *
- * @param string $str the identifier name to be quoted
- * @return string the quoted identifier
- */
- public function quoteIdentifier($str)
- {
- return '"' . str_replace('"', '""', $str) . '"';
- }
-
- /**
- * Formats input so it can be safely used in a query
- *
- * @see DB_common::escapeSimple()
- * @todo Implement mock DB_common::quoteSmart
- */
- public function quoteSmart($in)
- {
- // if (is_int($in) || is_double($in)) {
- // return $in;
- // } elseif (is_bool($in)) {
- // return $in ? 1 : 0;
- // } elseif (is_null($in)) {
- // return 'NULL';
- // } else {
- // return "'" . $this->escapeSimple($in) . "'";
- // }
- }
-
- /**
- * 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()
- * @todo Implement mock DB_common::escapeSimple
- */
- public function escapeSimple($str)
- {
- // return str_replace("'", "''", $str);
- }
-
- /**
- * Tells whether the present driver supports a given feature
- *
- * @param string $feature the feature you're curious about
- * @return bool whether this driver supports $feature
- * @todo Implement mock DB_common::provides
- */
- public function provides($feature)
- {
- // return $this->features[$feature];
- }
-
- /**
- * Sets the fetch mode that should be used by default for query results
- *
- * @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
- * or DB_FETCHMODE_OBJECT
- * @param string $object_class the class name of the object to be returned
- * by the fetch methods when the
- * DB_FETCHMODE_OBJECT mode is selected.
- * If no class is specified by default a cast
- * to object from the assoc array row will be
- * done. There is also the posibility to use
- * and extend the 'DB_row' class.
- *
- * @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
- * @todo Implement mock DB_common::setFetchMode
- */
- public function setFetchMode($fetchmode, $object_class = 'stdClass')
- {
- // switch ($fetchmode) {
- // case DB_FETCHMODE_OBJECT:
- // $this->fetchmode_object_class = $object_class;
- // case DB_FETCHMODE_ORDERED:
- // case DB_FETCHMODE_ASSOC:
- // $this->fetchmode = $fetchmode;
- // break;
- // default:
- // return $this->raiseError('invalid fetchmode mode');
- // }
- }
-
- /**
- * Sets run-time configuration options for PEAR DB
- *
- * @param string $option option name
- * @param mixed $value value for the option
- * @return int DB_OK on success. A DB_Error object on failure.
- * @see DB_common::$options
- * @todo Implement mock DB_common::setOption
- */
- public function setOption($option, $value)
- {
- if (isset($this->options[$option])) {
- $this->options[$option] = $value;
- return DB_OK;
- }
- PHPUnit2_Framework_Assert::fail("DB_common::setOption called"
- ." with unknown option $option");
- }
-
- /**
- * Returns the value of an option
- *
- * @param string $option the option name you're curious about
- * @return mixed the option's value
- * @todo Implement mock DB_common::getOption
- */
- public function getOption($option)
- {
- // if (isset($this->options[$option])) {
- // return $this->options[$option];
- // }
- // return $this->raiseError("unknown option $option");
- }
-
- /**
- * Prepares a query for multiple execution with execute()
- *
- * @param string $query the query to be prepared
- * @return mixed DB statement resource on success. A DB_Error object
- * on failure.
- * @see DB_common::execute()
- * @todo Implement mock DB_common::prepare
- */
- public function prepare($query)
- {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- // $tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1,
- // PREG_SPLIT_DELIM_CAPTURE);
- // $token = 0;
- // $types = array();
- // $newtokens = array();
- //
- // foreach ($tokens as $val) {
- // switch ($val) {
- // case '?':
- // $types[$token++] = DB_PARAM_SCALAR;
- // break;
- // case '&':
- // $types[$token++] = DB_PARAM_OPAQUE;
- // break;
- // case '!':
- // $types[$token++] = DB_PARAM_MISC;
- // break;
- // default:
- // $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val);
- // }
- // }
- //
- // $this->prepare_tokens[] = &$newtokens;
- // end($this->prepare_tokens);
- //
- // $k = key($this->prepare_tokens);
- // $this->prepare_types[$k] = $types;
- // $this->prepared_queries[$k] = implode(' ', $newtokens);
- //
- // return $k;
- }
-
-
- /**
- * Automaticaly generates an insert or update query and pass it to
- * prepare()
- *
- * @param string $table the table name
- * @param array $table_fields the array of field names
- * @param int $mode a type of query to make:
- * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
- * @param string $where for update queries: the WHERE clause to
- * append to the SQL statement. Don't
- * include the "WHERE" keyword.
- *
- * @return resource the query handle
- * @uses DB_common::prepare(), DB_common::buildManipSQL()
- * @todo Implement mock DB_common::autoPrepare
- */
- public function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT,
- $where = false)
- {
- // $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
- // if (DB::isError($query)) {
- // return $query;
- // }
- // return $this->prepare($query);
- }
-
- /**
- * Automaticaly generates an insert or update query and call prepare()
- * and execute() with it
- *
- * @param string $table the table name
- * @param array $fields_values the associative array where $key is a
- * field name and $value its value
- * @param int $mode a type of query to make:
- * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
- * @param string $where for update queries: the WHERE clause to
- * append to the SQL statement. Don't
- * include the "WHERE" keyword.
- *
- * @return mixed a new DB_result object for successful SELECT queries
- * or DB_OK for successul data manipulation queries.
- * A DB_Error object on failure.
- *
- * @uses DB_common::autoPrepare(), DB_common::execute()
- * @todo Implement mock DB_common::autoExecute
- */
- public function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT,
- $where = false)
- {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- // $sth = $this->autoPrepare($table, array_keys($fields_values), $mode,
- // $where);
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- // $ret =& $this->execute($sth, array_values($fields_values));
- // $this->freePrepared($sth);
- // return $ret;
- }
-
- /**
- * Produces an SQL query string for autoPrepare()
- *
- * @param string $table the table name
- * @param array $table_fields the array of field names
- * @param int $mode a type of query to make:
- * DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
- * @param string $where for update queries: the WHERE clause to
- * append to the SQL statement. Don't
- * include the "WHERE" keyword.
- *
- * @return string the sql query for autoPrepare()
- * @todo Implement mock DB_common::buildManipSQL
- */
- public function buildManipSQL($table, $table_fields, $mode, $where = false)
- {
- // if (count($table_fields) == 0) {
- // return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
- // }
- // $first = true;
- // switch ($mode) {
- // case DB_AUTOQUERY_INSERT:
- // $values = '';
- // $names = '';
- // foreach ($table_fields as $value) {
- // if ($first) {
- // $first = false;
- // } else {
- // $names .= ',';
- // $values .= ',';
- // }
- // $names .= $value;
- // $values .= '?';
- // }
- // return "INSERT INTO $table ($names) VALUES ($values)";
- // case DB_AUTOQUERY_UPDATE:
- // $set = '';
- // foreach ($table_fields as $value) {
- // if ($first) {
- // $first = false;
- // } else {
- // $set .= ',';
- // }
- // $set .= "$value = ?";
- // }
- // $sql = "UPDATE $table SET $set";
- // if ($where) {
- // $sql .= " WHERE $where";
- // }
- // return $sql;
- // default:
- // return $this->raiseError(DB_ERROR_SYNTAX);
- // }
- }
-
- /**
- * Executes a DB statement prepared with prepare()
- *
- * @param resource $stmt a DB statement resource returned from prepare()
- * @param mixed $data 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 mixed a new DB_result object for successful SELECT queries
- * or DB_OK for successul data manipulation queries.
- * A DB_Error object on failure.
- *
- * @see DB_common::prepare()
- * @todo Implement mock DB_common::execute
- */
- public function &execute($stmt, $data = array())
- {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- // $realquery = $this->executeEmulateQuery($stmt, $data);
- // if (DB::isError($realquery)) {
- // return $realquery;
- // }
- // $result = $this->simpleQuery($realquery);
- //
- // if ($result === DB_OK || DB::isError($result)) {
- // return $result;
- // } else {
- // $tmp =& new DB_result($this, $result);
- // return $tmp;
- // }
- }
-
- /**
- * Emulates executing prepared statements if the DBMS not support them
- *
- * @param resource $stmt a DB statement resource returned from execute()
- * @param mixed $data 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 mixed a string containing the real query run when emulating
- * prepare/execute. A DB_Error object on failure.
- *
- * @see DB_common::execute()
- * @todo Implement mock DB_common::executeEmulateQuery
- */
- protected function executeEmulateQuery($stmt, $data = array())
- {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- // $stmt = (int)$stmt;
- // $data = (array)$data;
- // $this->last_parameters = $data;
- //
- // if (count($this->prepare_types[$stmt]) != count($data)) {
- // $this->last_query = $this->prepared_queries[$stmt];
- // return $this->raiseError(DB_ERROR_MISMATCH);
- // }
- //
- // $realquery = $this->prepare_tokens[$stmt][0];
- //
- // $i = 0;
- // foreach ($data as $value) {
- // if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) {
- // $realquery .= $this->quoteSmart($value);
- // } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) {
- // $fp = @fopen($value, 'rb');
- // if (!$fp) {
- // return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
- // }
- // $realquery .= $this->quoteSmart(fread($fp, filesize($value)));
- // fclose($fp);
- // } else {
- // $realquery .= $value;
- // }
- //
- // $realquery .= $this->prepare_tokens[$stmt][++$i];
- // }
- //
- // return $realquery;
- }
-
- /**
- * Performs several execute() calls on the same statement handle
- *
- * @param resource $stmt query handle from prepare()
- * @param array $data numeric array containing the
- * data to insert into the query
- * @return int DB_OK on success. A DB_Error object on failure.
- * @see DB_common::prepare(), DB_common::execute()
- * @todo Implement mock DB_common::executeMultiple
- */
- function executeMultiple($stmt, $data)
- {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- // foreach ($data as $value) {
- // $res =& $this->execute($stmt, $value);
- // if (DB::isError($res)) {
- // return $res;
- // }
- // }
- // return DB_OK;
- }
-
- /**
- * Frees the internal resources associated with a prepared query
- *
- * @param resource $stmt the prepared statement's PHP resource
- * @param bool $free_resource should the PHP resource be freed too?
- * Use false if you need to get data
- * from the result set later.
- * @return bool TRUE on success, FALSE if $result is invalid
- * @see DB_common::prepare()
- * @todo Implement mock DB_common::freePrepared
- */
- function freePrepared($stmt, $free_resource = true)
- {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- // $stmt = (int)$stmt;
- // if (isset($this->prepare_tokens[$stmt])) {
- // unset($this->prepare_tokens[$stmt]);
- // unset($this->prepare_types[$stmt]);
- // unset($this->prepared_queries[$stmt]);
- // return true;
- // }
- // return false;
- }
-
- /**
- * Changes a query string for various DBMS specific reasons
- *
- * @param string $query the query string to modify
- * @return string the modified query string
- * @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
- * DB_sqlite::modifyQuery()
- * @todo Implement mock DB_common::modifyQuery
- */
- protected function modifyQuery($query)
- {
- // return $query;
- }
-
- /**
- * 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
- * @todo Implement mock DB_common::modifyLimitQuery
- */
- protected function modifyLimitQuery($query, $from, $count, $params = array())
- {
- // return $query;
- }
-
- /**
- * Set expected query and return
- *
- * This is a test routine that does not exist in the PEAR DB package.
- * @param string $expected Expected query
- * @param string $result Result to be returned when expected
- * query is received.
- */
- public function expect_query($expected, $result) {
- $this->expected_query = $expected;
- $this->expected_result = $result;
- }
-
- /**
- * Set list of expected queries and returns
- *
- * This is a test routine that does not exist in the PEAR DB package.
- * @param string $list Expected queries and returns
- */
- public function expect_queries($list) {
- $this->expected_list = $list;
- $this->expected_list_cursor = 0;
- $this->expect_query($this->expected_list[0]['query'],
- $this->expected_list[0]['result']);
- }
-
- /**
- * Verify that all expected queries have been received
- *
- * This is a test routine that does not exist in the PEAR DB package.
- */
- public function tally_queries() {
- if ($this->expected_list_cursor < count($this->expected_list)) {
- PHPUnit2_Framework_Assert::fail("DB_mysql::expected query was"
- ." not received. expected $this->expected_query");
- }
- }
-
- /**
- * Sends a query to the database server
- *
- * @param string $query the SQL query or the statement to prepare
- * @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 mixed a new DB_result object for successful SELECT queries
- * or DB_OK for successul data manipulation queries.
- * A DB_Error object on failure.
- *
- * @see DB_result, DB_common::prepare(), DB_common::execute()
- * @todo Implement mock DB_common::query
- */
- public function &query($query, $params = array())
- {
- $params = (array)$params;
- if (sizeof($params) > 0) {
- PHPUnit2_Framework_Assert::fail("DB does not support"
- . " multiple execution");
- }
- if (!is_null($this->expected_list)) {
- // We are working through a list of queries. If the
- // number of queries received is greater than the number
- // on the list, that's an error
- if ($this->expected_list_cursor >= count($this->expected_list)) {
- PHPUnit2_Framework_Assert::fail(
- "DB_mysql::query called with"
- ."$query, exceeding number of queries expected");
- }
- }
- if ($query != $this->expected_query) {
- PHPUnit2_Framework_Assert::fail('DB_mysql::query() called with'
- .' "'.$query.'", expected "'.$this->expected_query.'"');
- }
- $result = $this->expected_result;
- if (!is_null($this->expected_list)) {
- // More queries are expected. Advance the cursor
- $this->expected_list_cursor++;
- $this->expect_query(
- $this->expected_list[$this->expected_list_cursor]['query'],
- $this->expected_list[$this->expected_list_cursor]['result']);
- }
- return $result;
- // if (sizeof($params) > 0) {
- // $sth = $this->prepare($query);
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- // $ret =& $this->execute($sth, $params);
- // $this->freePrepared($sth, false);
- // return $ret;
- // } else {
- // $this->last_parameters = array();
- // $result = $this->simpleQuery($query);
- // if ($result === DB_OK || DB::isError($result)) {
- // return $result;
- // } else {
- // $tmp =& new DB_result($this, $result);
- // return $tmp;
- // }
- // }
- }
-
- /**
- * Generates and executes a LIMIT query
- *
- * @param string $query the query
- * @param intr $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 mixed a new DB_result object for successful SELECT queries
- * or DB_OK for successul data manipulation queries.
- * A DB_Error object on failure.
- * @todo Implement mock DB_common::limitQuery
- */
- public function &limitQuery($query, $from, $count, $params = array())
- {
- // $query = $this->modifyLimitQuery($query, $from, $count, $params);
- // if (DB::isError($query)){
- // return $query;
- // }
- // $result =& $this->query($query, $params);
- // if (is_a($result, 'DB_result')) {
- // $result->setOption('limit_from', $from);
- // $result->setOption('limit_count', $count);
- // }
- // return $result;
- }
-
- /**
- * Fetches the first column of the first row from a query result
- *
- * @param string $query the SQL query
- * @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 mixed the returned value of the query.
- * A DB_Error object on failure.
- * @todo Implement mock DB_common::getOne
- */
- function &getOne($query, $params = array())
- {
- return $this->query($query,$params);
-
- // $sth = $this->prepare($query);
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- // $res =& $this->execute($sth, $params);
- // $this->freePrepared($sth);
- // } else {
- // $res =& $this->query($query);
- // }
- //
- // if (DB::isError($res)) {
- // return $res;
- // }
- //
- // $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
- // $res->free();
- //
- // if ($err !== DB_OK) {
- // return $err;
- // }
- //
- // return $row[0];
- }
-
- /**
- * Fetches the first row of data returned from a query result
- *
- * @param string $query the SQL query
- * @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.
- * @param int $fetchmode the fetch mode to use
- *
- * @return array the first row of results as an array.
- * A DB_Error object on failure.
- * @todo Implement mock DB_common::getRow
- */
- public function &getRow($query, $params = array(),
- $fetchmode = DB_FETCHMODE_DEFAULT)
- {
- // // compat check, the params and fetchmode parameters used to
- // // have the opposite order
- // if (!is_array($params)) {
- // if (is_array($fetchmode)) {
- // if ($params === null) {
- // $tmp = DB_FETCHMODE_DEFAULT;
- // } else {
- // $tmp = $params;
- // }
- // $params = $fetchmode;
- // $fetchmode = $tmp;
- // } elseif ($params !== null) {
- // $fetchmode = $params;
- // $params = array();
- // }
- // }
- // // modifyLimitQuery() would be nice here, but it causes BC issues
- // if (sizeof($params) > 0) {
- // $sth = $this->prepare($query);
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- // $res =& $this->execute($sth, $params);
- // $this->freePrepared($sth);
- // } else {
- // $res =& $this->query($query);
- // }
- //
- // if (DB::isError($res)) {
- // return $res;
- // }
- //
- // $err = $res->fetchInto($row, $fetchmode);
- //
- // $res->free();
- //
- // if ($err !== DB_OK) {
- // return $err;
- // }
- //
- // return $row;
- }
-
- /**
- * Fetches a single column from a query result and returns it as an
- * indexed array
- *
- * @param string $query the SQL query
- * @param mixed $col which column to return (integer [column number,
- * starting at 0] or string [column name])
- * @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 array the results as an array. A DB_Error object on failure.
- *
- * @see DB_common::query()
- * @todo Implement mock DB_common::getCol
- */
- public function &getCol($query, $col = 0, $params = array())
- {
- // $params = (array)$params;
- // if (sizeof($params) > 0) {
- // $sth = $this->prepare($query);
- //
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- //
- // $res =& $this->execute($sth, $params);
- // $this->freePrepared($sth);
- // } else {
- // $res =& $this->query($query);
- // }
- //
- // if (DB::isError($res)) {
- // return $res;
- // }
- //
- // $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
- //
- // if (!is_array($row = $res->fetchRow($fetchmode))) {
- // $ret = array();
- // } else {
- // if (!array_key_exists($col, $row)) {
- // $ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
- // } else {
- // $ret = array($row[$col]);
- // while (is_array($row = $res->fetchRow($fetchmode))) {
- // $ret[] = $row[$col];
- // }
- // }
- // }
- //
- // $res->free();
- //
- // if (DB::isError($row)) {
- // $ret = $row;
- // }
- //
- // return $ret;
- }
-
- /**
- * Fetches an entire query result and returns it as an
- * associative array using the first column as the key
- *
- * @param string $query the SQL query
- * @param bool $force_array used only when the query returns
- * exactly two columns. If true, the values
- * of the returned array will be one-element
- * arrays instead of scalars.
- * @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.
- * @param int $fetchmode the fetch mode to use
- * @param bool $group if true, the values of the returned array
- * is wrapped in another array. If the same
- * key value (in the first column) repeats
- * itself, the values will be appended to
- * this array instead of overwriting the
- * existing values.
- *
- * @return array the associative array containing the query results.
- * A DB_Error object on failure.
- * @todo Implement mock DB_common::getAssoc
- */
- public function &getAssoc($query, $force_array = false, $params = array(),
- $fetchmode = DB_FETCHMODE_DEFAULT, $group = false)
- {
- // $params = (array)$params;
- // if (sizeof($params) > 0) {
- // $sth = $this->prepare($query);
- //
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- //
- // $res =& $this->execute($sth, $params);
- // $this->freePrepared($sth);
- // } else {
- // $res =& $this->query($query);
- // }
- //
- // if (DB::isError($res)) {
- // return $res;
- // }
- // if ($fetchmode == DB_FETCHMODE_DEFAULT) {
- // $fetchmode = $this->fetchmode;
- // }
- // $cols = $res->numCols();
- //
- // if ($cols < 2) {
- // $tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
- // return $tmp;
- // }
- //
- // $results = array();
- //
- // if ($cols > 2 || $force_array) {
- // // return array values
- // // XXX this part can be optimized
- // if ($fetchmode == DB_FETCHMODE_ASSOC) {
- // while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) {
- // reset($row);
- // $key = current($row);
- // unset($row[key($row)]);
- // if ($group) {
- // $results[$key][] = $row;
- // } else {
- // $results[$key] = $row;
- // }
- // }
- // } elseif ($fetchmode == DB_FETCHMODE_OBJECT) {
- // while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) {
- // $arr = get_object_vars($row);
- // $key = current($arr);
- // if ($group) {
- // $results[$key][] = $row;
- // } else {
- // $results[$key] = $row;
- // }
- // }
- // } else {
- // while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
- // // we shift away the first element to get
- // // indices running from 0 again
- // $key = array_shift($row);
- // if ($group) {
- // $results[$key][] = $row;
- // } else {
- // $results[$key] = $row;
- // }
- // }
- // }
- // if (DB::isError($row)) {
- // $results = $row;
- // }
- // } else {
- // // return scalar values
- // while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
- // if ($group) {
- // $results[$row[0]][] = $row[1];
- // } else {
- // $results[$row[0]] = $row[1];
- // }
- // }
- // if (DB::isError($row)) {
- // $results = $row;
- // }
- // }
- //
- // $res->free();
- //
- // return $results;
- }
-
- /**
- * Fetches all of the rows from a query result
- *
- * @param string $query the SQL query
- * @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.
- * @param int $fetchmode the fetch mode to use:
- * + DB_FETCHMODE_ORDERED
- * + DB_FETCHMODE_ASSOC
- * + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
- * + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
- *
- * @return array the nested array. A DB_Error object on failure.
- * @todo Implement mock DB_common::getAll
- */
- public function &getAll($query, $params = array(),
- $fetchmode = DB_FETCHMODE_DEFAULT)
- {
- // // compat check, the params and fetchmode parameters used to
- // // have the opposite order
- // if (!is_array($params)) {
- // if (is_array($fetchmode)) {
- // if ($params === null) {
- // $tmp = DB_FETCHMODE_DEFAULT;
- // } else {
- // $tmp = $params;
- // }
- // $params = $fetchmode;
- // $fetchmode = $tmp;
- // } elseif ($params !== null) {
- // $fetchmode = $params;
- // $params = array();
- // }
- // }
- //
- // if (sizeof($params) > 0) {
- // $sth = $this->prepare($query);
- //
- // if (DB::isError($sth)) {
- // return $sth;
- // }
- //
- // $res =& $this->execute($sth, $params);
- // $this->freePrepared($sth);
- // } else {
- // $res =& $this->query($query);
- // }
- //
- // if ($res === DB_OK || DB::isError($res)) {
- // return $res;
- // }
- //
- // $results = array();
- // while (DB_OK === $res->fetchInto($row, $fetchmode)) {
- // if ($fetchmode & DB_FETCHMODE_FLIPPED) {
- // foreach ($row as $key => $val) {
- // $results[$key][] = $val;
- // }
- // } else {
- // $results[] = $row;
- // }
- // }
- //
- // $res->free();
- //
- // if (DB::isError($row)) {
- // $tmp =& $this->raiseError($row);
- // return $tmp;
- // }
- // return $results;
- }
-
- /**
- * 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.
- * @todo Implement mock DB_common::autoCommit
- */
- public function autoCommit($onoff = false)
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Commits the current transaction
- *
- * @return int DB_OK on success. A DB_Error object on failure.
- * @todo Implement mock DB_common::commit
- */
- public function commit()
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Reverts the current transaction
- *
- * @return int DB_OK on success. A DB_Error object on failure.
- * @todo Implement mock DB_common::rollback
- */
- public function rollback()
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Determines the number of rows in a query result
- *
- * @param resource $result the query result idenifier produced by PHP
- * @return int the number of rows. A DB_Error object on failure.
- * @todo Implement mock DB_common::numRows
- */
- public function numRows($result)
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * 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.
- * @todo Implement mock DB_common::affectedRows
- */
- public function affectedRows()
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Generates the name used inside the database for a sequence
- *
- * @param string $sqn the sequence's public name
- * @return string the sequence's name in the backend
- * @see DB_common::createSequence(), DB_common::dropSequence(),
- * DB_common::nextID(), DB_common::setOption()
- * @todo Implement mock DB_common::getSequenceName
- */
- protected function getSequenceName($sqn)
- {
- // return sprintf($this->getOption('seqname_format'),
- // preg_replace('/[^a-z0-9_.]/i', '_', $sqn));
- }
-
- /**
- * 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::createSequence(), DB_common::dropSequence(),
- * DB_common::getSequenceName()
- * @todo Implement mock DB_common::nextID
- */
- public function nextId($seq_name, $ondemand = true)
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * 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::dropSequence(), DB_common::getSequenceName(),
- * DB_common::nextID()
- * @todo Implement mock DB_common::createSequence
- */
- public function createSequence($seq_name)
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * 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::createSequence(), DB_common::getSequenceName(),
- * DB_common::nextID()
- * @todo Implement mock DB_common::dropSequence
- */
- public function dropSequence($seq_name)
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Communicates an error and invoke error callbacks, etc
- *
- * Basically a wrapper for PEAR::raiseError without the message string.
- *
- * @param mixed integer error code, or a PEAR error object (all
- * other parameters are ignored if this parameter is
- * an object
- * @param int error mode, see PEAR_Error docs
- * @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the
- * error level (E_USER_NOTICE etc). If error mode is
- * PEAR_ERROR_CALLBACK, this is the callback function,
- * either as a function name, or as an array of an
- * object and method name. For other error modes this
- * parameter is ignored.
- * @param string extra debug information. Defaults to the last
- * query and native error code.
- * @param mixed native error code, integer or string depending the
- * backend
- *
- * @return object the PEAR_Error object
- * @see PEAR_Error
- * @todo Implement mock DB_common::raiseError
- */
- public function &raiseError($code = DB_ERROR, $mode = null, $options = null,
- $userinfo = null, $nativecode = null)
- {
- // // The error is yet a DB error object
- // if (is_object($code)) {
- // // because we the static PEAR::raiseError, our global
- // // handler should be used if it is set
- // if ($mode === null && !empty($this->_default_error_mode)) {
- // $mode = $this->_default_error_mode;
- // $options = $this->_default_error_options;
- // }
- // $tmp = PEAR::raiseError($code, null, $mode, $options,
- // null, null, true);
- // return $tmp;
- // }
- //
- // if ($userinfo === null) {
- // $userinfo = $this->last_query;
- // }
- //
- // if ($nativecode) {
- // $userinfo .= ' [nativecode=' . trim($nativecode) . ']';
- // } else {
- // $userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']';
- // }
- //
- // $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo,
- // 'DB_Error', true);
- // return $tmp;
- }
-
- /**
- * Gets the DBMS' native error code produced by the last query
- *
- * @return mixed the DBMS' error code. A DB_Error object on failure.
- * @todo Implement mock DB_common::errorNative
- */
- public function errorNative()
- {
- // return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Maps native error codes to DB's portable ones
- *
- * Uses the <var>$errorcode_map</var> property defined in each driver.
- *
- * @param string|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.
- * @todo Implement mock DB_common::errorCode
- */
- public function errorCode($nativecode)
- {
- // if (isset($this->errorcode_map[$nativecode])) {
- // return $this->errorcode_map[$nativecode];
- // }
- // Fall back to DB_ERROR if there was no mapping.
- return DB_ERROR;
- }
-
- /**
- * Maps a DB error code to a textual message
- *
- * @param integer $dbcode the DB error code
- * @return string the error message corresponding to the error code
- * submitted. FALSE if the error code is unknown.
- * @see DB::errorMessage()
- * @todo Implement mock DB_common::errorMessage
- */
- public function errorMessage($dbcode)
- {
- // return DB::errorMessage($this->errorcode_map[$dbcode]);
- }
-
- /**
- * Returns information about a table or a result set
- *
- * @param object|string $result DB_result object from a query or a
- * string containing the name of a table.
- * While this also accepts a query result
- * resource identifier, this behavior is
- * deprecated.
- * @param int $mode either unused or one of the tableInfo modes:
- * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
- * <kbd>DB_TABLEINFO_ORDER</kbd> or
- * <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
- * These are bitwise, so the first two can be
- * combined using <kbd>|</kbd>.
- *
- * @return array an associative array with the information requested.
- * A DB_Error object on failure.
- *
- * @see DB_common::setOption()
- * @todo Implement mock DB_common::tableInfo
- */
- public function tableInfo($result, $mode = null)
- {
- /*
- * If the DB_<driver> class has a tableInfo() method, that one
- * overrides this one. But, if the driver doesn't have one,
- * this method runs and tells users about that fact.
- */
- return $this->raiseError(DB_ERROR_NOT_CAPABLE);
- }
-
- /**
- * Lists internal database information
- *
- * @param string $type type of information being sought.
- * Common items being sought are:
- * tables, databases, users, views, functions
- * Each DBMS's has its own capabilities.
- *
- * @return array an array listing the items sought.
- * A DB DB_Error object on failure.
- * @todo Implement mock DB_common::getListOf
- */
- public function getListOf($type)
- {
- // $sql = $this->getSpecialQuery($type);
- // if ($sql === null) {
- // $this->last_query = '';
- // return $this->raiseError(DB_ERROR_UNSUPPORTED);
- // } elseif (is_int($sql) || DB::isError($sql)) {
- // // Previous error
- // return $this->raiseError($sql);
- // } elseif (is_array($sql)) {
- // // Already the result
- // return $sql;
- // }
- // // Launch this query
- // return $this->getCol($sql);
- }
-
- /**
- * Obtains the query string needed for listing a given type of objects
- *
- * @param string $type the kind of objects you want to retrieve
- * @return string the SQL query string or null if the driver doesn't
- * support the object type requested
- * @see DB_common::getListOf()
- * @todo Implement mock DB_common::getSpecialQuery
- */
- protected function getSpecialQuery($type)
- {
- // return $this->raiseError(DB_ERROR_UNSUPPORTED);
- }
-
- /**
- * Right-trims all strings in an array
- *
- * @param array $array the array to be trimmed (passed by reference)
- * @return void
- */
- protected function _rtrimArrayValues(&$array)
- {
- foreach ($array as $key => $value) {
- if (is_string($value)) {
- $array[$key] = rtrim($value);
- }
- }
- }
-
- /**
- * Converts all null values in an array to empty strings
- *
- * @param array $array the array to be de-nullified (passed by reference)
- * @return void
- */
- protected function _convertNullArrayValuesToEmpty(&$array)
- {
- foreach ($array as $key => $value) {
- if (is_null($value)) {
- $array[$key] = '';
- }
- }
- }
- }
-
- /**
- * Mock DB_Error
- * @todo Implement mock DB_Error class
- */
- class DB_Error extends PEAR_Error
- {
- /**
- * DB_Error constructor
- *
- * @param mixed $code DB error code, or string with error message
- * @param int $mode what "error mode" to operate in
- * @param int $level what error level to use for $mode &
- * PEAR_ERROR_TRIGGER
- * @param mixed $debuginfo additional debug info, such as the last query
- * @see PEAR_Error
- * @todo Implement DB_Error::constructor
- */
- function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
- $level = E_USER_NOTICE, $debuginfo = null)
- {
- // if (is_int($code)) {
- // $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code,
- // $mode, $level, $debuginfo);
- // } else {
- // $this->PEAR_Error("DB Error: $code", DB_ERROR,
- // $mode, $level, $debuginfo);
- // }
- }
- }
-
- /**
- * Mock DB_result
- * @todo Implement mock DB_result
- */
- class DB_result
- {
-
- /**
- * This constructor sets the object's properties
- *
- * @param object &$dbh the DB object reference
- * @param resource $result the result resource id
- * @param array $options an associative array with result options
- * @return void
- * @todo Implement mock DB_result::constructor
- */
- function DB_result(&$dbh, $result, $options = array())
- {
- }
-
- /**
- * Set options for the DB_result object
- *
- * @param string $key the option to set
- * @param mixed $value the value to set the option to
- * @return void
- * @todo Implement mock DB_result::setOption()
- */
- function setOption($key, $value = null)
- {
- switch ($key) {
- case 'limit_from':
- // $this->limit_from = $value;
- break;
- case 'limit_count':
- // $this->limit_count = $value;
- }
- }
-
- /**
- * Fetch a row of data and return it by reference into an array
- *
- * @param int $fetchmode the constant indicating how to format the data
- * @param int $rownum the row number to fetch (index starts at 0)
- *
- * @return mixed an array or object containing the row's data,
- * NULL when the end of the result set is reached
- * or a DB_Error object on failure.
- *
- * @see DB_common::setOption(), DB_common::setFetchMode()
- * @todo Implement mock DB_result::fetchRow()
- */
- function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
- {
- // if ($fetchmode === DB_FETCHMODE_DEFAULT) {
- // $fetchmode = $this->fetchmode;
- // }
- // if ($fetchmode === DB_FETCHMODE_OBJECT) {
- // $fetchmode = DB_FETCHMODE_ASSOC;
- // $object_class = $this->fetchmode_object_class;
- // }
- // if ($this->limit_from !== null) {
- // if ($this->row_counter === null) {
- // $this->row_counter = $this->limit_from;
- // // Skip rows
- // if ($this->dbh->features['limit'] === false) {
- // $i = 0;
- // while ($i++ < $this->limit_from) {
- // $this->dbh->fetchInto($this->result, $arr, $fetchmode);
- // }
- // }
- // }
- // if ($this->row_counter >= ($this->limit_from + $this->limit_count))
- // {
- // if ($this->autofree) {
- // $this->free();
- // }
- // $tmp = null;
- // return $tmp;
- // }
- // if ($this->dbh->features['limit'] === 'emulate') {
- // $rownum = $this->row_counter;
- // }
- // $this->row_counter++;
- // }
- // $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
- // if ($res === DB_OK) {
- // if (isset($object_class)) {
- // // The default mode is specified in the
- // // DB_common::fetchmode_object_class property
- // if ($object_class == 'stdClass') {
- // $arr = (object) $arr;
- // } else {
- // $arr = &new $object_class($arr);
- // }
- // }
- // return $arr;
- // }
- // if ($res == null && $this->autofree) {
- // $this->free();
- // }
- // return $res;
- }
-
- /**
- * Fetch a row of data into an array which is passed by reference
- *
- * @param array &$arr the variable where the data should be placed
- * @param int $fetchmode the constant indicating how to format the data
- * @param int $rownum the row number to fetch (index starts at 0)
- * @return mixed DB_OK if a row is processed, NULL when the end of the
- * result set is reached or a DB_Error object on failure
- *
- * @see DB_common::setOption(), DB_common::setFetchMode()
- * @todo Implement mock DB_result::fetchInto()
- */
- function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
- {
- // if ($fetchmode === DB_FETCHMODE_DEFAULT) {
- // $fetchmode = $this->fetchmode;
- // }
- // if ($fetchmode === DB_FETCHMODE_OBJECT) {
- // $fetchmode = DB_FETCHMODE_ASSOC;
- // $object_class = $this->fetchmode_object_class;
- // }
- // if ($this->limit_from !== null) {
- // if ($this->row_counter === null) {
- // $this->row_counter = $this->limit_from;
- // // Skip rows
- // if ($this->dbh->features['limit'] === false) {
- // $i = 0;
- // while ($i++ < $this->limit_from) {
- // $this->dbh->fetchInto($this->result, $arr, $fetchmode);
- // }
- // }
- // }
- // if ($this->row_counter >= (
- // $this->limit_from + $this->limit_count))
- // {
- // if ($this->autofree) {
- // $this->free();
- // }
- // return null;
- // }
- // if ($this->dbh->features['limit'] === 'emulate') {
- // $rownum = $this->row_counter;
- // }
- //
- // $this->row_counter++;
- // }
- // $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
- // if ($res === DB_OK) {
- // if (isset($object_class)) {
- // // default mode specified in the
- // // DB_common::fetchmode_object_class property
- // if ($object_class == 'stdClass') {
- // $arr = (object) $arr;
- // } else {
- // $arr = new $object_class($arr);
- // }
- // }
- // return DB_OK;
- // }
- // if ($res == null && $this->autofree) {
- // $this->free();
- // }
- // return $res;
- }
-
- /**
- * Get the the number of columns in a result set
- *
- * @return int the number of columns. A DB_Error object on failure.
- * @todo Implement mock DB_result::numCols()
- */
- function numCols()
- {
- // return $this->dbh->numCols($this->result);
- }
-
- /**
- * Get the number of rows in a result set
- *
- * @return int the number of rows. A DB_Error object on failure.
- * @todo Implement mock DB_result::numRows()
- */
- function numRows()
- {
- // if ($this->dbh->features['numrows'] === 'emulate'
- // && $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS)
- // {
- // if ($this->dbh->features['prepare']) {
- // $res = $this->dbh->query($this->query, $this->parameters);
- // } else {
- // $res = $this->dbh->query($this->query);
- // }
- // if (DB::isError($res)) {
- // return $res;
- // }
- // $i = 0;
- // while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) {
- // $i++;
- // }
- // return $i;
- // } else {
- // return $this->dbh->numRows($this->result);
- // }
- }
-
- /**
- * Get the next result if a batch of queries was executed
- *
- * @return bool true if a new result is available or false if not
- * @todo Implement mock DB_result::nextResult()
- */
- function nextResult()
- {
- // return $this->dbh->nextResult($this->result);
- }
-
- /**
- * Frees the resources allocated for this result set
- *
- * @return bool true on success. A DB_Error object on failure.
- * @todo Implement mock DB_result::free()
- */
- function free()
- {
- // $err = $this->dbh->freeResult($this->result);
- // if (DB::isError($err)) {
- // return $err;
- // }
- // $this->result = false;
- // $this->statement = false;
- // return true;
- }
-
- /**
- * Determine the query string that created this result
- *
- * @return string the query string
- * @todo Implement mock DB_result::getQuery()
- */
- function getQuery()
- {
- // return $this->query;
- }
-
- /**
- * Tells which row number is currently being processed
- *
- * @return integer the current row being looked at. Starts at 1.
- * @todo Implement mock DB_result::getRowCounter()
- */
- function getRowCounter()
- {
- // return $this->row_counter;
- }
- }
-
- /**
- * Mock DB_row
- * @todo Implement mock DB_row
- */
- class DB_row
- {
-
- /**
- * The constructor places a row's data into properties of this object
- *
- * @param array the array containing the row's data
- * @return void
- * @todo Implement mock DB_row constructor
- */
- function DB_row(&$arr)
- {
- // foreach ($arr as $key => $value) {
- // $this->$key = &$arr[$key];
- // }
- }
- }
-
- /**
- * Mock DB_mysql class
- */
- class DB_mysql extends DB_common
- {
-
- /**
- * This constructor calls <kbd>$this->DB_common()</kbd>
- *
- * @return void
- */
- function DB_mysql()
- {
- $this->DB_common();
- }
-
- /**
- * Connect to the database server, log in and open the database
- *
- * @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.
- * @todo Implement mock DB_mysql::connect()
- */
- function connect($dsn, $persistent = false)
- {
- // if (!PEAR::loadExtension('mysql')) {
- // return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
- // }
- //
- // $this->dsn = $dsn;
- // if ($dsn['dbsyntax']) {
- // $this->dbsyntax = $dsn['dbsyntax'];
- // }
- //
- // $params = array();
- // if ($dsn['protocol'] && $dsn['protocol'] == 'unix') {
- // $params[0] = ':' . $dsn['socket'];
- // } else {
- // $params[0] = $dsn['hostspec'] ? $dsn['hostspec']
- // : 'localhost';
- // if ($dsn['port']) {
- // $params[0] .= ':' . $dsn['port'];
- // }
- // }
- // $params[] = $dsn['username'] ? $dsn['username'] : null;
- // $params[] = $dsn['password'] ? $dsn['password'] : null;
- //
- // if (!$persistent) {
- // if (isset($dsn['new_link'])
- // && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
- // {
- // $params[] = true;
- // } else {
- // $params[] = false;
- // }
- // }
- // if (version_compare(phpversion(), '4.3.0', '>=')) {
- // $params[] = isset($dsn['client_flags'])
- // ? $dsn['client_flags'] : null;
- // }
- //
- // $connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
- //
- // $ini = ini_get('track_errors');
- // $php_errormsg = '';
- // if ($ini) {
- // $this->connection = @call_user_func_array($connect_function,
- // $params);
- // } else {
- // ini_set('track_errors', 1);
- // $this->connection = @call_user_func_array($connect_function,
- // $params);
- // ini_set('track_errors', $ini);
- // }
- //
- // if (!$this->connection) {
- // if (($err = @mysql_error()) != '') {
- // return $this->raiseError(DB_ERROR_CONNECT_FAILED,
- // null, null, null,
- // $err);
- // } else {
- // return $this->raiseError(DB_ERROR_CONNECT_FAILED,
- // null, null, null,
- // $php_errormsg);
- // }
- // }
- //
- // if ($dsn['database']) {
- // if (!@mysql_select_db($dsn['database'], $this->connection)) {
- // return $this->mysqlRaiseError();
- // }
- // $this->_db = $dsn['database'];
- // }
- //
- // return DB_OK;
- }
-
- /**
- * Disconnects from the database server
- *
- * @return bool TRUE on success, FALSE on failure
- * @todo Implement mock DB_mysql::disconnect()
- */
- function disconnect()
- {
- // $ret = @mysql_close($this->connection);
- // $this->connection = null;
- // return $ret;
- }
-
- /**
- * Sends a query to the database server
- *
- * Generally uses mysql_query(). If you want to use
- * mysql_unbuffered_query() set the "result_buffering" option to 0 using
- * setOptions(). This option was added in Release 1.7.0.
- *
- * @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
- * @todo Implement mock DB_mysql::simpleQuery()
- */
- function simpleQuery($query)
- {
- // $ismanip = DB::isManip($query);
- // $this->last_query = $query;
- // $query = $this->modifyQuery($query);
- // if ($this->_db) {
- // if (!@mysql_select_db($this->_db, $this->connection)) {
- // return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
- // }
- // }
- // if (!$this->autocommit && $ismanip) {
- // if ($this->transaction_opcount == 0) {
- // $result = @mysql_query('SET AUTOCOMMIT=0', $this->connection);
- // $result = @mysql_query('BEGIN', $this->connection);
- // if (!$result) {
- // return $this->mysqlRaiseError();
- // }
- // }
- // $this->transaction_opcount++;
- // }
- // if (!$this->options['result_buffering']) {
- // $result = @mysql_unbuffered_query($query, $this->connection);
- // } else {
- // $result = @mysql_query($query, $this->connection);
- // }
- // if (!$result) {
- // return $this->mysqlRaiseError();
- // }
- // if (is_resource($result)) {
- // return $result;
- // }
- return DB_OK;
- }
-
- /**
- * Move the internal mysql result pointer to the next available result
- *
- * This method has not been implemented yet.
- *
- * @param a valid sql result resource
- *
- * @return false
- */
- function nextResult($result)
- {
- return false;
- }
-
- /**
- * Places a row from the result set into the given array
- *
- * @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()
- * @todo Implement mock DB_mysql::fetchInto()
- */
- function fetchInto($result, &$arr, $fetchmode, $rownum = null)
- {
- // if ($rownum !== null) {
- // if (!@mysql_data_seek($result, $rownum)) {
- // return null;
- // }
- // }
- // if ($fetchmode & DB_FETCHMODE_ASSOC) {
- // $arr = @mysql_fetch_array($result, MYSQL_ASSOC);
- // if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
- // $arr = array_change_key_case($arr, CASE_LOWER);
- // }
- // } else {
- // $arr = @mysql_fetch_row($result);
- // }
- // if (!$arr) {
- // return null;
- // }
- // if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
- // /*
- // * Even though this DBMS already trims output, we do this because
- // * a field might have intentional whitespace at the end that
- // * gets removed by DB_PORTABILITY_RTRIM under another driver.
- // */
- // $this->_rtrimArrayValues($arr);
- // }
- // if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
- // $this->_convertNullArrayValuesToEmpty($arr);
- // }
- return DB_OK;
- }
-
- /**
- * 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()
- * @todo Implement mock DB_mysql::freeResult()
- */
- function freeResult($result)
- {
- // return @mysql_free_result($result);
- }
-
-
- /**
- * 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()
- * @todo Implement mock DB_mysql::numCols()
- */
- function numCols($result)
- {
- // $cols = @mysql_num_fields($result);
- // if (!$cols) {
- // return $this->mysqlRaiseError();
- // }
- // 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 the number of rows. A DB_Error object on failure.
- *
- * @see DB_result::numRows()
- * @todo Implement mock DB_mysql::numRows()
- */
- function numRows($result)
- {
- // $rows = @mysql_num_rows($result);
- // if ($rows === null) {
- // return $this->mysqlRaiseError();
- // }
- // return $rows;
- }
-
- /**
- * 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.
- * @todo Implement mock DB_mysql::autoCommit()
- */
- 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;
- }
-
- /**
- * Commits the current transaction
- *
- * @return int DB_OK on success. A DB_Error object on failure.
- * @todo Implement mock DB_mysql::committ()
- */
- function commit()
- {
- // if ($this->transaction_opcount > 0) {
- // if ($this->_db) {
- // if (!@mysql_select_db($this->_db, $this->connection)) {
- // return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
- // }
- // }
- // $result = @mysql_query('COMMIT', $this->connection);
- // $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
- // $this->transaction_opcount = 0;
- // if (!$result) {
- // return $this->mysqlRaiseError();
- // }
- // }
- return DB_OK;
- }
-
- /**
- * Reverts the current transaction
- *
- * @return int DB_OK on success. A DB_Error object on failure.
- * @todo Implement mock DB_mysql::rollback()
- */
- function rollback()
- {
- // if ($this->transaction_opcount > 0) {
- // if ($this->_db) {
- // if (!@mysql_select_db($this->_db, $this->connection)) {
- // return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
- // }
- // }
- // $result = @mysql_query('ROLLBACK', $this->connection);
- // $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
- // $this->transaction_opcount = 0;
- // if (!$result) {
- // return $this->mysqlRaiseError();
- // }
- // }
- return DB_OK;
- }
-
- /**
- * 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.
- * @todo Implement mock DB_mysql::affectedRows()
- */
- function affectedRows()
- {
- // if (DB::isManip($this->last_query)) {
- // return @mysql_affected_rows($this->connection);
- // } else {
- // return 0;
- // }
- }
-
- /**
- * 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_mysql::createSequence(), DB_mysql::dropSequence()
- * @todo Implement mock DB_mysql::nextId()
- */
- function nextId($seq_name, $ondemand = true)
- {
- // $seqname = $this->getSequenceName($seq_name);
- // do {
- // $repeat = 0;
- // $this->pushErrorHandling(PEAR_ERROR_RETURN);
- // $result = $this->query("UPDATE ${seqname} ".
- // 'SET id=LAST_INSERT_ID(id+1)');
- // $this->popErrorHandling();
- // if ($result === DB_OK) {
- // // COMMON CASE
- // $id = @mysql_insert_id($this->connection);
- // if ($id != 0) {
- // return $id;
- // }
- // // EMPTY SEQ TABLE
- // // Sequence table must be empty for some reason, so fill
- // // it and return 1 and obtain a user-level lock
- // $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
- // if (DB::isError($result)) {
- // return $this->raiseError($result);
- // }
- // if ($result == 0) {
- // // Failed to get the lock
- // return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
- // }
- //
- // // add the default value
- // $result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)");
- // if (DB::isError($result)) {
- // return $this->raiseError($result);
- // }
- //
- // // Release the lock
- // $result = $this->getOne('SELECT RELEASE_LOCK('
- // . "'${seqname}_lock')");
- // if (DB::isError($result)) {
- // return $this->raiseError($result);
- // }
- // // We know what the result will be, so no need to try again
- // return 1;
- //
- // } elseif ($ondemand && DB::isError($result) &&
- // $result->getCode() == DB_ERROR_NOSUCHTABLE)
- // {
- // // ONDEMAND TABLE CREATION
- // $result = $this->createSequence($seq_name);
- // if (DB::isError($result)) {
- // return $this->raiseError($result);
- // } else {
- // $repeat = 1;
- // }
- //
- // } elseif (DB::isError($result) &&
- // $result->getCode() == DB_ERROR_ALREADY_EXISTS)
- // {
- // // BACKWARDS COMPAT
- // // see _BCsequence() comment
- // $result = $this->_BCsequence($seqname);
- // if (DB::isError($result)) {
- // return $this->raiseError($result);
- // }
- // $repeat = 1;
- // }
- // } while ($repeat);
- //
- // return $this->raiseError($result);
- }
-
- /**
- * 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_mysql::nextID(), DB_mysql::dropSequence()
- * @todo Implement mock DB_mysql::createSequence()
- */
- function createSequence($seq_name)
- {
- // $seqname = $this->getSequenceName($seq_name);
- // $res = $this->query('CREATE TABLE ' . $seqname
- // . ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'
- // . ' PRIMARY KEY(id))');
- // if (DB::isError($res)) {
- // return $res;
- // }
- // // insert yields value 1, nextId call will generate ID 2
- // $res = $this->query("INSERT INTO ${seqname} (id) VALUES (0)");
- // if (DB::isError($res)) {
- // return $res;
- // }
- // // so reset to zero
- // return $this->query("UPDATE ${seqname} SET id = 0");
- }
-
- /**
- * 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()
- * @todo Implement mock DB_mysql::dropSequence()
- */
- function dropSequence($seq_name)
- {
- // return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
- }
-
- /**
- * Backwards compatibility with old sequence emulation implementation
- * (clean up the dupes)
- *
- * @param string $seqname the sequence name to clean up
- *
- * @return bool true on success. A DB_Error object on failure.
- * @todo Implement mock DB_mysql::_BCsequence()
- */
- private function _BCsequence($seqname)
- {
- // // Obtain a user-level lock... this will release any previous
- // // application locks, but unlike LOCK TABLES, it does not abort
- // // the current transaction and is much less frequently used.
- // $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
- // if (DB::isError($result)) {
- // return $result;
- // }
- // if ($result == 0) {
- // // Failed to get the lock, can't do the conversion, bail
- // // with a DB_ERROR_NOT_LOCKED error
- // return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
- // }
- //
- // $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
- // if (DB::isError($highest_id)) {
- // return $highest_id;
- // }
- // // This should kill all rows except the highest
- // // We should probably do something if $highest_id isn't
- // // numeric, but I'm at a loss as how to handle that...
- // $result = $this->query('DELETE FROM ' . $seqname
- // . " WHERE id <> $highest_id");
- // if (DB::isError($result)) {
- // return $result;
- // }
- //
- // // If another thread has been waiting for this lock,
- // // it will go thru the above procedure, but will have no
- // // real effect
- // $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
- // if (DB::isError($result)) {
- // return $result;
- // }
- return true;
- }
-
- /**
- * Quotes a string so it can be safely used as a table or column name
- *
- * MySQL can't handle the backtick character (<kbd>`</kbd>) in
- * table or column names.
- *
- * @param string $str identifier name to be quoted
- * @return string quoted identifier string
- * @see DB_common::quoteIdentifier()
- * @access private
- */
- function quoteIdentifier($str)
- {
- return '`' . $str . '`';
- }
-
- /**
- * 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()
- * @todo Implement mock DB_mysql::escapeSimple()
- */
- function escapeSimple($str)
- {
- // if (function_exists('mysql_real_escape_string')) {
- // return @mysql_real_escape_string($str, $this->connection);
- // } else {
- // return @mysql_escape_string($str);
- // }
- }
-
- /**
- * 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
- * @see DB_common::setOption()
- * @todo Implement mock DB_mysql::modifyQuery()
- */
- protected 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;
- }
-
- /**
- * 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
- * @todo Implement mock DB_mysql::modifyLimitQuery()
- */
- protected function modifyLimitQuery($query, $from, $count, $params = array())
- {
- // if (DB::isManip($query)) {
- // return $query . " LIMIT $count";
- // } else {
- // return $query . " LIMIT $from, $count";
- // }
- }
-
- /**
- * 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()
- * @todo Implement mock DB_mysql::mysqlRaiseError()
- */
- 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));
- }
-
- /**
- * Gets the DBMS' native error code produced by the last query
- *
- * @return int the DBMS' error code
- * @todo Implement mock DB_mysql::errorNative()
- */
- function errorNative()
- {
- // return @mysql_errno($this->connection);
- }
-
- /**
- * Returns information about a table or a result set
- *
- * @param object|string $result DB_result object from a query or a
- * string containing the name of a table.
- * While this also accepts a query result
- * resource identifier, this behavior is
- * deprecated.
- * @param int $mode a valid tableInfo mode
- *
- * @return array an associative array with the information requested.
- * A DB_Error object on failure.
- *
- * @see DB_common::tableInfo()
- * @todo Implement mock DB_mysql::tableInfo()
- */
- function tableInfo($result, $mode = null)
- {
- // We only support the default mode
- PHPUnit2_Framework_Assert::assertNull($mode);
-
- // We only support table name as first argument
- PHPUnit2_Framework_Assert::assertTrue(is_string($result));
-
- // Look up table name in the mock database
- foreach(self::$database as $table => $value) {
- if ($result == $table) {
- return $value['info'];
- }
- }
- PHPUnit2_Framework_Assert::fail("DB_mysql::tableInfo called"
- ." with unknown table $result");
- }
-
- /**
- * Obtains the query string needed for listing a given type of objects
- *
- * @param string $type the kind of objects you want to retrieve
- *
- * @return string the SQL query string or null if the driver doesn't
- * support the object type requested
- *
- * @see DB_common::getListOf()
- */
- protected function getSpecialQuery($type)
- {
- switch ($type) {
- case 'tables':
- return 'SHOW TABLES';
- case 'users':
- return 'SELECT DISTINCT User FROM mysql.user';
- case 'databases':
- return 'SHOW DATABASES';
- default:
- return null;
- }
- }
- }
-
- // -- set Emacs parameters --
- // Local variables:
- // tab-width: 4
- // c-basic-offset: 4
- // c-hanging-comment-ender-p: nil
- // indent-tabs-mode: nil
- // End:
- ?>