PHPonTraxTest
[ class tree: PHPonTraxTest ] [ index: PHPonTraxTest ] [ all elements ]

Source for file DB.php

Documentation is available at DB.php

  1. <?php
  2. /**
  3.  *  File for mock DB class
  4.  *
  5.  *  This file has the same name as the file holding the {@link }
  6.  *  http://pear.php.net/package/DB PEAR DB class}.
  7.  *  To use the mock DB, put this file in the PHP include path ahead of
  8.  *  the PEAR library, so that any class which requires DB.php will
  9.  *  load this version.
  10.  *
  11.  * (PHP 5)
  12.  *
  13.  * @package PHPonTraxTest
  14.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  15.  * @copyright (c) Walter O. Haas 2006
  16.  * @version $Id: DB.php 198 2006-04-20 16:20:30Z haas $
  17.  * @author Walt Haas <haas@xmission.com>
  18.  */
  19.  
  20. require_once 'PEAR.php';
  21. require_once 'PHPUnit2/Framework/Assert.php';
  22.  
  23. /**
  24.  * The code returned by many methods upon success
  25.  */
  26. define('DB_OK'1);
  27.  
  28. /**
  29.  * Unkown error
  30.  */
  31. define('DB_ERROR'-1);
  32.  
  33. /**
  34.  * Syntax error
  35.  */
  36. define('DB_ERROR_SYNTAX'-2);
  37.  
  38. /**
  39.  * Tried to insert a duplicate value into a primary or unique index
  40.  */
  41. define('DB_ERROR_CONSTRAINT'-3);
  42.  
  43. /**
  44.  * An identifier in the query refers to a non-existant object
  45.  */
  46. define('DB_ERROR_NOT_FOUND'-4);
  47.  
  48. /**
  49.  * Tried to create a duplicate object
  50.  */
  51. define('DB_ERROR_ALREADY_EXISTS'-5);
  52.  
  53. /**
  54.  * The current driver does not support the action you attempted
  55.  */
  56. define('DB_ERROR_UNSUPPORTED'-6);
  57.  
  58. /**
  59.  * The number of parameters does not match the number of placeholders
  60.  */
  61. define('DB_ERROR_MISMATCH'-7);
  62.  
  63. /**
  64.  * A literal submitted did not match the data type expected
  65.  */
  66. define('DB_ERROR_INVALID'-8);
  67.  
  68. /**
  69.  * The current DBMS does not support the action you attempted
  70.  */
  71. define('DB_ERROR_NOT_CAPABLE'-9);
  72.  
  73. /**
  74.  * A literal submitted was too long so the end of it was removed
  75.  */
  76. define('DB_ERROR_TRUNCATED'-10);
  77.  
  78. /**
  79.  * A literal number submitted did not match the data type expected
  80.  */
  81. define('DB_ERROR_INVALID_NUMBER'-11);
  82.  
  83. /**
  84.  * A literal date submitted did not match the data type expected
  85.  */
  86. define('DB_ERROR_INVALID_DATE'-12);
  87.  
  88. /**
  89.  * Attempt to divide something by zero
  90.  */
  91. define('DB_ERROR_DIVZERO'-13);
  92.  
  93. /**
  94.  * A database needs to be selected
  95.  */
  96. define('DB_ERROR_NODBSELECTED'-14);
  97.  
  98. /**
  99.  * Could not create the object requested
  100.  */
  101. define('DB_ERROR_CANNOT_CREATE'-15);
  102.  
  103. /**
  104.  * Could not drop the database requested because it does not exist
  105.  */
  106. define('DB_ERROR_CANNOT_DROP'-17);
  107.  
  108. /**
  109.  * An identifier in the query refers to a non-existant table
  110.  */
  111. define('DB_ERROR_NOSUCHTABLE'-18);
  112.  
  113. /**
  114.  * An identifier in the query refers to a non-existant column
  115.  */
  116. define('DB_ERROR_NOSUCHFIELD'-19);
  117.  
  118. /**
  119.  * The data submitted to the method was inappropriate
  120.  */
  121. define('DB_ERROR_NEED_MORE_DATA'-20);
  122.  
  123. /**
  124.  * The attempt to lock the table failed
  125.  */
  126. define('DB_ERROR_NOT_LOCKED'-21);
  127.  
  128. /**
  129.  * The number of columns doesn't match the number of values
  130.  */
  131. define('DB_ERROR_VALUE_COUNT_ON_ROW'-22);
  132.  
  133. /**
  134.  * The DSN submitted has problems
  135.  */
  136. define('DB_ERROR_INVALID_DSN'-23);
  137.  
  138. /**
  139.  * Could not connect to the database
  140.  */
  141. define('DB_ERROR_CONNECT_FAILED'-24);
  142.  
  143. /**
  144.  * The PHP extension needed for this DBMS could not be found
  145.  */
  146. define('DB_ERROR_EXTENSION_NOT_FOUND',-25);
  147.  
  148. /**
  149.  * The present user has inadequate permissions to perform the task requestd
  150.  */
  151. define('DB_ERROR_ACCESS_VIOLATION'-26);
  152.  
  153. /**
  154.  * The database requested does not exist
  155.  */
  156. define('DB_ERROR_NOSUCHDB'-27);
  157.  
  158. /**
  159.  * Tried to insert a null value into a column that doesn't allow nulls
  160.  */
  161. define('DB_ERROR_CONSTRAINT_NOT_NULL',-29);
  162.  
  163. /**
  164.  * Identifiers for the placeholders used in prepared statements.
  165.  * @see prepare()
  166.  */
  167.  
  168. /**
  169.  * Indicates a scalar (<kbd>?</kbd>) placeholder was used
  170.  *
  171.  * Quote and escape the value as necessary.
  172.  */
  173. define('DB_PARAM_SCALAR'1);
  174.  
  175. /**
  176.  * Indicates an opaque (<kbd>&</kbd>) placeholder was used
  177.  *
  178.  * The value presented is a file name.  Extract the contents of that file
  179.  * and place them in this column.
  180.  */
  181. define('DB_PARAM_OPAQUE'2);
  182.  
  183. /**
  184.  * Indicates a misc (<kbd>!</kbd>) placeholder was used
  185.  *
  186.  * The value should not be quoted or escaped.
  187.  */
  188. define('DB_PARAM_MISC',   3);
  189.  
  190. /**
  191.  * The different ways of returning binary data from queries.
  192.  */
  193.  
  194. /**
  195.  * Sends the fetched data straight through to output
  196.  */
  197. define('DB_BINMODE_PASSTHRU'1);
  198.  
  199. /**
  200.  * Lets you return data as usual
  201.  */
  202. define('DB_BINMODE_RETURN'2);
  203.  
  204. /**
  205.  * Converts the data to hex format before returning it
  206.  *
  207.  * For example the string "123" would become "313233".
  208.  */
  209. define('DB_BINMODE_CONVERT'3);
  210.  
  211. /**
  212.  * Fetchmode constants
  213.  */
  214. define('DB_FETCHMODE_DEFAULT'0);
  215. define('DB_FETCHMODE_ORDERED'1);
  216. define('DB_FETCHMODE_ASSOC'2);
  217. define('DB_FETCHMODE_OBJECT'3);
  218.  
  219. /**
  220.  * For multi-dimensional results, make the column name the first level
  221.  * of the array and put the row number in the second level of the array
  222.  *
  223.  * This is flipped from the normal behavior, which puts the row numbers
  224.  * in the first level of the array and the column names in the second level.
  225.  */
  226. define('DB_FETCHMODE_FLIPPED'4);
  227.  
  228. /**
  229.  * Old fetch modes.  Left here for compatibility.
  230.  */
  231. define('DB_GETMODE_ORDERED'DB_FETCHMODE_ORDERED);
  232. define('DB_GETMODE_ASSOC',   DB_FETCHMODE_ASSOC);
  233. define('DB_GETMODE_FLIPPED'DB_FETCHMODE_FLIPPED);
  234.  
  235. /**
  236.  * The type of information to return from the tableInfo() method.
  237.  *
  238.  * Bitwised constants, so they can be combined using <kbd>|</kbd>
  239.  * and removed using <kbd>^</kbd>.
  240.  *
  241.  * @see tableInfo()
  242.  */
  243. define('DB_TABLEINFO_ORDER'1);
  244. define('DB_TABLEINFO_ORDERTABLE'2);
  245. define('DB_TABLEINFO_FULL'3);
  246.  
  247. /**
  248.  * The type of query to create with the automatic query building methods.
  249.  * @see autoPrepare(), autoExecute()
  250.  */
  251. define('DB_AUTOQUERY_INSERT'1);
  252. define('DB_AUTOQUERY_UPDATE'2);
  253.  
  254. /**
  255.  * Portability Modes.
  256.  *
  257.  * Bitwised constants, so they can be combined using <kbd>|</kbd>
  258.  * and removed using <kbd>^</kbd>.
  259.  *
  260.  * @see setOption()
  261.  */
  262.  
  263. /**
  264.  * Turn off all portability features
  265.  */
  266. define('DB_PORTABILITY_NONE'0);
  267.  
  268. /**
  269.  * Convert names of tables and fields to lower case
  270.  * when using the get*(), fetch*() and tableInfo() methods
  271.  */
  272. define('DB_PORTABILITY_LOWERCASE'1);
  273.  
  274. /**
  275.  * Right trim the data output by get*() and fetch*()
  276.  */
  277. define('DB_PORTABILITY_RTRIM'2);
  278.  
  279. /**
  280.  * Force reporting the number of rows deleted
  281.  */
  282. define('DB_PORTABILITY_DELETE_COUNT'4);
  283.  
  284. /**
  285.  * Enable hack that makes numRows() work in Oracle
  286.  */
  287. define('DB_PORTABILITY_NUMROWS'8);
  288.  
  289. /**
  290.  * Makes certain error messages in certain drivers compatible
  291.  * with those from other DBMS's
  292.  *
  293.  * + mysql, mysqli:  change unique/primary key constraints
  294.  *   DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
  295.  *
  296.  * + odbc(access):  MS's ODBC driver reports 'no such field' as code
  297.  *   07001, which means 'too few parameters.'  When this option is on
  298.  *   that code gets mapped to DB_ERROR_NOSUCHFIELD.
  299.  */
  300. define('DB_PORTABILITY_ERRORS'16);
  301.  
  302. /**
  303.  * Convert null values to empty strings in data output by
  304.  * get*() and fetch*()
  305.  */
  306. define('DB_PORTABILITY_NULL_TO_EMPTY'32);
  307.  
  308. /**
  309.  * Turn on all portability features
  310.  */
  311. define('DB_PORTABILITY_ALL'63);
  312.  
  313. /**
  314.  *  Mock DB class for testing
  315.  *
  316.  *  This class is a mock version of the
  317.  *  {@link http://pear.php.net/package/DB PEAR DB class}.  It is
  318.  *  intended to provide the same interface as the real DB class, plus
  319.  *  a small database sufficient to test software.
  320.  */
  321.  
  322. class DB {
  323.  
  324.     /**
  325.      * Create a new DB object for the specified database type but don't
  326.      * connect to the database
  327.      *
  328.      * @param string $type     the database type (eg "mysql")
  329.      * @param array  $options  an associative array of option names and values
  330.      * @return object  new DB object.  A DB_Error object on failure.
  331.      * @see DB_common::setOption()
  332.      *  @todo Implement mock DB::factory
  333.      */
  334.     public function &factory($type$options false)
  335.     {
  336. //        if (!is_array($options)) {
  337. //            $options = array('persistent' => $options);
  338. //        }
  339. //
  340. //        if (isset($options['debug']) && $options['debug'] >= 2) {
  341. //            // expose php errors with sufficient debug level
  342. //            include_once "DB/{$type}.php";
  343. //        } else {
  344. //            @include_once "DB/{$type}.php";
  345. //        }
  346. //
  347. //        $classname = "DB_${type}";
  348. //
  349. //        if (!class_exists($classname)) {
  350. //            $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
  351. //                                    "Unable to include the DB/{$type}.php"
  352. //                                    . " file for '$dsn'",
  353. //                                    'DB_Error', true);
  354. //            return $tmp;
  355. //        }
  356. //
  357. //        @$obj =& new $classname;
  358. //
  359. //        foreach ($options as $option => $value) {
  360. //            $test = $obj->setOption($option, $value);
  361. //            if (DB::isError($test)) {
  362. //                return $test;
  363. //            }
  364. //        }
  365. //
  366. //        return $obj;
  367.     }
  368.  
  369.     /**
  370.      * Create a new DB object including a connection to the specified database
  371.      *
  372.      * @param mixed $dsn      the string "data source name" or array in the
  373.      *                          format returned by DB::parseDSN()
  374.      * @param array $options  an associative array of option names and values
  375.      * @return object  new DB object.  A DB_Error object on failure.
  376.      * @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError()
  377.      *  @todo Implement mock DB::connect
  378.      */
  379.     function &connect($dsn$options array())
  380.     {
  381.         $dsninfo DB::parseDSN($dsn);
  382.         $type $dsninfo['phptype'];
  383.  
  384.         // only support MySQL at the moment
  385.         PHPUnit2_Framework_Assert::assertEquals($type,'mysql');
  386.         @$obj =new DB_mysql;
  387.  
  388.         foreach ($options as $option => $value{
  389.             $test $obj->setOption($option$value);
  390.             if (DB::isError($test)) {
  391.                 return $test;
  392.             }
  393.         }
  394.  
  395. //        $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
  396. //        if (DB::isError($err)) {
  397. //            $err->addUserInfo($dsn);
  398. //            return $err;
  399. //        }
  400. //
  401.         return $obj;
  402.     }
  403.  
  404.     /**
  405.      * Return the DB API version
  406.      *
  407.      * @return string  the DB API version number
  408.      */
  409.     function apiVersion()
  410.     {
  411.         return '1.7.6';
  412.     }
  413.  
  414.     /**
  415.      * Determines if a variable is a DB_Error object
  416.      *
  417.      * @param mixed $value  the variable to check
  418.      * @return bool  whether $value is DB_Error object
  419.      */
  420.     function isError($value)
  421.     {
  422.         return is_a($value'DB_Error');
  423.     }
  424.  
  425.     /**
  426.      * Determines if a value is a DB_<driver> object
  427.      *
  428.      * @param mixed $value  the value to test
  429.      * @return bool  whether $value is a DB_<driver> object
  430.      *  @todo Implement mock DB::isConnection
  431.      */
  432.     function isConnection($value)
  433.     {
  434. //        return (is_object($value) &&
  435. //                is_subclass_of($value, 'db_common') &&
  436. //                method_exists($value, 'simpleQuery'));
  437.     }
  438.  
  439.     /**
  440.      * Tell whether a query is a data manipulation or data definition query
  441.      *
  442.      * @param string $query  the query
  443.      * @return boolean  whether $query is a data manipulation query
  444.      */
  445.     function isManip($query)
  446.     {
  447.         $manips 'INSERT|UPDATE|DELETE|REPLACE|'
  448.                 . 'CREATE|DROP|'
  449.                 . 'LOAD DATA|SELECT .* INTO|COPY|'
  450.                 . 'ALTER|GRANT|REVOKE|'
  451.                 . 'LOCK|UNLOCK';
  452.         if (preg_match('/^\s*"?(' $manips ')\s+/i'$query)) {
  453.             return true;
  454.         }
  455.         return false;
  456.     }
  457.  
  458.     /**
  459.      * Return a textual error message for a DB error code
  460.      *
  461.      * @param integer $value  the DB error code
  462.      * @return string  the error message or false if the error code was
  463.      *                   not recognized
  464.      *  @todo Implement mock DB::errorMessage
  465.      */
  466.     public function errorMessage($value)
  467.     {
  468.         static $errorMessages;
  469.         if (!isset($errorMessages)) {
  470.             $errorMessages array(
  471.                 DB_ERROR                    => 'unknown error',
  472.                 DB_ERROR_ACCESS_VIOLATION   => 'insufficient permissions',
  473.                 DB_ERROR_ALREADY_EXISTS     => 'already exists',
  474.                 DB_ERROR_CANNOT_CREATE      => 'can not create',
  475.                 DB_ERROR_CANNOT_DROP        => 'can not drop',
  476.                 DB_ERROR_CONNECT_FAILED     => 'connect failed',
  477.                 DB_ERROR_CONSTRAINT         => 'constraint violation',
  478.                 DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
  479.                 DB_ERROR_DIVZERO            => 'division by zero',
  480.                 DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
  481.                 DB_ERROR_INVALID            => 'invalid',
  482.                 DB_ERROR_INVALID_DATE       => 'invalid date or time',
  483.                 DB_ERROR_INVALID_DSN        => 'invalid DSN',
  484.                 DB_ERROR_INVALID_NUMBER     => 'invalid number',
  485.                 DB_ERROR_MISMATCH           => 'mismatch',
  486.                 DB_ERROR_NEED_MORE_DATA     => 'insufficient data supplied',
  487.                 DB_ERROR_NODBSELECTED       => 'no database selected',
  488.                 DB_ERROR_NOSUCHDB           => 'no such database',
  489.                 DB_ERROR_NOSUCHFIELD        => 'no such field',
  490.                 DB_ERROR_NOSUCHTABLE        => 'no such table',
  491.                 DB_ERROR_NOT_CAPABLE        => 'DB backend not capable',
  492.                 DB_ERROR_NOT_FOUND          => 'not found',
  493.                 DB_ERROR_NOT_LOCKED         => 'not locked',
  494.                 DB_ERROR_SYNTAX             => 'syntax error',
  495.                 DB_ERROR_UNSUPPORTED        => 'not supported',
  496.                 DB_ERROR_TRUNCATED          => 'truncated',
  497.                 DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
  498.                 DB_OK                       => 'no error',
  499.             );
  500.         }
  501.  
  502. //        if (DB::isError($value)) {
  503. //            $value = $value->getCode();
  504. //        }
  505. //
  506. //        return isset($errorMessages[$value]) ? $errorMessages[$value]
  507. //                     : $errorMessages[DB_ERROR];
  508.     }
  509.  
  510.     /**
  511.      * Parse a data source name
  512.      *
  513.      * @param string $dsn Data Source Name to be parsed
  514.      * @return array an associative array with the following keys:
  515.      *   + phptype:  Database backend used in PHP (mysql, odbc etc.)
  516.      *   + dbsyntax: Database used with regards to SQL syntax etc.
  517.      *   + protocol: Communication protocol to use (tcp, unix etc.)
  518.      *   + hostspec: Host specification (hostname[:port])
  519.      *   + database: Database to use on the DBMS server
  520.      *   + username: User name for login
  521.      *   + password: Password for login
  522.      *  @todo Implement mock DB::parseDSN
  523.      */
  524.     public function parseDSN($dsn)
  525.     {
  526.         $parsed array(
  527.             'phptype'  => false,
  528.             'dbsyntax' => false,
  529.             'username' => false,
  530.             'password' => false,
  531.             'protocol' => false,
  532.             'hostspec' => false,
  533.             'port'     => false,
  534.             'socket'   => false,
  535.             'database' => false,
  536.         );
  537.  
  538.         if (is_array($dsn)) {
  539.             $dsn array_merge($parsed$dsn);
  540.             if (!$dsn['dbsyntax']{
  541.                 $dsn['dbsyntax'$dsn['phptype'];
  542.             }
  543.             return $dsn;
  544.         }
  545.  
  546.         // Find phptype and dbsyntax
  547.         if (($pos strpos($dsn'://')) !== false{
  548.             $str substr($dsn0$pos);
  549.             $dsn substr($dsn$pos 3);
  550.         else {
  551.             $str $dsn;
  552.             $dsn null;
  553.         }
  554.  
  555.         // Get phptype and dbsyntax
  556.         // $str => phptype(dbsyntax)
  557.         if (preg_match('|^(.+?)\((.*?)\)$|'$str$arr)) {
  558.             $parsed['phptype']  $arr[1];
  559.             $parsed['dbsyntax'!$arr[2$arr[1$arr[2];
  560.         else {
  561.             $parsed['phptype']  $str;
  562.             $parsed['dbsyntax'$str;
  563.         }
  564.  
  565.         if (!count($dsn)) {
  566.             return $parsed;
  567.         }
  568.  
  569.         // Get (if found): username and password
  570.         // $dsn => username:password@protocol+hostspec/database
  571.         if (($at strrpos($dsn,'@')) !== false{
  572.             $str substr($dsn0$at);
  573.             $dsn substr($dsn$at 1);
  574.             if (($pos strpos($str':')) !== false{
  575.                 $parsed['username'rawurldecode(substr($str0$pos));
  576.                 $parsed['password'rawurldecode(substr($str$pos 1));
  577.             else {
  578.                 $parsed['username'rawurldecode($str);
  579.             }
  580.         }
  581.  
  582.         // Find protocol and hostspec
  583.  
  584.         if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|'$dsn$match)) {
  585.             // $dsn => proto(proto_opts)/database
  586.             $proto       $match[1];
  587.             $proto_opts  $match[2$match[2false;
  588.             $dsn         $match[3];
  589.  
  590.         else {
  591.             // $dsn => protocol+hostspec/database (old format)
  592.             if (strpos($dsn'+'!== false{
  593.                 list($proto$dsnexplode('+'$dsn2);
  594.             }
  595.             if (strpos($dsn'/'!== false{
  596.                 list($proto_opts$dsnexplode('/'$dsn2);
  597.             else {
  598.                 $proto_opts $dsn;
  599.                 $dsn null;
  600.             }
  601.         }
  602.  
  603.         // process the different protocol options
  604.         $parsed['protocol'(!empty($proto)) $proto 'tcp';
  605.         $proto_opts rawurldecode($proto_opts);
  606.         if ($parsed['protocol'== 'tcp'{
  607.             if (strpos($proto_opts':'!== false{
  608.                 list($parsed['hostspec'],
  609.                      $parsed['port']explode(':'$proto_opts);
  610.             else {
  611.                 $parsed['hostspec'$proto_opts;
  612.             }
  613.         elseif ($parsed['protocol'== 'unix'{
  614.             $parsed['socket'$proto_opts;
  615.         }
  616.  
  617.         // Get dabase if any
  618.         // $dsn => database
  619.         if ($dsn{
  620.             if (($pos strpos($dsn'?')) === false{
  621.                 // /database
  622.                 $parsed['database'rawurldecode($dsn);
  623.             else {
  624.                 // /database?param1=value1&param2=value2
  625.                 $parsed['database'rawurldecode(substr($dsn0$pos));
  626.                 $dsn substr($dsn$pos 1);
  627.                 if (strpos($dsn'&'!== false{
  628.                     $opts explode('&'$dsn);
  629.                 else // database?param1=value1
  630.                     $opts array($dsn);
  631.                 }
  632.                 foreach ($opts as $opt{
  633.                     list($key$valueexplode('='$opt);
  634.                     if (!isset($parsed[$key])) {
  635.                         // don't allow params overwrite
  636.                         $parsed[$keyrawurldecode($value);
  637.                     }
  638.                 }
  639.             }
  640.         }
  641.  
  642.         return $parsed;
  643.     }
  644. }
  645.  
  646. /**
  647.  *  Mock DB_common for testing
  648.  *  @todo Implement mock DB_common class
  649.  */
  650. class DB_common extends PEAR {
  651.  
  652.     /**
  653.      *  Mock Database
  654.      */
  655.     protected static $database =
  656.         //  Person names table
  657.         array('person_names' =>
  658.               //  Description
  659.               array('info' =>
  660.                     array(array('table' => 'person_names',
  661.                                 'name'  => 'id',
  662.                                 'type'  => 'int',
  663.                                 'len'   => '11',
  664.                                 'flags' => 'primary_key not_null'),
  665.                           array('table' => 'person_names',
  666.                                 'name'  => 'prefix',
  667.                                 'type'  => 'string',
  668.                                 'len'   => '20',
  669.                                 'flags' => ''),
  670.                           array('table' => 'person_names',
  671.                                 'name'  => 'first_name',
  672.                                 'type'  => 'string',
  673.                                 'len'   => '40',
  674.                                 'flags' => ''),
  675.                           array('table' => 'person_names',
  676.                                 'name'  => 'mi',
  677.                                 'type'  => 'string',
  678.                                 'len'   => '1',
  679.                                 'flags' => ''),
  680.                           array('table' => 'person_names',
  681.                                 'name'  => 'last_name',
  682.                                 'type'  => 'string',
  683.                                 'len'   => '40',
  684.                                 'flags' => ''),
  685.                           array('table' => 'person_names',
  686.                                 'name'  => 'suffix',
  687.                                 'type'  => 'string',
  688.                                 'len'   => '20',
  689.                                 'flags' => ''),
  690.                           ),
  691.                     'data' =>
  692.                     array()
  693.                     ),
  694.  
  695.               //  Data types table
  696.               'data_types' =>
  697.  
  698.               //  Description
  699.               array('info' =>
  700.                     array(array("table" => "data_types",
  701.                                 "name"  => "id",
  702.                                 "type"  => "int",
  703.                                 "len"   => '11',
  704.                                 "flags" => "not_null primary_key auto_increment"),
  705.                           array("table" => "data_types",
  706.                                 "name"  => "bit_type",
  707.                                 "type"  => "int",
  708.                                 "len"   => '1',
  709.                                 "flags" => ""),
  710.                           array("table" => "data_types",
  711.                                 "name"  => "tinyint_type",
  712.                                 "type"  => "int",
  713.                                 "len"   =>  '4',
  714.                                 "flags" =>  ""),
  715.                           array("table" =>  "data_types",
  716.                                 "name"  =>  "bool_type",
  717.                                 "type"  =>  "int",
  718.                                 "len"   =>  '1',
  719.                                 "flags" =>  ""),
  720.                           array("table" =>  "data_types",
  721.                                 "name"  =>  "boolean_type",
  722.                                 "type"  =>  "int",
  723.                                 "len"   =>  '1',
  724.                                 "flags" =>  ""),
  725.                           array("table" =>  "data_types",
  726.                                 "name"  =>  "smallint_type",
  727.                                 "type"  =>  "int",
  728.                                 "len"   =>  '6',
  729.                                 "flags" =>  ""),
  730.                           array("table" =>  "data_types",
  731.                                 "name"  =>  "mediumint_type",
  732.                                 "type"  =>  "int",
  733.                                 "len"   =>  '9',
  734.                                 "flags" =>  ""),
  735.                           array("table"   =>  "data_types",
  736.                                 "name"    =>  "int_type",
  737.                                 "type"    =>  "int",
  738.                                 "len"     =>  '11',
  739.                                 "flags"   =>  ""),
  740.                           array("table" =>  "data_types",
  741.                                 "name"  =>  "integer_type",
  742.                                 "type"  =>  "int",
  743.                                 "len"   =>  '11',
  744.                                 "flags" =>  ""),
  745.                           array("table" =>  "data_types",
  746.                                 "name"  =>  "bigint_type",
  747.                                 "type"  =>  "int",
  748.                                 "len"   =>  '20',
  749.                                 "flags" =>  ""),
  750.                           array("table" =>  "data_types",
  751.                                 "name"  =>  "float_type",
  752.                                 "type"  =>  "real",
  753.                                 "len"   =>  '12',
  754.                                 "flags" =>  ""),
  755.                           array("table" =>  "data_types",
  756.                                 "name"  =>  "double_type",
  757.                                 "type"  =>  "real",
  758.                                 "len"   =>  '22',
  759.                                 "flags" =>  ""),
  760.                           array("table" =>  "data_types",
  761.                                 "name"  =>  "double_precision_type",
  762.                                 "type"  =>  "real",
  763.                                 "len"   =>  '22',
  764.                                 "flags" =>  ""),
  765.                           array("table" =>  "data_types",
  766.                                 "name"  =>  "decimal_type",
  767.                                 "type"  =>  "real",
  768.                                 "len"   =>  '11',
  769.                                 "flags" =>  ""),
  770.                           array("table" =>  "data_types",
  771.                                 "name"  =>  "dec_type",
  772.                                 "type"  =>  "real",
  773.                                 "len"   =>  '11',
  774.                                 "flags" =>  ""),
  775.                           array("table" => "data_types",
  776.                                 "name"  => "numeric_type",
  777.                                 "type"  => "real",
  778.                                 "len"   => '11',
  779.                                 "flags" => ""),
  780.                           array("table" => "data_types",
  781.                                 "name"  => "fixed_type",
  782.                                 "type"  => "real",
  783.                                 "len"   => '11',
  784.                                 "flags" => ""),
  785.                           array("table" => "data_types",
  786.                                 "name"  => "date_type",
  787.                                 "type"  => "date",
  788.                                 "len"   => '10',
  789.                                 "flags" => "binary"),
  790.                           array("table" => "data_types",
  791.                                 "name"  => "datetime_type",
  792.                                 "type"  => "datetime",
  793.                                 "len"   => '19',
  794.                                 "flags" => "binary"),
  795.                           array("table" => "data_types",
  796.                                 "name"  => "timestamp_type",
  797.                                 "type"  => "timestamp",
  798.                                 "len"   => '19',
  799.                                 "flags" => "unsigned zerofill binary"),
  800.                           array("table" => "data_types",
  801.                                 "name"  => "time_type",
  802.                                 "type"  => "time",
  803.                                 "len"   => '8',
  804.                                 "flags" => "binary"),
  805.                           array("table" => "data_types",
  806.                                 "name"  => "year_type",
  807.                                 "type"  => "year",
  808.                                 "len"   => '4',
  809.                                 "flags" => "unsigned zerofill"),
  810.                           array("table" => "data_types",
  811.                                 "name"  => "char_type",
  812.                                 "type"  => "string",
  813.                                 "len"   => '20',
  814.                                 "flags" => ""),
  815.                           array("table" => "data_types",
  816.                                 "name"  => "varchar_type",
  817.                                 "type"  => "string",
  818.                                 "len"   => '20',
  819.                                 "flags" => ""),
  820.                           array("table" => "data_types",
  821.                                 "name"  => "nchar_type",
  822.                                 "type"  => "string",
  823.                                 "len"   => '20',
  824.                                 "flags" => ""),
  825.                           array("table" => "data_types",
  826.                                 "name"  => "binary_type",
  827.                                 "type"  => "string",
  828.                                 "len"   => '20',
  829.                                 "flags" => "binary"),
  830.                           array("table" => "data_types",
  831.                                 "name"  => "varbinary_type",
  832.                                 "type"  => "string",
  833.                                 "len"   => '20',
  834.                                 "flags" => "binary"),
  835.                           array("table" => "data_types",
  836.                                 "name"  => "tinyblob_type",
  837.                                 "type"  => "blob",
  838.                                 "len"   => '255',
  839.                                 "flags" => "blob binary"),
  840.                           array("table" => "data_types",
  841.                                 "name"  => "tinytext_type",
  842.                                 "type"  => "blob",
  843.                                 "len"   => '255',
  844.                                 "flags" => "blob"),
  845.                           array("table" => "data_types",
  846.                                 "name"  => "blob_type",
  847.                                 "type"  => "blob",
  848.                                 "len"   => '65535',
  849.                                 "flags" => "blob binary"),
  850.                           array("table" => "data_types",
  851.                                 "name"  => "text_type",
  852.                                 "type"  => "blob",
  853.                                 "len"   => '65535',
  854.                                 "flags" => "blob"),
  855.                           array("table" => "data_types",
  856.                                 "name"  => "mediumblob_type",
  857.                                 "type"  => "blob",
  858.                                 "len"   => '16777215',
  859.                                 "flags" => "blob binary"),
  860.                           array("table" => "data_types",
  861.                                 "name"  => "mediumtext_type",
  862.                                 "type"  => "blob",
  863.                                 "len"   => '16777215',
  864.                                 "flags" => "blob"),
  865.                           array("table" => "data_types",
  866.                                 "name"  => "longblob_type",
  867.                                 "type"  => "blob",
  868.                                 "len"   => '-1',
  869.                                 "flags" => "blob binary"),
  870.                           array("table" => "data_types",
  871.                                 "name"  => "longtext_type",
  872.                                 "type"  => "blob",
  873.                                 "len"   => '-1',
  874.                                 "flags" => "blob"),
  875.                           array("table" => "data_types",
  876.                                 "name"  => "enum_type",
  877.                                 "type"  => "string",
  878.                                 "len"   => '3',
  879.                                 "flags" => "enum"),
  880.                           array("table" => "data_types",
  881.                                 "name"  => "set_type",
  882.                                 "type"  => "string",
  883.                                 "len"   => '7',
  884.                                 "flags" => "set"),
  885.                           ),
  886.                     'data' =>
  887.                     array()
  888.                     ),
  889.               );
  890.  
  891.     /**
  892.      * Run-time configuration options
  893.      *
  894.      * @var array 
  895.      * @see DB_common::setOption()
  896.      */
  897.     var $options = array(
  898.         'result_buffering' => 500,
  899.         'persistent' => false,
  900.         'ssl' => false,
  901.         'debug' => 0,
  902.         'seqname_format' => '%s_seq',
  903.         'autofree' => false,
  904.         'portability' => DB_PORTABILITY_NONE,
  905.         'optimize' => 'performance',  // Deprecated.  Use 'portability'.
  906.     );
  907.  
  908.     /**
  909.      *  List of expected queries and returns
  910.      */
  911.     private $expected_list = null;
  912.  
  913.     /**
  914.      *  Cursor in list of expected queries and returns
  915.      */
  916.     private $expected_list_cursor = null;
  917.  
  918.     /**
  919.      *  Expected query
  920.      *  @var string 
  921.      */
  922.     private $expected_query = null;
  923.  
  924.     /**
  925.      *  Result to be returned from expected query
  926.      *  @var string 
  927.      */
  928.     private $expected_result = null;
  929.  
  930.     /**
  931.      * This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
  932.      *
  933.      * @return void 
  934.      */
  935.     function DB_common()
  936.     {
  937.         $this->PEAR('DB_Error');
  938.     }
  939.  
  940.     /**
  941.      * Automatically indicates which properties should be saved
  942.      * when PHP's serialize() function is called
  943.      *
  944.      * @return array  the array of properties names that should be saved
  945.      *  @todo Implement mock DB_common::__sleep
  946.      */
  947.     function __sleep()
  948.     {
  949. //        if ($this->connection) {
  950. //            // Don't disconnect(), people use serialize() for many reasons
  951. //            $this->was_connected = true;
  952. //        } else {
  953. //            $this->was_connected = false;
  954. //        }
  955. //        if (isset($this->autocommit)) {
  956. //            return array('autocommit',
  957. //                         'dbsyntax',
  958. //                         'dsn',
  959. //                         'features',
  960. //                         'fetchmode',
  961. //                         'fetchmode_object_class',
  962. //                         'options',
  963. //                         'was_connected',
  964. //                   );
  965. //        } else {
  966. //            return array('dbsyntax',
  967. //                         'dsn',
  968. //                         'features',
  969. //                         'fetchmode',
  970. //                         'fetchmode_object_class',
  971. //                         'options',
  972. //                         'was_connected',
  973. //                   );
  974. //        }
  975.     }
  976.  
  977.     /**
  978.      * Automatically reconnects to the database when PHP's unserialize()
  979.      * function is called
  980.      *
  981.      * @return void 
  982.      *  @todo Implement mock DB_common::__wakeup
  983.      */
  984.     function __wakeup()
  985.     {
  986. //        if ($this->was_connected) {
  987. //            $this->connect($this->dsn, $this->options);
  988. //        }
  989.     }
  990.  
  991.     /**
  992.      * Automatic string conversion for PHP 5
  993.      *
  994.      * @return string  a string describing the current PEAR DB object
  995.      *  @todo Implement mock DB_common::__toString
  996.      */
  997.     public function __toString()
  998.     {
  999. //        $info = strtolower(get_class($this));
  1000. //        $info .=  ': (phptype=' . $this->phptype .
  1001. //                  ', dbsyntax=' . $this->dbsyntax .
  1002. //                  ')';
  1003. //        if ($this->connection) {
  1004. //            $info .= ' [connected]';
  1005. //        }
  1006. //        return $info;
  1007.     }
  1008.  
  1009.     /**
  1010.      * Quotes a string so it can be safely used as a table or column name
  1011.      *
  1012.      * @param string $str  the identifier name to be quoted
  1013.      * @return string  the quoted identifier
  1014.      */
  1015.     public function quoteIdentifier($str)
  1016.     {
  1017.         return '"' str_replace('"''""'$str'"';
  1018.     }
  1019.  
  1020.     /**
  1021.      * Formats input so it can be safely used in a query
  1022.      *
  1023.      * @see DB_common::escapeSimple()
  1024.      *  @todo Implement mock DB_common::quoteSmart
  1025.      */
  1026.     public function quoteSmart($in)
  1027.     {
  1028. //        if (is_int($in) || is_double($in)) {
  1029. //            return $in;
  1030. //        } elseif (is_bool($in)) {
  1031. //            return $in ? 1 : 0;
  1032. //        } elseif (is_null($in)) {
  1033. //            return 'NULL';
  1034. //        } else {
  1035. //            return "'" . $this->escapeSimple($in) . "'";
  1036. //        }
  1037.     }
  1038.  
  1039.     /**
  1040.      * Escapes a string according to the current DBMS's standards
  1041.      *
  1042.      * @param string $str  the string to be escaped
  1043.      * @return string  the escaped string
  1044.      * @see DB_common::quoteSmart()
  1045.      *  @todo Implement mock DB_common::escapeSimple
  1046.      */
  1047.     public function escapeSimple($str)
  1048.     {
  1049. //        return str_replace("'", "''", $str);
  1050.     }
  1051.  
  1052.     /**
  1053.      * Tells whether the present driver supports a given feature
  1054.      *
  1055.      * @param string $feature  the feature you're curious about
  1056.      * @return bool  whether this driver supports $feature
  1057.      *  @todo Implement mock DB_common::provides
  1058.      */
  1059.     public function provides($feature)
  1060.     {
  1061. //        return $this->features[$feature];
  1062.     }
  1063.  
  1064.     /**
  1065.      * Sets the fetch mode that should be used by default for query results
  1066.      *
  1067.      * @param integer $fetchmode    DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
  1068.      *                                or DB_FETCHMODE_OBJECT
  1069.      * @param string $object_class  the class name of the object to be returned
  1070.      *                                by the fetch methods when the
  1071.      *                                DB_FETCHMODE_OBJECT mode is selected.
  1072.      *                                If no class is specified by default a cast
  1073.      *                                to object from the assoc array row will be
  1074.      *                                done.  There is also the posibility to use
  1075.      *                                and extend the 'DB_row' class.
  1076.      *
  1077.      * @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
  1078.      *  @todo Implement mock DB_common::setFetchMode
  1079.      */
  1080.     public function setFetchMode($fetchmode$object_class 'stdClass')
  1081.     {
  1082. //        switch ($fetchmode) {
  1083. //            case DB_FETCHMODE_OBJECT:
  1084. //                $this->fetchmode_object_class = $object_class;
  1085. //            case DB_FETCHMODE_ORDERED:
  1086. //            case DB_FETCHMODE_ASSOC:
  1087. //                $this->fetchmode = $fetchmode;
  1088. //                break;
  1089. //            default:
  1090. //                return $this->raiseError('invalid fetchmode mode');
  1091. //        }
  1092.     }
  1093.  
  1094.     /**
  1095.      * Sets run-time configuration options for PEAR DB
  1096.      *
  1097.      * @param string $option option name
  1098.      * @param mixed  $value value for the option
  1099.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1100.      * @see DB_common::$options
  1101.      *  @todo Implement mock DB_common::setOption
  1102.      */
  1103.     public function setOption($option$value)
  1104.     {
  1105.         if (isset($this->options[$option])) {
  1106.             $this->options[$option$value;
  1107.             return DB_OK;
  1108.         }
  1109.         PHPUnit2_Framework_Assert::fail("DB_common::setOption called"
  1110.                                         ." with unknown option $option");
  1111.     }
  1112.  
  1113.     /**
  1114.      * Returns the value of an option
  1115.      *
  1116.      * @param string $option  the option name you're curious about
  1117.      * @return mixed  the option's value
  1118.      *  @todo Implement mock DB_common::getOption
  1119.      */
  1120.     public function getOption($option)
  1121.     {
  1122. //        if (isset($this->options[$option])) {
  1123. //            return $this->options[$option];
  1124. //        }
  1125. //        return $this->raiseError("unknown option $option");
  1126.     }
  1127.  
  1128.     /**
  1129.      * Prepares a query for multiple execution with execute()
  1130.      *
  1131.      * @param string $query  the query to be prepared
  1132.      * @return mixed  DB statement resource on success. A DB_Error object
  1133.      *                  on failure.
  1134.      * @see DB_common::execute()
  1135.      *  @todo Implement mock DB_common::prepare
  1136.      */
  1137.     public function prepare($query)
  1138.     {
  1139.         PHPUnit2_Framework_Assert::fail("DB does not support"
  1140.                                         . " multiple execution");
  1141. //        $tokens   = preg_split('/((?<!\\\)[&?!])/', $query, -1,
  1142. //                               PREG_SPLIT_DELIM_CAPTURE);
  1143. //        $token     = 0;
  1144. //        $types     = array();
  1145. //        $newtokens = array();
  1146. //
  1147. //        foreach ($tokens as $val) {
  1148. //            switch ($val) {
  1149. //                case '?':
  1150. //                    $types[$token++] = DB_PARAM_SCALAR;
  1151. //                    break;
  1152. //                case '&':
  1153. //                    $types[$token++] = DB_PARAM_OPAQUE;
  1154. //                    break;
  1155. //                case '!':
  1156. //                    $types[$token++] = DB_PARAM_MISC;
  1157. //                    break;
  1158. //                default:
  1159. //                    $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val);
  1160. //            }
  1161. //        }
  1162. //
  1163. //        $this->prepare_tokens[] = &$newtokens;
  1164. //        end($this->prepare_tokens);
  1165. //
  1166. //        $k = key($this->prepare_tokens);
  1167. //        $this->prepare_types[$k] = $types;
  1168. //        $this->prepared_queries[$k] = implode(' ', $newtokens);
  1169. //
  1170. //        return $k;
  1171.     }
  1172.  
  1173.  
  1174.     /**
  1175.      * Automaticaly generates an insert or update query and pass it to
  1176.      * prepare()
  1177.      *
  1178.      * @param string $table         the table name
  1179.      * @param array  $table_fields  the array of field names
  1180.      * @param int    $mode          a type of query to make:
  1181.      *                                DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  1182.      * @param string $where         for update queries: the WHERE clause to
  1183.      *                                append to the SQL statement.  Don't
  1184.      *                                include the "WHERE" keyword.
  1185.      *
  1186.      * @return resource  the query handle
  1187.      * @uses DB_common::prepare(), DB_common::buildManipSQL()
  1188.      *  @todo Implement mock DB_common::autoPrepare
  1189.      */
  1190.     public function autoPrepare($table$table_fields$mode DB_AUTOQUERY_INSERT,
  1191.                          $where false)
  1192.     {
  1193. //        $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
  1194. //        if (DB::isError($query)) {
  1195. //            return $query;
  1196. //        }
  1197. //        return $this->prepare($query);
  1198.     }
  1199.  
  1200.     /**
  1201.      * Automaticaly generates an insert or update query and call prepare()
  1202.      * and execute() with it
  1203.      *
  1204.      * @param string $table         the table name
  1205.      * @param array  $fields_values the associative array where $key is a
  1206.      *                                field name and $value its value
  1207.      * @param int    $mode          a type of query to make:
  1208.      *                                DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  1209.      * @param string $where         for update queries: the WHERE clause to
  1210.      *                                append to the SQL statement.  Don't
  1211.      *                                include the "WHERE" keyword.
  1212.      *
  1213.      * @return mixed  a new DB_result object for successful SELECT queries
  1214.      *                  or DB_OK for successul data manipulation queries.
  1215.      *                  A DB_Error object on failure.
  1216.      *
  1217.      * @uses DB_common::autoPrepare(), DB_common::execute()
  1218.      *  @todo Implement mock DB_common::autoExecute
  1219.      */
  1220.     public function autoExecute($table$fields_values$mode DB_AUTOQUERY_INSERT,
  1221.                          $where false)
  1222.     {
  1223.         PHPUnit2_Framework_Assert::fail("DB does not support"
  1224.                                         . " multiple execution");
  1225. //        $sth = $this->autoPrepare($table, array_keys($fields_values), $mode,
  1226. //                                  $where);
  1227. //        if (DB::isError($sth)) {
  1228. //            return $sth;
  1229. //        }
  1230. //        $ret =& $this->execute($sth, array_values($fields_values));
  1231. //        $this->freePrepared($sth);
  1232. //        return $ret;
  1233.     }
  1234.  
  1235.     /**
  1236.      * Produces an SQL query string for autoPrepare()
  1237.      *
  1238.      * @param string $table         the table name
  1239.      * @param array  $table_fields  the array of field names
  1240.      * @param int    $mode          a type of query to make:
  1241.      *                                DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  1242.      * @param string $where         for update queries: the WHERE clause to
  1243.      *                                append to the SQL statement.  Don't
  1244.      *                                include the "WHERE" keyword.
  1245.      *
  1246.      * @return string  the sql query for autoPrepare()
  1247.      *  @todo Implement mock DB_common::buildManipSQL
  1248.      */
  1249.     public function buildManipSQL($table$table_fields$mode$where false)
  1250.     {
  1251. //        if (count($table_fields) == 0) {
  1252. //            return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
  1253. //        }
  1254. //        $first = true;
  1255. //        switch ($mode) {
  1256. //            case DB_AUTOQUERY_INSERT:
  1257. //                $values = '';
  1258. //                $names = '';
  1259. //                foreach ($table_fields as $value) {
  1260. //                    if ($first) {
  1261. //                        $first = false;
  1262. //                    } else {
  1263. //                        $names .= ',';
  1264. //                        $values .= ',';
  1265. //                    }
  1266. //                    $names .= $value;
  1267. //                    $values .= '?';
  1268. //                }
  1269. //                return "INSERT INTO $table ($names) VALUES ($values)";
  1270. //            case DB_AUTOQUERY_UPDATE:
  1271. //                $set = '';
  1272. //                foreach ($table_fields as $value) {
  1273. //                    if ($first) {
  1274. //                        $first = false;
  1275. //                    } else {
  1276. //                        $set .= ',';
  1277. //                    }
  1278. //                    $set .= "$value = ?";
  1279. //                }
  1280. //                $sql = "UPDATE $table SET $set";
  1281. //                if ($where) {
  1282. //                    $sql .= " WHERE $where";
  1283. //                }
  1284. //                return $sql;
  1285. //            default:
  1286. //                return $this->raiseError(DB_ERROR_SYNTAX);
  1287. //        }
  1288.     }
  1289.  
  1290.     /**
  1291.      * Executes a DB statement prepared with prepare()
  1292.      *
  1293.      * @param resource $stmt  a DB statement resource returned from prepare()
  1294.      * @param mixed    $data  array, string or numeric data to be used in
  1295.      *                          execution of the statement.  Quantity of items
  1296.      *                          passed must match quantity of placeholders in
  1297.      *                          query:  meaning 1 placeholder for non-array
  1298.      *                          parameters or 1 placeholder per array element.
  1299.      *
  1300.      * @return mixed  a new DB_result object for successful SELECT queries
  1301.      *                  or DB_OK for successul data manipulation queries.
  1302.      *                  A DB_Error object on failure.
  1303.      *
  1304.      * @see DB_common::prepare()
  1305.      *  @todo Implement mock DB_common::execute
  1306.      */
  1307.     public function &execute($stmt$data array())
  1308.     {
  1309.         PHPUnit2_Framework_Assert::fail("DB does not support"
  1310.                                         . " multiple execution");
  1311. //        $realquery = $this->executeEmulateQuery($stmt, $data);
  1312. //        if (DB::isError($realquery)) {
  1313. //            return $realquery;
  1314. //        }
  1315. //        $result = $this->simpleQuery($realquery);
  1316. //
  1317. //        if ($result === DB_OK || DB::isError($result)) {
  1318. //            return $result;
  1319. //        } else {
  1320. //            $tmp =& new DB_result($this, $result);
  1321. //            return $tmp;
  1322. //        }
  1323.     }
  1324.  
  1325.     /**
  1326.      * Emulates executing prepared statements if the DBMS not support them
  1327.      *
  1328.      * @param resource $stmt  a DB statement resource returned from execute()
  1329.      * @param mixed    $data  array, string or numeric data to be used in
  1330.      *                          execution of the statement.  Quantity of items
  1331.      *                          passed must match quantity of placeholders in
  1332.      *                          query:  meaning 1 placeholder for non-array
  1333.      *                          parameters or 1 placeholder per array element.
  1334.      *
  1335.      * @return mixed  a string containing the real query run when emulating
  1336.      *                  prepare/execute.  A DB_Error object on failure.
  1337.      *
  1338.      * @see DB_common::execute()
  1339.      *  @todo Implement mock DB_common::executeEmulateQuery
  1340.      */
  1341.     protected function executeEmulateQuery($stmt$data array())
  1342.     {
  1343.         PHPUnit2_Framework_Assert::fail("DB does not support"
  1344.                                         . " multiple execution");
  1345. //        $stmt = (int)$stmt;
  1346. //        $data = (array)$data;
  1347. //        $this->last_parameters = $data;
  1348. //
  1349. //        if (count($this->prepare_types[$stmt]) != count($data)) {
  1350. //            $this->last_query = $this->prepared_queries[$stmt];
  1351. //            return $this->raiseError(DB_ERROR_MISMATCH);
  1352. //        }
  1353. //
  1354. //        $realquery = $this->prepare_tokens[$stmt][0];
  1355. //
  1356. //        $i = 0;
  1357. //        foreach ($data as $value) {
  1358. //            if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) {
  1359. //                $realquery .= $this->quoteSmart($value);
  1360. //            } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) {
  1361. //                $fp = @fopen($value, 'rb');
  1362. //                if (!$fp) {
  1363. //                    return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
  1364. //                }
  1365. //                $realquery .= $this->quoteSmart(fread($fp, filesize($value)));
  1366. //                fclose($fp);
  1367. //            } else {
  1368. //                $realquery .= $value;
  1369. //            }
  1370. //
  1371. //            $realquery .= $this->prepare_tokens[$stmt][++$i];
  1372. //        }
  1373. //
  1374. //        return $realquery;
  1375.     }
  1376.  
  1377.     /**
  1378.      * Performs several execute() calls on the same statement handle
  1379.      *
  1380.      * @param resource $stmt  query handle from prepare()
  1381.      * @param array    $data  numeric array containing the
  1382.      *                          data to insert into the query
  1383.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1384.      * @see DB_common::prepare(), DB_common::execute()
  1385.      *  @todo Implement mock DB_common::executeMultiple
  1386.      */
  1387.     function executeMultiple($stmt$data)
  1388.     {
  1389.         PHPUnit2_Framework_Assert::fail("DB does not support"
  1390.                                         . " multiple execution");
  1391. //        foreach ($data as $value) {
  1392. //            $res =& $this->execute($stmt, $value);
  1393. //            if (DB::isError($res)) {
  1394. //                return $res;
  1395. //            }
  1396. //        }
  1397. //        return DB_OK;
  1398.     }
  1399.  
  1400.     /**
  1401.      * Frees the internal resources associated with a prepared query
  1402.      *
  1403.      * @param resource $stmt           the prepared statement's PHP resource
  1404.      * @param bool     $free_resource  should the PHP resource be freed too?
  1405.      *                                   Use false if you need to get data
  1406.      *                                   from the result set later.
  1407.      * @return bool  TRUE on success, FALSE if $result is invalid
  1408.      * @see DB_common::prepare()
  1409.      *  @todo Implement mock DB_common::freePrepared
  1410.      */
  1411.     function freePrepared($stmt$free_resource true)
  1412.     {
  1413.         PHPUnit2_Framework_Assert::fail("DB does not support"
  1414.                                         . " multiple execution");
  1415. //        $stmt = (int)$stmt;
  1416. //        if (isset($this->prepare_tokens[$stmt])) {
  1417. //            unset($this->prepare_tokens[$stmt]);
  1418. //            unset($this->prepare_types[$stmt]);
  1419. //            unset($this->prepared_queries[$stmt]);
  1420. //            return true;
  1421. //        }
  1422. //        return false;
  1423.     }
  1424.  
  1425.     /**
  1426.      * Changes a query string for various DBMS specific reasons
  1427.      *
  1428.      * @param string $query  the query string to modify
  1429.      * @return string  the modified query string
  1430.      * @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
  1431.      *       DB_sqlite::modifyQuery()
  1432.      *  @todo Implement mock DB_common::modifyQuery
  1433.      */
  1434.     protected function modifyQuery($query)
  1435.     {
  1436. //        return $query;
  1437.     }
  1438.  
  1439.     /**
  1440.      * Adds LIMIT clauses to a query string according to current DBMS standards
  1441.      *
  1442.      * @param string $query   the query to modify
  1443.      * @param int    $from    the row to start to fetching (0 = the first row)
  1444.      * @param int    $count   the numbers of rows to fetch
  1445.      * @param mixed  $params  array, string or numeric data to be used in
  1446.      *                          execution of the statement.  Quantity of items
  1447.      *                          passed must match quantity of placeholders in
  1448.      *                          query:  meaning 1 placeholder for non-array
  1449.      *                          parameters or 1 placeholder per array element.
  1450.      *
  1451.      * @return string  the query string with LIMIT clauses added
  1452.      *  @todo Implement mock DB_common::modifyLimitQuery
  1453.      */
  1454.     protected function modifyLimitQuery($query$from$count$params array())
  1455.     {
  1456. //        return $query;
  1457.     }
  1458.  
  1459.     /**
  1460.      *  Set expected query and return
  1461.      *
  1462.      *  This is a test routine that does not exist in the PEAR DB package.
  1463.      *  @param string $expected Expected query
  1464.      *  @param string $result Result to be returned when expected
  1465.      *   query is received.
  1466.      */
  1467.     public function expect_query($expected$result{
  1468.         $this->expected_query = $expected;
  1469.         $this->expected_result = $result;
  1470.     }
  1471.  
  1472.     /**
  1473.      *  Set list of expected queries and returns
  1474.      *
  1475.      *  This is a test routine that does not exist in the PEAR DB package.
  1476.      *  @param string $list Expected queries and returns
  1477.      */
  1478.     public function expect_queries($list{
  1479.         $this->expected_list = $list;
  1480.         $this->expected_list_cursor = 0;
  1481.         $this->expect_query($this->expected_list[0]['query'],
  1482.                             $this->expected_list[0]['result']);
  1483.     }
  1484.  
  1485.     /**
  1486.      *  Verify that all expected queries have been received
  1487.      *
  1488.      *  This is a test routine that does not exist in the PEAR DB package.
  1489.      */
  1490.     public function tally_queries({
  1491.         if ($this->expected_list_cursor < count($this->expected_list)) {
  1492.             PHPUnit2_Framework_Assert::fail("DB_mysql::expected query was"
  1493.                           ." not receivedexpected $this->expected_query");
  1494.         }
  1495.     }
  1496.  
  1497.     /**
  1498.      * Sends a query to the database server
  1499.      *
  1500.      * @param string $query   the SQL query or the statement to prepare
  1501.      * @param mixed  $params  array, string or numeric data to be used in
  1502.      *                          execution of the statement.  Quantity of items
  1503.      *                          passed must match quantity of placeholders in
  1504.      *                          query:  meaning 1 placeholder for non-array
  1505.      *                          parameters or 1 placeholder per array element.
  1506.      *
  1507.      * @return mixed  a new DB_result object for successful SELECT queries
  1508.      *                  or DB_OK for successul data manipulation queries.
  1509.      *                  A DB_Error object on failure.
  1510.      *
  1511.      * @see DB_result, DB_common::prepare(), DB_common::execute()
  1512.      *  @todo Implement mock DB_common::query
  1513.      */
  1514.     public function &query($query$params array())
  1515.     {
  1516.         $params = (array)$params;
  1517.         if (sizeof($params0{
  1518.             PHPUnit2_Framework_Assert::fail("DB does not support"
  1519.                                             . " multiple execution");
  1520.         }
  1521.         if (!is_null($this->expected_list)) {
  1522.             //  We are working through a list of queries.  If the
  1523.             //  number of queries received is greater than the number
  1524.             //  on the list, that's an error
  1525.             if ($this->expected_list_cursor >= count($this->expected_list)) {
  1526.                 PHPUnit2_Framework_Assert::fail(
  1527.                               "DB_mysql::query called with"
  1528.                              ."$queryexceeding number of queries expected");
  1529.                 }            
  1530.         }
  1531.         if ($query != $this->expected_query{
  1532.             PHPUnit2_Framework_Assert::fail('DB_mysql::query() called with'
  1533.                  .' "'.$query.'", expected "'.$this->expected_query.'"');
  1534.         }
  1535.         $result $this->expected_result;
  1536.         if (!is_null($this->expected_list)) {
  1537.             //  More queries are expected.  Advance the cursor
  1538.             $this->expected_list_cursor++;
  1539.             $this->expect_query(
  1540.               $this->expected_list[$this->expected_list_cursor]['query'],
  1541.               $this->expected_list[$this->expected_list_cursor]['result']);
  1542.         }
  1543.         return $result;
  1544. //        if (sizeof($params) > 0) {
  1545. //            $sth = $this->prepare($query);
  1546. //            if (DB::isError($sth)) {
  1547. //                return $sth;
  1548. //            }
  1549. //            $ret =& $this->execute($sth, $params);
  1550. //            $this->freePrepared($sth, false);
  1551. //            return $ret;
  1552. //        } else {
  1553. //            $this->last_parameters = array();
  1554. //            $result = $this->simpleQuery($query);
  1555. //            if ($result === DB_OK || DB::isError($result)) {
  1556. //                return $result;
  1557. //            } else {
  1558. //                $tmp =& new DB_result($this, $result);
  1559. //                return $tmp;
  1560. //            }
  1561. //        }
  1562.     }
  1563.  
  1564.     /**
  1565.      * Generates and executes a LIMIT query
  1566.      *
  1567.      * @param string $query   the query
  1568.      * @param intr   $from    the row to start to fetching (0 = the first row)
  1569.      * @param int    $count   the numbers of rows to fetch
  1570.      * @param mixed  $params  array, string or numeric data to be used in
  1571.      *                          execution of the statement.  Quantity of items
  1572.      *                          passed must match quantity of placeholders in
  1573.      *                          query:  meaning 1 placeholder for non-array
  1574.      *                          parameters or 1 placeholder per array element.
  1575.      *
  1576.      * @return mixed  a new DB_result object for successful SELECT queries
  1577.      *                  or DB_OK for successul data manipulation queries.
  1578.      *                  A DB_Error object on failure.
  1579.      *  @todo Implement mock DB_common::limitQuery
  1580.      */
  1581.     public function &limitQuery($query$from$count$params array())
  1582.     {
  1583. //        $query = $this->modifyLimitQuery($query, $from, $count, $params);
  1584. //        if (DB::isError($query)){
  1585. //            return $query;
  1586. //        }
  1587. //        $result =& $this->query($query, $params);
  1588. //        if (is_a($result, 'DB_result')) {
  1589. //            $result->setOption('limit_from', $from);
  1590. //            $result->setOption('limit_count', $count);
  1591. //        }
  1592. //        return $result;
  1593.     }
  1594.  
  1595.     /**
  1596.      * Fetches the first column of the first row from a query result
  1597.      *
  1598.      * @param string $query   the SQL query
  1599.      * @param mixed  $params  array, string or numeric data to be used in
  1600.      *                          execution of the statement.  Quantity of items
  1601.      *                          passed must match quantity of placeholders in
  1602.      *                          query:  meaning 1 placeholder for non-array
  1603.      *                          parameters or 1 placeholder per array element.
  1604.      *
  1605.      * @return mixed  the returned value of the query.
  1606.      *                  A DB_Error object on failure.
  1607.      *  @todo Implement mock DB_common::getOne
  1608.      */
  1609.     function &getOne($query$params array())
  1610.     {
  1611.         return $this->query($query,$params);
  1612.  
  1613. //            $sth = $this->prepare($query);
  1614. //            if (DB::isError($sth)) {
  1615. //                return $sth;
  1616. //            }
  1617. //            $res =& $this->execute($sth, $params);
  1618. //            $this->freePrepared($sth);
  1619. //        } else {
  1620. //            $res =& $this->query($query);
  1621. //        }
  1622. //
  1623. //        if (DB::isError($res)) {
  1624. //            return $res;
  1625. //        }
  1626. //
  1627. //        $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
  1628. //        $res->free();
  1629. //
  1630. //        if ($err !== DB_OK) {
  1631. //            return $err;
  1632. //        }
  1633. //
  1634. //        return $row[0];
  1635.     }
  1636.  
  1637.     /**
  1638.      * Fetches the first row of data returned from a query result
  1639.      *
  1640.      * @param string $query   the SQL query
  1641.      * @param mixed  $params  array, string or numeric data to be used in
  1642.      *                          execution of the statement.  Quantity of items
  1643.      *                          passed must match quantity of placeholders in
  1644.      *                          query:  meaning 1 placeholder for non-array
  1645.      *                          parameters or 1 placeholder per array element.
  1646.      * @param int $fetchmode  the fetch mode to use
  1647.      *
  1648.      * @return array  the first row of results as an array.
  1649.      *                  A DB_Error object on failure.
  1650.      *  @todo Implement mock DB_common::getRow
  1651.      */
  1652.     public function &getRow($query$params array(),
  1653.                      $fetchmode DB_FETCHMODE_DEFAULT)
  1654.     {
  1655. //        // compat check, the params and fetchmode parameters used to
  1656. //        // have the opposite order
  1657. //        if (!is_array($params)) {
  1658. //            if (is_array($fetchmode)) {
  1659. //                if ($params === null) {
  1660. //                    $tmp = DB_FETCHMODE_DEFAULT;
  1661. //                } else {
  1662. //                    $tmp = $params;
  1663. //                }
  1664. //                $params = $fetchmode;
  1665. //                $fetchmode = $tmp;
  1666. //            } elseif ($params !== null) {
  1667. //                $fetchmode = $params;
  1668. //                $params = array();
  1669. //            }
  1670. //        }
  1671. //        // modifyLimitQuery() would be nice here, but it causes BC issues
  1672. //        if (sizeof($params) > 0) {
  1673. //            $sth = $this->prepare($query);
  1674. //            if (DB::isError($sth)) {
  1675. //                return $sth;
  1676. //            }
  1677. //            $res =& $this->execute($sth, $params);
  1678. //            $this->freePrepared($sth);
  1679. //        } else {
  1680. //            $res =& $this->query($query);
  1681. //        }
  1682. //
  1683. //        if (DB::isError($res)) {
  1684. //            return $res;
  1685. //        }
  1686. //
  1687. //        $err = $res->fetchInto($row, $fetchmode);
  1688. //
  1689. //        $res->free();
  1690. //
  1691. //        if ($err !== DB_OK) {
  1692. //            return $err;
  1693. //        }
  1694. //
  1695. //        return $row;
  1696.     }
  1697.  
  1698.     /**
  1699.      * Fetches a single column from a query result and returns it as an
  1700.      * indexed array
  1701.      *
  1702.      * @param string $query   the SQL query
  1703.      * @param mixed  $col     which column to return (integer [column number,
  1704.      *                          starting at 0] or string [column name])
  1705.      * @param mixed  $params  array, string or numeric data to be used in
  1706.      *                          execution of the statement.  Quantity of items
  1707.      *                          passed must match quantity of placeholders in
  1708.      *                          query:  meaning 1 placeholder for non-array
  1709.      *                          parameters or 1 placeholder per array element.
  1710.      *
  1711.      * @return array  the results as an array.  A DB_Error object on failure.
  1712.      *
  1713.      * @see DB_common::query()
  1714.      *  @todo Implement mock DB_common::getCol
  1715.      */
  1716.     public function &getCol($query$col 0$params array())
  1717.     {
  1718. //        $params = (array)$params;
  1719. //        if (sizeof($params) > 0) {
  1720. //            $sth = $this->prepare($query);
  1721. //
  1722. //            if (DB::isError($sth)) {
  1723. //                return $sth;
  1724. //            }
  1725. //
  1726. //            $res =& $this->execute($sth, $params);
  1727. //            $this->freePrepared($sth);
  1728. //        } else {
  1729. //            $res =& $this->query($query);
  1730. //        }
  1731. //
  1732. //        if (DB::isError($res)) {
  1733. //            return $res;
  1734. //        }
  1735. //
  1736. //        $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
  1737. //
  1738. //        if (!is_array($row = $res->fetchRow($fetchmode))) {
  1739. //            $ret = array();
  1740. //        } else {
  1741. //            if (!array_key_exists($col, $row)) {
  1742. //                $ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
  1743. //            } else {
  1744. //                $ret = array($row[$col]);
  1745. //                while (is_array($row = $res->fetchRow($fetchmode))) {
  1746. //                    $ret[] = $row[$col];
  1747. //                }
  1748. //            }
  1749. //        }
  1750. //
  1751. //        $res->free();
  1752. //
  1753. //        if (DB::isError($row)) {
  1754. //            $ret = $row;
  1755. //        }
  1756. //
  1757. //        return $ret;
  1758.     }
  1759.  
  1760.     /**
  1761.      * Fetches an entire query result and returns it as an
  1762.      * associative array using the first column as the key
  1763.      *
  1764.      * @param string $query        the SQL query
  1765.      * @param bool   $force_array  used only when the query returns
  1766.      *                               exactly two columns.  If true, the values
  1767.      *                               of the returned array will be one-element
  1768.      *                               arrays instead of scalars.
  1769.      * @param mixed  $params       array, string or numeric data to be used in
  1770.      *                               execution of the statement.  Quantity of
  1771.      *                               items passed must match quantity of
  1772.      *                               placeholders in query:  meaning 1
  1773.      *                               placeholder for non-array parameters or
  1774.      *                               1 placeholder per array element.
  1775.      * @param int   $fetchmode     the fetch mode to use
  1776.      * @param bool  $group         if true, the values of the returned array
  1777.      *                               is wrapped in another array.  If the same
  1778.      *                               key value (in the first column) repeats
  1779.      *                               itself, the values will be appended to
  1780.      *                               this array instead of overwriting the
  1781.      *                               existing values.
  1782.      *
  1783.      * @return array  the associative array containing the query results.
  1784.      *                 A DB_Error object on failure.
  1785.      *  @todo Implement mock DB_common::getAssoc
  1786.      */
  1787.     public function &getAssoc($query$force_array false$params array(),
  1788.                        $fetchmode DB_FETCHMODE_DEFAULT$group false)
  1789.     {
  1790. //        $params = (array)$params;
  1791. //        if (sizeof($params) > 0) {
  1792. //            $sth = $this->prepare($query);
  1793. //
  1794. //            if (DB::isError($sth)) {
  1795. //                return $sth;
  1796. //            }
  1797. //
  1798. //            $res =& $this->execute($sth, $params);
  1799. //            $this->freePrepared($sth);
  1800. //        } else {
  1801. //            $res =& $this->query($query);
  1802. //        }
  1803. //
  1804. //        if (DB::isError($res)) {
  1805. //            return $res;
  1806. //        }
  1807. //        if ($fetchmode == DB_FETCHMODE_DEFAULT) {
  1808. //            $fetchmode = $this->fetchmode;
  1809. //        }
  1810. //        $cols = $res->numCols();
  1811. //
  1812. //        if ($cols < 2) {
  1813. //            $tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
  1814. //            return $tmp;
  1815. //        }
  1816. //
  1817. //        $results = array();
  1818. //
  1819. //        if ($cols > 2 || $force_array) {
  1820. //            // return array values
  1821. //            // XXX this part can be optimized
  1822. //            if ($fetchmode == DB_FETCHMODE_ASSOC) {
  1823. //                while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) {
  1824. //                    reset($row);
  1825. //                    $key = current($row);
  1826. //                    unset($row[key($row)]);
  1827. //                    if ($group) {
  1828. //                        $results[$key][] = $row;
  1829. //                    } else {
  1830. //                        $results[$key] = $row;
  1831. //                    }
  1832. //                }
  1833. //            } elseif ($fetchmode == DB_FETCHMODE_OBJECT) {
  1834. //                while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) {
  1835. //                    $arr = get_object_vars($row);
  1836. //                    $key = current($arr);
  1837. //                    if ($group) {
  1838. //                        $results[$key][] = $row;
  1839. //                    } else {
  1840. //                        $results[$key] = $row;
  1841. //                    }
  1842. //                }
  1843. //            } else {
  1844. //                while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
  1845. //                    // we shift away the first element to get
  1846. //                    // indices running from 0 again
  1847. //                    $key = array_shift($row);
  1848. //                    if ($group) {
  1849. //                        $results[$key][] = $row;
  1850. //                    } else {
  1851. //                        $results[$key] = $row;
  1852. //                    }
  1853. //                }
  1854. //            }
  1855. //            if (DB::isError($row)) {
  1856. //                $results = $row;
  1857. //            }
  1858. //        } else {
  1859. //            // return scalar values
  1860. //            while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
  1861. //                if ($group) {
  1862. //                    $results[$row[0]][] = $row[1];
  1863. //                } else {
  1864. //                    $results[$row[0]] = $row[1];
  1865. //                }
  1866. //            }
  1867. //            if (DB::isError($row)) {
  1868. //                $results = $row;
  1869. //            }
  1870. //        }
  1871. //
  1872. //        $res->free();
  1873. //
  1874. //        return $results;
  1875.     }
  1876.  
  1877.     /**
  1878.      * Fetches all of the rows from a query result
  1879.      *
  1880.      * @param string $query      the SQL query
  1881.      * @param mixed  $params     array, string or numeric data to be used in
  1882.      *                             execution of the statement.  Quantity of
  1883.      *                             items passed must match quantity of
  1884.      *                             placeholders in query:  meaning 1
  1885.      *                             placeholder for non-array parameters or
  1886.      *                             1 placeholder per array element.
  1887.      * @param int    $fetchmode  the fetch mode to use:
  1888.      *                             + DB_FETCHMODE_ORDERED
  1889.      *                             + DB_FETCHMODE_ASSOC
  1890.      *                             + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
  1891.      *                             + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
  1892.      *
  1893.      * @return array  the nested array.  A DB_Error object on failure.
  1894.      *  @todo Implement mock DB_common::getAll
  1895.      */
  1896.     public function &getAll($query$params array(),
  1897.                      $fetchmode DB_FETCHMODE_DEFAULT)
  1898.     {
  1899. //        // compat check, the params and fetchmode parameters used to
  1900. //        // have the opposite order
  1901. //        if (!is_array($params)) {
  1902. //            if (is_array($fetchmode)) {
  1903. //                if ($params === null) {
  1904. //                    $tmp = DB_FETCHMODE_DEFAULT;
  1905. //                } else {
  1906. //                    $tmp = $params;
  1907. //                }
  1908. //                $params = $fetchmode;
  1909. //                $fetchmode = $tmp;
  1910. //            } elseif ($params !== null) {
  1911. //                $fetchmode = $params;
  1912. //                $params = array();
  1913. //            }
  1914. //        }
  1915. //
  1916. //        if (sizeof($params) > 0) {
  1917. //            $sth = $this->prepare($query);
  1918. //
  1919. //            if (DB::isError($sth)) {
  1920. //                return $sth;
  1921. //            }
  1922. //
  1923. //            $res =& $this->execute($sth, $params);
  1924. //            $this->freePrepared($sth);
  1925. //        } else {
  1926. //            $res =& $this->query($query);
  1927. //        }
  1928. //
  1929. //        if ($res === DB_OK || DB::isError($res)) {
  1930. //            return $res;
  1931. //        }
  1932. //
  1933. //        $results = array();
  1934. //        while (DB_OK === $res->fetchInto($row, $fetchmode)) {
  1935. //            if ($fetchmode & DB_FETCHMODE_FLIPPED) {
  1936. //                foreach ($row as $key => $val) {
  1937. //                    $results[$key][] = $val;
  1938. //                }
  1939. //            } else {
  1940. //                $results[] = $row;
  1941. //            }
  1942. //        }
  1943. //
  1944. //        $res->free();
  1945. //
  1946. //        if (DB::isError($row)) {
  1947. //            $tmp =& $this->raiseError($row);
  1948. //            return $tmp;
  1949. //        }
  1950. //        return $results;
  1951.     }
  1952.  
  1953.     /**
  1954.      * Enables or disables automatic commits
  1955.      *
  1956.      * @param bool $onoff  true turns it on, false turns it off
  1957.      * @return int  DB_OK on success.  A DB_Error object if the driver
  1958.      *                doesn't support auto-committing transactions.
  1959.      *  @todo Implement mock DB_common::autoCommit
  1960.      */
  1961.     public function autoCommit($onoff false)
  1962.     {
  1963. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1964.     }
  1965.  
  1966.     /**
  1967.      * Commits the current transaction
  1968.      *
  1969.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1970.      *  @todo Implement mock DB_common::commit
  1971.      */
  1972.     public function commit()
  1973.     {
  1974. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1975.     }
  1976.  
  1977.     /**
  1978.      * Reverts the current transaction
  1979.      *
  1980.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1981.      *  @todo Implement mock DB_common::rollback
  1982.      */
  1983.     public function rollback()
  1984.     {
  1985. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1986.     }
  1987.  
  1988.     /**
  1989.      * Determines the number of rows in a query result
  1990.      *
  1991.      * @param resource $result  the query result idenifier produced by PHP
  1992.      * @return int  the number of rows.  A DB_Error object on failure.
  1993.      *  @todo Implement mock DB_common::numRows
  1994.      */
  1995.     public function numRows($result)
  1996.     {
  1997. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1998.     }
  1999.  
  2000.     /**
  2001.      * Determines the number of rows affected by a data maniuplation query
  2002.      *
  2003.      * 0 is returned for queries that don't manipulate data.
  2004.      *
  2005.      * @return int  the number of rows.  A DB_Error object on failure.
  2006.      *  @todo Implement mock DB_common::affectedRows
  2007.      */
  2008.     public function affectedRows()
  2009.     {
  2010. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2011.     }
  2012.  
  2013.     /**
  2014.      * Generates the name used inside the database for a sequence
  2015.      *
  2016.      * @param string $sqn  the sequence's public name
  2017.      * @return string  the sequence's name in the backend
  2018.      * @see DB_common::createSequence(), DB_common::dropSequence(),
  2019.      *       DB_common::nextID(), DB_common::setOption()
  2020.      *  @todo Implement mock DB_common::getSequenceName
  2021.      */
  2022.     protected function getSequenceName($sqn)
  2023.     {
  2024. //        return sprintf($this->getOption('seqname_format'),
  2025. //                       preg_replace('/[^a-z0-9_.]/i', '_', $sqn));
  2026.     }
  2027.  
  2028.     /**
  2029.      * Returns the next free id in a sequence
  2030.      *
  2031.      * @param string  $seq_name  name of the sequence
  2032.      * @param boolean $ondemand  when true, the seqence is automatically
  2033.      *                             created if it does not exist
  2034.      *
  2035.      * @return int  the next id number in the sequence.
  2036.      *                A DB_Error object on failure.
  2037.      *
  2038.      * @see DB_common::createSequence(), DB_common::dropSequence(),
  2039.      *       DB_common::getSequenceName()
  2040.      *  @todo Implement mock DB_common::nextID
  2041.      */
  2042.     public function nextId($seq_name$ondemand true)
  2043.     {
  2044. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2045.     }
  2046.  
  2047.     /**
  2048.      * Creates a new sequence
  2049.      *
  2050.      * @param string $seq_name  name of the new sequence
  2051.      * @return int  DB_OK on success.  A DB_Error object on failure.
  2052.      * @see DB_common::dropSequence(), DB_common::getSequenceName(),
  2053.      *       DB_common::nextID()
  2054.      *  @todo Implement mock DB_common::createSequence
  2055.      */
  2056.     public function createSequence($seq_name)
  2057.     {
  2058. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2059.     }
  2060.  
  2061.     /**
  2062.      * Deletes a sequence
  2063.      *
  2064.      * @param string $seq_name  name of the sequence to be deleted
  2065.      * @return int  DB_OK on success.  A DB_Error object on failure.
  2066.      * @see DB_common::createSequence(), DB_common::getSequenceName(),
  2067.      *       DB_common::nextID()
  2068.      *  @todo Implement mock DB_common::dropSequence
  2069.      */
  2070.     public function dropSequence($seq_name)
  2071.     {
  2072. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2073.     }
  2074.  
  2075.     /**
  2076.      * Communicates an error and invoke error callbacks, etc
  2077.      *
  2078.      * Basically a wrapper for PEAR::raiseError without the message string.
  2079.      *
  2080.      * @param mixed   integer error code, or a PEAR error object (all
  2081.      *                  other parameters are ignored if this parameter is
  2082.      *                  an object
  2083.      * @param int     error mode, see PEAR_Error docs
  2084.      * @param mixed   if error mode is PEAR_ERROR_TRIGGER, this is the
  2085.      *                  error level (E_USER_NOTICE etc).  If error mode is
  2086.      *                  PEAR_ERROR_CALLBACK, this is the callback function,
  2087.      *                  either as a function name, or as an array of an
  2088.      *                  object and method name.  For other error modes this
  2089.      *                  parameter is ignored.
  2090.      * @param string  extra debug information.  Defaults to the last
  2091.      *                  query and native error code.
  2092.      * @param mixed   native error code, integer or string depending the
  2093.      *                  backend
  2094.      *
  2095.      * @return object  the PEAR_Error object
  2096.      * @see PEAR_Error
  2097.      *  @todo Implement mock DB_common::raiseError
  2098.      */
  2099.     public function &raiseError($code DB_ERROR$mode null$options null,
  2100.                          $userinfo null$nativecode null)
  2101.     {
  2102. //        // The error is yet a DB error object
  2103. //        if (is_object($code)) {
  2104. //            // because we the static PEAR::raiseError, our global
  2105. //            // handler should be used if it is set
  2106. //            if ($mode === null && !empty($this->_default_error_mode)) {
  2107. //                $mode    = $this->_default_error_mode;
  2108. //                $options = $this->_default_error_options;
  2109. //            }
  2110. //            $tmp = PEAR::raiseError($code, null, $mode, $options,
  2111. //                                    null, null, true);
  2112. //            return $tmp;
  2113. //        }
  2114. //
  2115. //        if ($userinfo === null) {
  2116. //            $userinfo = $this->last_query;
  2117. //        }
  2118. //
  2119. //        if ($nativecode) {
  2120. //            $userinfo .= ' [nativecode=' . trim($nativecode) . ']';
  2121. //        } else {
  2122. //            $userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']';
  2123. //        }
  2124. //
  2125. //        $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo,
  2126. //                                'DB_Error', true);
  2127. //        return $tmp;
  2128.     }
  2129.  
  2130.     /**
  2131.      * Gets the DBMS' native error code produced by the last query
  2132.      *
  2133.      * @return mixed  the DBMS' error code.  A DB_Error object on failure.
  2134.      *  @todo Implement mock DB_common::errorNative
  2135.      */
  2136.     public function errorNative()
  2137.     {
  2138. //        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2139.     }
  2140.  
  2141.     /**
  2142.      * Maps native error codes to DB's portable ones
  2143.      *
  2144.      * Uses the <var>$errorcode_map</var> property defined in each driver.
  2145.      *
  2146.      * @param string|int$nativecode  the error code returned by the DBMS
  2147.      *
  2148.      * @return int  the portable DB error code.  Return DB_ERROR if the
  2149.      *                current driver doesn't have a mapping for the
  2150.      *                $nativecode submitted.
  2151.      *  @todo Implement mock DB_common::errorCode
  2152.      */
  2153.     public function errorCode($nativecode)
  2154.     {
  2155. //        if (isset($this->errorcode_map[$nativecode])) {
  2156. //            return $this->errorcode_map[$nativecode];
  2157. //        }
  2158.         // Fall back to DB_ERROR if there was no mapping.
  2159.         return DB_ERROR;
  2160.     }
  2161.  
  2162.     /**
  2163.      * Maps a DB error code to a textual message
  2164.      *
  2165.      * @param integer $dbcode  the DB error code
  2166.      * @return string  the error message corresponding to the error code
  2167.      *                   submitted.  FALSE if the error code is unknown.
  2168.      * @see DB::errorMessage()
  2169.      *  @todo Implement mock DB_common::errorMessage
  2170.      */
  2171.     public function errorMessage($dbcode)
  2172.     {
  2173. //        return DB::errorMessage($this->errorcode_map[$dbcode]);
  2174.     }
  2175.  
  2176.     /**
  2177.      * Returns information about a table or a result set
  2178.      *
  2179.      * @param object|string $result  DB_result object from a query or a
  2180.      *                                 string containing the name of a table.
  2181.      *                                 While this also accepts a query result
  2182.      *                                 resource identifier, this behavior is
  2183.      *                                 deprecated.
  2184.      * @param int  $mode   either unused or one of the tableInfo modes:
  2185.      *                      <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
  2186.      *                      <kbd>DB_TABLEINFO_ORDER</kbd> or
  2187.      *                      <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
  2188.      *                      These are bitwise, so the first two can be
  2189.      *                      combined using <kbd>|</kbd>.
  2190.      *
  2191.      * @return array  an associative array with the information requested.
  2192.      *                  A DB_Error object on failure.
  2193.      *
  2194.      * @see DB_common::setOption()
  2195.      *  @todo Implement mock DB_common::tableInfo
  2196.      */
  2197.     public function tableInfo($result$mode null)
  2198.     {
  2199.         /*
  2200.          * If the DB_<driver> class has a tableInfo() method, that one
  2201.          * overrides this one.  But, if the driver doesn't have one,
  2202.          * this method runs and tells users about that fact.
  2203.          */
  2204.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2205.     }
  2206.  
  2207.     /**
  2208.      * Lists internal database information
  2209.      *
  2210.      * @param string $type  type of information being sought.
  2211.      *                        Common items being sought are:
  2212.      *                        tables, databases, users, views, functions
  2213.      *                        Each DBMS's has its own capabilities.
  2214.      *
  2215.      * @return array  an array listing the items sought.
  2216.      *                  A DB DB_Error object on failure.
  2217.      *  @todo Implement mock DB_common::getListOf
  2218.      */
  2219.     public function getListOf($type)
  2220.     {
  2221. //        $sql = $this->getSpecialQuery($type);
  2222. //        if ($sql === null) {
  2223. //            $this->last_query = '';
  2224. //            return $this->raiseError(DB_ERROR_UNSUPPORTED);
  2225. //        } elseif (is_int($sql) || DB::isError($sql)) {
  2226. //            // Previous error
  2227. //            return $this->raiseError($sql);
  2228. //        } elseif (is_array($sql)) {
  2229. //            // Already the result
  2230. //            return $sql;
  2231. //        }
  2232. //        // Launch this query
  2233. //        return $this->getCol($sql);
  2234.     }
  2235.  
  2236.     /**
  2237.      * Obtains the query string needed for listing a given type of objects
  2238.      *
  2239.      * @param string $type  the kind of objects you want to retrieve
  2240.      * @return string  the SQL query string or null if the driver doesn't
  2241.      *                   support the object type requested
  2242.      * @see DB_common::getListOf()
  2243.      *  @todo Implement mock DB_common::getSpecialQuery
  2244.      */
  2245.     protected function getSpecialQuery($type)
  2246.     {