[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/MDB/ -> Common.php (source)

   1  <?php
   2  // +----------------------------------------------------------------------+
   3  // | PHP Version 4                                                        |
   4  // +----------------------------------------------------------------------+
   5  // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
   6  // | Stig. S. Bakken, Lukas Smith                                         |
   7  // | All rights reserved.                                                 |
   8  // +----------------------------------------------------------------------+
   9  // | MDB is a merge of PEAR DB and Metabases that provides a unified DB   |
  10  // | API as well as database abstraction for PHP applications.            |
  11  // | This LICENSE is in the BSD license style.                            |
  12  // |                                                                      |
  13  // | Redistribution and use in source and binary forms, with or without   |
  14  // | modification, are permitted provided that the following conditions   |
  15  // | are met:                                                             |
  16  // |                                                                      |
  17  // | Redistributions of source code must retain the above copyright       |
  18  // | notice, this list of conditions and the following disclaimer.        |
  19  // |                                                                      |
  20  // | Redistributions in binary form must reproduce the above copyright    |
  21  // | notice, this list of conditions and the following disclaimer in the  |
  22  // | documentation and/or other materials provided with the distribution. |
  23  // |                                                                      |
  24  // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25  // | Lukas Smith nor the names of his contributors may be used to endorse |
  26  // | or promote products derived from this software without specific prior|
  27  // | written permission.                                                  |
  28  // |                                                                      |
  29  // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30  // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31  // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32  // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33  // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34  // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35  // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36  // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37  // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38  // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39  // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40  // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41  // +----------------------------------------------------------------------+
  42  // | Author: Lukas Smith <smith@backendmedia.com>                         |
  43  // +----------------------------------------------------------------------+
  44  //
  45  // $Id: Common.php,v 1.114.4.22 2004/04/08 19:11:58 lsmith Exp $
  46  
  47  /**
  48   * @package MDB
  49   * @author Lukas Smith <smith@backendmedia.com>
  50   */
  51  
  52  // }}}
  53  // {{{ MDB_defaultDebugOutput()
  54  
  55  /**
  56   * default debug output handler
  57   *
  58   * @param object $db reference to an MDB database object
  59   * @param string $message message that should be appended to the debug
  60   *       variable
  61   * @return string the corresponding error message, of FALSE
  62   * if the error code was unknown
  63   * @access public
  64   */
  65  function MDB_defaultDebugOutput(&$db, $message)
  66  {
  67      $db->debug_output .= $db->database . " $message" . $db->getOption('log_line_break');
  68  }
  69  
  70  /**
  71   * MDB_Common: Base class that is extended by each MDB driver
  72   *
  73   * @package MDB
  74   * @category Database
  75   * @author Lukas Smith <smith@backendmedia.com>
  76   */
  77  class MDB_Common extends PEAR
  78  {
  79      // {{{ properties
  80      /**
  81      * index of the MDB object withing the global $_MDB_databases array
  82      * @var integer
  83      * @access private
  84      */
  85      var $database = 0;
  86  
  87      /**
  88      * @var string
  89      * @access private
  90      */
  91      var $host = '';
  92  
  93      /**
  94      * @var string
  95      * @access private
  96      */
  97      var $port = '';
  98  
  99      /**
 100      * @var string
 101      * @access private
 102      */
 103      var $user = '';
 104  
 105      /**
 106      * @var string
 107      * @access private
 108      */
 109      var $password = '';
 110  
 111      /**
 112      * @var string
 113      * @access private
 114      */
 115      var $database_name = '';
 116  
 117      /**
 118      * @var array
 119      * @access private
 120      */
 121      var $supported = array();
 122  
 123      /**
 124      * $options["persistent"] -> boolean persistent connection true|false?
 125      * $options["debug"] -> integer numeric debug level
 126      * $options["autofree"] -> boolean
 127      * $options["lob_buffer_length"] -> integer LOB buffer length
 128      * $options["log_line_break"] -> string line-break format
 129      * $options["seqname_format"] -> string pattern for sequence name
 130      * $options["includelob"] -> boolean
 131      * $options["includemanager"] -> boolean
 132      * $options["UseTransactions"] -> boolean
 133      * $options["optimize"] -> string 'performance' or 'portability'
 134      * @var array
 135      * @access private
 136      */
 137      var $options = array(
 138              'persistent' => FALSE,
 139              'debug' => FALSE,
 140              'autofree' => FALSE,
 141              'lob_buffer_length' => 8192,
 142              'log_line_break' => "\n",
 143              'seqname_format' => '%s_seq',
 144              'sequence_col_name' => 'sequence',
 145              'includelob' => FALSE,
 146              'includemanager' => FALSE,
 147              'UseTransactions' => FALSE,
 148              'optimize' => 'performance',
 149          );
 150  
 151      /**
 152      * @var string
 153      * @access private
 154      */
 155      var $escape_quotes = '';
 156  
 157      /**
 158      * @var integer
 159      * @access private
 160      */
 161      var $decimal_places = 2;
 162  
 163      /**
 164      * @var string
 165      * @access private
 166      */
 167      var $manager_included_constant = '';
 168  
 169      /**
 170      * @var string
 171      * @access private
 172      */
 173      var $manager_include = '';
 174  
 175      /**
 176      * @var string
 177      * @access private
 178      */
 179      var $manager_class_name = '';
 180  
 181      /**
 182      * @var object
 183      * @access private
 184      */
 185      var $manager;
 186  
 187      /**
 188      * @var array
 189      * @access private
 190      */
 191      var $warnings = array();
 192  
 193      /**
 194      * @var string
 195      * @access private
 196      */
 197      var $debug = '';
 198  
 199      /**
 200      * @var string
 201      * @access private
 202      */
 203      var $debug_output = '';
 204  
 205      /**
 206      * @var boolean
 207      * @access private
 208      */
 209      var $pass_debug_handle = FALSE;
 210  
 211      /**
 212      * @var boolean
 213      * @access private
 214      */
 215      var $auto_commit = TRUE;
 216  
 217      /**
 218      * @var boolean
 219      * @access private
 220      */
 221      var $in_transaction = FALSE;
 222  
 223      /**
 224      * @var integer
 225      * @access private
 226      */
 227      var $first_selected_row = 0;
 228  
 229      /**
 230      * @var integer
 231      * @access private
 232      */
 233      var $selected_row_limit = 0;
 234  
 235      /**
 236      * DB type (mysql, oci8, odbc etc.)
 237      * @var string
 238      * @access private
 239      */
 240      var $type;
 241  
 242      /**
 243      * @var array
 244      * @access private
 245      */
 246      var $prepared_queries = array();
 247  
 248      /**
 249      * @var array
 250      * @access private
 251      */
 252      var $result_types;
 253  
 254      /**
 255      * @var string
 256      * @access private
 257      */
 258      var $last_query = '';
 259  
 260      /**
 261      * @var integer
 262      * @access private
 263      */
 264      var $fetchmode = MDB_FETCHMODE_ORDERED;
 265  
 266      /**
 267      * @var integer
 268      * @access private
 269      */
 270      var $affected_rows = -1;
 271  
 272      /**
 273      * @var array
 274      * @access private
 275      */
 276      var $lobs = array();
 277  
 278      /**
 279      * @var array
 280      * @access private
 281      */
 282      var $clobs = array();
 283  
 284      /**
 285      * @var array
 286      * @access private
 287      */
 288      var $blobs = array();
 289  
 290      // }}}
 291      // {{{ constructor
 292  
 293      /**
 294       * Constructor
 295       */
 296      function MDB_Common()
 297      {
 298          $database = count($GLOBALS['_MDB_databases']) + 1;
 299          $GLOBALS['_MDB_databases'][$database] = &$this;
 300          $this->database = $database;
 301  
 302          $this->PEAR('MDB_Error');
 303          $this->supported = array();
 304          $this->errorcode_map = array();
 305          $this->fetchmode = MDB_FETCHMODE_ORDERED;
 306      }
 307  
 308      // }}}
 309      // {{{ __toString()
 310  
 311      /**
 312       * String conversation
 313       *
 314       * @return string
 315       * @access public
 316       */
 317      function __toString()
 318      {
 319          $info = get_class($this);
 320          $info .= ': (phptype = ' . $this->phptype . ', dbsyntax = ' . $this->dbsyntax . ')';
 321          if ($this->connection) {
 322              $info .= ' [connected]';
 323          }
 324          return($info);
 325      }
 326  
 327      // }}}
 328      // {{{ errorCode()
 329  
 330      /**
 331       * Map native error codes to MDB's portable ones.  Requires that
 332       * the DB implementation's constructor fills in the $errorcode_map
 333       * property.
 334       *
 335       * @param mixed $nativecode the native error code, as returned by the
 336       *      backend database extension (string or integer)
 337       * @return int a portable MDB error code, or FALSE if this MDB
 338       *      implementation has no mapping for the given error code.
 339       * @access public
 340       */
 341      function errorCode($nativecode)
 342      {
 343          if (isset($this->errorcode_map[$nativecode])) {
 344              return($this->errorcode_map[$nativecode]);
 345          }
 346          // Fall back to MDB_ERROR if there was no mapping.
 347          return(MDB_ERROR);
 348      }
 349  
 350      // }}}
 351      // {{{ errorMessage()
 352  
 353      /**
 354       * Map a MDB error code to a textual message.  This is actually
 355       * just a wrapper for MDB::errorMessage().
 356       *
 357       * @param integer $dbcode the MDB error code
 358       * @return string the corresponding error message, of FALSE
 359       *      if the error code was unknown
 360       * @access public
 361       */
 362      function errorMessage($dbcode)
 363      {
 364          return(MDB::errorMessage($this->errorcode_map[$dbcode]));
 365      }
 366  
 367      // }}}
 368      // {{{ raiseError()
 369  
 370      /**
 371       * This method is used to communicate an error and invoke error
 372       * callbacks etc.  Basically a wrapper for PEAR::raiseError
 373       * without the message string.
 374       *
 375       * @param mixed $code integer error code, or a PEAR error object (all
 376       *      other parameters are ignored if this parameter is an object
 377       * @param int $mode error mode, see PEAR_Error docs
 378       * @param mixed $options If error mode is PEAR_ERROR_TRIGGER, this is the
 379       *      error level (E_USER_NOTICE etc).  If error mode is
 380       *      PEAR_ERROR_CALLBACK, this is the callback function, either as a
 381       *      function name, or as an array of an object and method name. For
 382       *      other error modes this parameter is ignored.
 383       * @param string $userinfo Extra debug information.  Defaults to the last
 384       *      query and native error code.
 385       * @param mixed $nativecode Native error code, integer or string depending
 386       *      the backend.
 387       * @return object a PEAR error object
 388       * @access public
 389       * @see PEAR_Error
 390       */
 391      function &raiseError($code = MDB_ERROR, $mode = NULL, $options = NULL,
 392          $userinfo = NULL, $nativecode = NULL)
 393      {
 394          // The error is yet a MDB error object
 395          if (is_object($code)) {
 396              // because we the static PEAR::raiseError, our global
 397              // handler should be used if it is set
 398              if ($mode === null && !empty($this->_default_error_mode)) {
 399                  $mode    = $this->_default_error_mode;
 400                  $options = $this->_default_error_options;
 401              }
 402              $err = PEAR::raiseError($code, NULL, $mode, $options, NULL, NULL, TRUE);
 403              return($err);
 404          }
 405  
 406          if ($userinfo === NULL) {
 407              $userinfo = $this->last_query;
 408          }
 409  
 410          if ($nativecode) {
 411              $userinfo .= ' [nativecode=' . trim($nativecode) . ']';
 412          }
 413  
 414          $err = PEAR::raiseError(NULL, $code, $mode, $options, $userinfo, 'MDB_Error', TRUE);
 415          return($err);
 416      }
 417  
 418      // }}}
 419      // {{{ errorNative()
 420  
 421      /**
 422       * returns an errormessage, provides by the database
 423       *
 424       * @return mixed MDB_Error or message
 425       * @access public
 426       */
 427      function errorNative()
 428      {
 429          return($this->raiseError(MDB_ERROR_NOT_CAPABLE));
 430      }
 431  
 432      // }}}
 433      // {{{ resetWarnings()
 434  
 435      /**
 436       * reset the warning array
 437       *
 438       * @access public
 439       */
 440      function resetWarnings()
 441      {
 442          $this->warnings = array();
 443      }
 444  
 445      // }}}
 446      // {{{ getWarnings()
 447  
 448      /**
 449       * get all warnings in reverse order.
 450       * This means that the last warning is the first element in the array
 451       *
 452       * @return array with warnings
 453       * @access public
 454       * @see resetWarnings()
 455       */
 456      function getWarnings()
 457      {
 458          return array_reverse($this->warnings);
 459      }
 460  
 461      // }}}
 462      // {{{ setOption()
 463  
 464      /**
 465       * set the option for the db class
 466       *
 467       * @param string $option option name
 468       * @param mixed $value value for the option
 469       * @return mixed MDB_OK or MDB_Error
 470       * @access public
 471       */
 472      function setOption($option, $value)
 473      {
 474          if (isset($this->options[$option])) {
 475              $this->options[$option] = $value;
 476              return MDB_OK;
 477          }
 478          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
 479      }
 480  
 481      // }}}
 482      // {{{ getOption()
 483  
 484      /**
 485       * returns the value of an option
 486       *
 487       * @param string $option option name
 488       * @return mixed the option value or error object
 489       * @access public
 490       */
 491      function getOption($option)
 492      {
 493          if (isset($this->options[$option])) {
 494              return($this->options[$option]);
 495          }
 496          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
 497      }
 498  
 499      // }}}
 500      // {{{ captureDebugOutput()
 501  
 502      /**
 503       * set a debug handler
 504       *
 505       * @param string $capture name of the function that should be used in
 506       *      debug()
 507       * @access public
 508       * @see debug()
 509       */
 510      function captureDebugOutput($capture)
 511      {
 512          $this->pass_debug_handle = $capture;
 513          $this->debug = ($capture ? 'MDB_defaultDebugOutput' : '');
 514      }
 515  
 516      // }}}
 517      // {{{ debug()
 518  
 519      /**
 520       * set a debug message
 521       *
 522       * @param string $message Message with information for the user.
 523       * @access public
 524       */
 525      function debug($message)
 526      {
 527          if (strcmp($function = $this->debug, '')) {
 528              if ($this->pass_debug_handle) {
 529                  $function($this, $message);
 530              } else {
 531                  $function($message);
 532              }
 533          }
 534      }
 535  
 536      // }}}
 537      // {{{ debugOutput()
 538  
 539      /**
 540       * output debug info
 541       *
 542       * @return string content of the debug_output class variable
 543       * @access public
 544       */
 545      function debugOutput()
 546      {
 547          return($this->debug_output);
 548      }
 549  
 550      // }}}
 551      // {{{ setError() (deprecated)
 552  
 553      /**
 554       * set an error (deprecated)
 555       *
 556       * @param string $scope Scope of the error message
 557       *     (usually the method tht caused the error)
 558       * @param string $message Message with information for the user.
 559       * @return boolean FALSE
 560       * @access private
 561       */
 562      function setError($scope, $message)
 563      {
 564          $this->last_error = $message;
 565          $this->debug($scope . ': ' . $message);
 566          if (($function = $this->error_handler) != '') {
 567              $error = array(
 568                  'Scope' => $scope,
 569                  'Message' => $message
 570              );
 571              $function($this, $error);
 572          }
 573          return(0);
 574      }
 575  
 576      // }}}
 577      // {{{ setErrorHandler() (deprecated)
 578  
 579      /**
 580       * Specify a function that is called when an error occurs.
 581       *
 582       * @param string $function Name of the function that will be called on
 583       *      error. If an empty string is specified, no handler function is
 584       *      called on error. The error handler function receives two arguments.
 585       *      The first argument a reference to the driver class object that
 586       *      triggered the error.
 587       *
 588       *      The second argument is a reference to an associative array that
 589       *      provides details about the error that occured. These details provide
 590       *      more information than it is returned by the MetabaseError function.
 591       *
 592       *      These are the currently supported error detail entries:
 593       *
 594       *      Scope
 595       *       String that indicates the scope of the driver object class
 596       *       within which the error occured.
 597       *
 598       *      Message
 599       *       Error message as is returned by the MetabaseError function.
 600       * @return string name of last function
 601       * @access public
 602       */
 603      function setErrorHandler($function)
 604      {
 605          $last_function = $this->error_handler;
 606          $this->error_handler = $function;
 607          return($last_function);
 608      }
 609  
 610      // }}}
 611      // {{{ error() (deprecated)
 612  
 613      /**
 614       * Retrieve the error message text associated with the last operation that
 615       * failed. Some functions may fail but they do not return the reason that
 616       * makes them to fail. This function is meant to retrieve a textual
 617       * description of the failure cause.
 618       *
 619       * @return string the error message text associated with the last failure.
 620       * @access public
 621       */
 622      function error()
 623      {
 624          return($this->last_error);
 625      }
 626  
 627      // }}}
 628      // {{{ _quote()
 629  
 630      /**
 631       * Quotes a string so it can be safely used in a query. It will quote
 632       * the text so it can safely be used within a query.
 633       *
 634       * @param string $text the input string to quote
 635       * @return string quoted string
 636       * @access private
 637       */
 638      function _quote($text)
 639      {
 640          if (strcmp($this->escape_quotes, "'")) {
 641              $text = str_replace($this->escape_quotes, $this->escape_quotes . $this->escape_quotes, $text);
 642          }
 643          return str_replace("'", $this->escape_quotes . "'", $text);
 644      }
 645  
 646      // }}}
 647      // {{{ quoteIdentifier()
 648  
 649      /**
 650       * Quote a string so it can be safely used as a table or column name
 651       *
 652       * Delimiting style depends on which database driver is being used.
 653       *
 654       * NOTE: just because you CAN use delimited identifiers doesn't mean
 655       * you SHOULD use them.  In general, they end up causing way more
 656       * problems than they solve.
 657       *
 658       * Portability is broken by using the following characters inside
 659       * delimited identifiers:
 660       *   + backtick (<kbd>`</kbd>) -- due to MySQL
 661       *   + double quote (<kbd>"</kbd>) -- due to Oracle
 662       *   + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
 663       *
 664       * Delimited identifiers are known to generally work correctly under
 665       * the following drivers:
 666       *   + mssql
 667       *   + mysql
 668       *   + mysqli
 669       *   + oci8
 670       *   + odbc(access)
 671       *   + odbc(db2)
 672       *   + pgsql
 673       *   + sqlite
 674       *   + sybase
 675       *
 676       * InterBase doesn't seem to be able to use delimited identifiers
 677       * via PHP 4.  They work fine under PHP 5.
 678       *
 679       * @param string $str  identifier name to be quoted
 680       *
 681       * @return string  quoted identifier string
 682       *
 683       * @access public
 684       */
 685      function quoteIdentifier($str)
 686      {
 687          return '"' . str_replace('"', '""', $str) . '"';
 688      }
 689  
 690      // }}}
 691      // {{{ _loadModule()
 692  
 693      /**
 694       * loads an module
 695       *
 696       * @param string $scope information about what method is being loaded,
 697       *      that is used for error messages
 698       * @param string $module name of the module that should be loaded
 699       *      (only used for error messages)
 700       * @param string $included_constant name of the constant that should be
 701       *      defined when the module has been loaded
 702       * @param string $include name of the script that includes the module
 703       * @access private
 704       */
 705      function _loadModule($scope, $module, $included_constant, $include)
 706      {
 707          if (strlen($included_constant) == 0 || !defined($included_constant)) {
 708              if($include) {
 709                  $include = 'MDB/Modules/'.$include;
 710                  if(MDB::isError($debug = $this->getOption('debug')) || $debug > 2) {
 711                      include_once($include);
 712                  } else {
 713                      @include_once($include);
 714                  }
 715              } else {
 716                  return($this->raiseError(MDB_ERROR_LOADMODULE, NULL, NULL,
 717                      $scope . ': it was not specified an existing ' . $module . ' file (' . $include . ')'));
 718              }
 719          }
 720          return(MDB_OK);
 721      }
 722  
 723      // }}}
 724      // {{{ loadLob()
 725  
 726      /**
 727       * loads the LOB module
 728       *
 729       * @param string $scope information about what method is being loaded,
 730       *                       that is used for error messages
 731       * @access public
 732       */
 733      function loadLob($scope = '')
 734      {
 735          if (defined('MDB_LOB_INCLUDED')) {
 736              return(MDB_OK);
 737          }
 738          $result = $this->_loadModule($scope, 'LOB',
 739              'MDB_LOB_INCLUDED', 'LOB.php');
 740          if (MDB::isError($result)) {
 741              return($result);
 742          }
 743          return(MDB_OK);
 744      }
 745  
 746      // }}}
 747      // {{{ loadManager()
 748  
 749      /**
 750       * loads the Manager module
 751       *
 752       * @param string $scope information about what method is being loaded,
 753       *                       that is used for error messages
 754       * @access public
 755       */
 756      function loadManager($scope = '')
 757      {
 758          if (isset($this->manager) && is_object($this->manager)) {
 759              return(MDB_OK);
 760          }
 761          $result = $this->_loadModule($scope, 'Manager',
 762              'MDB_MANAGER_'.strtoupper($this->phptype).'_INCLUDED',
 763              'Manager/'.$this->phptype.'.php');
 764          if (MDB::isError($result)) {
 765              return($result);
 766          }
 767          $class_name = 'MDB_Manager_'.$this->dbsyntax;
 768          if (!class_exists($class_name)) {
 769              return($this->raiseError(MDB_ERROR_LOADMODULE, NULL, NULL,
 770                  'Unable to load extension'));
 771          }
 772          @$this->manager = new $class_name;
 773          return(MDB_OK);
 774      }
 775  
 776      // }}}
 777      // {{{ autoCommit()
 778  
 779      /**
 780       * Define whether database changes done on the database be automatically
 781       * committed. This function may also implicitly start or end a transaction.
 782       *
 783       * @param boolean $auto_commit flag that indicates whether the database
 784       *      changes should be committed right after executing every query
 785       *      statement. If this argument is 0 a transaction implicitly started.
 786       *      Otherwise, if a transaction is in progress it is ended by committing
 787       *      any database changes that were pending.
 788       * @return mixed MDB_OK on success, a MDB error on failure
 789       * @access public
 790       */
 791      function autoCommit($auto_commit)
 792      {
 793          $this->debug('AutoCommit: ' . ($auto_commit ? 'On' : 'Off'));
 794          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
 795              'Auto-commit transactions: transactions are not supported'));
 796      }
 797  
 798      // }}}
 799      // {{{ commit()
 800  
 801      /**
 802       * Commit the database changes done during a transaction that is in
 803       * progress. This function may only be called when auto-committing is
 804       * disabled, otherwise it will fail. Therefore, a new transaction is
 805       * implicitly started after committing the pending changes.
 806       *
 807       * @return mixed MDB_OK on success, a MDB error on failure
 808       * @access public
 809       */
 810      function commit()
 811      {
 812          $this->debug('Commit Transaction');
 813          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
 814              'Commit transaction: commiting transactions are not supported'));
 815      }
 816  
 817      // }}}
 818      // {{{ rollback()
 819  
 820      /**
 821       * Cancel any database changes done during a transaction that is in
 822       * progress. This function may only be called when auto-committing is
 823       * disabled, otherwise it will fail. Therefore, a new transaction is
 824       * implicitly started after canceling the pending changes.
 825       *
 826       * @return mixed MDB_OK on success, a MDB error on failure
 827       * @access public
 828       */
 829      function rollback()
 830      {
 831          $this->debug('Rollback Transaction');
 832          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
 833              'Rollback transaction: rolling back transactions are not supported'));
 834      }
 835  
 836      // }}}
 837      // {{{ disconnect()
 838  
 839      /**
 840       * Log out and disconnect from the database.
 841       *
 842       * @return mixed TRUE on success, FALSE if not connected and error
 843       *                object on error
 844       * @access public
 845       */
 846      function disconnect()
 847      {
 848          if ($this->in_transaction && !MDB::isError($this->rollback()) && !MDB::isError($this->autoCommit(TRUE))) {
 849              $this->in_transaction = FALSE;
 850          }
 851          return($this->_close());
 852      }
 853  
 854      // }}}
 855      // {{{ _close()
 856  
 857      /**
 858       * all the RDBMS specific things needed to close a DB connection
 859       *
 860       * @access private
 861       */
 862      function _close()
 863      {
 864          unset($GLOBALS['_MDB_databases'][$this->database]);
 865      }
 866  
 867      // }}}
 868      // {{{ setDatabase()
 869  
 870      /**
 871       * Select a different database
 872       *
 873       * @param string $name name of the database that should be selected
 874       * @return string name of the database previously connected to
 875       * @access public
 876       */
 877      function setDatabase($name)
 878      {
 879          $previous_database_name = $this->database_name;
 880          $this->database_name = $name;
 881          return($previous_database_name);
 882      }
 883  
 884      // }}}
 885      // {{{ setDSN()
 886  
 887      /**
 888       * set the DSN
 889       *
 890       * @param mixed     $dsninfo    DSN string or array
 891       * @return MDB_OK
 892       * @access public
 893       */
 894      function setDSN($dsn)
 895      {
 896          $dsninfo = MDB::parseDSN($dsn);
 897          if(isset($dsninfo['hostspec'])) {
 898              $this->host = $dsninfo['hostspec'];
 899          }
 900          if(isset($dsninfo['port'])) {
 901              $this->port = $dsninfo['port'];
 902          }
 903          if(isset($dsninfo['username'])) {
 904              $this->user = $dsninfo['username'];
 905          }
 906          if(isset($dsninfo['password'])) {
 907              $this->password = $dsninfo['password'];
 908          }
 909          if(isset($dsninfo['database'])) {
 910              $this->database_name = $dsninfo['database'];
 911          }
 912          return(MDB_OK);
 913      }
 914  
 915      // }}}
 916      // {{{ getDSN()
 917  
 918      /**
 919       * return the DSN as a string
 920       *
 921       * @param string     $type    type to return
 922       * @return mixed DSN in the chosen type
 923       * @access public
 924       */
 925      function getDSN($type = 'string')
 926      {
 927          switch($type) {
 928              case 'array':
 929                  $dsn = array(
 930                      'phptype' => $this->phptype,
 931                      'username' => $this->user,
 932                      'password' => $this->password,
 933                      'hostspec' => $this->host,
 934                      'database' => $this->database_name
 935                  );
 936                  break;
 937              default:
 938                  $dsn = $this->phptype.'://'.$this->user.':'
 939                      .$this->password.'@'.$this->host
 940                      .($this->port ? (':'.$this->port) : '')
 941                      .'/'.$this->database_name;
 942                  break;
 943          }
 944          return($dsn);
 945      }
 946  
 947      // }}}
 948      // {{{ createDatabase()
 949  
 950      /**
 951       * create a new database
 952       *
 953       * @param string $name name of the database that should be created
 954       * @return mixed MDB_OK on success, a MDB error on failure
 955       * @access public
 956       */
 957      function createDatabase($name)
 958      {
 959          $result = $this->loadManager('Create database');
 960          if (MDB::isError($result)) {
 961              return($result);
 962          }
 963          return($this->manager->createDatabase($this, $name));
 964      }
 965  
 966      // }}}
 967      // {{{ dropDatabase()
 968  
 969      /**
 970       * drop an existing database
 971       *
 972       * @param string $name name of the database that should be dropped
 973       * @return mixed MDB_OK on success, a MDB error on failure
 974       * @access public
 975       */
 976      function dropDatabase($name)
 977      {
 978          $result = $this->loadManager('Drop database');
 979          if (MDB::isError($result)) {
 980              return($result);
 981          }
 982          return($this->manager->dropDatabase($this, $name));
 983      }
 984  
 985      // }}}
 986      // {{{ createTable()
 987  
 988      /**
 989       * create a new table
 990       *
 991       * @param string $name Name of the database that should be created
 992       * @param array $fields Associative array that contains the definition of
 993       *      each field of the new table. The indexes of the array entries are
 994       *      the names of the fields of the table an the array entry values are
 995       *      associative arrays like those that are meant to be passed with the
 996       *      field definitions to get[Type]Declaration() functions.
 997       *
 998       *      Example
 999       *        array(
1000       *            'id' => array(
1001       *                'type' => 'integer',
1002       *                'unsigned' => 1
1003       *                'notnull' => 1
1004       *                'default' => 0
1005       *            ),
1006       *            'name' => array(
1007       *                'type' => 'text',
1008       *                'length' => 12
1009       *            ),
1010       *            'password' => array(
1011       *                'type' => 'text',
1012       *                'length' => 12
1013       *            )
1014       *        );
1015       * @return mixed MDB_OK on success, a MDB error on failure
1016       * @access public
1017       */
1018      function createTable($name, $fields)
1019      {
1020          $result = $this->loadManager('Create table');
1021          if (MDB::isError($result)) {
1022              return($result);
1023          }
1024          return($this->manager->createTable($this, $name, $fields));
1025      }
1026  
1027      // }}}
1028      // {{{ dropTable()
1029  
1030      /**
1031       * drop an existing table
1032       *
1033       * @param string $name name of the table that should be dropped
1034       * @return mixed MDB_OK on success, a MDB error on failure
1035       * @access public
1036       */
1037      function dropTable($name)
1038      {
1039          $result = $this->loadManager('Drop table');
1040          if (MDB::isError($result)) {
1041              return($result);
1042          }
1043          return($this->manager->dropTable($this, $name));
1044      }
1045  
1046      // }}}
1047      // {{{ alterTable()
1048  
1049      /**
1050       * alter an existing table
1051       *
1052       * @param string $name name of the table that is intended to be changed.
1053       * @param array  $changes associative array that contains the details of
1054       *       each type of change that is intended to be performed. The types of
1055       *       changes that are currently supported are defined as follows:
1056       *
1057       *  name
1058       *      New name for the table.
1059       *
1060       *  AddedFields
1061       *      Associative array with the names of fields to be added as indexes of
1062       *      the array. The value of each entry of the array should be set to
1063       *      another associative array with the properties of the fields to be
1064       *      added. The properties of the fields should be the same as defined by
1065       *      the Metabase parser.
1066       *
1067       *      Additionally, there should be an entry named Declaration that is
1068       *      expected to contain the portion of the field declaration already in
1069       *       DBMS specific SQL code as it is used in the CREATE TABLE statement.
1070       *
1071       *  RemovedFields
1072       *      Associative array with the names of fields to be removed as indexes of
1073       *      the array. Currently the values assigned to each entry are ignored. An
1074       *      empty array should be used for future compatibility.
1075       *
1076       *  RenamedFields
1077       *      Associative array with the names of fields to be renamed as indexes of
1078       *      the array. The value of each entry of the array should be set to another
1079       *      associative array with the entry named name with the new field name and
1080       *      the entry named Declaration that is expected to contain the portion of
1081       *      the field declaration already in DBMS specific SQL code as it is used
1082       *      in the CREATE TABLE statement.
1083       *
1084       *  ChangedFields
1085       *      Associative array with the names of the fields to be changed as indexes
1086       *      of the array. Keep in mind that if it is intended to change either the
1087       *      name of a field and any other properties, the ChangedFields array
1088       *      entries should have the new names of the fields as array indexes.
1089       *
1090       *      The value of each entry of the array should be set to another
1091       *      associative array with the properties of the fields to that are meant
1092       *      to be changed as array entries. These entries should be assigned to the
1093       *      new values of the respective properties. The properties of the fields
1094       *      should be the* same as defined by the Metabase parser.
1095       *
1096       *      If the default property is meant to be added, removed or changed, there
1097       *      should also be an entry with index ChangedDefault assigned to 1.
1098       *      Similarly, if the notnull constraint is to be added or removed, there
1099       *      should also be an entry with index ChangedNotNull assigned to 1.
1100       *
1101       *      Additionally, there should be an entry named Declaration that is
1102       *      expected to contain the portion of the field changed declaration
1103       *      already in DBMS specific SQL code as it is used in the CREATE TABLE
1104       *      statement.
1105       *
1106       *  Example
1107       *      array(
1108       *          'name' => 'userlist',
1109       *          'AddedFields' => array(
1110       *              'quota' => array(
1111       *                  'type' => 'integer',
1112       *                  'unsigned' => 1,
1113       *                  'Declaration' => 'quota INT'
1114       *              )
1115       *          ),
1116       *          'RemovedFields' => array(
1117       *              'file_limit' => array(),
1118       *              'time_limit' => array()
1119       *          ),
1120       *          'ChangedFields' => array(
1121       *              'gender' => array(
1122       *                  'default' => 'M',
1123       *                  'ChangeDefault' => 1,
1124       *                  'Declaration' => "gender CHAR(1) DEFAULT 'M'"
1125       *              )
1126       *          ),
1127       *          'RenamedFields' => array(
1128       *              'sex' => array(
1129       *                  'name' => 'gender',
1130       *                  'Declaration' => "gender CHAR(1) DEFAULT 'M'"
1131       *              )
1132       *          )
1133       *      )
1134       *
1135       * @param boolean $check indicates whether the function should just check
1136       *       if the DBMS driver can perform the requested table alterations if
1137       *       the value is TRUE or actually perform them otherwise.
1138       * @return mixed MDB_OK on success, a MDB error on failure
1139       * @access public
1140       */
1141      function alterTable($name, $changes, $check)
1142      {
1143          $result = $this->loadManager('Alter table');
1144          if (MDB::isError($result)) {
1145              return($result);
1146          }
1147          return($this->manager->alterTable($this, $name, $changes, $check));
1148      }
1149  
1150      // }}}
1151      // {{{ listDatabases()
1152  
1153      /**
1154       * list all databases
1155       *
1156       * @return mixed data array on success, a MDB error on failure
1157       * @access public
1158       */
1159      function listDatabases()
1160      {
1161          $result = $this->loadManager('List databases');
1162          if (MDB::isError($result)) {
1163              return($result);
1164          }
1165          return($this->manager->listDatabases($this));
1166      }
1167  
1168      // }}}
1169      // {{{ listUsers()
1170  
1171      /**
1172       * list all users
1173       *
1174       * @return mixed data array on success, a MDB error on failure
1175       * @access public
1176       */
1177      function listUsers()
1178      {
1179          $result = $this->loadManager('List users');
1180          if (MDB::isError($result)) {
1181              return($result);
1182          }
1183          return($this->manager->listUsers($this));
1184      }
1185  
1186      // }}}
1187      // {{{ listViews()
1188  
1189      /**
1190       * list all viewes in the current database
1191       *
1192       * @return mixed data array on success, a MDB error on failure
1193       * @access public
1194       */
1195      function listViews()
1196      {
1197          $result = $this->loadManager('List views');
1198          if (MDB::isError($result)) {
1199              return($result);
1200          }
1201          return($this->manager->listViews($this));
1202      }
1203  
1204      // }}}
1205      // {{{ listFunctions()
1206  
1207      /**
1208       * list all functions in the current database
1209       *
1210       * @return mixed data array on success, a MDB error on failure
1211       * @access public
1212       */
1213      function listFunctions()
1214      {
1215          $result = $this->loadManager('List functions');
1216          if (MDB::isError($result)) {
1217              return($result);
1218          }
1219          return($this->manager->listFunctions($this));
1220      }
1221  
1222      // }}}
1223      // {{{ listTables()
1224  
1225      /**
1226       * list all tables in the current database
1227       *
1228       * @return mixed data array on success, a MDB error on failure
1229       * @access public
1230       */
1231      function listTables()
1232      {
1233          $result = $this->loadManager('List tables');
1234          if (MDB::isError($result)) {
1235              return($result);
1236          }
1237          return($this->manager->listTables($this));
1238      }
1239  
1240      // }}}
1241      // {{{ listTableFields()
1242  
1243      /**
1244       * list all fields in a tables in the current database
1245       *
1246       * @param string $table name of table that should be used in method
1247       * @return mixed data array on success, a MDB error on failure
1248       * @access public
1249       */
1250      function listTableFields($table)
1251      {
1252          $result = $this->loadManager('List table fields');
1253          if (MDB::isError($result)) {
1254              return($result);
1255          }
1256          return($this->manager->listTableFields($this, $table));
1257      }
1258  
1259      // }}}
1260      // {{{ getTableFieldDefinition()
1261  
1262      /**
1263       * get the stucture of a field into an array
1264       *
1265       * @param string $table name of table that should be used in method
1266       * @param string $fields name of field that should be used in method
1267       * @return mixed data array on success, a MDB error on failure
1268       * @access public
1269       */
1270      function getTableFieldDefinition($table, $field)
1271      {
1272          $result = $this->loadManager('Get table field definition');
1273          if (MDB::isError($result)) {
1274              return($result);
1275          }
1276          return($this->manager->getTableFieldDefinition($this, $table, $field));
1277      }
1278  
1279      // }}}
1280      // {{{ getFieldDeclaration()
1281  
1282      /**
1283       * get declaration of a field
1284       *
1285       * @param string $field_name name of the field to be created
1286       * @param string $field associative array with the name of the properties
1287       *       of the field being declared as array indexes. Currently, the types
1288       *       of supported field properties are as follows:
1289       *
1290       *       default
1291       *           Boolean value to be used as default for this field.
1292       *
1293       *       notnull
1294       *           Boolean flag that indicates whether this field is constrained
1295       *           to not be set to NULL.
1296       * @return mixed string on success, a MDB error on failure
1297       * @access public
1298       */
1299      function getFieldDeclaration($field_name, $field)
1300      {
1301          $result = $this->loadManager('Get table field definition');
1302          if (MDB::isError($result)) {
1303              return($result);
1304          }
1305          return($this->manager->getFieldDeclaration($this, $field_name, $field));
1306      }
1307  
1308      // }}}
1309      // {{{ getFieldDeclarationList()
1310  
1311      /**
1312       * get declaration of a number of field in bulk
1313       *
1314       * @param string $fields a multidimensional associative array.
1315       * The first dimension determines the field name, while the second
1316       * dimension is keyed with the name of the properties
1317       *       of the field being declared as array indexes. Currently, the types
1318       *       of supported field properties are as follows:
1319       *
1320       *       default
1321       *           Boolean value to be used as default for this field.
1322       *
1323       *       notnull
1324       *           Boolean flag that indicates whether this field is constrained
1325       *           to not be set to NULL.
1326       *
1327       *       default
1328       *           Boolean value to be used as default for this field.
1329       *
1330       *       notnull
1331       *           Boolean flag that indicates whether this field is constrained
1332       *           to not be set to NULL.
1333       * @return mixed string on success, a MDB error on failure
1334       * @access public
1335       */
1336      function getFieldDeclarationList($fields)
1337      {
1338          $result = $this->loadManager('Get table field list');
1339          if (MDB::isError($result)) {
1340              return($result);
1341          }
1342          return($this->manager->getFieldDeclarationList($this, $fields));
1343      }
1344  
1345      // }}}
1346      // {{{ _isSequenceName()
1347  
1348      /**
1349       * list all tables in the current database
1350       *
1351       * @param string $sqn string that containts name of a potential sequence
1352       * @return mixed name of the sequence if $sqn is a name of a sequence, else FALSE
1353       * @access private
1354       */
1355      function _isSequenceName($sqn)
1356      {
1357          $result = $this->loadManager('is sequence name');
1358          if (MDB::isError($result)) {
1359              return($result);
1360          }
1361          return($this->manager->_isSequenceName($this, $sqn));
1362      }
1363  
1364      // }}}
1365      // {{{ createIndex()
1366  
1367      /**
1368       * get the stucture of a field into an array
1369       *
1370       * @param string $table name of the table on which the index is to be
1371       *       created
1372       * @param string $name name of the index to be created
1373       * @param array $definition associative array that defines properties of
1374       *       the index to be created. Currently, only one property named FIELDS
1375       *       is supported. This property is also an associative with the names
1376       *       of the index fields as array indexes. Each entry of this array is
1377       *       set to another type of associative array that specifies properties
1378       *       of the index that are specific to each field.
1379       *
1380       *       Currently, only the sorting property is supported. It should be
1381       *       used to define the sorting direction of the index. It may be set
1382       *       to either ascending or descending. Not all DBMS support index
1383       *       sorting direction configuration. The DBMS drivers of those that do
1384       *       not support it ignore this property. Use the function support() to
1385       *       determine whether the DBMS driver can manage indexes.
1386       *
1387       *       Example
1388       *          array(
1389       *              'FIELDS' => array(
1390       *                  'user_name' => array(
1391       *                      'sorting' => 'ascending'
1392       *                  ),
1393       *                  'last_login' => array()
1394       *              )
1395       *          )
1396       * @return mixed MDB_OK on success, a MDB error on failure
1397       * @access public
1398       */
1399      function createIndex($table, $name, $definition)
1400      {
1401          $result = $this->loadManager('Create index');
1402          if (MDB::isError($result)) {
1403              return($result);
1404          }
1405          return($this->manager->createIndex($this, $table, $name, $definition));
1406      }
1407  
1408      // }}}
1409      // {{{ dropIndex()
1410  
1411      /**
1412       * drop existing index
1413       *
1414       * @param string $table name of table that should be used in method
1415       * @param string $name name of the index to be dropped
1416       * @return mixed MDB_OK on success, a MDB error on failure
1417       * @access public
1418       */
1419      function dropIndex($table, $name)
1420      {
1421          $result = $this->loadManager('Drop index');
1422          if (MDB::isError($result)) {
1423              return($result);
1424          }
1425          return($this->manager->dropIndex($this, $table , $name));
1426      }
1427  
1428      // }}}
1429      // {{{ listTableIndexes()
1430  
1431      /**
1432       * list all indexes in a table
1433       *
1434       * @param string $table name of table that should be used in method
1435       * @return mixed data array on success, a MDB error on failure
1436       * @access public
1437       */
1438      function listTableIndexes($table)
1439      {
1440          $result = $this->loadManager('List table index');
1441          if (MDB::isError($result)) {
1442              return($result);
1443          }
1444          return($this->manager->listTableIndexes($this, $table));
1445      }
1446  
1447      // }}}
1448      // {{{ getTableIndexDefinition()
1449  
1450      /**
1451       * get the stucture of an index into an array
1452       *
1453       * @param string $table name of table that should be used in method
1454       * @param string $index name of index that should be used in method
1455       * @return mixed data array on success, a MDB error on failure
1456       * @access public
1457       */
1458      function getTableIndexDefinition($table, $index)
1459      {
1460          $result = $this->loadManager('Get table index definition');
1461          if (MDB::isError($result)) {
1462              return($result);
1463          }
1464          return($this->manager->getTableIndexDefinition($this, $table, $index));
1465      }
1466  
1467      // }}}
1468      // {{{ createSequence()
1469  
1470      /**
1471       * create sequence
1472       *
1473       * @param string $name name of the sequence to be created
1474       * @param string $start start value of the sequence; default is 1
1475       * @return mixed MDB_OK on success, a MDB error on failure
1476       * @access public
1477       */
1478      function createSequence($name, $start = 1)
1479      {
1480          $result = $this->loadManager('Create sequence');
1481          if (MDB::isError($result)) {
1482              return($result);
1483          }
1484          return($this->manager->createSequence($this, $name, $start));
1485      }
1486  
1487      // }}}
1488      // {{{ dropSequence()
1489  
1490      /**
1491       * drop existing sequence
1492       *
1493       * @param string $name name of the sequence to be dropped
1494       * @return mixed MDB_OK on success, a MDB error on failure
1495       * @access public
1496       */
1497      function dropSequence($name)
1498      {
1499          $result = $this->loadManager('Drop sequence');
1500          if (MDB::isError($result)) {
1501              return($result);
1502          }
1503          return($this->manager->dropSequence($this, $name));
1504      }
1505  
1506      // }}}
1507      // {{{ listSequences()
1508  
1509      /**
1510       * list all tables in the current database
1511       *
1512       * @return mixed data array on success, a MDB error on failure
1513       * @access public
1514       */
1515      function listSequences()
1516      {
1517          $result = $this->loadManager('List sequences');
1518          if (MDB::isError($result)) {
1519              return($result);
1520          }
1521          return($this->manager->listSequences($this));
1522      }
1523  
1524      // }}}
1525      // {{{ getSequenceDefinition()
1526  
1527      /**
1528       * get the stucture of a sequence into an array
1529       *
1530       * @param string $sequence name of sequence that should be used in method
1531       * @return mixed data array on success, a MDB error on failure
1532       * @access public
1533       */
1534      function getSequenceDefinition($sequence)
1535      {
1536          $result = $this->loadManager('Get sequence definition');
1537          if (MDB::isError($result)) {
1538              return($result);
1539          }
1540          return($this->manager->getSequenceDefinition($this, $sequence));
1541      }
1542  
1543      // }}}
1544      // {{{ query()
1545  
1546      /**
1547       * Send a query to the database and return any results
1548       *
1549       * @param string $query the SQL query
1550       * @param mixed   $types  array that contains the types of the columns in
1551       *                        the result set
1552       * @return mixed a result handle or MDB_OK on success, a MDB error on failure
1553       * @access public
1554       */
1555      function query($query, $types = NULL)
1556      {
1557          $this->debug("Query: $query");
1558          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Query: database queries are not implemented'));
1559      }
1560  
1561      // }}}
1562      // {{{ setSelectedRowRange()
1563  
1564      /**
1565       * set the range of the next query
1566       *
1567       * @param string $first first row to select
1568       * @param string $limit number of rows to select
1569       * @return mixed MDB_OK on success, a MDB error on failure
1570       * @access public
1571       */
1572      function setSelectedRowRange($first, $limit)
1573      {
1574          if (!isset($this->supported['SelectRowRanges'])) {
1575              return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
1576                  'Set selected row range: selecting row ranges is not supported by this driver'));
1577          }
1578          $first = (int)$first;
1579          if ($first < 0) {
1580              return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
1581                  'Set selected row range: it was not specified a valid first selected range row'));
1582          }
1583          $limit = (int)$limit;
1584          if ($limit < 1) {
1585              return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
1586                  'Set selected row range: it was not specified a valid selected range row limit'));
1587          }
1588          $this->first_selected_row = $first;
1589          $this->selected_row_limit = $limit;
1590          return(MDB_OK);
1591      }
1592  
1593      // }}}
1594      // {{{ limitQuery()
1595  
1596      /**
1597       * Generates a limited query
1598       *
1599       * @param string $query query
1600       * @param mixed   $types  array that contains the types of the columns in
1601       *                        the result set
1602       * @param integer $from the row to start to fetching
1603       * @param integer $count the numbers of rows to fetch
1604       * @return mixed a valid ressource pointer or a MDB_Error
1605       * @access public
1606       */
1607      function limitQuery($query, $types = NULL, $from, $count)
1608      {
1609          $result = $this->setSelectedRowRange($from, $count);
1610          if (MDB::isError($result)) {
1611              return($result);
1612          }
1613          return($this->query($query, $types));
1614      }
1615  
1616      // }}}
1617      // {{{ subSelect()
1618  
1619      /**
1620       * simple subselect emulation: leaves the query untouched for all RDBMS
1621       * that support subselects
1622       *
1623       * @access public
1624       *
1625       * @param string $query the SQL query for the subselect that may only
1626       *                      return a column
1627       * @param string $quote determines if the data needs to be quoted before
1628       *                      being returned
1629       *
1630       * @return string the query
1631       */
1632      function subSelect($query, $quote = FALSE)
1633      {
1634          if ($this->supported['SubSelects'] == 1) {
1635              return($query);
1636          }
1637          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Subselect: subselect not implemented'));
1638      }
1639  
1640      // }}}
1641      // {{{ replace()
1642  
1643      /**
1644       * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
1645       * query, except that if there is already a row in the table with the same
1646       * key field values, the REPLACE query just updates its values instead of
1647       * inserting a new row.
1648       *
1649       * The REPLACE type of query does not make part of the SQL standards. Since
1650       * pratically only MySQL implements it natively, this type of query is
1651       * emulated through this method for other DBMS using standard types of
1652       * queries inside a transaction to assure the atomicity of the operation.
1653       *
1654       * @param string $table name of the table on which the REPLACE query will
1655       *       be executed.
1656       * @param array $fields associative array that describes the fields and the
1657       *       values that will be inserted or updated in the specified table. The
1658       *       indexes of the array are the names of all the fields of the table.
1659       *       The values of the array are also associative arrays that describe
1660       *       the values and other properties of the table fields.
1661       *
1662       *       Here follows a list of field properties that need to be specified:
1663       *
1664       *       Value
1665       *           Value to be assigned to the specified field. This value may be
1666       *           of specified in database independent type format as this
1667       *           function can perform the necessary datatype conversions.
1668       *
1669       *           Default: this property is required unless the Null property is
1670       *           set to 1.
1671       *
1672       *       Type
1673       *           Name of the type of the field. Currently, all types Metabase
1674       *           are supported except for clob and blob.
1675       *
1676       *           Default: no type conversion
1677       *
1678       *       Null
1679       *           Boolean property that indicates that the value for this field
1680       *           should be set to NULL.
1681       *
1682       *           The default value for fields missing in INSERT queries may be
1683       *           specified the definition of a table. Often, the default value
1684       *           is already NULL, but since the REPLACE may be emulated using
1685       *           an UPDATE query, make sure that all fields of the table are
1686       *           listed in this function argument array.
1687       *
1688       *           Default: 0
1689       *
1690       *       Key
1691       *           Boolean property that indicates that this field should be
1692       *           handled as a primary key or at least as part of the compound
1693       *           unique index of the table that will determine the row that will
1694       *           updated if it exists or inserted a new row otherwise.
1695       *
1696       *           This function will fail if no key field is specified or if the
1697       *           value of a key field is set to NULL because fields that are
1698       *           part of unique index they may not be NULL.
1699       *
1700       *           Default: 0
1701       * @return mixed MDB_OK on success, a MDB error on failure
1702       * @access public
1703       */
1704      function replace($table, $fields)
1705      {
1706          if (!$this->supported['Replace']) {
1707              return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Replace: replace query is not supported'));
1708          }
1709          $count = count($fields);
1710          for($keys = 0, $condition = $insert = $values = '', reset($fields), $field = 0;
1711              $field < $count;
1712              next($fields), $field++)
1713          {
1714              $name = key($fields);
1715              if ($field > 0) {
1716                  $insert .= ', ';
1717                  $values .= ', ';
1718              }
1719              $insert .= $name;
1720              if (isset($fields[$name]['Null']) && $fields[$name]['Null']) {
1721                  $value = 'NULL';
1722              } else {
1723                  if(isset($fields[$name]['Type'])) {
1724                      switch ($fields[$name]['Type']) {
1725                          case 'text':
1726                              $value = $this->getTextValue($fields[$name]['Value']);
1727                              break;
1728                          case 'boolean':
1729                              $value = $this->getBooleanValue($fields[$name]['Value']);
1730                              break;
1731                          case 'integer':
1732                              $value = $this->getIntegerValue($fields[$name]['Value']);
1733                              break;
1734                          case 'decimal':
1735                              $value = $this->getDecimalValue($fields[$name]['Value']);
1736                              break;
1737                          case 'float':
1738                              $value = $this->getFloatValue($fields[$name]['Value']);
1739                              break;
1740                          case 'date':
1741                              $value = $this->getDateValue($fields[$name]['Value']);
1742                              break;
1743                          case 'time':
1744                              $value = $this->getTimeValue($fields[$name]['Value']);
1745                              break;
1746                          case 'timestamp':
1747                              $value = $this->getTimestampValue($fields[$name]['Value']);
1748                              break;
1749                          default:
1750                              return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
1751                                  'no supported type for field "' . $name . '" specified'));
1752                      }
1753                  } else {
1754                      $value = $fields[$name]['Value'];
1755                  }
1756              }
1757              $values .= $value;
1758              if (isset($fields[$name]['Key']) && $fields[$name]['Key']) {
1759                  if ($value === 'NULL') {
1760                      return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
1761                          'key values may not be NULL'));
1762                  }
1763                  $condition .= ($keys ? ' AND ' : ' WHERE ') . $name . '=' . $value;
1764                  $keys++;
1765              }
1766          }
1767          if ($keys == 0) {
1768              return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
1769                  'not specified which fields are keys'));
1770          }
1771          $in_transaction = $this->in_transaction;
1772          if (!$in_transaction && MDB::isError($result = $this->autoCommit(FALSE))) {
1773              return($result);
1774          }
1775          $success = $this->query("DELETE FROM $table$condition");
1776          if (!MDB::isError($success)) {
1777              $affected_rows = $this->affected_rows;
1778              $success = $this->query("INSERT INTO $table ($insert) VALUES ($values)");
1779              $affected_rows += $this->affected_rows;
1780          }
1781  
1782          if (!$in_transaction) {
1783              if (!MDB::isError($success)) {
1784                  if (!MDB::isError($success = $this->commit())
1785                      && !MDB::isError($success = $this->autoCommit(TRUE))
1786                      && isset($this->supported['AffectedRows'])
1787                  ) {
1788                      $this->affected_rows = $affected_rows;
1789                  }
1790              } else {
1791                  $this->rollback();
1792                  $this->autoCommit(TRUE);
1793              }
1794          }
1795          return($success);
1796      }
1797  
1798      // }}}
1799      // {{{ prepareQuery()
1800  
1801      /**
1802       * Prepares a query for multiple execution with execute().
1803       * With some database backends, this is emulated.
1804       * prepareQuery() requires a generic query as string like
1805       * 'INSERT INTO numbers VALUES(?,?,?)'. The ? are wildcards.
1806       * Types of wildcards:
1807       *    ? - a quoted scalar value, i.e. strings, integers
1808       *
1809       * @param string $ the query to prepare
1810       * @return mixed resource handle for the prepared query on success, a DB
1811       *        error on failure
1812       * @access public
1813       * @see execute
1814       */
1815      function prepareQuery($query)
1816      {
1817          $this->debug("PrepareQuery: $query");
1818          $positions = array();
1819          for($position = 0;
1820              $position < strlen($query) && is_integer($question = strpos($query, '?', $position));
1821          ) {
1822              if (is_integer($quote = strpos($query, "'", $position))
1823                  && $quote < $question
1824              ) {
1825                  if (!is_integer($end_quote = strpos($query, "'", $quote + 1))) {
1826                      return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
1827                          'Prepare query: query with an unterminated text string specified'));
1828                  }
1829                  switch ($this->escape_quotes) {
1830                      case '':
1831                      case "'":
1832                          $position = $end_quote + 1;
1833                          break;
1834                      default:
1835                          if ($end_quote == $quote + 1) {
1836                              $position = $end_quote + 1;
1837                          } else {
1838                              if ($query[$end_quote-1] == $this->escape_quotes) {
1839                                  $position = $end_quote;
1840                              } else {
1841                                  $position = $end_quote + 1;
1842                              }
1843                          }
1844                          break;
1845                  }
1846              } else {
1847                  $positions[] = $question;
1848                  $position = $question + 1;
1849              }
1850          }
1851          $this->prepared_queries[] = array(
1852              'Query' => $query,
1853              'Positions' => $positions,
1854              'Values' => array(),
1855              'Types' => array()
1856              );
1857          $prepared_query = count($this->prepared_queries);
1858          if ($this->selected_row_limit > 0) {
1859              $this->prepared_queries[$prepared_query-1]['First'] = $this->first_selected_row;
1860              $this->prepared_queries[$prepared_query-1]['Limit'] = $this->selected_row_limit;
1861          }
1862          return($prepared_query);
1863      }
1864  
1865      // }}}
1866      // {{{ _validatePreparedQuery()
1867  
1868      /**
1869       * validate that a handle is infact a prepared query
1870       *
1871       * @param int $prepared_query argument is a handle that was returned by
1872       *       the function prepareQuery()
1873       * @access private
1874       */
1875      function _validatePreparedQuery($prepared_query)
1876      {
1877          if ($prepared_query < 1 || $prepared_query > count($this->prepared_queries)) {
1878              return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
1879                  'Validate prepared query: invalid prepared query'));
1880          }
1881          if (gettype($this->prepared_queries[$prepared_query-1]) != 'array') {
1882              return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
1883                  'Validate prepared query: prepared query was already freed'));
1884          }
1885          return(MDB_OK);
1886      }
1887  
1888      // }}}
1889      // {{{ freePreparedQuery()
1890  
1891      /**
1892       * Release resources allocated for the specified prepared query.
1893       *
1894       * @param int $prepared_query argument is a handle that was returned by
1895       *       the function prepareQuery()
1896       * @return mixed MDB_OK on success, a MDB error on failure
1897       * @access public
1898       */
1899      function freePreparedQuery($prepared_query)
1900      {
1901          $result = $this->_validatePreparedQuery($prepared_query);
1902          if (MDB::isError($result)) {
1903              return($result);
1904          }
1905          $this->prepared_queries[$prepared_query-1] = '';
1906          return(MDB_OK);
1907      }
1908  
1909      // }}}
1910      // {{{ _executePreparedQuery()
1911  
1912      /**
1913       * Execute a prepared query statement.
1914       *
1915       * @param int $prepared_query argument is a handle that was returned by
1916       *       the function prepareQuery()
1917       * @param string $query query to be executed
1918       * @param array $types array that contains the types of the columns in
1919       *       the result set
1920       * @return mixed a result handle or MDB_OK on success, a MDB error on failure
1921       * @access private
1922       */
1923      function _executePreparedQuery($prepared_query, $query, $types = NULL)
1924      {
1925          return($this->query($query, $types));
1926      }
1927  
1928      // }}}
1929      // {{{ executeQuery()
1930  
1931      /**
1932       * Execute a prepared query statement.
1933       *
1934       * @param int $prepared_query argument is a handle that was returned by
1935       *       the function prepareQuery()
1936       * @param array $types array that contains the types of the columns in the
1937       *       result set
1938       * @return mixed a result handle or MDB_OK on success, a MDB error on failure
1939       * @access public
1940       */
1941      function executeQuery($prepared_query, $types = NULL)
1942      {
1943          $result = $this->_validatePreparedQuery($prepared_query);
1944          if (MDB::isError($result)) {
1945              return($result);
1946          }
1947          $index = $prepared_query-1;
1948          $success = MDB_OK;
1949          $this->clobs[$prepared_query] = $this->blobs[$prepared_query] = array();
1950          $query = '';
1951          for($last_position = $position = 0;
1952              $position < count($this->prepared_queries[$index]['Positions']);
1953              $position++) {
1954              if (!isset($this->prepared_queries[$index]['Values'][$position])) {
1955                  return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
1956                      'Execute query: it was not defined query argument '.($position + 1)));
1957              }
1958              $current_position = $this->prepared_queries[$index]['Positions'][$position];
1959              $query .= substr($this->prepared_queries[$index]['Query'], $last_position, $current_position - $last_position);
1960              $value = $this->prepared_queries[$index]['Values'][$position];
1961              if ($this->prepared_queries[$index]['IsNULL'][$position]) {
1962                  $query .= $value;
1963              } else {
1964                  switch ($this->prepared_queries[$index]['Types'][$position]) {
1965                      case 'clob':
1966                          if (!MDB::isError($success = $this->getClobValue($prepared_query, $position + 1, $value))) {
1967                              $this->clobs[$prepared_query][$position + 1] = $success;
1968                              $query .= $this->clobs[$prepared_query][$position + 1];
1969                          }
1970                          break;
1971                      case 'blob':
1972                          if (!MDB::isError($success = $this->getBlobValue($prepared_query, $position + 1, $value))) {
1973                              $this->blobs[$prepared_query][$position + 1] = $success;
1974                              $query .= $this->blobs[$prepared_query][$position + 1];
1975                          }
1976                          break;
1977                      default:
1978                          $query .= $value;
1979                          break;
1980                  }
1981              }
1982              $last_position = $current_position + 1;
1983          }
1984          if (!MDB::isError($success)) {
1985              $query .= substr($this->prepared_queries[$index]['Query'], $last_position);
1986              if ($this->selected_row_limit > 0) {
1987                  $this->prepared_queries[$index]['First'] = $this->first_selected_row;
1988                  $this->prepared_queries[$index]['Limit'] = $this->selected_row_limit;
1989              }
1990              if (isset($this->prepared_queries[$index]['Limit'])
1991                  && $this->prepared_queries[$index]['Limit'] > 0
1992              ) {
1993                  $this->first_selected_row = $this->prepared_queries[$index]['First'];
1994                  $this->selected_row_limit = $this->prepared_queries[$index]['Limit'];
1995              } else {
1996                  $this->first_selected_row = $this->selected_row_limit = 0;
1997              }
1998              $success = $this->_executePreparedQuery($prepared_query, $query, $types);
1999          }
2000          for(reset($this->clobs[$prepared_query]), $clob = 0;
2001              $clob < count($this->clobs[$prepared_query]);
2002              $clob++, next($this->clobs[$prepared_query])) {
2003              $this->freeClobValue($prepared_query, key($this->clobs[$prepared_query]), $this->clobs[$prepared_query][key($this->clobs[$prepared_query])], $success);
2004          }
2005          unset($this->clobs[$prepared_query]);
2006          for(reset($this->blobs[$prepared_query]), $blob = 0;
2007              $blob < count($this->blobs[$prepared_query]);
2008              $blob++, next($this->blobs[$prepared_query])) {
2009              $this->freeBlobValue($prepared_query, key($this->blobs[$prepared_query]), $this->blobs[$prepared_query][key($this->blobs[$prepared_query])], $success);
2010          }
2011          unset($this->blobs[$prepared_query]);
2012          return($success);
2013      }
2014  
2015      // }}}
2016      // {{{ execute()
2017  
2018      /**
2019       * Executes a prepared SQL query
2020       * With execute() the generic query of prepare is assigned with the given
2021       * data array. The values of the array inserted into the query in the same
2022       * order like the array order
2023       *
2024       * @param resource $prepared_query query handle from prepare()
2025       * @param array $types array that contains the types of the columns in
2026       *        the result set
2027       * @param array $params numeric array containing the data to insert into
2028       *        the query
2029       * @param array $param_types array that contains the types of the values
2030       *        defined in $params
2031       * @return mixed a new result handle or a MDB_Error when fail
2032       * @access public
2033       * @see prepare()
2034       */
2035      function execute($prepared_query, $types = NULL, $params = FALSE, $param_types = NULL)
2036      {
2037          $this->setParamArray($prepared_query, $params, $param_types);
2038  
2039          return($this->executeQuery($prepared_query, $types));
2040      }
2041  
2042      // }}}
2043      // {{{ executeMultiple()
2044  
2045      /**
2046       * This function does several execute() calls on the same statement handle.
2047       * $params must be an array indexed numerically from 0, one execute call is
2048       * done for every 'row' in the array.
2049       *
2050       * If an error occurs during execute(), executeMultiple() does not execute
2051       * the unfinished rows, but rather returns that error.
2052       *
2053       * @param resource $stmt query handle from prepare()
2054       * @param array $types array that contains the types of the columns in
2055       *        the result set
2056       * @param array $params numeric array containing the
2057       *        data to insert into the query
2058       * @param array $parAM_types array that contains the types of the values
2059       *        defined in $params
2060       * @return mixed a result handle or MDB_OK on success, a MDB error on failure
2061       * @access public
2062       * @see prepare(), execute()
2063       */
2064      function executeMultiple($prepared_query, $types = NULL, $params, $param_types = NULL)
2065      {
2066          for($i = 0, $j = count($params); $i < $j; $i++) {
2067              $result = $this->execute($prepared_query, $types, $params[$i], $param_types);
2068              if (MDB::isError($result)) {
2069                  return($result);
2070              }
2071          }
2072          return(MDB_OK);
2073      }
2074  
2075      // }}}
2076      // {{{ setParam()
2077  
2078      /**
2079       * Set the value of a parameter of a prepared query.
2080       *
2081       * @param int $prepared_query argument is a handle that was returned
2082       *       by the function prepareQuery()
2083       * @param int $parameter the order number of the parameter in the query
2084       *       statement. The order number of the first parameter is 1.
2085       * @param string $type designation of the type of the parameter to be set.
2086       *       The designation of the currently supported types is as follows:
2087       *           text, boolean, integer, decimal, float, date, time, timestamp,
2088       *           clob, blob
2089       * @param mixed $value value that is meant to be assigned to specified
2090       *       parameter. The type of the value depends on the $type argument.
2091       * @param boolean $is_null flag that indicates whether whether the
2092       *       parameter is a NULL
2093       * @param string $field name of the field that is meant to be assigned
2094       *       with this parameter value when it is of type clob or blob
2095       * @return mixed MDB_OK on success, a MDB error on failure
2096       * @access public
2097       */
2098      function setParam($prepared_query, $parameter, $type, $value, $is_null = 0, $field = '')
2099      {
2100          $result = $this->_validatePreparedQuery($prepared_query);
2101          if (MDB::isError($result)) {
2102              return($result);
2103          }
2104          $index = $prepared_query - 1;
2105          if ($parameter < 1 || $parameter > count($this->prepared_queries[$index]['Positions'])) {
2106              return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
2107                  'Query set: it was not specified a valid argument number'));
2108          }
2109          $this->prepared_queries[$index]['Values'][$parameter-1] = $value;
2110          $this->prepared_queries[$index]['Types'][$parameter-1] = $type;
2111          $this->prepared_queries[$index]['Fields'][$parameter-1] = $field;
2112          $this->prepared_queries[$index]['IsNULL'][$parameter-1] = $is_null;
2113          return(MDB_OK);
2114      }
2115  
2116      // }}}
2117      // {{{ setParamArray()
2118  
2119      /**
2120       * Set the values of multiple a parameter of a prepared query in bulk.
2121       *
2122       * @param int $prepared_query argument is a handle that was returned by
2123       *       the function prepareQuery()
2124       * @param array $params array thats specifies all necessary infromation
2125       *       for setParam() the array elements must use keys corresponding to
2126       *       the number of the position of the parameter.
2127       * @param array $types array thats specifies the types of the fields
2128       * @return mixed MDB_OK on success, a MDB error on failure
2129       * @access public
2130       * @see setParam()
2131       */
2132      function setParamArray($prepared_query, $params, $types = NULL)
2133      {
2134          if (is_array($types)) {
2135              if (count($params) != count($types)) {
2136                  return $this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
2137                      'setParamArray: the number of given types ('.count($types).')'
2138                      .'is not corresponding to the number of given parameters ('.count($params).')');
2139              }
2140              for($i = 0, $j = count($params); $i < $j; ++$i) {
2141                  switch ($types[$i]) {
2142                      case 'NULL':
2143                          $success = $this->setParam($prepared_query, $i + 1, $params[$i][0], 'NULL', 1, '');
2144                          break;
2145                      case 'text':
2146                          $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
2147                          break;
2148                      case 'clob':
2149                          $success = $this->setParam($prepared_query, $i + 1, 'clob', $params[$i][0], 0, $params[$i][1]);
2150                          break;
2151                      case 'blob':
2152                          $success = $this->setParam($prepared_query, $i + 1, 'blob', $params[$i][0], 0, $params[$i][1]);
2153                          break;
2154                      case 'integer':
2155                          $success = $this->setParam($prepared_query, $i + 1, 'integer', $this->getIntegerValue($params[$i]));
2156                          break;
2157                      case 'boolean':
2158                          $success = $this->setParam($prepared_query, $i + 1, 'boolean', $this->getBooleanValue($params[$i]));
2159                          break;
2160                      case 'date':
2161                          $success = $this->setParam($prepared_query, $i + 1, 'date', $this->getDateValue($params[$i]));
2162                          break;
2163                      case 'timestamp':
2164                          $success = $this->setParam($prepared_query, $i + 1, 'timestamp', $this->getTimestampValue($params[$i]));
2165                          break;
2166                      case 'time':
2167                          $success = $this->setParam($prepared_query, $i + 1, 'time', $this->getTimeValue($params[$i]));
2168                          break;
2169                      case 'float':
2170                          $success = $this->setParam($prepared_query, $i + 1, 'float', $this->getFloatValue($params[$i]));
2171                          break;
2172                      case 'decimal':
2173                          $success = $this->setParam($prepared_query, $i + 1, 'decimal', $this->getDecimalValue($params[$i]));
2174                          break;
2175                      default:
2176                          $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
2177                          break;
2178                  }
2179                  if (MDB::isError($success)) {
2180                      return($success);
2181                  }
2182              }
2183          } else {
2184              for($i = 0, $j = count($params); $i < $j; ++$i) {
2185                  $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
2186                  if (MDB::isError($success)) {
2187                      return($success);
2188                  }
2189              }
2190          }
2191          return(MDB_OK);
2192      }
2193  
2194      // }}}
2195      // {{{ setParamNull()
2196  
2197      /**
2198       * Set the value of a parameter of a prepared query to NULL.
2199       *
2200       * @param int $prepared_query argument is a handle that was returned by
2201       *       the function prepareQuery()
2202       * @param int $parameter order number of the parameter in the query
2203       *       statement. The order number of the first parameter is 1.
2204       * @param string $type designation of the type of the parameter to be set.
2205       *       The designation of the currently supported types is list in the
2206       *       usage of the function  setParam()
2207       * @return mixed MDB_OK on success, a MDB error on failure
2208       * @access public
2209       * @see setParam()
2210       */
2211      function setParamNull($prepared_query, $parameter, $type)
2212      {
2213          return($this->setParam($prepared_query, $parameter, $type, 'NULL', 1, ''));
2214      }
2215  
2216      // }}}
2217      // {{{ setParamText()
2218  
2219      /**
2220       * Set a parameter of a prepared query with a text value.
2221       *
2222       * @param int $prepared_query argument is a handle that was returned by
2223       *       the function prepareQuery()
2224       * @param int $parameter order number of the parameter in the query
2225       *       statement. The order number of the first parameter is 1.
2226       * @param string $value text value that is meant to be assigned to
2227       *       specified parameter.
2228       * @return mixed MDB_OK on success, a MDB error on failure
2229       * @access public
2230       * @see setParam()
2231       */
2232      function setParamText($prepared_query, $parameter, $value)
2233      {
2234          return($this->setParam($prepared_query, $parameter, 'text', $this->getTextValue($value)));
2235      }
2236  
2237      // }}}
2238      // {{{ setParamClob()
2239  
2240      /**
2241       * Set a parameter of a prepared query with a character large object value.
2242       *
2243       * @param int $prepared_query argument is a handle that was returned by
2244       *       the function prepareQuery()
2245       * @param int $parameter order number of the parameter in the query
2246       *       statement. The order number of the first parameter is 1.
2247       * @param int $value handle of large object created with createLOB()
2248       *       function from which it will be read the data value that is meant
2249       *       to be assigned to specified parameter.
2250       * @param string $field name of the field of a INSERT or UPDATE query to
2251       *       which it will be assigned the value to specified parameter.
2252       * @return mixed MDB_OK on success, a MDB error on failure
2253       * @access public
2254       * @see setParam()
2255       */
2256      function setParamClob($prepared_query, $parameter, $value, $field)
2257      {
2258          return($this->setParam($prepared_query, $parameter, 'clob', $value, 0, $field));
2259      }
2260  
2261      // }}}
2262      // {{{ setParamBlob()
2263  
2264      /**
2265       * Set a parameter of a prepared query with a binary large object value.
2266       *
2267       * @param int $prepared_query argument is a handle that was returned by
2268       *       the function prepareQuery()
2269       * @param int $parameter order number of the parameter in the query
2270       *       statement. The order number of the first parameter is 1.
2271       * @param int $value handle of large object created with createLOB()
2272       *       function from which it will be read the data value that is meant
2273       *       to be assigned to specified parameter.
2274       * @param string $field name of the field of a INSERT or UPDATE query to
2275       *       which it will be assigned the value to specified parameter.
2276       * @return mixed MDB_OK on success, a MDB error on failure
2277       * @access public
2278       * @see setParam()
2279       */
2280      function setParamBlob($prepared_query, $parameter, $value, $field)
2281      {
2282          return($this->setParam($prepared_query, $parameter, 'blob', $value, 0, $field));
2283      }
2284  
2285      // }}}
2286      // {{{ setParamInteger()
2287  
2288      /**
2289       * Set a parameter of a prepared query with a text value.
2290       *
2291       * @param int $prepared_query argument is a handle that was returned by
2292       *       the function prepareQuery()
2293       * @param int $parameter order number of the parameter in the query
2294       *       statement. The order number of the first parameter is 1.
2295       * @param int $value an integer value that is meant to be assigned to
2296       *       specified parameter.
2297       * @return mixed MDB_OK on success, a MDB error on failure
2298       * @access public
2299       * @see setParam()
2300       */
2301      function setParamInteger($prepared_query, $parameter, $value)
2302      {
2303          return($this->setParam($prepared_query, $parameter, 'integer', $this->getIntegerValue($value)));
2304      }
2305  
2306      // }}}
2307      // {{{ setParamBoolean()
2308  
2309      /**
2310       * Set a parameter of a prepared query with a boolean value.
2311       *
2312       * @param int $prepared_query argument is a handle that was returned by
2313       *       the function prepareQuery()
2314       * @param int $parameter order number of the parameter in the query
2315       *       statement. The order number of the first parameter is 1.
2316       * @param boolean $value boolean value that is meant to be assigned to
2317       *       specified parameter.
2318       * @return mixed MDB_OK on success, a MDB error on failure
2319       * @access public
2320       * @see setParam()
2321       */
2322      function setParamBoolean($prepared_query, $parameter, $value)
2323      {
2324          return($this->setParam($prepared_query, $parameter, 'boolean', $this->getBooleanValue($value)));
2325      }
2326  
2327      // }}}
2328      // {{{ setParamDate()
2329  
2330      /**
2331       * Set a parameter of a prepared query with a date value.
2332       *
2333       * @param int $prepared_query argument is a handle that was returned by
2334       *       the function prepareQuery()
2335       * @param int $parameter order number of the parameter in the query
2336       *       statement. The order number of the first parameter is 1.
2337       * @param string $value date value that is meant to be assigned to
2338       *       specified parameter.
2339       * @return mixed MDB_OK on success, a MDB error on failure
2340       * @access public
2341       * @see setParam()
2342       */
2343      function setParamDate($prepared_query, $parameter, $value)
2344      {
2345          return($this->setParam($prepared_query, $parameter, 'date', $this->getDateValue($value)));
2346      }
2347  
2348      // }}}
2349      // {{{ setParamTimestamp()
2350  
2351      /**
2352       * Set a parameter of a prepared query with a time stamp value.
2353       *
2354       * @param int $prepared_query argument is a handle that was returned by
2355       *       the function prepareQuery()
2356       * @param int $parameter order number of the parameter in the query
2357       *       statement. The order number of the first parameter is 1.
2358       * @param string $value time stamp value that is meant to be assigned to
2359       *       specified parameter.
2360       * @return mixed MDB_OK on success, a MDB error on failure
2361       * @access public
2362       * @see setParam()
2363       */
2364      function setParamTimestamp($prepared_query, $parameter, $value)
2365      {
2366          return($this->setParam($prepared_query, $parameter, 'timestamp', $this->getTimestampValue($value)));
2367      }
2368  
2369      // }}}
2370      // {{{ setParamTime()
2371  
2372      /**
2373       * Set a parameter of a prepared query with a time value.
2374       *
2375       * @param int $prepared_query argument is a handle that was returned by
2376       *       the function prepareQuery()
2377       * @param int $parameter order number of the parameter in the query
2378       *       statement. The order number of the first parameter is 1.
2379       * @param string $value time value that is meant to be assigned to
2380       *       specified parameter.
2381       * @return mixed MDB_OK on success, a MDB error on failure
2382       * @access public
2383       * @see setParam()
2384       */
2385      function setParamTime($prepared_query, $parameter, $value)
2386      {
2387          return($this->setParam($prepared_query, $parameter, 'time', $this->getTimeValue($value)));
2388      }
2389  
2390      // }}}
2391      // {{{ setParamFloat()
2392  
2393      /**
2394       * Set a parameter of a prepared query with a float value.
2395       *
2396       * @param int $prepared_query argument is a handle that was returned by
2397       *       the function prepareQuery()
2398       * @param int $parameter order number of the parameter in the query
2399       *       statement. The order number of the first parameter is 1.
2400       * @param string $value float value that is meant to be assigned to
2401       *       specified parameter.
2402       * @return mixed MDB_OK on success, a MDB error on failure
2403       * @access public
2404       * @see setParam()
2405       */
2406      function setParamFloat($prepared_query, $parameter, $value)
2407      {
2408          return($this->setParam($prepared_query, $parameter, 'float', $this->getFloatValue($value)));
2409      }
2410  
2411      // }}}
2412      // {{{ setParamDecimal()
2413  
2414      /**
2415       * Set a parameter of a prepared query with a decimal value.
2416       *
2417       * @param int $prepared_query argument is a handle that was returned by
2418       *       the function prepareQuery()
2419       * @param int $parameter order number of the parameter in the query
2420       *       statement. The order number of the first parameter is 1.
2421       * @param string $value decimal value that is meant to be assigned to
2422       *       specified parameter.
2423       * @return mixed MDB_OK on success, a MDB error on failure
2424       * @access public
2425       * @see setParam()
2426       */
2427      function setParamDecimal($prepared_query, $parameter, $value)
2428      {
2429          return($this->setParam($prepared_query, $parameter, 'decimal', $this->getDecimalValue($value)));
2430      }
2431  
2432      // }}}
2433      // {{{ setResultTypes()
2434  
2435      /**
2436       * Define the list of types to be associated with the columns of a given
2437       * result set.
2438       *
2439       * This function may be called before invoking fetchInto(), fetchOne(),
2440       * fetchRow(), fetchCol() and fetchAll() so that the necessary data type
2441       * conversions are performed on the data to be retrieved by them. If this
2442       * function is not called, the type of all result set columns is assumed
2443       * to be text, thus leading to not perform any conversions.
2444       *
2445       * @param resource $result result identifier
2446       * @param string $types array variable that lists the
2447       *       data types to be expected in the result set columns. If this array
2448       *       contains less types than the number of columns that are returned
2449       *       in the result set, the remaining columns are assumed to be of the
2450       *       type text. Currently, the types clob and blob are not fully
2451       *       supported.
2452       * @return mixed MDB_OK on success, a MDB error on failure
2453       * @access public
2454       */
2455      function setResultTypes($result, $types)
2456      {
2457          $result_value = intval($result);
2458          if (isset($this->result_types[$result_value])) {
2459              return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
2460                  'Set result types: attempted to redefine the types of the columns of a result set'));
2461          }
2462          $columns = $this->numCols($result);
2463          if (MDB::isError($columns)) {
2464              return($columns);
2465          }
2466          if ($columns < count($types)) {
2467              return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
2468                  'Set result types: it were specified more result types (' . count($types) . ') than result columns (' . $columns . ')'));
2469          }
2470          $valid_types = array(
2471              'text'      => MDB_TYPE_TEXT,
2472              'boolean'   => MDB_TYPE_BOOLEAN,
2473              'integer'   => MDB_TYPE_INTEGER,
2474              'decimal'   => MDB_TYPE_DECIMAL,
2475              'float'     => MDB_TYPE_FLOAT,
2476              'date'      => MDB_TYPE_DATE,
2477              'time'      => MDB_TYPE_TIME,
2478              'timestamp' => MDB_TYPE_TIMESTAMP,
2479              'clob'      => MDB_TYPE_CLOB,
2480              'blob'      => MDB_TYPE_BLOB
2481          );
2482          for($column = 0; $column < count($types); $column++) {
2483              if (!isset($valid_types[$types[$column]])) {
2484                  return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2485                      'Set result types: ' . $types[$column] . ' is not a supported column type'));
2486              }
2487              $this->result_types[$result_value][$column] = $valid_types[$types[$column]];
2488          }
2489          while ($column < $columns) {
2490              $this->result_types[$result_value][$column] = MDB_TYPE_TEXT;
2491              $column++;
2492          }
2493          return(MDB_OK);
2494      }
2495  
2496      // }}}
2497      // {{{ affectedRows()
2498  
2499      /**
2500       * returns the affected rows of a query
2501       *
2502       * @return mixed MDB_Error or number of rows
2503       * @access public
2504       */
2505      function affectedRows()
2506      {
2507          if ($this->affected_rows == -1) {
2508              return($this->raiseError(MDB_ERROR_NEED_MORE_DATA));
2509          }
2510          return($this->affected_rows);
2511      }
2512  
2513      // }}}
2514      // {{{ getColumnNames()
2515  
2516      /**
2517       * Retrieve the names of columns returned by the DBMS in a query result.
2518       *
2519       * @param resource $result result identifier
2520       * @return mixed associative array variable
2521       *       that holds the names of columns. The indexes of the array are
2522       *       the column names mapped to lower case and the values are the
2523       *       respective numbers of the columns starting from 0. Some DBMS may
2524       *       not return any columns when the result set does not contain any
2525       *       rows.
2526       *      a MDB error on failure
2527       * @access public
2528       */
2529      function getColumnNames($result)
2530      {
2531          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2532              'Get column names: obtaining result column names is not implemented'));
2533      }
2534  
2535      // }}}
2536      // {{{ numCols()
2537  
2538      /**
2539       * Count the number of columns returned by the DBMS in a query result.
2540       *
2541       * @param resource $result result identifier
2542       * @return mixed integer value with the number of columns, a MDB error
2543       *       on failure
2544       * @access public
2545       */
2546      function numCols($result)
2547      {
2548          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2549              'Number of columns: obtaining the number of result columns is not implemented'));
2550      }
2551  
2552      // }}}
2553      // {{{ endOfResult()
2554  
2555      /**
2556       * check if the end of the result set has been reached
2557       *
2558       * @param resource $result result identifier
2559       * @return mixed TRUE or FALSE on sucess, a MDB error on failure
2560       * @access public
2561       */
2562      function endOfResult($result)
2563      {
2564          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2565              'End of result: end of result method not implemented'));
2566      }
2567  
2568      // }}}
2569      // {{{ setFetchMode()
2570  
2571      /**
2572       * Sets which fetch mode should be used by default on queries
2573       * on this connection.
2574       *
2575       * @param integer $fetchmode MDB_FETCHMODE_ORDERED or MDB_FETCHMODE_ASSOC,
2576       *       possibly bit-wise OR'ed with MDB_FETCHMODE_FLIPPED.
2577       * @access public
2578       * @see MDB_FETCHMODE_ORDERED
2579       * @see MDB_FETCHMODE_ASSOC
2580       * @see MDB_FETCHMODE_FLIPPED
2581       */
2582      function setFetchMode($fetchmode)
2583      {
2584          switch ($fetchmode) {
2585              case MDB_FETCHMODE_ORDERED:
2586              case MDB_FETCHMODE_ASSOC:
2587                  $this->fetchmode = $fetchmode;
2588                  break;
2589              default:
2590                  return($this->raiseError('invalid fetchmode mode'));
2591          }
2592      }
2593  
2594      // }}}
2595      // {{{ fetch()
2596  
2597      /**
2598       * fetch value from a result set
2599       *
2600       * @param resource $result result identifier
2601       * @param int $row number of the row where the data can be found
2602       * @param int $field field number where the data can be found
2603       * @return mixed string on success, a MDB error on failure
2604       * @access public
2605       */
2606      function fetch($result, $row, $field)
2607      {
2608          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2609              'Fetch: fetch result method not implemented'));
2610      }
2611  
2612      // }}}
2613      // {{{ fetchLob()
2614  
2615      /**
2616       * fetch a lob value from a result set
2617       *
2618       * @param resource $result result identifier
2619       * @param int $row number of the row where the data can be found
2620       * @param int $field field number where the data can be found
2621       * @return mixed string on success, a MDB error on failure
2622       * @access public
2623       */
2624      function fetchLob($result, $row, $field)
2625      {
2626          $lob = count($this->lobs) + 1;
2627          $this->lobs[$lob] = array(
2628              'Result' => $result,
2629              'Row' => $row,
2630              'Field' => $field,
2631              'Position' => 0
2632          );
2633          $dst_lob = array(
2634              'Database' => $this,
2635              'Error' => '',
2636              'Type' => 'resultlob',
2637              'ResultLOB' => $lob
2638          );
2639          if (MDB::isError($lob = $this->createLob($dst_lob))) {
2640              return($this->raiseError(MDB_ERROR, NULL, NULL,
2641                  'Fetch LOB result: ' . $dst_lob['Error']));
2642          }
2643          return($lob);
2644      }
2645  
2646      // }}}
2647      // {{{ _retrieveLob()
2648  
2649      /**
2650       * fetch a float value from a result set
2651       *
2652       * @param int $lob handle to a lob created by the createLob() function
2653       * @return mixed MDB_OK on success, a MDB error on failure
2654       * @access private
2655       */
2656      function _retrieveLob($lob)
2657      {
2658          if (!isset($this->lobs[$lob])) {
2659              return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
2660                  'Fetch LOB result: it was not specified a valid lob'));
2661          }
2662          if (!isset($this->lobs[$lob]['Value'])) {
2663              $this->lobs[$lob]['Value'] = $this->fetch($this->lobs[$lob]['Result'], $this->lobs[$lob]['Row'], $this->lobs[$lob]['Field']);
2664          }
2665          return(MDB_OK);
2666      }
2667  
2668      // }}}
2669      // {{{ endOfResultLob()
2670  
2671      /**
2672       * Determine whether it was reached the end of the large object and
2673       * therefore there is no more data to be read for the its input stream.
2674       *
2675       * @param int $lob handle to a lob created by the createLob() function
2676       * @return mixed TRUE or FALSE on success, a MDB error on failure
2677       * @access public
2678       */
2679      function endOfResultLob($lob)
2680      {
2681          $result = $this->_retrieveLob($lob);
2682          if (MDB::isError($result)) {
2683              return($result);
2684          }
2685          return($this->lobs[$lob]['Position'] >= strlen($this->lobs[$lob]['Value']));
2686      }
2687  
2688      // }}}
2689      // {{{ _readResultLob()
2690  
2691      /**
2692       * Read data from large object input stream.
2693       *
2694       * @param int $lob handle to a lob created by the createLob() function
2695       * @param blob $data reference to a variable that will hold data to be
2696       *       read from the large object input stream
2697       * @param int $length integer value that indicates the largest ammount of
2698       *       data to be read from the large object input stream.
2699       * @return mixed length on success, a MDB error on failure
2700       * @access private
2701       */
2702      function _readResultLob($lob, &$data, $length)
2703      {
2704          $result = $this->_retrieveLob($lob);
2705          if (MDB::isError($result)) {
2706              return($result);
2707          }
2708          $length = min($length, strlen($this->lobs[$lob]['Value']) - $this->lobs[$lob]['Position']);
2709          $data = substr($this->lobs[$lob]['Value'], $this->lobs[$lob]['Position'], $length);
2710          $this->lobs[$lob]['Position'] += $length;
2711          return($length);
2712      }
2713  
2714      // }}}
2715      // {{{ _destroyResultLob()
2716  
2717      /**
2718       * Free any resources allocated during the lifetime of the large object
2719       * handler object.
2720       *
2721       * @param int $lob handle to a lob created by the createLob() function
2722       * @access private
2723       */
2724      function _destroyResultLob($lob)
2725      {
2726          if (isset($this->lobs[$lob])) {
2727              $this->lobs[$lob] = '';
2728          }
2729      }
2730  
2731      // }}}
2732      // {{{ fetchClob()
2733  
2734      /**
2735       * fetch a clob value from a result set
2736       *
2737       * @param resource $result result identifier
2738       * @param int $row number of the row where the data can be found
2739       * @param int $field field number where the data can be found
2740       * @return mixed content of the specified data cell, a MDB error on failure,
2741       *        a MDB error on failure
2742       * @access public
2743       */
2744      function fetchClob($result, $row, $field)
2745      {
2746          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2747              'fetch clob result method is not implemented'));
2748      }
2749  
2750      // }}}
2751      // {{{ fetchBlob()
2752  
2753      /**
2754       * fetch a blob value from a result set
2755       *
2756       * @param resource $result result identifier
2757       * @param int $row number of the row where the data can be found
2758       * @param int $field field number where the data can be found
2759       * @return mixed content of the specified data cell, a MDB error on failure
2760       * @access public
2761       */
2762      function fetchBlob($result, $row, $field)
2763      {
2764          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
2765              'fetch blob result method is not implemented'));
2766      }
2767  
2768      // }}}
2769      // {{{ resultIsNull()
2770  
2771      /**
2772       * Determine whether the value of a query result located in given row and
2773       *    field is a NULL.
2774       *
2775       * @param resource $result result identifier
2776       * @param int $row number of the row where the data can be found
2777       * @param int $field field number where the data can be found
2778       * @return mixed TRUE or FALSE on success, a MDB error on failure
2779       * @access public
2780       */
2781      function resultIsNull($result, $row, $field)
2782      {
2783          $result = $this->fetch($result, $row, $field);
2784          if (MDB::isError($result)) {
2785              return($result);
2786          }
2787          return(!isset($result));
2788      }
2789  
2790      // }}}
2791      // {{{ _baseConvertResult()
2792  
2793      /**
2794       * general type conversion method
2795       *
2796       * @param mixed $value refernce to a value to be converted
2797       * @param int $type constant that specifies which type to convert to
2798       * @return object a MDB error on failure
2799       * @access private
2800       */
2801      function _baseConvertResult($value, $type)
2802      {
2803          switch ($type) {
2804              case MDB_TYPE_TEXT:
2805                  return($value);
2806              case MDB_TYPE_BLOB:
2807                  return($value);
2808              case MDB_TYPE_CLOB:
2809                  return($value);
2810              case MDB_TYPE_INTEGER:
2811                  return(intval($value));
2812              case MDB_TYPE_BOOLEAN:
2813                  return ($value == 'Y') ? TRUE : FALSE;
2814              case MDB_TYPE_DECIMAL:
2815                  return($value);
2816              case MDB_TYPE_FLOAT:
2817                  return(doubleval($value));
2818              case MDB_TYPE_DATE:
2819                  return($value);
2820              case MDB_TYPE_TIME:
2821                  return($value);
2822              case MDB_TYPE_TIMESTAMP:
2823                  return($value);
2824              case MDB_TYPE_CLOB:
2825                  return($value);
2826              case MDB_TYPE_BLOB:
2827                  return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
2828                      'BaseConvertResult: attempt to convert result value to an unsupported type ' . $type));
2829              default:
2830                  return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
2831                      'BaseConvertResult: attempt to convert result value to an unknown type ' . $type));
2832          }
2833      }
2834  
2835      // }}}
2836      // {{{ convertResult()
2837  
2838      /**
2839       * convert a value to a RDBMS indepdenant MDB type
2840       *
2841       * @param mixed $value value to be converted
2842       * @param int $type constant that specifies which type to convert to
2843       * @return mixed converted value or a MDB error on failure
2844       * @access public
2845       */
2846      function convertResult($value, $type)
2847      {
2848          return($this->_baseConvertResult($value, $type));
2849      }
2850  
2851      // }}}
2852      // {{{ convertResultRow()
2853  
2854      /**
2855       * convert a result row
2856       *
2857       * @param resource $result result identifier
2858       * @param array $row array with data
2859       * @return mixed MDB_OK on success,  a MDB error on failure
2860       * @access public
2861       */
2862      function convertResultRow($result, $row)
2863      {
2864          $result_value = intval($result);
2865          if (isset($this->result_types[$result_value])) {
2866              $current_column = -1;
2867              foreach($row as $key => $column) {
2868                  ++$current_column;
2869                  if (!isset($this->result_types[$result_value][$current_column])
2870                     ||!isset($column)
2871                  ) {
2872                      continue;
2873                  }
2874                  switch ($type = $this->result_types[$result_value][$current_column]) {
2875                      case MDB_TYPE_TEXT:
2876                      case MDB_TYPE_BLOB:
2877                      case MDB_TYPE_CLOB:
2878                          break;
2879                      case MDB_TYPE_INTEGER:
2880                          $row[$key] = intval($row[$key]);
2881                          break;
2882                      default:
2883                          $value = $this->convertResult($row[$key], $type);
2884                          if (MDB::isError($value)) {
2885                              return $value;
2886                          }
2887                          $row[$key] = $value;
2888                          break;
2889                  }
2890              }
2891          }
2892          return ($row);
2893      }
2894  
2895      // }}}
2896      // {{{ fetchDate()
2897  
2898      /**
2899       * fetch a date value from a result set
2900       *
2901       * @param resource $result result identifier
2902       * @param int $row number of the row where the data can be found
2903       * @param int $field field number where the data can be found
2904       * @return mixed content of the specified data cell, a MDB error on failure
2905       * @access public
2906       */
2907      function fetchDate($result, $row, $field)
2908      {
2909          $value = $this->fetch($result, $row, $field);
2910          return($this->convertResult($value, MDB_TYPE_DATE));
2911      }
2912  
2913      // }}}
2914      // {{{ fetchTimestamp()
2915  
2916      /**
2917       * fetch a timestamp value from a result set
2918       *
2919       * @param resource $result result identifier
2920       * @param int $row number of the row where the data can be found
2921       * @param int $field field number where the data can be found
2922       * @return mixed content of the specified data cell, a MDB error on failure
2923       * @access public
2924       */
2925      function fetchTimestamp($result, $row, $field)
2926      {
2927          $value = $this->fetch($result, $row, $field);
2928          return($this->convertResult($value, MDB_TYPE_TIMESTAMP));
2929      }
2930  
2931      // }}}
2932      // {{{ fetchTime()
2933  
2934      /**
2935       * fetch a time value from a result set
2936       *
2937       * @param resource $result result identifier
2938       * @param int $row number of the row where the data can be found
2939       * @param int $field field number where the data can be found
2940       * @return mixed content of the specified data cell, a MDB error on failure
2941       * @access public
2942       */
2943      function fetchTime($result, $row, $field)
2944      {
2945          $value = $this->fetch($result, $row, $field);
2946          return($this->convertResult($value, MDB_TYPE_TIME));
2947      }
2948  
2949      // }}}
2950      // {{{ fetchBoolean()
2951  
2952      /**
2953       * fetch a boolean value from a result set
2954       *
2955       * @param resource $result result identifier
2956       * @param int $row number of the row where the data can be found
2957       * @param int $field field number where the data can be found
2958       * @return mixed content of the specified data cell, a MDB error on failure
2959       * @access public
2960       */
2961      function fetchBoolean($result, $row, $field)
2962      {
2963          $value = $this->fetch($result, $row, $field);
2964          return($this->convertResult($value, MDB_TYPE_BOOLEAN));
2965      }
2966  
2967      // }}}
2968      // {{{ fetchFloat()
2969  
2970      /**
2971       * fetch a float value from a result set
2972       *
2973       * @param resource $result result identifier
2974       * @param int $row number of the row where the data can be found
2975       * @param int $field field number where the data can be found
2976       * @return mixed content of the specified data cell, a MDB error on failure
2977       * @access public
2978       */
2979      function fetchFloat($result, $row, $field)
2980      {
2981          $value = $this->fetch($result, $row, $field);
2982          return($this->convertResult($value, MDB_TYPE_FLOAT));
2983      }
2984  
2985      // }}}
2986      // {{{ fetchDecimal()
2987  
2988      /**
2989       * fetch a decimal value from a result set
2990       *
2991       * @param resource $result result identifier
2992       * @param int $row number of the row where the data can be found
2993       * @param int $field field number where the data can be found
2994       * @return mixed content of the specified data cell, a MDB error on failure
2995       * @access public
2996       */
2997      function fetchDecimal($result, $row, $field)
2998      {
2999          $value = $this->fetch($result, $row, $field);
3000          return($this->convertResult($value, MDB_TYPE_DECIMAL));
3001      }
3002  
3003      // }}}
3004      // {{{ numRows()
3005  
3006      /**
3007       * returns the number of rows in a result object
3008       *
3009       * @param ressource $result a valid result ressouce pointer
3010       * @return mixed MDB_Error or the number of rows
3011       * @access public
3012       */
3013      function numRows($result)
3014      {
3015          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Num Rows: number of rows method not implemented'));
3016      }
3017  
3018      // }}}
3019      // {{{ freeResult()
3020  
3021      /**
3022       * Free the internal resources associated with $result.
3023       *
3024       * @param  $result result identifier
3025       * @return boolean TRUE on success, FALSE if $result is invalid
3026       * @access public
3027       */
3028      function freeResult($result)
3029      {
3030          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Free Result: free result method not implemented'));
3031      }
3032  
3033      // }}}
3034      // {{{ getIntegerDeclaration()
3035  
3036      /**
3037       * Obtain DBMS specific SQL code portion needed to declare an integer type
3038       * field to be used in statements like CREATE TABLE.
3039       *
3040       * @param string $name name the field to be declared.
3041       * @param string $field associative array with the name of the properties
3042       *       of the field being declared as array indexes. Currently, the types
3043       *       of supported field properties are as follows:
3044       *
3045       *       unsigned
3046       *           Boolean flag that indicates whether the field should be
3047       *           declared as unsigned integer if possible.
3048       *
3049       *       default
3050       *           Integer value to be used as default for this field.
3051       *
3052       *       notnull
3053       *           Boolean flag that indicates whether this field is constrained
3054       *           to not be set to NULL.
3055       * @return string DBMS specific SQL code portion that should be used to
3056       *       declare the specified field.
3057       * @access public
3058       */
3059      function getIntegerDeclaration($name, $field)
3060      {
3061          if (isset($field['unsigned'])) {
3062              $this->warnings[] = "unsigned integer field \"$name\" is being
3063                  declared as signed integer";
3064          }
3065          return("$name INT" . (isset($field['default']) ? ' DEFAULT ' . $field['default'] : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3066      }
3067  
3068      // }}}
3069      // {{{ getTextDeclaration()
3070  
3071      /**
3072       * Obtain DBMS specific SQL code portion needed to declare an text type
3073       * field to be used in statements like CREATE TABLE.
3074       *
3075       * @param string $name name the field to be declared.
3076       * @param string $field associative array with the name of the properties
3077       *       of the field being declared as array indexes. Currently, the types
3078       *       of supported field properties are as follows:
3079       *
3080       *       length
3081       *           Integer value that determines the maximum length of the text
3082       *           field. If this argument is missing the field should be
3083       *           declared to have the longest length allowed by the DBMS.
3084       *
3085       *       default
3086       *           Text value to be used as default for this field.
3087       *
3088       *       notnull
3089       *           Boolean flag that indicates whether this field is constrained
3090       *           to not be set to NULL.
3091       * @return string DBMS specific SQL code portion that should be used to
3092       *       declare the specified field.
3093       * @access public
3094       */
3095      function getTextDeclaration($name, $field)
3096      {
3097          return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3098      }
3099  
3100      // }}}
3101      // {{{ getClobDeclaration()
3102  
3103      /**
3104       * Obtain DBMS specific SQL code portion needed to declare an character
3105       * large object type field to be used in statements like CREATE TABLE.
3106       *
3107       * @param string $name name the field to be declared.
3108       * @param string $field associative array with the name of the properties
3109       *       of the field being declared as array indexes. Currently, the types
3110       *       of supported field properties are as follows:
3111       *
3112       *       length
3113       *           Integer value that determines the maximum length of the large
3114       *           object field. If this argument is missing the field should be
3115       *           declared to have the longest length allowed by the DBMS.
3116       *
3117       *       notnull
3118       *           Boolean flag that indicates whether this field is constrained
3119       *           to not be set to NULL.
3120       * @return string DBMS specific SQL code portion that should be used to
3121       *       declare the specified field.
3122       * @access public
3123       */
3124      function getClobDeclaration($name, $field)
3125      {
3126          return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3127      }
3128  
3129      // }}}
3130      // {{{ getBlobDeclaration()
3131  
3132      /**
3133       * Obtain DBMS specific SQL code portion needed to declare an binary large
3134       * object type field to be used in statements like CREATE TABLE.
3135       *
3136       * @param string $name name the field to be declared.
3137       * @param string $field associative array with the name of the properties
3138       *       of the field being declared as array indexes. Currently, the types
3139       *       of supported field properties are as follows:
3140       *
3141       *       length
3142       *           Integer value that determines the maximum length of the large
3143       *           object field. If this argument is missing the field should be
3144       *           declared to have the longest length allowed by the DBMS.
3145       *
3146       *       notnull
3147       *           Boolean flag that indicates whether this field is constrained
3148       *           to not be set to NULL.
3149       * @return string DBMS specific SQL code portion that should be used to
3150       *       declare the specified field.
3151       * @access public
3152       */
3153      function getBlobDeclaration($name, $field)
3154      {
3155          return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3156      }
3157  
3158      // }}}
3159      // {{{ getBooleanDeclaration()
3160  
3161      /**
3162       * Obtain DBMS specific SQL code portion needed to declare a boolean type
3163       * field to be used in statements like CREATE TABLE.
3164       *
3165       * @param string $name name the field to be declared.
3166       * @param string $field associative array with the name of the properties
3167       *       of the field being declared as array indexes. Currently, the types
3168       *       of supported field properties are as follows:
3169       *
3170       *       default
3171       *           Boolean value to be used as default for this field.
3172       *
3173       *       notnullL
3174       *           Boolean flag that indicates whether this field is constrained
3175       *           to not be set to NULL.
3176       * @return string DBMS specific SQL code portion that should be used to
3177       *       declare the specified field.
3178       * @access public
3179       */
3180      function getBooleanDeclaration($name, $field)
3181      {
3182          return("$name CHAR (1)" . (isset($field['default']) ? ' DEFAULT ' . $this->getBooleanValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3183      }
3184  
3185      // }}}
3186      // {{{ getDateDeclaration()
3187  
3188      /**
3189       * Obtain DBMS specific SQL code portion needed to declare a date type
3190       * field to be used in statements like CREATE TABLE.
3191       *
3192       * @param string $name name the field to be declared.
3193       * @param string $field associative array with the name of the properties
3194       *       of the field being declared as array indexes. Currently, the types
3195       *       of supported field properties are as follows:
3196       *
3197       *       default
3198       *           Date value to be used as default for this field.
3199       *
3200       *       notnull
3201       *           Boolean flag that indicates whether this field is constrained
3202       *           to not be set to NULL.
3203       * @return string DBMS specific SQL code portion that should be used to
3204       *       declare the specified field.
3205       * @access public
3206       */
3207      function getDateDeclaration($name, $field)
3208      {
3209          return("$name CHAR (" . strlen("YYYY-MM-DD") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getDateValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3210      }
3211  
3212      // }}}
3213      // {{{ getTimestampDeclaration()
3214  
3215      /**
3216       * Obtain DBMS specific SQL code portion needed to declare a timestamp
3217       * field to be used in statements like CREATE TABLE.
3218       *
3219       * @param string $name name the field to be declared.
3220       * @param string $field associative array with the name of the properties
3221       *       of the field being declared as array indexes. Currently, the types
3222       *       of supported field properties are as follows:
3223       *
3224       *       default
3225       *           Timestamp value to be used as default for this field.
3226       *
3227       *       notnull
3228       *           Boolean flag that indicates whether this field is constrained
3229       *           to not be set to NULL.
3230       * @return string DBMS specific SQL code portion that should be used to
3231       *       declare the specified field.
3232       * @access public
3233       */
3234      function getTimestampDeclaration($name, $field)
3235      {
3236          return("$name CHAR (" . strlen("YYYY-MM-DD HH:MM:SS") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getTimestampValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3237      }
3238  
3239      // }}}
3240      // {{{ getTimeDeclaration()
3241  
3242      /**
3243       * Obtain DBMS specific SQL code portion needed to declare a time
3244       * field to be used in statements like CREATE TABLE.
3245       *
3246       * @param string $name name the field to be declared.
3247       * @param string $field associative array with the name of the properties
3248       *       of the field being declared as array indexes. Currently, the types
3249       *       of supported field properties are as follows:
3250       *
3251       *       default
3252       *           Time value to be used as default for this field.
3253       *
3254       *       notnull
3255       *           Boolean flag that indicates whether this field is constrained
3256       *           to not be set to NULL.
3257       * @return string DBMS specific SQL code portion that should be used to
3258       *       declare the specified field.
3259       * @access public
3260       */
3261      function getTimeDeclaration($name, $field)
3262      {
3263          return("$name CHAR (" . strlen("HH:MM:SS") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getTimeValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3264      }
3265  
3266      // }}}
3267      // {{{ getFloatDeclaration()
3268  
3269      /**
3270       * Obtain DBMS specific SQL code portion needed to declare a float type
3271       * field to be used in statements like CREATE TABLE.
3272       *
3273       * @param string $name name the field to be declared.
3274       * @param string $field associative array with the name of the properties
3275       *       of the field being declared as array indexes. Currently, the types
3276       *       of supported field properties are as follows:
3277       *
3278       *       default
3279       *           Float value to be used as default for this field.
3280       *
3281       *       notnull
3282       *           Boolean flag that indicates whether this field is constrained
3283       *           to not be set to NULL.
3284       * @return string DBMS specific SQL code portion that should be used to
3285       *       declare the specified field.
3286       * @access public
3287       */
3288      function getFloatDeclaration($name, $field)
3289      {
3290          return("$name TEXT " . (isset($field['default']) ? ' DEFAULT ' . $this->getFloatValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3291      }
3292  
3293      // }}}
3294      // {{{ getDecimalDeclaration()
3295  
3296      /**
3297       * Obtain DBMS specific SQL code portion needed to declare a decimal type
3298       * field to be used in statements like CREATE TABLE.
3299       *
3300       * @param string $name name the field to be declared.
3301       * @param string $field associative array with the name of the properties
3302       *       of the field being declared as array indexes. Currently, the types
3303       *       of supported field properties are as follows:
3304       *
3305       *       default
3306       *           Decimal value to be used as default for this field.
3307       *
3308       *       notnull
3309       *           Boolean flag that indicates whether this field is constrained
3310       *           to not be set to NULL.
3311       * @return string DBMS specific SQL code portion that should be used to
3312       *       declare the specified field.
3313       * @access public
3314       */
3315      function getDecimalDeclaration($name, $field)
3316      {
3317          return("$name TEXT " . (isset($field['default']) ? ' DEFAULT ' . $this->getDecimalValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
3318      }
3319  
3320      // }}}
3321      // {{{ getIntegerValue()
3322  
3323      /**
3324       * Convert a text value into a DBMS specific format that is suitable to
3325       * compose query statements.
3326       *
3327       * @param string $value text string value that is intended to be converted.
3328       * @return string text string that represents the given argument value in
3329       *       a DBMS specific format.
3330       * @access public
3331       */
3332      function getIntegerValue($value)
3333      {
3334          return(($value === NULL) ? 'NULL' : (int)$value);
3335      }
3336  
3337      // }}}
3338      // {{{ getTextValue()
3339  
3340      /**
3341       * Convert a text value into a DBMS specific format that is suitable to
3342       * compose query statements.
3343       *
3344       * @param string $value text string value that is intended to be converted.
3345       * @return string text string that already contains any DBMS specific
3346       *       escaped character sequences.
3347       * @access public
3348       */
3349      function getTextValue($value)
3350      {
3351          return(($value === NULL) ? 'NULL' : "'".$this->_quote($value)."'");
3352      }
3353  
3354      // }}}
3355      // {{{ getClobValue()
3356  
3357      /**
3358       * Convert a text value into a DBMS specific format that is suitable to
3359       * compose query statements.
3360       *
3361       * @param resource $prepared_query query handle from prepare()
3362       * @param  $parameter
3363       * @param  $clob
3364       * @return string text string that represents the given argument value in
3365       *       a DBMS specific format.
3366       * @access public
3367       */
3368      function getClobValue($prepared_query, $parameter, $clob)
3369      {
3370          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
3371              'Get CLOB field value: prepared queries with values of type "clob" are not yet supported'));
3372      }
3373  
3374      // }}}
3375      // {{{ freeClobValue()
3376  
3377      /**
3378       * free a character large object
3379       *
3380       * @param resource $prepared_query query handle from prepare()
3381       * @param string $blob
3382       * @param string $value
3383       * @access public
3384       */
3385      function freeClobValue($prepared_query, $clob, &$value)
3386      {
3387      }
3388  
3389      // }}}
3390      // {{{ getBlobValue()
3391  
3392      /**
3393       * Convert a text value into a DBMS specific format that is suitable to
3394       * compose query statements.
3395       *
3396       * @param resource $prepared_query query handle from prepare()
3397       * @param  $parameter
3398       * @param  $blob
3399       * @return string text string that represents the given argument value in
3400       *       a DBMS specific format.
3401       * @access public
3402       */
3403      function getBlobValue($prepared_query, $parameter, $blob)
3404      {
3405          return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
3406              'Get BLOB field value: prepared queries with values of type "blob" are not yet supported'));
3407      }
3408  
3409      // }}}
3410      // {{{ freeBlobValue()
3411  
3412      /**
3413       * free a binary large object
3414       *
3415       * @param resource $prepared_query query handle from prepare()
3416       * @param string $blob
3417       * @param string $value
3418       * @access public
3419       */
3420      function freeBlobValue($prepared_query, $blob, &$value)
3421      {
3422      }
3423  
3424      // }}}
3425      // {{{ getBooleanValue()
3426  
3427      /**
3428       * Convert a text value into a DBMS specific format that is suitable to
3429       * compose query statements.
3430       *
3431       * @param string $value text string value that is intended to be converted.
3432       * @return string text string that represents the given argument value in
3433       *       a DBMS specific format.
3434       * @access public
3435       */
3436      function getBooleanValue($value)
3437      {
3438          return(($value === NULL) ? 'NULL' : ($value ? "'Y'" : "'N'"));
3439      }
3440  
3441      // }}}
3442      // {{{ getDateValue()
3443  
3444      /**
3445       * Convert a text value into a DBMS specific format that is suitable to
3446       * compose query statements.
3447       *
3448       * @param string $value text string value that is intended to be converted.
3449       * @return string text string that represents the given argument value in
3450       *       a DBMS specific format.
3451       * @access public
3452       */
3453      function getDateValue($value)
3454      {
3455          return(($value === NULL) ? 'NULL' : "'$value'");
3456      }
3457  
3458      // }}}
3459      // {{{ getTimestampValue()
3460  
3461      /**
3462       * Convert a text value into a DBMS specific format that is suitable to
3463       * compose query statements.
3464       *
3465       * @param string $value text string value that is intended to be converted.
3466       * @return string text string that represents the given argument value in
3467       *       a DBMS specific format.
3468       * @access public
3469       */
3470      function getTimestampValue($value)
3471      {
3472          return(($value === NULL) ? 'NULL' : "'$value'");
3473      }
3474  
3475      // }}}
3476      // {{{ getTimeValue()
3477  
3478      /**
3479       * Convert a text value into a DBMS specific format that is suitable to
3480       *       compose query statements.
3481       *
3482       * @param string $value text string value that is intended to be converted.
3483       * @return string text string that represents the given argument value in
3484       *       a DBMS specific format.
3485       * @access public
3486       */
3487      function getTimeValue($value)
3488      {
3489          return(($value === NULL) ? 'NULL' : "'$value'");
3490      }
3491  
3492      // }}}
3493      // {{{ getFloatValue()
3494  
3495      /**
3496       * Convert a text value into a DBMS specific format that is suitable to
3497       * compose query statements.
3498       *
3499       * @param string $value text string value that is intended to be converted.
3500       * @return string text string that represents the given argument value in
3501       *       a DBMS specific format.
3502       * @access public
3503       */
3504      function getFloatValue($value)
3505      {
3506          return(($value === NULL) ? 'NULL' : "'$value'");
3507      }
3508  
3509      // }}}
3510      // {{{ getDecimalValue()
3511  
3512      /**
3513       * Convert a text value into a DBMS specific format that is suitable to
3514       * compose query statements.
3515       *
3516       * @param string $value text string value that is intended to be converted.
3517       * @return string text string that represents the given argument value in
3518       *       a DBMS specific format.
3519       * @access public
3520       */
3521      function getDecimalValue($value)
3522      {
3523          return(($value === NULL) ? 'NULL' : "'$value'");
3524      }
3525  
3526      // }}}
3527      // {{{ getValue()
3528  
3529      /**
3530       * Convert a text value into a DBMS specific format that is suitable to
3531       * compose query statements.
3532       *
3533       * @param string $type type to which the value should be converted to
3534       * @param string $value text string value that is intended to be converted.
3535       * @return string text string that represents the given argument value in
3536       *       a DBMS specific format.
3537       * @access public
3538       */
3539      function getValue($type, $value)
3540      {
3541          if (empty($type)) {
3542              return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
3543                  'getValue: called without type to convert to'));
3544          }
3545          if (method_exists($this,"get{$type}Value")) {
3546              return $this->{"get{$type}Value"}($value);
3547          }
3548          return $value;
3549      }
3550  
3551      // }}}
3552      // {{{ support()
3553  
3554      /**
3555       * Tell whether a DB implementation or its backend extension
3556       * supports a given feature.
3557       *
3558       * @param string $feature name of the feature (see the MDB class doc)
3559       * @return boolean whether this DB implementation supports $feature
3560       * @access public
3561       */
3562      function support($feature)
3563      {
3564          return(isset($this->supported[$feature]) && $this->supported[$feature]);
3565      }
3566  
3567      // }}}
3568      // {{{ getSequenceName()
3569  
3570      /**
3571       * adds sequence name formating to a sequence name
3572       *
3573       * @param string $sqn name of the sequence
3574       * @return string formatted sequence name
3575       * @access public
3576       */
3577      function getSequenceName($sqn)
3578      {
3579          return sprintf($this->options['seqname_format'],
3580              preg_replace('/[^a-z0-9_]/i', '_', $sqn));
3581      }
3582  
3583      // }}}
3584      // {{{ nextId()
3585  
3586      /**
3587       * returns the next free id of a sequence
3588       *
3589       * @param string $seq_name name of the sequence
3590       * @param boolean $ondemand when TRUE the seqence is
3591       *                           automatic created, if it
3592       *                           not exists
3593       * @return mixed MDB_Error or id
3594       * @access public
3595       */
3596      function nextId($seq_name, $ondemand = FALSE)
3597      {
3598          return($this->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL,
3599              'Next Sequence: getting next sequence value not supported'));
3600      }
3601  
3602      // }}}
3603      // {{{ currId()
3604  
3605      /**
3606       * returns the current id of a sequence
3607       *
3608       * @param string $seq_name name of the sequence
3609       * @return mixed MDB_Error or id
3610       * @access public
3611       */
3612      function currId($seq_name)
3613      {
3614          $this->warnings[] = 'database does not support getting current
3615              sequence value, the sequence value was incremented';
3616          $this->expectError(MDB_ERROR_NOT_CAPABLE);
3617          $id = $this->nextId($seq_name);
3618          $this->popExpect(MDB_ERROR_NOT_CAPABLE);
3619          if (MDB::isError($id)) {
3620              if ($id->getCode() == MDB_ERROR_NOT_CAPABLE) {
3621                  return($this->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL,
3622                      'Current Sequence: getting current sequence value not supported'));
3623              }
3624              return($id);
3625          }
3626          return($id);
3627      }
3628  
3629      // }}}
3630      // {{{ fetchInto()
3631  
3632      /**
3633       * Fetch a row and return data in an array.
3634       *
3635       * @param resource $result result identifier
3636       * @param int $fetchmode ignored
3637       * @param int $rownum the row number to fetch
3638       * @return mixed data array or NULL on success, a MDB error on failure
3639       * @access public
3640       */
3641      function fetchInto($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL)
3642      {
3643          $result_value = intval($result);
3644          if (MDB::isError($this->endOfResult($result))) {
3645              $this->freeResult($result);
3646              $result = $this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
3647                  'Fetch field: result set is empty');
3648          }
3649          if ($rownum == NULL) {
3650              ++$this->highest_fetched_row[$result_value];
3651              $rownum = $this->highest_fetched_row[$result_value];
3652          } else {
3653              $this->highest_fetched_row[$result_value] =
3654                  max($this->highest_fetched_row[$result_value], $row);
3655          }
3656          if ($fetchmode == MDB_FETCHMODE_DEFAULT) {
3657              $fetchmode = $this->fetchmode;
3658          }
3659          $columns = $this->numCols($result);
3660          if (MDB::isError($columns)) {
3661              return($columns);
3662          }
3663          if ($fetchmode & MDB_FETCHMODE_ASSOC) {
3664              $column_names = $this->getColumnNames($result);
3665          }
3666          for($column = 0; $column < $columns; $column++) {
3667              if (!$this->resultIsNull($result, $rownum, $column)) {
3668                  $value = $this->fetch($result, $rownum, $column);
3669                  if ($value === FALSE) {
3670                      if ($this->options['autofree']) {
3671                          $this->freeResult($result);
3672                      }
3673                      return(NULL);
3674                  } elseif (MDB::isError($value)) {
3675                      if ($value->getMessage() == '') {
3676                          if ($this->options['autofree']) {
3677                              $this->freeResult($result);
3678                          }
3679                          return(NULL);
3680                      } else {
3681                          return($value);
3682                      }
3683                  }
3684              }
3685              $row[$column] = $value;
3686          }
3687          if ($fetchmode & MDB_FETCHMODE_ASSOC) {
3688              $row = array_combine($column_names, $row);
3689              if (is_array($row) && $this->options['optimize'] == 'portability') {
3690                  $row = array_change_key_case($row, CASE_LOWER);
3691              }
3692          }
3693          if (isset($this->result_types[$result_value])) {
3694              $row = $this->convertResultRow($result, $row);
3695          }
3696          return($row);
3697      }
3698  
3699      // }}}
3700      // {{{ fetchOne()
3701  
3702      /**
3703       * Fetch and return a field of data (it uses fetchInto for that)
3704       *
3705       * @param resource $result result identifier
3706       * @return mixed data on success, a MDB error on failure
3707       * @access public
3708       */
3709      function fetchOne($result)
3710      {
3711          $row = $this->fetchInto($result, MDB_FETCHMODE_ORDERED);
3712          if (!$this->options['autofree'] || $row != NULL) {
3713              $this->freeResult($result);
3714          }
3715          if (is_array($row)) {
3716              return($row[0]);
3717          }
3718          return($row);
3719      }
3720  
3721      // }}}
3722      // {{{ fetchRow()
3723  
3724      /**
3725       * Fetch and return a row of data (it uses fetchInto for that)
3726       *
3727       * @param resource $result result identifier
3728       * @param int $fetchmode how the array data should be indexed
3729       * @param int $rownum the row number to fetch
3730       * @return mixed data array on success, a MDB error on failure
3731       * @access public
3732       */
3733      function fetchRow($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL)
3734      {
3735          $row = $this->fetchInto($result, $fetchmode, $rownum);
3736          if (!$this->options['autofree'] || $row != NULL) {
3737              $this->freeResult($result);
3738          }
3739          return($row);
3740      }
3741  
3742      // }}}
3743      // {{{ fetchCol()
3744  
3745      /**
3746       * Fetch and return a column of data (it uses fetchInto for that)
3747       *
3748       * @param resource $result result identifier
3749       * @param int $colnum the row number to fetch
3750       * @return mixed data array on success, a MDB error on failure
3751       * @access public
3752       */
3753      function fetchCol($result, $colnum = 0)
3754      {
3755          $fetchmode = is_numeric($colnum) ? MDB_FETCHMODE_ORDERED : MDB_FETCHMODE_ASSOC;
3756          $column = array();
3757          $row = $this->fetchInto($result, $fetchmode);
3758          if (is_array($row)) {
3759              if (!array_key_exists($colnum, $row)) {
3760                  return($this->raiseError(MDB_ERROR_TRUNCATED));
3761              }
3762              do {
3763                  $column[] = $row[$colnum];
3764              } while (is_array($row = $this->fetchInto($result, $fetchmode)));
3765          }
3766          if (!$this->options['autofree']) {
3767              $this->freeResult($result);
3768          }
3769          if (MDB::isError($row)) {
3770              return($row);
3771          }
3772          return($column);
3773      }
3774  
3775      // }}}
3776      // {{{ fetchAll()
3777  
3778      /**
3779       * Fetch and return a column of data (it uses fetchInto for that)
3780       *
3781       * @param resource $result result identifier
3782       * @param int $fetchmode how the array data should be indexed
3783       * @param boolean $rekey if set to TRUE, the $all will have the first
3784       *       column as its first dimension
3785       * @param boolean $force_array used only when the query returns exactly
3786       *       two columns. If TRUE, the values of the returned array will be
3787       *       one-element arrays instead of scalars.
3788       * @param boolean $group if TRUE, the values of the returned array is
3789       *       wrapped in another array.  If the same key value (in the first
3790       *       column) repeats itself, the values will be appended to this array
3791       *       instead of overwriting the existing values.
3792       * @return mixed data array on success, a MDB error on failure
3793       * @access public
3794       * @see getAssoc()
3795       */
3796      function fetchAll($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rekey = FALSE, $force_array = FALSE, $group = FALSE)
3797      {
3798          if ($rekey) {
3799              $cols = $this->numCols($result);
3800              if (MDB::isError($cols)) {
3801                  return($cols);
3802              }
3803              if ($cols < 2) {
3804                  return($this->raiseError(MDB_ERROR_TRUNCATED));
3805              }
3806          }
3807          $all = array();
3808          while (is_array($row = $this->fetchInto($result, $fetchmode))) {
3809              if ($rekey) {
3810                  if ($fetchmode & MDB_FETCHMODE_ASSOC) {
3811                      $key = reset($row);
3812                      unset($row[key($row)]);
3813                  } else {
3814                      $key = array_shift($row);
3815                  }
3816                  if (!$force_array && count($row) == 1) {
3817                      $row = array_shift($row);
3818                  }
3819                  if ($group) {
3820                      $all[$key][] = $row;
3821                  } else {
3822                      $all[$key] = $row;
3823                  }
3824              } else {
3825                  if ($fetchmode & MDB_FETCHMODE_FLIPPED) {
3826                      foreach ($row as $key => $val) {
3827                          $all[$key][] = $val;
3828                      }
3829                  } else {
3830                     $all[] = $row;
3831                  }
3832              }
3833          }
3834          if (!$this->options['autofree']) {
3835              $this->freeResult($result);
3836          }
3837          if (MDB::isError($row)) {
3838              return($row);
3839          }
3840          return($all);
3841      }
3842  
3843      // }}}
3844      // {{{ queryOne()
3845  
3846      /**
3847       * Execute the specified query, fetch the value from the first column of
3848       * the first row of the result set and then frees
3849       * the result set.
3850       *
3851       * @param string $query the SELECT query statement to be executed.
3852       * @param string $type optional argument that specifies the expected
3853       *       datatype of the result set field, so that an eventual conversion
3854       *       may be performed. The default datatype is text, meaning that no
3855       *       conversion is performed
3856       * @return mixed field value on success, a MDB error on failure
3857       * @access public
3858       */
3859      function queryOne($query, $type = NULL)
3860      {
3861          if ($type != NULL) {
3862              $type = array($type);
3863          }
3864          $result = $this->query($query, $type);
3865          if (MDB::isError($result)) {
3866              return($result);
3867          }
3868          return($this->fetchOne($result));
3869      }
3870  
3871      // }}}
3872      // {{{ queryRow()
3873  
3874      /**
3875       * Execute the specified query, fetch the values from the first
3876       * row of the result set into an array and then frees
3877       * the result set.
3878       *
3879       * @param string $query the SELECT query statement to be executed.
3880       * @param array $types optional array argument that specifies a list of
3881       *       expected datatypes of the result set columns, so that the eventual
3882       *       conversions may be performed. The default list of datatypes is
3883       *       empty, meaning that no conversion is performed.
3884       * @param int $fetchmode how the array data should be indexed
3885       * @return mixed data array on success, a MDB error on failure
3886       * @access public
3887       */
3888      function queryRow($query, $types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
3889      {
3890          $result = $this->query($query, $types);
3891          if (MDB::isError($result)) {
3892              return($result);
3893          }
3894          return($this->fetchRow($result, $fetchmode));
3895      }
3896  
3897      // }}}
3898      // {{{ queryCol()
3899  
3900      /**
3901       * Execute the specified query, fetch the value from the first column of
3902       * each row of the result set into an array and then frees the result set.
3903       *
3904       * @param string $query the SELECT query statement to be executed.
3905       * @param string $type optional argument that specifies the expected
3906       *       datatype of the result set field, so that an eventual conversion
3907       *       may be performed. The default datatype is text, meaning that no
3908       *       conversion is performed
3909       * @param int $colnum the row number to fetch
3910       * @return mixed data array on success, a MDB error on failure
3911       * @access public
3912       */
3913      function queryCol($query, $type = NULL, $colnum = 0)
3914      {
3915          if ($type != NULL) {
3916              $type = array($type);
3917          }
3918          $result = $this->query($query, $type);
3919          if (MDB::isError($result)) {
3920              return($result);
3921          }
3922          return($this->fetchCol($result, $colnum));
3923      }
3924  
3925      // }}}
3926      // {{{ queryAll()
3927  
3928      /**
3929       * Execute the specified query, fetch all the rows of the result set into
3930       * a two dimensional array and then frees the result set.
3931       *
3932       * @param string $query the SELECT query statement to be executed.
3933       * @param array $types optional array argument that specifies a list of
3934       *       expected datatypes of the result set columns, so that the eventual
3935       *       conversions may be performed. The default list of datatypes is
3936       *       empty, meaning that no conversion is performed.
3937       * @param int $fetchmode how the array data should be indexed
3938       * @param boolean $rekey if set to TRUE, the $all will have the first
3939       *       column as its first dimension
3940       * @param boolean $force_array used only when the query returns exactly
3941       *       two columns. If TRUE, the values of the returned array will be
3942       *       one-element arrays instead of scalars.
3943       * @param boolean $group if TRUE, the values of the returned array is
3944       *       wrapped in another array.  If the same key value (in the first
3945       *       column) repeats itself, the values will be appended to this array
3946       *       instead of overwriting the existing values.
3947       * @return mixed data array on success, a MDB error on failure
3948       * @access public
3949       */
3950      function queryAll($query, $types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT,
3951          $rekey = FALSE, $force_array = FALSE, $group = FALSE)
3952      {
3953          if (MDB::isError($result = $this->query($query, $types))) {
3954              return($result);
3955          }
3956          return($this->fetchAll($result, $fetchmode, $rekey, $force_array, $group));
3957      }
3958  
3959      // }}}
3960      // {{{ getOne()
3961  
3962      /**
3963       * Fetch the first column of the first row of data returned from
3964       * a query.  Takes care of doing the query and freeing the results
3965       * when finished.
3966       *
3967       * @param string $query the SQL query
3968       * @param string $type string that contains the type of the column in the
3969       *       result set
3970       * @param array $params if supplied, prepare/execute will be used
3971       *       with this array as execute parameters
3972       * @param array $param_types array that contains the types of the values
3973       *       defined in $params
3974       * @return mixed MDB_Error or the returned value of the query
3975       * @access public
3976       */
3977      function getOne($query, $type = NULL, $params = array(), $param_types = NULL)
3978      {
3979          if ($type != NULL) {
3980              $type = array($type);
3981          }
3982          settype($params, 'array');
3983          if (count($params) > 0) {
3984              $prepared_query = $this->prepareQuery($query);
3985              if (MDB::isError($prepared_query)) {
3986                  return($prepared_query);
3987              }
3988              $this->setParamArray($prepared_query, $params, $param_types);
3989              $result = $this->executeQuery($prepared_query, $type);
3990          } else {
3991              $result = $this->query($query, $type);
3992          }
3993  
3994          if (MDB::isError($result)) {
3995              return($result);
3996          }
3997  
3998          $value = $this->fetchOne($result, MDB_FETCHMODE_ORDERED);
3999          if (MDB::isError($value)) {
4000              return($value);
4001          }
4002          if (isset($prepared_query)) {
4003              $result = $this->freePreparedQuery($prepared_query);
4004              if (MDB::isError($result)) {
4005                  return($result);
4006              }
4007          }
4008  
4009          return($value);
4010      }
4011  
4012      // }}}
4013      // {{{ getRow()
4014  
4015      /**
4016       * Fetch the first row of data returned from a query.  Takes care
4017       * of doing the query and freeing the results when finished.
4018       *
4019       * @param string $query the SQL query
4020       * @param array $types array that contains the types of the columns in
4021       *       the result set
4022       * @param array $params array if supplied, prepare/execute will be used
4023       *       with this array as execute parameters
4024       * @param array $param_types array that contains the types of the values
4025       *       defined in $params
4026       * @param integer $fetchmode the fetch mode to use
4027       * @return array the first row of results as an array indexed from
4028       * 0, or a MDB error code.
4029       * @access public
4030       */
4031      function getRow($query, $types = NULL, $params = array(), $param_types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
4032      {
4033          settype($params, 'array');
4034          if (count($params) > 0) {
4035              $prepared_query = $this->prepareQuery($query);
4036              if (MDB::isError($prepared_query)) {
4037                  return($prepared_query);
4038              }
4039              $this->setParamArray($prepared_query, $params, $param_types);
4040              $result = $this->executeQuery($prepared_query, $types);
4041          } else {
4042              $result = $this->query($query, $types);
4043          }
4044  
4045          if (MDB::isError($result)) {
4046              return($result);
4047          }
4048  
4049          $row = $this->fetchRow($result, $fetchmode);
4050          if (MDB::isError($row)) {
4051              return($row);
4052          }
4053          if (isset($prepared_query)) {
4054              $result = $this->freePreparedQuery($prepared_query);
4055              if (MDB::isError($result)) {
4056                  return($result);
4057              }
4058          }
4059  
4060          return($row);
4061      }
4062  
4063      // }}}
4064      // {{{ getCol()
4065  
4066      /**
4067       * Fetch a single column from a result set and return it as an
4068       * indexed array.
4069       *
4070       * @param string $query the SQL query
4071       * @param string $type string that contains the type of the column in the
4072       *       result set
4073       * @param array $params array if supplied, prepare/execute will be used
4074       *       with this array as execute parameters
4075       * @param array $param_types array that contains the types of the values
4076       *       defined in $params
4077       * @param mixed $colnum which column to return(integer [column number,
4078       *       starting at 0] or string [column name])
4079       * @return array an indexed array with the data from the first
4080       * row at index 0, or a MDB error code.
4081       * @access public
4082       */
4083      function getCol($query, $type = NULL, $params = array(), $param_types = NULL, $colnum = 0)
4084      {
4085          if ($type != NULL) {
4086              $type = array($type);
4087          }
4088          settype($params, 'array');
4089          if (count($params) > 0) {
4090              $prepared_query = $this->prepareQuery($query);
4091  
4092              if (MDB::isError($prepared_query)) {
4093                  return($prepared_query);
4094              }
4095              $this->setParamArray($prepared_query, $params, $param_types);
4096              $result = $this->executeQuery($prepared_query, $type);
4097          } else {
4098              $result = $this->query($query, $type);
4099          }
4100  
4101          if (MDB::isError($result)) {
4102              return($result);
4103          }
4104  
4105          $col = $this->fetchCol($result, $colnum);
4106          if (MDB::isError($col)) {
4107              return($col);
4108          }
4109          if (isset($prepared_query)) {
4110              $result = $this->freePreparedQuery($prepared_query);
4111              if (MDB::isError($result)) {
4112                  return($result);
4113              }
4114          }
4115          return($col);
4116      }
4117  
4118      // }}}
4119      // {{{ getAssoc()
4120  
4121      /**
4122       * Fetch the entire result set of a query and return it as an
4123       * associative array using the first column as the key.
4124       *
4125       * If the result set contains more than two columns, the value
4126       * will be an array of the values from column 2-n.  If the result
4127       * set contains only two columns, the returned value will be a
4128       * scalar with the value of the second column (unless forced to an
4129       * array with the $force_array parameter).  A MDB error code is
4130       * returned on errors.  If the result set contains fewer than two
4131       * columns, a MDB_ERROR_TRUNCATED error is returned.
4132       *
4133       * For example, if the table 'mytable' contains:
4134       *
4135       *   ID      TEXT       DATE
4136       * --------------------------------
4137       *   1       'one'      944679408
4138       *   2       'two'      944679408
4139       *   3       'three'    944679408
4140       *
4141       * Then the call getAssoc('SELECT id,text FROM mytable') returns:
4142       *    array(
4143       *      '1' => 'one',
4144       *      '2' => 'two',
4145       *      '3' => 'three',
4146       *    )
4147       *
4148       * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
4149       *    array(
4150       *      '1' => array('one', '944679408'),
4151       *      '2' => array('two', '944679408'),
4152       *      '3' => array('three', '944679408')
4153       *    )
4154       *
4155       * If the more than one row occurs with the same value in the
4156       * first column, the last row overwrites all previous ones by
4157       * default.  Use the $group parameter if you don't want to
4158       * overwrite like this.  Example:
4159       *
4160       * getAssoc('SELECT category,id,name FROM mytable', NULL, NULL
4161       *           MDB_FETCHMODE_ASSOC, FALSE, TRUE) returns:
4162       *    array(
4163       *      '1' => array(array('id' => '4', 'name' => 'number four'),
4164       *                   array('id' => '6', 'name' => 'number six')
4165       *             ),
4166       *      '9' => array(array('id' => '4', 'name' => 'number four'),
4167       *                   array('id' => '6', 'name' => 'number six')
4168       *             )
4169       *    )
4170       *
4171       * Keep in mind that database functions in PHP usually return string
4172       * values for results regardless of the database's internal type.
4173       *
4174       * @param string $query the SQL query
4175       * @param array $types array that contains the types of the columns in
4176       *       the result set
4177       * @param array $params array if supplied, prepare/execute will be used
4178       *       with this array as execute parameters
4179       * @param array $param_types array that contains the types of the values
4180       *       defined in $params
4181       * @param boolean $force_array used only when the query returns
4182       * exactly two columns.  If TRUE, the values of the returned array
4183       * will be one-element arrays instead of scalars.
4184       * @param boolean $group if TRUE, the values of the returned array
4185       *       is wrapped in another array.  If the same key value (in the first
4186       *       column) repeats itself, the values will be appended to this array
4187       *       instead of overwriting the existing values.
4188       * @return array associative array with results from the query.
4189       * @access public
4190       */
4191      function getAssoc($query, $types = NULL, $params = array(), $param_types = NULL,
4192          $fetchmode = MDB_FETCHMODE_ORDERED, $force_array = FALSE, $group = FALSE)
4193      {
4194          settype($params, 'array');
4195          if (count($params) > 0) {
4196              $prepared_query = $this->prepareQuery($query);
4197  
4198              if (MDB::isError($prepared_query)) {
4199                  return($prepared_query);
4200              }
4201              $this->setParamArray($prepared_query, $params, $param_types);
4202              $result = $this->executeQuery($prepared_query, $types);
4203          } else {
4204              $result = $this->query($query, $types);
4205          }
4206  
4207          if (MDB::isError($result)) {
4208              return($result);
4209          }
4210  
4211          $all = $this->fetchAll($result, $fetchmode, TRUE, $force_array, $group);
4212          if (MDB::isError($all)) {
4213              return($all);
4214          }
4215          if (isset($prepared_query)) {
4216              $result = $this->freePreparedQuery($prepared_query);
4217              if (MDB::isError($result)) {
4218                  return($result);
4219              }
4220          }
4221          return($all);
4222      }
4223  
4224      // }}}
4225      // {{{ getAll()
4226  
4227      /**
4228       * Fetch all the rows returned from a query.
4229       *
4230       * @param string $query the SQL query
4231       * @param array $types array that contains the types of the columns in
4232       *       the result set
4233       * @param array $params array if supplied, prepare/execute will be used
4234       *       with this array as execute parameters
4235       * @param array $param_types array that contains the types of the values
4236       *       defined in $params
4237       * @param integer $fetchmode the fetch mode to use
4238       * @return array an nested array, or a MDB error
4239       * @access public
4240       */
4241      function getAll($query, $types = NULL, $params = array(), $param_types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
4242      {
4243          settype($params, 'array');
4244          if (count($params) > 0) {
4245              $prepared_query = $this->prepareQuery($query);
4246  
4247              if (MDB::isError($prepared_query)) {
4248                  return($prepared_query);
4249              }
4250              $this->setParamArray($prepared_query, $params, $param_types);
4251              $result = $this->executeQuery($prepared_query, $types);
4252          } else {
4253              $result = $this->query($query, $types);
4254          }
4255  
4256          if (MDB::isError($result)) {
4257              return($result);
4258          }
4259  
4260          $all = $this->fetchAll($result, $fetchmode);
4261          if (MDB::isError($all)) {
4262              return($all);
4263          }
4264          if (isset($prepared_query)) {
4265              $result = $this->freePreparedQuery($prepared_query);
4266              if (MDB::isError($result)) {
4267                  return($result);
4268              }
4269          }
4270          return($all);
4271      }
4272  
4273      // }}}
4274      // {{{ tableInfo()
4275  
4276      /**
4277       * returns meta data about the result set
4278       *
4279       * @param resource $result result identifier
4280       * @param mixed $mode depends on implementation
4281       * @return array an nested array, or a MDB error
4282       * @access public
4283       */
4284      function tableInfo($result, $mode = NULL)
4285      {
4286          return($this->raiseError(MDB_ERROR_NOT_CAPABLE));
4287      }
4288  
4289      // }}}
4290      // {{{ createLob()
4291  
4292      /**
4293       * Create a handler object of a specified class with functions to
4294       * retrieve data from a large object data stream.
4295       *
4296       * @param array $arguments An associative array with parameters to create
4297       *                  the handler object. The array indexes are the names of
4298       *                  the parameters and the array values are the respective
4299       *                  parameter values.
4300       *
4301       *                  Some parameters are specific of the class of each type
4302       *                  of handler object that is created. The following
4303       *                  parameters are common to all handler object classes:
4304       *
4305       *                  Type
4306       *
4307       *                      Name of the type of the built-in supported class
4308       *                      that will be used to create the handler object.
4309       *                      There are currently four built-in types of handler
4310       *                      object classes: data, resultlob, inputfile and
4311       *                      outputfile.
4312       *
4313       *                      The data handler class is the default class. It
4314       *                      simply reads data from a given data string.
4315       *
4316       *                      The resultlob handler class is meant to read data
4317       *                      from a large object retrieved from a query result.
4318       *                      This class is not used directly by applications.
4319       *
4320       *                      The inputfile handler class is meant to read data
4321       *                      from a file to use in prepared queries with large
4322       *                      object field parameters.
4323       *
4324       *                      The outputfile handler class is meant to write to
4325       *                      a file data from result columns with large object
4326       *                      fields. The functions to read from this type of
4327       *                      large object do not return any data. Instead, the
4328       *                      data is just written to the output file with the
4329       *                      data retrieved from a specified large object handle.
4330       *
4331       *                  Class
4332       *
4333       *                      Name of the class of the handler object that will be
4334       *                      created if the Type argument is not specified. This
4335       *                      argument should be used when you need to specify a
4336       *                      custom handler class.
4337       *
4338       *                  Database
4339       *
4340       *                      Database object as returned by MDB::connect.
4341       *                      This is an option argument needed by some handler
4342       *                      classes like resultlob.
4343       *
4344       *                  The following arguments are specific of the inputfile
4345       *                  handler class:
4346       *
4347       *                      File
4348       *
4349       *                          Integer handle value of a file already opened
4350       *                          for writing.
4351       *
4352       *                      FileName
4353       *
4354       *                          Name of a file to be opened for writing if the
4355       *                          File argument is not specified.
4356       *
4357       *                  The following arguments are specific of the outputfile
4358       *                  handler class:
4359       *
4360       *                      File
4361       *
4362       *                          Integer handle value of a file already opened
4363       *                          for writing.
4364       *
4365       *                      FileName
4366       *
4367       *                          Name of a file to be opened for writing if the
4368       *                          File argument is not specified.
4369       *
4370       *                      BufferLength
4371       *
4372       *                          Integer value that specifies the length of a
4373       *                          buffer that will be used to read from the
4374       *                          specified large object.
4375       *
4376       *                      LOB
4377       *
4378       *                          Integer handle value that specifies a large
4379       *                          object from which the data to be stored in the
4380       *                          output file will be written.
4381       *
4382       *                      Result
4383       *
4384       *                          Integer handle value as returned by the function
4385       *                          MDB::query() or MDB::executeQuery() that specifies
4386       *                          the result set that contains the large object value
4387       *                          to be retrieved. If the LOB argument is specified,
4388       *                          this argument is ignored.
4389       *
4390       *                      Row
4391       *
4392       *                          Integer value that specifies the number of the
4393       *                          row of the result set that contains the large
4394       *                          object value to be retrieved. If the LOB
4395       *                          argument is specified, this argument is ignored.
4396       *
4397       *                      Field
4398       *
4399       *                          Integer or string value that specifies the
4400       *                          number or the name of the column of the result
4401       *                          set that contains the large object value to be
4402       *                          retrieved. If the LOB argument is specified,
4403       *                          this argument is ignored.
4404       *
4405       *                      Binary
4406       *
4407       *                          Boolean value that specifies whether the large
4408       *                          object column to be retrieved is of binary type
4409       *                          (blob) or otherwise is of character type (clob).
4410       *                          If the LOB argument is specified, this argument
4411       *                          is ignored.
4412       *
4413       *                  The following argument is specific of the data
4414       *                  handler class:
4415       *
4416       *                  Data
4417       *
4418       *                      String of data that will be returned by the class
4419       *                      when it requested with the readLOB() method.
4420       *
4421       *                  The following argument is specific of the resultlob
4422       *                  handler class:
4423       *
4424       *                      ResultLOB
4425       *
4426       *                          Integer handle value of a large object result
4427       *                          row field.
4428       * @return integer handle value that should be passed as argument insubsequent
4429       * calls to functions that retrieve data from the large object input stream.
4430       * @access public
4431       */
4432      function createLob($arguments)
4433      {
4434          $result = $this->loadLob('Create LOB');
4435          if (MDB::isError($result)) {
4436              return($result);
4437          }
4438          $class_name = 'MDB_LOB';
4439          if (isset($arguments['Type'])) {
4440              switch ($arguments['Type']) {
4441                  case 'data':
4442                      break;
4443                  case 'resultlob':
4444                      $class_name = 'MDB_LOB_Result';
4445                      break;
4446                  case 'inputfile':
4447                      $class_name = 'MDB_LOB_Input_File';
4448                      break;
4449                  case 'outputfile':
4450                      $class_name = 'MDB_LOB_Output_File';
4451                      break;
4452                  default:
4453                      if (isset($arguments['Error'])) {
4454                          $arguments['Error'] = $arguments['Type'] . ' is not a valid type of large object';
4455                      }
4456                      return($this->raiseError());
4457              }
4458          } else {
4459              if (isset($arguments['Class'])) {
4460                  $class = $arguments['Class'];
4461              }
4462          }
4463          $lob = count($GLOBALS['_MDB_lobs']) + 1;
4464          $GLOBALS['_MDB_lobs'][$lob] = &new $class_name;
4465          if (isset($arguments['Database'])) {
4466              $GLOBALS['_MDB_lobs'][$lob]->database = $arguments['Database'];
4467          } else {
4468              $GLOBALS['_MDB_lobs'][$lob]->database = &$this;
4469          }
4470          if (MDB::isError($result = $GLOBALS['_MDB_lobs'][$lob]->create($arguments))) {
4471              $GLOBALS['_MDB_lobs'][$lob]->database->destroyLob($lob);
4472              return($result);
4473          }
4474          return($lob);
4475      }
4476  
4477      // }}}
4478      // {{{ readLob()
4479  
4480      /**
4481       * Read data from large object input stream.
4482       *
4483       * @param integer $lob argument handle that is returned by the
4484       *                          MDB::createLob() method.
4485       * @param string $data reference to a variable that will hold data
4486       *                          to be read from the large object input stream
4487       * @param integer $length    value that indicates the largest ammount ofdata
4488       *                          to be read from the large object input stream.
4489       * @return mixed the effective number of bytes read from the large object
4490       *                      input stream on sucess or an MDB error object.
4491       * @access public
4492       * @see endOfLob()
4493       */
4494      function readLob($lob, &$data, $length)
4495      {
4496          return($GLOBALS['_MDB_lobs'][$lob]->readLob($data, $length));
4497      }
4498  
4499      // }}}
4500      // {{{ endOfLob()
4501  
4502      /**
4503       * Determine whether it was reached the end of the large object and
4504       * therefore there is no more data to be read for the its input stream.
4505       *
4506       * @param integer $lob argument handle that is returned by the
4507       *                          MDB::createLob() method.
4508       * @access public
4509       * @return boolean flag that indicates whether it was reached the end of the large object input stream
4510       */
4511      function endOfLob($lob)
4512      {
4513          return($GLOBALS['_MDB_lobs'][$lob]->endOfLob());
4514      }
4515  
4516      // }}}
4517      // {{{ destroyLob()
4518  
4519      /**
4520       * Free any resources allocated during the lifetime of the large object
4521       * handler object.
4522       *
4523       * @param integer $lob argument handle that is returned by the
4524       *                          MDB::createLob() method.
4525       * @access public
4526       */
4527      function destroyLob($lob)
4528      {
4529          $GLOBALS['_MDB_lobs'][$lob]->destroy();
4530          unset($GLOBALS['_MDB_lobs'][$lob]);
4531      }
4532  
4533      // }}}
4534      // {{{ Destructor
4535  
4536      /**
4537      * this function closes open transactions to be executed at shutdown
4538      *
4539      * @access private
4540      */
4541      function _MDB_Common()
4542      {
4543          if ($this->in_transaction && !MDB::isError($this->rollback())) {
4544              $this->autoCommit(TRUE);
4545          }
4546      }
4547  };
4548  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7