| 418 | aurelien | 1 | <?php
 | 
        
           |  |  | 2 | /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
 | 
        
           |  |  | 3 | // +----------------------------------------------------------------------+
 | 
        
           |  |  | 4 | // | PHP Version 4                                                        |
 | 
        
           |  |  | 5 | // +----------------------------------------------------------------------+
 | 
        
           |  |  | 6 | // | Copyright (c) 1997-2004 The PHP Group                                |
 | 
        
           |  |  | 7 | // +----------------------------------------------------------------------+
 | 
        
           |  |  | 8 | // | This source file is subject to version 2.02 of the PHP license,      |
 | 
        
           |  |  | 9 | // | that is bundled with this package in the file LICENSE, and is        |
 | 
        
           |  |  | 10 | // | available at through the world-wide-web at                           |
 | 
        
           |  |  | 11 | // | http://www.php.net/license/2_02.txt.                                 |
 | 
        
           |  |  | 12 | // | If you did not receive a copy of the PHP license and are unable to   |
 | 
        
           |  |  | 13 | // | obtain it through the world-wide-web, please send a note to          |
 | 
        
           |  |  | 14 | // | license@php.net so we can mail you a copy immediately.               |
 | 
        
           |  |  | 15 | // +----------------------------------------------------------------------+
 | 
        
           |  |  | 16 | // | Author: Stig Bakken <ssb@php.net>                                    |
 | 
        
           |  |  | 17 | // |         Tomas V.V.Cox <cox@idecnet.com>                              |
 | 
        
           |  |  | 18 | // | Maintainer: Daniel Convissor <danielc@php.net>                       |
 | 
        
           |  |  | 19 | // +----------------------------------------------------------------------+
 | 
        
           |  |  | 20 | //
 | 
        
           |  |  | 21 | // $Id$
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 | require_once 'PEAR.php';
 | 
        
           |  |  | 24 |   | 
        
           |  |  | 25 | /**
 | 
        
           |  |  | 26 |  * DB_common is a base class for DB implementations, and must be
 | 
        
           |  |  | 27 |  * inherited by all such
 | 
        
           |  |  | 28 |  *
 | 
        
           |  |  | 29 |  * @package  DB
 | 
        
           |  |  | 30 |  * @version  $Id$
 | 
        
           |  |  | 31 |  * @category Database
 | 
        
           |  |  | 32 |  * @author   Stig Bakken <ssb@php.net>
 | 
        
           |  |  | 33 |  * @author   Tomas V.V.Cox <cox@idecnet.com>
 | 
        
           |  |  | 34 |  */
 | 
        
           |  |  | 35 | class DB_common extends PEAR
 | 
        
           |  |  | 36 | {
 | 
        
           |  |  | 37 |     // {{{ properties
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 |     /**
 | 
        
           |  |  | 40 |      * assoc of capabilities for this DB implementation
 | 
        
           |  |  | 41 |      * $features['limit'] =>  'emulate' => emulate with fetch row by number
 | 
        
           |  |  | 42 |      *                        'alter'   => alter the query
 | 
        
           |  |  | 43 |      *                        false     => skip rows
 | 
        
           |  |  | 44 |      * @var array
 | 
        
           |  |  | 45 |      */
 | 
        
           |  |  | 46 |     var $features = array();
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |     /**
 | 
        
           |  |  | 49 |      * assoc mapping native error codes to DB ones
 | 
        
           |  |  | 50 |      * @var array
 | 
        
           |  |  | 51 |      */
 | 
        
           |  |  | 52 |     var $errorcode_map = array();
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 |     /**
 | 
        
           |  |  | 55 |      * DB type (mysql, oci8, odbc etc.)
 | 
        
           |  |  | 56 |      * @var string
 | 
        
           |  |  | 57 |      */
 | 
        
           |  |  | 58 |     var $phptype;
 | 
        
           |  |  | 59 |   | 
        
           |  |  | 60 |     /**
 | 
        
           |  |  | 61 |      * @var string
 | 
        
           |  |  | 62 |      */
 | 
        
           |  |  | 63 |     var $prepare_tokens;
 | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |     /**
 | 
        
           |  |  | 66 |      * @var string
 | 
        
           |  |  | 67 |      */
 | 
        
           |  |  | 68 |     var $prepare_types;
 | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 |     /**
 | 
        
           |  |  | 71 |      * @var string
 | 
        
           |  |  | 72 |      */
 | 
        
           |  |  | 73 |     var $prepared_queries;
 | 
        
           |  |  | 74 |   | 
        
           |  |  | 75 |     /**
 | 
        
           |  |  | 76 |      * @var integer
 | 
        
           |  |  | 77 |      */
 | 
        
           |  |  | 78 |     var $prepare_maxstmt = 0;
 | 
        
           |  |  | 79 |   | 
        
           |  |  | 80 |     /**
 | 
        
           |  |  | 81 |      * @var string
 | 
        
           |  |  | 82 |      */
 | 
        
           |  |  | 83 |     var $last_query = '';
 | 
        
           |  |  | 84 |   | 
        
           |  |  | 85 |     /**
 | 
        
           |  |  | 86 |      * @var integer
 | 
        
           |  |  | 87 |      */
 | 
        
           |  |  | 88 |     var $fetchmode = DB_FETCHMODE_ORDERED;
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 |     /**
 | 
        
           |  |  | 91 |      * @var string
 | 
        
           |  |  | 92 |      */
 | 
        
           |  |  | 93 |     var $fetchmode_object_class = 'stdClass';
 | 
        
           |  |  | 94 |   | 
        
           |  |  | 95 |     /**
 | 
        
           |  |  | 96 |      * Run-time configuration options.
 | 
        
           |  |  | 97 |      *
 | 
        
           |  |  | 98 |      * The 'optimize' option has been deprecated.  Use the 'portability'
 | 
        
           |  |  | 99 |      * option instead.
 | 
        
           |  |  | 100 |      *
 | 
        
           |  |  | 101 |      * @see DB_common::setOption()
 | 
        
           |  |  | 102 |      * @var array
 | 
        
           |  |  | 103 |      */
 | 
        
           |  |  | 104 |     var $options = array(
 | 
        
           |  |  | 105 |         'persistent' => false,
 | 
        
           |  |  | 106 |         'ssl' => false,
 | 
        
           |  |  | 107 |         'debug' => 0,
 | 
        
           |  |  | 108 |         'seqname_format' => '%s_seq',
 | 
        
           |  |  | 109 |         'autofree' => false,
 | 
        
           |  |  | 110 |         'portability' => DB_PORTABILITY_NONE,
 | 
        
           |  |  | 111 |         'optimize' => 'performance',  // Deprecated.  Use 'portability'.
 | 
        
           |  |  | 112 |     );
 | 
        
           |  |  | 113 |   | 
        
           |  |  | 114 |     /**
 | 
        
           |  |  | 115 |      * DB handle
 | 
        
           |  |  | 116 |      * @var resource
 | 
        
           |  |  | 117 |      */
 | 
        
           |  |  | 118 |     var $dbh;
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |     // }}}
 | 
        
           |  |  | 121 |     // {{{ toString()
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |     /**
 | 
        
           |  |  | 124 |      * String conversation
 | 
        
           |  |  | 125 |      *
 | 
        
           |  |  | 126 |      * @return string
 | 
        
           |  |  | 127 |      * @access private
 | 
        
           |  |  | 128 |      */
 | 
        
           |  |  | 129 |     function toString()
 | 
        
           |  |  | 130 |     {
 | 
        
           |  |  | 131 |         $info = strtolower(get_class($this));
 | 
        
           |  |  | 132 |         $info .=  ': (phptype=' . $this->phptype .
 | 
        
           |  |  | 133 |                   ', dbsyntax=' . $this->dbsyntax .
 | 
        
           |  |  | 134 |                   ')';
 | 
        
           |  |  | 135 |   | 
        
           |  |  | 136 |         if ($this->connection) {
 | 
        
           |  |  | 137 |             $info .= ' [connected]';
 | 
        
           |  |  | 138 |         }
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 |         return $info;
 | 
        
           |  |  | 141 |     }
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |     // }}}
 | 
        
           |  |  | 144 |     // {{{ constructor
 | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 |     /**
 | 
        
           |  |  | 147 |      * Constructor
 | 
        
           |  |  | 148 |      */
 | 
        
           |  |  | 149 |     function DB_common()
 | 
        
           |  |  | 150 |     {
 | 
        
           |  |  | 151 |         $this->PEAR('DB_Error');
 | 
        
           |  |  | 152 |     }
 | 
        
           |  |  | 153 |   | 
        
           |  |  | 154 |     // }}}
 | 
        
           |  |  | 155 |     // {{{ quoteString()
 | 
        
           |  |  | 156 |   | 
        
           |  |  | 157 |     /**
 | 
        
           |  |  | 158 |      * DEPRECATED: Quotes a string so it can be safely used within string
 | 
        
           |  |  | 159 |      * delimiters in a query
 | 
        
           |  |  | 160 |      *
 | 
        
           |  |  | 161 |      * @return string quoted string
 | 
        
           |  |  | 162 |      *
 | 
        
           |  |  | 163 |      * @see DB_common::quoteSmart(), DB_common::escapeSimple()
 | 
        
           |  |  | 164 |      * @deprecated  Deprecated in release 1.2 or lower
 | 
        
           |  |  | 165 |      * @internal
 | 
        
           |  |  | 166 |      */
 | 
        
           |  |  | 167 |     function quoteString($string)
 | 
        
           |  |  | 168 |     {
 | 
        
           |  |  | 169 |         $string = $this->quote($string);
 | 
        
           |  |  | 170 |         if ($string{0} == "'") {
 | 
        
           |  |  | 171 |             return substr($string, 1, -1);
 | 
        
           |  |  | 172 |         }
 | 
        
           |  |  | 173 |         return $string;
 | 
        
           |  |  | 174 |     }
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 |     // }}}
 | 
        
           |  |  | 177 |     // {{{ quote()
 | 
        
           |  |  | 178 |   | 
        
           |  |  | 179 |     /**
 | 
        
           |  |  | 180 |      * DEPRECATED: Quotes a string so it can be safely used in a query
 | 
        
           |  |  | 181 |      *
 | 
        
           |  |  | 182 |      * @param string $string the input string to quote
 | 
        
           |  |  | 183 |      *
 | 
        
           |  |  | 184 |      * @return string The NULL string or the string quotes
 | 
        
           |  |  | 185 |      *                in magic_quote_sybase style
 | 
        
           |  |  | 186 |      *
 | 
        
           |  |  | 187 |      * @see DB_common::quoteSmart(), DB_common::escapeSimple()
 | 
        
           |  |  | 188 |      * @deprecated  Deprecated in release 1.6.0
 | 
        
           |  |  | 189 |      * @internal
 | 
        
           |  |  | 190 |      */
 | 
        
           |  |  | 191 |     function quote($string = null)
 | 
        
           |  |  | 192 |     {
 | 
        
           |  |  | 193 |         return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'";
 | 
        
           |  |  | 194 |     }
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 |     // }}}
 | 
        
           |  |  | 197 |     // {{{ quoteIdentifier()
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 |     /**
 | 
        
           |  |  | 200 |      * Quote a string so it can be safely used as a table or column name
 | 
        
           |  |  | 201 |      *
 | 
        
           |  |  | 202 |      * Delimiting style depends on which database driver is being used.
 | 
        
           |  |  | 203 |      *
 | 
        
           |  |  | 204 |      * NOTE: just because you CAN use delimited identifiers doesn't mean
 | 
        
           |  |  | 205 |      * you SHOULD use them.  In general, they end up causing way more
 | 
        
           |  |  | 206 |      * problems than they solve.
 | 
        
           |  |  | 207 |      *
 | 
        
           |  |  | 208 |      * Portability is broken by using the following characters inside
 | 
        
           |  |  | 209 |      * delimited identifiers:
 | 
        
           |  |  | 210 |      *   + backtick (<kbd>`</kbd>) -- due to MySQL
 | 
        
           |  |  | 211 |      *   + double quote (<kbd>"</kbd>) -- due to Oracle
 | 
        
           |  |  | 212 |      *   + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
 | 
        
           |  |  | 213 |      *
 | 
        
           |  |  | 214 |      * Delimited identifiers are known to generally work correctly under
 | 
        
           |  |  | 215 |      * the following drivers:
 | 
        
           |  |  | 216 |      *   + mssql
 | 
        
           |  |  | 217 |      *   + mysql
 | 
        
           |  |  | 218 |      *   + mysqli
 | 
        
           |  |  | 219 |      *   + oci8
 | 
        
           |  |  | 220 |      *   + odbc(access)
 | 
        
           |  |  | 221 |      *   + odbc(db2)
 | 
        
           |  |  | 222 |      *   + pgsql
 | 
        
           |  |  | 223 |      *   + sqlite
 | 
        
           |  |  | 224 |      *   + sybase
 | 
        
           |  |  | 225 |      *
 | 
        
           |  |  | 226 |      * InterBase doesn't seem to be able to use delimited identifiers
 | 
        
           |  |  | 227 |      * via PHP 4.  They work fine under PHP 5.
 | 
        
           |  |  | 228 |      *
 | 
        
           |  |  | 229 |      * @param string $str  identifier name to be quoted
 | 
        
           |  |  | 230 |      *
 | 
        
           |  |  | 231 |      * @return string  quoted identifier string
 | 
        
           |  |  | 232 |      *
 | 
        
           |  |  | 233 |      * @since 1.6.0
 | 
        
           |  |  | 234 |      * @access public
 | 
        
           |  |  | 235 |      */
 | 
        
           |  |  | 236 |     function quoteIdentifier($str)
 | 
        
           |  |  | 237 |     {
 | 
        
           |  |  | 238 |         return '"' . str_replace('"', '""', $str) . '"';
 | 
        
           |  |  | 239 |     }
 | 
        
           |  |  | 240 |   | 
        
           |  |  | 241 |     // }}}
 | 
        
           |  |  | 242 |     // {{{ quoteSmart()
 | 
        
           |  |  | 243 |   | 
        
           |  |  | 244 |     /**
 | 
        
           |  |  | 245 |      * Format input so it can be safely used in a query
 | 
        
           |  |  | 246 |      *
 | 
        
           |  |  | 247 |      * The output depends on the PHP data type of input and the database
 | 
        
           |  |  | 248 |      * type being used.
 | 
        
           |  |  | 249 |      *
 | 
        
           |  |  | 250 |      * @param mixed $in  data to be quoted
 | 
        
           |  |  | 251 |      *
 | 
        
           |  |  | 252 |      * @return mixed  the format of the results depends on the input's
 | 
        
           |  |  | 253 |      *                PHP type:
 | 
        
           |  |  | 254 |      *
 | 
        
           |  |  | 255 |      * <ul>
 | 
        
           |  |  | 256 |      *  <li>
 | 
        
           |  |  | 257 |      *    <kbd>input</kbd> -> <samp>returns</samp>
 | 
        
           |  |  | 258 |      *  </li>
 | 
        
           |  |  | 259 |      *  <li>
 | 
        
           |  |  | 260 |      *    <kbd>null</kbd> -> the string <samp>NULL</samp>
 | 
        
           |  |  | 261 |      *  </li>
 | 
        
           |  |  | 262 |      *  <li>
 | 
        
           |  |  | 263 |      *    <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
 | 
        
           |  |  | 264 |      *  </li>
 | 
        
           |  |  | 265 |      *  <li>
 | 
        
           |  |  | 266 |      *    &type.bool; -> output depends on the driver in use
 | 
        
           |  |  | 267 |      *    Most drivers return integers: <samp>1</samp> if
 | 
        
           |  |  | 268 |      *    <kbd>true</kbd> or <samp>0</samp> if
 | 
        
           |  |  | 269 |      *    <kbd>false</kbd>.
 | 
        
           |  |  | 270 |      *    Some return strings: <samp>TRUE</samp> if
 | 
        
           |  |  | 271 |      *    <kbd>true</kbd> or <samp>FALSE</samp> if
 | 
        
           |  |  | 272 |      *    <kbd>false</kbd>.
 | 
        
           |  |  | 273 |      *    Finally one returns strings: <samp>T</samp> if
 | 
        
           |  |  | 274 |      *    <kbd>true</kbd> or <samp>F</samp> if
 | 
        
           |  |  | 275 |      *    <kbd>false</kbd>. Here is a list of each DBMS,
 | 
        
           |  |  | 276 |      *    the values returned and the suggested column type:
 | 
        
           |  |  | 277 |      *    <ul>
 | 
        
           |  |  | 278 |      *      <li>
 | 
        
           |  |  | 279 |      *        <kbd>dbase</kbd> -> <samp>T/F</samp>
 | 
        
           |  |  | 280 |      *        (<kbd>Logical</kbd>)
 | 
        
           |  |  | 281 |      *      </li>
 | 
        
           |  |  | 282 |      *      <li>
 | 
        
           |  |  | 283 |      *        <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
 | 
        
           |  |  | 284 |      *        (<kbd>BOOLEAN</kbd>)
 | 
        
           |  |  | 285 |      *      </li>
 | 
        
           |  |  | 286 |      *      <li>
 | 
        
           |  |  | 287 |      *        <kbd>ibase</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 288 |      *        (<kbd>SMALLINT</kbd>) [1]
 | 
        
           |  |  | 289 |      *      </li>
 | 
        
           |  |  | 290 |      *      <li>
 | 
        
           |  |  | 291 |      *        <kbd>ifx</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 292 |      *        (<kbd>SMALLINT</kbd>) [1]
 | 
        
           |  |  | 293 |      *      </li>
 | 
        
           |  |  | 294 |      *      <li>
 | 
        
           |  |  | 295 |      *        <kbd>msql</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 296 |      *        (<kbd>INTEGER</kbd>)
 | 
        
           |  |  | 297 |      *      </li>
 | 
        
           |  |  | 298 |      *      <li>
 | 
        
           |  |  | 299 |      *        <kbd>mssql</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 300 |      *        (<kbd>BIT</kbd>)
 | 
        
           |  |  | 301 |      *      </li>
 | 
        
           |  |  | 302 |      *      <li>
 | 
        
           |  |  | 303 |      *        <kbd>mysql</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 304 |      *        (<kbd>TINYINT(1)</kbd>)
 | 
        
           |  |  | 305 |      *      </li>
 | 
        
           |  |  | 306 |      *      <li>
 | 
        
           |  |  | 307 |      *        <kbd>mysqli</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 308 |      *        (<kbd>TINYINT(1)</kbd>)
 | 
        
           |  |  | 309 |      *      </li>
 | 
        
           |  |  | 310 |      *      <li>
 | 
        
           |  |  | 311 |      *        <kbd>oci8</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 312 |      *        (<kbd>NUMBER(1)</kbd>)
 | 
        
           |  |  | 313 |      *      </li>
 | 
        
           |  |  | 314 |      *      <li>
 | 
        
           |  |  | 315 |      *        <kbd>odbc</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 316 |      *        (<kbd>SMALLINT</kbd>) [1]
 | 
        
           |  |  | 317 |      *      </li>
 | 
        
           |  |  | 318 |      *      <li>
 | 
        
           |  |  | 319 |      *        <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
 | 
        
           |  |  | 320 |      *        (<kbd>BOOLEAN</kbd>)
 | 
        
           |  |  | 321 |      *      </li>
 | 
        
           |  |  | 322 |      *      <li>
 | 
        
           |  |  | 323 |      *        <kbd>sqlite</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 324 |      *        (<kbd>INTEGER</kbd>)
 | 
        
           |  |  | 325 |      *      </li>
 | 
        
           |  |  | 326 |      *      <li>
 | 
        
           |  |  | 327 |      *        <kbd>sybase</kbd> -> <samp>1/0</samp>
 | 
        
           |  |  | 328 |      *        (<kbd>TINYINT(1)</kbd>)
 | 
        
           |  |  | 329 |      *      </li>
 | 
        
           |  |  | 330 |      *    </ul>
 | 
        
           |  |  | 331 |      *    [1] Accommodate the lowest common denominator because not all
 | 
        
           |  |  | 332 |      *    versions of have <kbd>BOOLEAN</kbd>.
 | 
        
           |  |  | 333 |      *  </li>
 | 
        
           |  |  | 334 |      *  <li>
 | 
        
           |  |  | 335 |      *    other (including strings and numeric strings) ->
 | 
        
           |  |  | 336 |      *    the data with single quotes escaped by preceeding
 | 
        
           |  |  | 337 |      *    single quotes, backslashes are escaped by preceeding
 | 
        
           |  |  | 338 |      *    backslashes, then the whole string is encapsulated
 | 
        
           |  |  | 339 |      *    between single quotes
 | 
        
           |  |  | 340 |      *  </li>
 | 
        
           |  |  | 341 |      * </ul>
 | 
        
           |  |  | 342 |      *
 | 
        
           |  |  | 343 |      * @since 1.6.0
 | 
        
           |  |  | 344 |      * @see DB_common::escapeSimple()
 | 
        
           |  |  | 345 |      * @access public
 | 
        
           |  |  | 346 |      */
 | 
        
           |  |  | 347 |     function quoteSmart($in)
 | 
        
           |  |  | 348 |     {
 | 
        
           |  |  | 349 |         if (is_int($in) || is_double($in)) {
 | 
        
           |  |  | 350 |             return $in;
 | 
        
           |  |  | 351 |         } elseif (is_bool($in)) {
 | 
        
           |  |  | 352 |             return $in ? 1 : 0;
 | 
        
           |  |  | 353 |         } elseif (is_null($in)) {
 | 
        
           |  |  | 354 |             return 'NULL';
 | 
        
           |  |  | 355 |         } else {
 | 
        
           |  |  | 356 |             return "'" . $this->escapeSimple($in) . "'";
 | 
        
           |  |  | 357 |         }
 | 
        
           |  |  | 358 |     }
 | 
        
           |  |  | 359 |   | 
        
           |  |  | 360 |     // }}}
 | 
        
           |  |  | 361 |     // {{{ escapeSimple()
 | 
        
           |  |  | 362 |   | 
        
           |  |  | 363 |     /**
 | 
        
           |  |  | 364 |      * Escape a string according to the current DBMS's standards
 | 
        
           |  |  | 365 |      *
 | 
        
           |  |  | 366 |      * In SQLite, this makes things safe for inserts/updates, but may
 | 
        
           |  |  | 367 |      * cause problems when performing text comparisons against columns
 | 
        
           |  |  | 368 |      * containing binary data. See the
 | 
        
           |  |  | 369 |      * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
 | 
        
           |  |  | 370 |      *
 | 
        
           |  |  | 371 |      * @param string $str  the string to be escaped
 | 
        
           |  |  | 372 |      *
 | 
        
           |  |  | 373 |      * @return string  the escaped string
 | 
        
           |  |  | 374 |      *
 | 
        
           |  |  | 375 |      * @since 1.6.0
 | 
        
           |  |  | 376 |      * @see DB_common::quoteSmart()
 | 
        
           |  |  | 377 |      * @access public
 | 
        
           |  |  | 378 |      */
 | 
        
           |  |  | 379 |     function escapeSimple($str) {
 | 
        
           |  |  | 380 |         return str_replace("'", "''", $str);
 | 
        
           |  |  | 381 |     }
 | 
        
           |  |  | 382 |   | 
        
           |  |  | 383 |     // }}}
 | 
        
           |  |  | 384 |     // {{{ provides()
 | 
        
           |  |  | 385 |   | 
        
           |  |  | 386 |     /**
 | 
        
           |  |  | 387 |      * Tell whether a DB implementation or its backend extension
 | 
        
           |  |  | 388 |      * supports a given feature
 | 
        
           |  |  | 389 |      *
 | 
        
           |  |  | 390 |      * @param array $feature name of the feature (see the DB class doc)
 | 
        
           |  |  | 391 |      * @return bool whether this DB implementation supports $feature
 | 
        
           |  |  | 392 |      * @access public
 | 
        
           |  |  | 393 |      */
 | 
        
           |  |  | 394 |     function provides($feature)
 | 
        
           |  |  | 395 |     {
 | 
        
           |  |  | 396 |         return $this->features[$feature];
 | 
        
           |  |  | 397 |     }
 | 
        
           |  |  | 398 |   | 
        
           |  |  | 399 |     // }}}
 | 
        
           |  |  | 400 |     // {{{ errorCode()
 | 
        
           |  |  | 401 |   | 
        
           |  |  | 402 |     /**
 | 
        
           |  |  | 403 |      * Map native error codes to DB's portable ones
 | 
        
           |  |  | 404 |      *
 | 
        
           |  |  | 405 |      * Requires that the DB implementation's constructor fills
 | 
        
           |  |  | 406 |      * in the <var>$errorcode_map</var> property.
 | 
        
           |  |  | 407 |      *
 | 
        
           |  |  | 408 |      * @param mixed  $nativecode  the native error code, as returned by the
 | 
        
           |  |  | 409 |      * backend database extension (string or integer)
 | 
        
           |  |  | 410 |      *
 | 
        
           |  |  | 411 |      * @return int a portable DB error code, or DB_ERROR if this DB
 | 
        
           |  |  | 412 |      * implementation has no mapping for the given error code.
 | 
        
           |  |  | 413 |      *
 | 
        
           |  |  | 414 |      * @access public
 | 
        
           |  |  | 415 |      */
 | 
        
           |  |  | 416 |     function errorCode($nativecode)
 | 
        
           |  |  | 417 |     {
 | 
        
           |  |  | 418 |         if (isset($this->errorcode_map[$nativecode])) {
 | 
        
           |  |  | 419 |             return $this->errorcode_map[$nativecode];
 | 
        
           |  |  | 420 |         }
 | 
        
           |  |  | 421 |         // Fall back to DB_ERROR if there was no mapping.
 | 
        
           |  |  | 422 |         return DB_ERROR;
 | 
        
           |  |  | 423 |     }
 | 
        
           |  |  | 424 |   | 
        
           |  |  | 425 |     // }}}
 | 
        
           |  |  | 426 |     // {{{ errorMessage()
 | 
        
           |  |  | 427 |   | 
        
           |  |  | 428 |     /**
 | 
        
           |  |  | 429 |      * Map a DB error code to a textual message.  This is actually
 | 
        
           |  |  | 430 |      * just a wrapper for DB::errorMessage()
 | 
        
           |  |  | 431 |      *
 | 
        
           |  |  | 432 |      * @param integer $dbcode the DB error code
 | 
        
           |  |  | 433 |      *
 | 
        
           |  |  | 434 |      * @return string the corresponding error message, of false
 | 
        
           |  |  | 435 |      * if the error code was unknown
 | 
        
           |  |  | 436 |      *
 | 
        
           |  |  | 437 |      * @access public
 | 
        
           |  |  | 438 |      */
 | 
        
           |  |  | 439 |     function errorMessage($dbcode)
 | 
        
           |  |  | 440 |     {
 | 
        
           |  |  | 441 |         return DB::errorMessage($this->errorcode_map[$dbcode]);
 | 
        
           |  |  | 442 |     }
 | 
        
           |  |  | 443 |   | 
        
           |  |  | 444 |     // }}}
 | 
        
           |  |  | 445 |     // {{{ raiseError()
 | 
        
           |  |  | 446 |   | 
        
           |  |  | 447 |     /**
 | 
        
           |  |  | 448 |      * Communicate an error and invoke error callbacks, etc
 | 
        
           |  |  | 449 |      *
 | 
        
           |  |  | 450 |      * Basically a wrapper for PEAR::raiseError without the message string.
 | 
        
           |  |  | 451 |      *
 | 
        
           |  |  | 452 |      * @param mixed    integer error code, or a PEAR error object (all
 | 
        
           |  |  | 453 |      *                 other parameters are ignored if this parameter is
 | 
        
           |  |  | 454 |      *                 an object
 | 
        
           |  |  | 455 |      *
 | 
        
           |  |  | 456 |      * @param int      error mode, see PEAR_Error docs
 | 
        
           |  |  | 457 |      *
 | 
        
           |  |  | 458 |      * @param mixed    If error mode is PEAR_ERROR_TRIGGER, this is the
 | 
        
           |  |  | 459 |      *                 error level (E_USER_NOTICE etc).  If error mode is
 | 
        
           |  |  | 460 |      *                 PEAR_ERROR_CALLBACK, this is the callback function,
 | 
        
           |  |  | 461 |      *                 either as a function name, or as an array of an
 | 
        
           |  |  | 462 |      *                 object and method name.  For other error modes this
 | 
        
           |  |  | 463 |      *                 parameter is ignored.
 | 
        
           |  |  | 464 |      *
 | 
        
           |  |  | 465 |      * @param string   Extra debug information.  Defaults to the last
 | 
        
           |  |  | 466 |      *                 query and native error code.
 | 
        
           |  |  | 467 |      *
 | 
        
           |  |  | 468 |      * @param mixed    Native error code, integer or string depending the
 | 
        
           |  |  | 469 |      *                 backend.
 | 
        
           |  |  | 470 |      *
 | 
        
           |  |  | 471 |      * @return object  a PEAR error object
 | 
        
           |  |  | 472 |      *
 | 
        
           |  |  | 473 |      * @access public
 | 
        
           |  |  | 474 |      * @see PEAR_Error
 | 
        
           |  |  | 475 |      */
 | 
        
           |  |  | 476 |     function &raiseError($code = DB_ERROR, $mode = null, $options = null,
 | 
        
           |  |  | 477 |                          $userinfo = null, $nativecode = null)
 | 
        
           |  |  | 478 |     {
 | 
        
           |  |  | 479 |         // The error is yet a DB error object
 | 
        
           |  |  | 480 |         if (is_object($code)) {
 | 
        
           |  |  | 481 |             // because we the static PEAR::raiseError, our global
 | 
        
           |  |  | 482 |             // handler should be used if it is set
 | 
        
           |  |  | 483 |             if ($mode === null && !empty($this->_default_error_mode)) {
 | 
        
           |  |  | 484 |                 $mode    = $this->_default_error_mode;
 | 
        
           |  |  | 485 |                 $options = $this->_default_error_options;
 | 
        
           |  |  | 486 |             }
 | 
        
           |  |  | 487 |             $tmp = PEAR::raiseError($code, null, $mode, $options, null, null, true);
 | 
        
           |  |  | 488 |             return $tmp;
 | 
        
           |  |  | 489 |         }
 | 
        
           |  |  | 490 |   | 
        
           |  |  | 491 |         if ($userinfo === null) {
 | 
        
           |  |  | 492 |             $userinfo = $this->last_query;
 | 
        
           |  |  | 493 |         }
 | 
        
           |  |  | 494 |   | 
        
           |  |  | 495 |         if ($nativecode) {
 | 
        
           |  |  | 496 |             $userinfo .= ' [nativecode=' . trim($nativecode) . ']';
 | 
        
           |  |  | 497 |         }
 | 
        
           |  |  | 498 |   | 
        
           |  |  | 499 |         $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo,
 | 
        
           |  |  | 500 |                                 'DB_Error', true);
 | 
        
           |  |  | 501 |         return $tmp;
 | 
        
           |  |  | 502 |     }
 | 
        
           |  |  | 503 |   | 
        
           |  |  | 504 |     // }}}
 | 
        
           |  |  | 505 |     // {{{ setFetchMode()
 | 
        
           |  |  | 506 |   | 
        
           |  |  | 507 |     /**
 | 
        
           |  |  | 508 |      * Sets which fetch mode should be used by default on queries
 | 
        
           |  |  | 509 |      * on this connection
 | 
        
           |  |  | 510 |      *
 | 
        
           |  |  | 511 |      * @param integer $fetchmode DB_FETCHMODE_ORDERED or
 | 
        
           |  |  | 512 |      *        DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with
 | 
        
           |  |  | 513 |      *        DB_FETCHMODE_FLIPPED.
 | 
        
           |  |  | 514 |      *
 | 
        
           |  |  | 515 |      * @param string $object_class The class of the object
 | 
        
           |  |  | 516 |      *                      to be returned by the fetch methods when
 | 
        
           |  |  | 517 |      *                      the DB_FETCHMODE_OBJECT mode is selected.
 | 
        
           |  |  | 518 |      *                      If no class is specified by default a cast
 | 
        
           |  |  | 519 |      *                      to object from the assoc array row will be done.
 | 
        
           |  |  | 520 |      *                      There is also the posibility to use and extend the
 | 
        
           |  |  | 521 |      *                      'DB_row' class.
 | 
        
           |  |  | 522 |      *
 | 
        
           |  |  | 523 |      * @see DB_FETCHMODE_ORDERED
 | 
        
           |  |  | 524 |      * @see DB_FETCHMODE_ASSOC
 | 
        
           |  |  | 525 |      * @see DB_FETCHMODE_FLIPPED
 | 
        
           |  |  | 526 |      * @see DB_FETCHMODE_OBJECT
 | 
        
           |  |  | 527 |      * @see DB_row::DB_row()
 | 
        
           |  |  | 528 |      * @access public
 | 
        
           |  |  | 529 |      */
 | 
        
           |  |  | 530 |     function setFetchMode($fetchmode, $object_class = 'stdClass')
 | 
        
           |  |  | 531 |     {
 | 
        
           |  |  | 532 |         switch ($fetchmode) {
 | 
        
           |  |  | 533 |             case DB_FETCHMODE_OBJECT:
 | 
        
           |  |  | 534 |                 $this->fetchmode_object_class = $object_class;
 | 
        
           |  |  | 535 |             case DB_FETCHMODE_ORDERED:
 | 
        
           |  |  | 536 |             case DB_FETCHMODE_ASSOC:
 | 
        
           |  |  | 537 |                 $this->fetchmode = $fetchmode;
 | 
        
           |  |  | 538 |                 break;
 | 
        
           |  |  | 539 |             default:
 | 
        
           |  |  | 540 |                 return $this->raiseError('invalid fetchmode mode');
 | 
        
           |  |  | 541 |         }
 | 
        
           |  |  | 542 |     }
 | 
        
           |  |  | 543 |   | 
        
           |  |  | 544 |     // }}}
 | 
        
           |  |  | 545 |     // {{{ setOption()
 | 
        
           |  |  | 546 |   | 
        
           |  |  | 547 |     /**
 | 
        
           |  |  | 548 |      * Set run-time configuration options for PEAR DB
 | 
        
           |  |  | 549 |      *
 | 
        
           |  |  | 550 |      * Options, their data types, default values and description:
 | 
        
           |  |  | 551 |      * <ul>
 | 
        
           |  |  | 552 |      * <li>
 | 
        
           |  |  | 553 |      * <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
 | 
        
           |  |  | 554 |      *      <br />should results be freed automatically when there are no
 | 
        
           |  |  | 555 |      *            more rows?
 | 
        
           |  |  | 556 |      * </li><li>
 | 
        
           |  |  | 557 |      * <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
 | 
        
           |  |  | 558 |      *      <br />debug level
 | 
        
           |  |  | 559 |      * </li><li>
 | 
        
           |  |  | 560 |      * <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
 | 
        
           |  |  | 561 |      *      <br />should the connection be persistent?
 | 
        
           |  |  | 562 |      * </li><li>
 | 
        
           |  |  | 563 |      * <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
 | 
        
           |  |  | 564 |      *      <br />portability mode constant (see below)
 | 
        
           |  |  | 565 |      * </li><li>
 | 
        
           |  |  | 566 |      * <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
 | 
        
           |  |  | 567 |      *      <br />the sprintf() format string used on sequence names.  This
 | 
        
           |  |  | 568 |      *            format is applied to sequence names passed to
 | 
        
           |  |  | 569 |      *            createSequence(), nextID() and dropSequence().
 | 
        
           |  |  | 570 |      * </li><li>
 | 
        
           |  |  | 571 |      * <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
 | 
        
           |  |  | 572 |      *      <br />use ssl to connect?
 | 
        
           |  |  | 573 |      * </li>
 | 
        
           |  |  | 574 |      * </ul>
 | 
        
           |  |  | 575 |      *
 | 
        
           |  |  | 576 |      * -----------------------------------------
 | 
        
           |  |  | 577 |      *
 | 
        
           |  |  | 578 |      * PORTABILITY MODES
 | 
        
           |  |  | 579 |      *
 | 
        
           |  |  | 580 |      * These modes are bitwised, so they can be combined using <kbd>|</kbd>
 | 
        
           |  |  | 581 |      * and removed using <kbd>^</kbd>.  See the examples section below on how
 | 
        
           |  |  | 582 |      * to do this.
 | 
        
           |  |  | 583 |      *
 | 
        
           |  |  | 584 |      * <samp>DB_PORTABILITY_NONE</samp>
 | 
        
           |  |  | 585 |      * turn off all portability features
 | 
        
           |  |  | 586 |      *
 | 
        
           |  |  | 587 |      * This mode gets automatically turned on if the deprecated
 | 
        
           |  |  | 588 |      * <var>optimize</var> option gets set to <samp>performance</samp>.
 | 
        
           |  |  | 589 |      *
 | 
        
           |  |  | 590 |      *
 | 
        
           |  |  | 591 |      * <samp>DB_PORTABILITY_LOWERCASE</samp>
 | 
        
           |  |  | 592 |      * convert names of tables and fields to lower case when using
 | 
        
           |  |  | 593 |      * <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
 | 
        
           |  |  | 594 |      *
 | 
        
           |  |  | 595 |      * This mode gets automatically turned on in the following databases
 | 
        
           |  |  | 596 |      * if the deprecated option <var>optimize</var> gets set to
 | 
        
           |  |  | 597 |      * <samp>portability</samp>:
 | 
        
           |  |  | 598 |      * + oci8
 | 
        
           |  |  | 599 |      *
 | 
        
           |  |  | 600 |      *
 | 
        
           |  |  | 601 |      * <samp>DB_PORTABILITY_RTRIM</samp>
 | 
        
           |  |  | 602 |      * right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
 | 
        
           |  |  | 603 |      *
 | 
        
           |  |  | 604 |      *
 | 
        
           |  |  | 605 |      * <samp>DB_PORTABILITY_DELETE_COUNT</samp>
 | 
        
           |  |  | 606 |      * force reporting the number of rows deleted
 | 
        
           |  |  | 607 |      *
 | 
        
           |  |  | 608 |      * Some DBMS's don't count the number of rows deleted when performing
 | 
        
           |  |  | 609 |      * simple <kbd>DELETE FROM tablename</kbd> queries.  This portability
 | 
        
           |  |  | 610 |      * mode tricks such DBMS's into telling the count by adding
 | 
        
           |  |  | 611 |      * <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
 | 
        
           |  |  | 612 |      *
 | 
        
           |  |  | 613 |      * This mode gets automatically turned on in the following databases
 | 
        
           |  |  | 614 |      * if the deprecated option <var>optimize</var> gets set to
 | 
        
           |  |  | 615 |      * <samp>portability</samp>:
 | 
        
           |  |  | 616 |      * + fbsql
 | 
        
           |  |  | 617 |      * + mysql
 | 
        
           |  |  | 618 |      * + mysqli
 | 
        
           |  |  | 619 |      * + sqlite
 | 
        
           |  |  | 620 |      *
 | 
        
           |  |  | 621 |      *
 | 
        
           |  |  | 622 |      * <samp>DB_PORTABILITY_NUMROWS</samp>
 | 
        
           |  |  | 623 |      * enable hack that makes <kbd>numRows()</kbd> work in Oracle
 | 
        
           |  |  | 624 |      *
 | 
        
           |  |  | 625 |      * This mode gets automatically turned on in the following databases
 | 
        
           |  |  | 626 |      * if the deprecated option <var>optimize</var> gets set to
 | 
        
           |  |  | 627 |      * <samp>portability</samp>:
 | 
        
           |  |  | 628 |      * + oci8
 | 
        
           |  |  | 629 |      *
 | 
        
           |  |  | 630 |      *
 | 
        
           |  |  | 631 |      * <samp>DB_PORTABILITY_ERRORS</samp>
 | 
        
           |  |  | 632 |      * makes certain error messages in certain drivers compatible
 | 
        
           |  |  | 633 |      * with those from other DBMS's
 | 
        
           |  |  | 634 |      *
 | 
        
           |  |  | 635 |      * + mysql, mysqli:  change unique/primary key constraints
 | 
        
           |  |  | 636 |      *   DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
 | 
        
           |  |  | 637 |      *
 | 
        
           |  |  | 638 |      * + odbc(access):  MS's ODBC driver reports 'no such field' as code
 | 
        
           |  |  | 639 |      *   07001, which means 'too few parameters.'  When this option is on
 | 
        
           |  |  | 640 |      *   that code gets mapped to DB_ERROR_NOSUCHFIELD.
 | 
        
           |  |  | 641 |      *   DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
 | 
        
           |  |  | 642 |      *
 | 
        
           |  |  | 643 |      *
 | 
        
           |  |  | 644 |      * <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
 | 
        
           |  |  | 645 |      * convert null values to empty strings in data output by get*() and
 | 
        
           |  |  | 646 |      * fetch*().  Needed because Oracle considers empty strings to be null,
 | 
        
           |  |  | 647 |      * while most other DBMS's know the difference between empty and null.
 | 
        
           |  |  | 648 |      *
 | 
        
           |  |  | 649 |      *
 | 
        
           |  |  | 650 |      * <samp>DB_PORTABILITY_ALL</samp>
 | 
        
           |  |  | 651 |      * turn on all portability features
 | 
        
           |  |  | 652 |      *
 | 
        
           |  |  | 653 |      * -----------------------------------------
 | 
        
           |  |  | 654 |      *
 | 
        
           |  |  | 655 |      * Example 1. Simple setOption() example
 | 
        
           |  |  | 656 |      * <code> <?php
 | 
        
           |  |  | 657 |      * $dbh->setOption('autofree', true);
 | 
        
           |  |  | 658 |      * ?></code>
 | 
        
           |  |  | 659 |      *
 | 
        
           |  |  | 660 |      * Example 2. Portability for lowercasing and trimming
 | 
        
           |  |  | 661 |      * <code> <?php
 | 
        
           |  |  | 662 |      * $dbh->setOption('portability',
 | 
        
           |  |  | 663 |      *                  DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
 | 
        
           |  |  | 664 |      * ?></code>
 | 
        
           |  |  | 665 |      *
 | 
        
           |  |  | 666 |      * Example 3. All portability options except trimming
 | 
        
           |  |  | 667 |      * <code> <?php
 | 
        
           |  |  | 668 |      * $dbh->setOption('portability',
 | 
        
           |  |  | 669 |      *                  DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
 | 
        
           |  |  | 670 |      * ?></code>
 | 
        
           |  |  | 671 |      *
 | 
        
           |  |  | 672 |      * @param string $option option name
 | 
        
           |  |  | 673 |      * @param mixed  $value value for the option
 | 
        
           |  |  | 674 |      *
 | 
        
           |  |  | 675 |      * @return int  DB_OK on success.  DB_Error object on failure.
 | 
        
           |  |  | 676 |      *
 | 
        
           |  |  | 677 |      * @see DB_common::$options
 | 
        
           |  |  | 678 |      */
 | 
        
           |  |  | 679 |     function setOption($option, $value)
 | 
        
           |  |  | 680 |     {
 | 
        
           |  |  | 681 |         if (isset($this->options[$option])) {
 | 
        
           |  |  | 682 |             $this->options[$option] = $value;
 | 
        
           |  |  | 683 |   | 
        
           |  |  | 684 |             /*
 | 
        
           |  |  | 685 |              * Backwards compatibility check for the deprecated 'optimize'
 | 
        
           |  |  | 686 |              * option.  Done here in case settings change after connecting.
 | 
        
           |  |  | 687 |              */
 | 
        
           |  |  | 688 |             if ($option == 'optimize') {
 | 
        
           |  |  | 689 |                 if ($value == 'portability') {
 | 
        
           |  |  | 690 |                     switch ($this->phptype) {
 | 
        
           |  |  | 691 |                         case 'oci8':
 | 
        
           |  |  | 692 |                             $this->options['portability'] =
 | 
        
           |  |  | 693 |                                     DB_PORTABILITY_LOWERCASE |
 | 
        
           |  |  | 694 |                                     DB_PORTABILITY_NUMROWS;
 | 
        
           |  |  | 695 |                             break;
 | 
        
           |  |  | 696 |                         case 'fbsql':
 | 
        
           |  |  | 697 |                         case 'mysql':
 | 
        
           |  |  | 698 |                         case 'mysqli':
 | 
        
           |  |  | 699 |                         case 'sqlite':
 | 
        
           |  |  | 700 |                             $this->options['portability'] =
 | 
        
           |  |  | 701 |                                     DB_PORTABILITY_DELETE_COUNT;
 | 
        
           |  |  | 702 |                             break;
 | 
        
           |  |  | 703 |                     }
 | 
        
           |  |  | 704 |                 } else {
 | 
        
           |  |  | 705 |                     $this->options['portability'] = DB_PORTABILITY_NONE;
 | 
        
           |  |  | 706 |                 }
 | 
        
           |  |  | 707 |             }
 | 
        
           |  |  | 708 |   | 
        
           |  |  | 709 |             return DB_OK;
 | 
        
           |  |  | 710 |         }
 | 
        
           |  |  | 711 |         return $this->raiseError("unknown option $option");
 | 
        
           |  |  | 712 |     }
 | 
        
           |  |  | 713 |   | 
        
           |  |  | 714 |     // }}}
 | 
        
           |  |  | 715 |     // {{{ getOption()
 | 
        
           |  |  | 716 |   | 
        
           |  |  | 717 |     /**
 | 
        
           |  |  | 718 |      * Returns the value of an option
 | 
        
           |  |  | 719 |      *
 | 
        
           |  |  | 720 |      * @param string $option option name
 | 
        
           |  |  | 721 |      *
 | 
        
           |  |  | 722 |      * @return mixed the option value
 | 
        
           |  |  | 723 |      */
 | 
        
           |  |  | 724 |     function getOption($option)
 | 
        
           |  |  | 725 |     {
 | 
        
           |  |  | 726 |         if (isset($this->options[$option])) {
 | 
        
           |  |  | 727 |             return $this->options[$option];
 | 
        
           |  |  | 728 |         }
 | 
        
           |  |  | 729 |         return $this->raiseError("unknown option $option");
 | 
        
           |  |  | 730 |     }
 | 
        
           |  |  | 731 |   | 
        
           |  |  | 732 |     // }}}
 | 
        
           |  |  | 733 |     // {{{ prepare()
 | 
        
           |  |  | 734 |   | 
        
           |  |  | 735 |     /**
 | 
        
           |  |  | 736 |      * Prepares a query for multiple execution with execute()
 | 
        
           |  |  | 737 |      *
 | 
        
           |  |  | 738 |      * Creates a query that can be run multiple times.  Each time it is run,
 | 
        
           |  |  | 739 |      * the placeholders, if any, will be replaced by the contents of
 | 
        
           |  |  | 740 |      * execute()'s $data argument.
 | 
        
           |  |  | 741 |      *
 | 
        
           |  |  | 742 |      * Three types of placeholders can be used:
 | 
        
           |  |  | 743 |      *   + <kbd>?</kbd>  scalar value (i.e. strings, integers).  The system
 | 
        
           |  |  | 744 |      *                   will automatically quote and escape the data.
 | 
        
           |  |  | 745 |      *   + <kbd>!</kbd>  value is inserted 'as is'
 | 
        
           |  |  | 746 |      *   + <kbd>&</kbd>  requires a file name.  The file's contents get
 | 
        
           |  |  | 747 |      *                   inserted into the query (i.e. saving binary
 | 
        
           |  |  | 748 |      *                   data in a db)
 | 
        
           |  |  | 749 |      *
 | 
        
           |  |  | 750 |      * Example 1.
 | 
        
           |  |  | 751 |      * <code> <?php
 | 
        
           |  |  | 752 |      * $sth = $dbh->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
 | 
        
           |  |  | 753 |      * $data = array(
 | 
        
           |  |  | 754 |      *     "John's text",
 | 
        
           |  |  | 755 |      *     "'it''s good'",
 | 
        
           |  |  | 756 |      *     'filename.txt'
 | 
        
           |  |  | 757 |      * );
 | 
        
           |  |  | 758 |      * $res = $dbh->execute($sth, $data);
 | 
        
           |  |  | 759 |      * ?></code>
 | 
        
           |  |  | 760 |      *
 | 
        
           |  |  | 761 |      * Use backslashes to escape placeholder characters if you don't want
 | 
        
           |  |  | 762 |      * them to be interpreted as placeholders:
 | 
        
           |  |  | 763 |      * <pre>
 | 
        
           |  |  | 764 |      *    "UPDATE foo SET col=? WHERE col='over \& under'"
 | 
        
           |  |  | 765 |      * </pre>
 | 
        
           |  |  | 766 |      *
 | 
        
           |  |  | 767 |      * With some database backends, this is emulated.
 | 
        
           |  |  | 768 |      *
 | 
        
           |  |  | 769 |      * {@internal ibase and oci8 have their own prepare() methods.}}
 | 
        
           |  |  | 770 |      *
 | 
        
           |  |  | 771 |      * @param string $query query to be prepared
 | 
        
           |  |  | 772 |      *
 | 
        
           |  |  | 773 |      * @return mixed DB statement resource on success. DB_Error on failure.
 | 
        
           |  |  | 774 |      *
 | 
        
           |  |  | 775 |      * @see DB_common::execute()
 | 
        
           |  |  | 776 |      * @access public
 | 
        
           |  |  | 777 |      */
 | 
        
           |  |  | 778 |     function prepare($query)
 | 
        
           |  |  | 779 |     {
 | 
        
           |  |  | 780 |         $tokens   = preg_split('/((?<!\\\)[&?!])/', $query, -1,
 | 
        
           |  |  | 781 |                                PREG_SPLIT_DELIM_CAPTURE);
 | 
        
           |  |  | 782 |         $token     = 0;
 | 
        
           |  |  | 783 |         $types     = array();
 | 
        
           |  |  | 784 |         $newtokens = array();
 | 
        
           |  |  | 785 |   | 
        
           |  |  | 786 |         foreach ($tokens as $val) {
 | 
        
           |  |  | 787 |             switch ($val) {
 | 
        
           |  |  | 788 |                 case '?':
 | 
        
           |  |  | 789 |                     $types[$token++] = DB_PARAM_SCALAR;
 | 
        
           |  |  | 790 |                     break;
 | 
        
           |  |  | 791 |                 case '&':
 | 
        
           |  |  | 792 |                     $types[$token++] = DB_PARAM_OPAQUE;
 | 
        
           |  |  | 793 |                     break;
 | 
        
           |  |  | 794 |                 case '!':
 | 
        
           |  |  | 795 |                     $types[$token++] = DB_PARAM_MISC;
 | 
        
           |  |  | 796 |                     break;
 | 
        
           |  |  | 797 |                 default:
 | 
        
           |  |  | 798 |                     $newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val);
 | 
        
           |  |  | 799 |             }
 | 
        
           |  |  | 800 |         }
 | 
        
           |  |  | 801 |   | 
        
           |  |  | 802 |         $this->prepare_tokens[] = &$newtokens;
 | 
        
           |  |  | 803 |         end($this->prepare_tokens);
 | 
        
           |  |  | 804 |   | 
        
           |  |  | 805 |         $k = key($this->prepare_tokens);
 | 
        
           |  |  | 806 |         $this->prepare_types[$k] = $types;
 | 
        
           |  |  | 807 |         $this->prepared_queries[$k] = implode(' ', $newtokens);
 | 
        
           |  |  | 808 |   | 
        
           |  |  | 809 |         return $k;
 | 
        
           |  |  | 810 |     }
 | 
        
           |  |  | 811 |   | 
        
           |  |  | 812 |     // }}}
 | 
        
           |  |  | 813 |     // {{{ autoPrepare()
 | 
        
           |  |  | 814 |   | 
        
           |  |  | 815 |     /**
 | 
        
           |  |  | 816 |      * Automaticaly generate an insert or update query and pass it to prepare()
 | 
        
           |  |  | 817 |      *
 | 
        
           |  |  | 818 |      * @param string $table name of the table
 | 
        
           |  |  | 819 |      * @param array $table_fields ordered array containing the fields names
 | 
        
           |  |  | 820 |      * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
 | 
        
           |  |  | 821 |      * @param string $where in case of update queries, this string will be put after the sql WHERE statement
 | 
        
           |  |  | 822 |      * @return resource handle for the query
 | 
        
           |  |  | 823 |      * @see DB_common::prepare(), DB_common::buildManipSQL()
 | 
        
           |  |  | 824 |      * @access public
 | 
        
           |  |  | 825 |      */
 | 
        
           |  |  | 826 |     function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, $where = false)
 | 
        
           |  |  | 827 |     {
 | 
        
           |  |  | 828 |         $query = $this->buildManipSQL($table, $table_fields, $mode, $where);
 | 
        
           |  |  | 829 |         return $this->prepare($query);
 | 
        
           |  |  | 830 |     }
 | 
        
           |  |  | 831 |   | 
        
           |  |  | 832 |     // }}}
 | 
        
           |  |  | 833 |     // {{{ autoExecute()
 | 
        
           |  |  | 834 |   | 
        
           |  |  | 835 |     /**
 | 
        
           |  |  | 836 |      * Automaticaly generate an insert or update query and call prepare()
 | 
        
           |  |  | 837 |      * and execute() with it
 | 
        
           |  |  | 838 |      *
 | 
        
           |  |  | 839 |      * @param string $table name of the table
 | 
        
           |  |  | 840 |      * @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value
 | 
        
           |  |  | 841 |      * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
 | 
        
           |  |  | 842 |      * @param string $where in case of update queries, this string will be put after the sql WHERE statement
 | 
        
           |  |  | 843 |      * @return mixed  a new DB_Result or a DB_Error when fail
 | 
        
           |  |  | 844 |      * @see DB_common::autoPrepare(), DB_common::buildManipSQL()
 | 
        
           |  |  | 845 |      * @access public
 | 
        
           |  |  | 846 |      */
 | 
        
           |  |  | 847 |     function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, $where = false)
 | 
        
           |  |  | 848 |     {
 | 
        
           |  |  | 849 |         $sth = $this->autoPrepare($table, array_keys($fields_values), $mode, $where);
 | 
        
           |  |  | 850 |         $ret =& $this->execute($sth, array_values($fields_values));
 | 
        
           |  |  | 851 |         $this->freePrepared($sth);
 | 
        
           |  |  | 852 |         return $ret;
 | 
        
           |  |  | 853 |   | 
        
           |  |  | 854 |     }
 | 
        
           |  |  | 855 |   | 
        
           |  |  | 856 |     // }}}
 | 
        
           |  |  | 857 |     // {{{ buildManipSQL()
 | 
        
           |  |  | 858 |   | 
        
           |  |  | 859 |     /**
 | 
        
           |  |  | 860 |      * Make automaticaly an sql query for prepare()
 | 
        
           |  |  | 861 |      *
 | 
        
           |  |  | 862 |      * Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), DB_AUTOQUERY_INSERT)
 | 
        
           |  |  | 863 |      *           will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
 | 
        
           |  |  | 864 |      * NB : - This belongs more to a SQL Builder class, but this is a simple facility
 | 
        
           |  |  | 865 |      *      - Be carefull ! If you don't give a $where param with an UPDATE query, all
 | 
        
           |  |  | 866 |      *        the records of the table will be updated !
 | 
        
           |  |  | 867 |      *
 | 
        
           |  |  | 868 |      * @param string $table name of the table
 | 
        
           |  |  | 869 |      * @param array $table_fields ordered array containing the fields names
 | 
        
           |  |  | 870 |      * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
 | 
        
           |  |  | 871 |      * @param string $where in case of update queries, this string will be put after the sql WHERE statement
 | 
        
           |  |  | 872 |      * @return string sql query for prepare()
 | 
        
           |  |  | 873 |      * @access public
 | 
        
           |  |  | 874 |      */
 | 
        
           |  |  | 875 |     function buildManipSQL($table, $table_fields, $mode, $where = false)
 | 
        
           |  |  | 876 |     {
 | 
        
           |  |  | 877 |         if (count($table_fields) == 0) {
 | 
        
           |  |  | 878 |             $this->raiseError(DB_ERROR_NEED_MORE_DATA);
 | 
        
           |  |  | 879 |         }
 | 
        
           |  |  | 880 |         $first = true;
 | 
        
           |  |  | 881 |         switch ($mode) {
 | 
        
           |  |  | 882 |             case DB_AUTOQUERY_INSERT:
 | 
        
           |  |  | 883 |                 $values = '';
 | 
        
           |  |  | 884 |                 $names = '';
 | 
        
           |  |  | 885 |                 foreach ($table_fields as $value) {
 | 
        
           |  |  | 886 |                     if ($first) {
 | 
        
           |  |  | 887 |                         $first = false;
 | 
        
           |  |  | 888 |                     } else {
 | 
        
           |  |  | 889 |                         $names .= ',';
 | 
        
           |  |  | 890 |                         $values .= ',';
 | 
        
           |  |  | 891 |                     }
 | 
        
           |  |  | 892 |                     $names .= $value;
 | 
        
           |  |  | 893 |                     $values .= '?';
 | 
        
           |  |  | 894 |                 }
 | 
        
           |  |  | 895 |                 return "INSERT INTO $table ($names) VALUES ($values)";
 | 
        
           |  |  | 896 |             case DB_AUTOQUERY_UPDATE:
 | 
        
           |  |  | 897 |                 $set = '';
 | 
        
           |  |  | 898 |                 foreach ($table_fields as $value) {
 | 
        
           |  |  | 899 |                     if ($first) {
 | 
        
           |  |  | 900 |                         $first = false;
 | 
        
           |  |  | 901 |                     } else {
 | 
        
           |  |  | 902 |                         $set .= ',';
 | 
        
           |  |  | 903 |                     }
 | 
        
           |  |  | 904 |                     $set .= "$value = ?";
 | 
        
           |  |  | 905 |                 }
 | 
        
           |  |  | 906 |                 $sql = "UPDATE $table SET $set";
 | 
        
           |  |  | 907 |                 if ($where) {
 | 
        
           |  |  | 908 |                     $sql .= " WHERE $where";
 | 
        
           |  |  | 909 |                 }
 | 
        
           |  |  | 910 |                 return $sql;
 | 
        
           |  |  | 911 |             default:
 | 
        
           |  |  | 912 |                 $this->raiseError(DB_ERROR_SYNTAX);
 | 
        
           |  |  | 913 |         }
 | 
        
           |  |  | 914 |     }
 | 
        
           |  |  | 915 |   | 
        
           |  |  | 916 |     // }}}
 | 
        
           |  |  | 917 |     // {{{ execute()
 | 
        
           |  |  | 918 |   | 
        
           |  |  | 919 |     /**
 | 
        
           |  |  | 920 |      * Executes a DB statement prepared with prepare()
 | 
        
           |  |  | 921 |      *
 | 
        
           |  |  | 922 |      * Example 1.
 | 
        
           |  |  | 923 |      * <code> <?php
 | 
        
           |  |  | 924 |      * $sth = $dbh->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
 | 
        
           |  |  | 925 |      * $data = array(
 | 
        
           |  |  | 926 |      *     "John's text",
 | 
        
           |  |  | 927 |      *     "'it''s good'",
 | 
        
           |  |  | 928 |      *     'filename.txt'
 | 
        
           |  |  | 929 |      * );
 | 
        
           |  |  | 930 |      * $res =& $dbh->execute($sth, $data);
 | 
        
           |  |  | 931 |      * ?></code>
 | 
        
           |  |  | 932 |      *
 | 
        
           |  |  | 933 |      * @param resource  $stmt  a DB statement resource returned from prepare()
 | 
        
           |  |  | 934 |      * @param mixed  $data  array, string or numeric data to be used in
 | 
        
           |  |  | 935 |      *                      execution of the statement.  Quantity of items
 | 
        
           |  |  | 936 |      *                      passed must match quantity of placeholders in
 | 
        
           |  |  | 937 |      *                      query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 938 |      *                      parameters or 1 placeholder per array element.
 | 
        
           |  |  | 939 |      *
 | 
        
           |  |  | 940 |      * @return object  a new DB_Result or a DB_Error when fail
 | 
        
           |  |  | 941 |      *
 | 
        
           |  |  | 942 |      * {@internal ibase and oci8 have their own execute() methods.}}
 | 
        
           |  |  | 943 |      *
 | 
        
           |  |  | 944 |      * @see DB_common::prepare()
 | 
        
           |  |  | 945 |      * @access public
 | 
        
           |  |  | 946 |      */
 | 
        
           |  |  | 947 |     function &execute($stmt, $data = array())
 | 
        
           |  |  | 948 |     {
 | 
        
           |  |  | 949 |         $realquery = $this->executeEmulateQuery($stmt, $data);
 | 
        
           |  |  | 950 |         if (DB::isError($realquery)) {
 | 
        
           |  |  | 951 |             return $realquery;
 | 
        
           |  |  | 952 |         }
 | 
        
           |  |  | 953 |         $result = $this->simpleQuery($realquery);
 | 
        
           |  |  | 954 |   | 
        
           |  |  | 955 |         if (DB::isError($result) || $result === DB_OK) {
 | 
        
           |  |  | 956 |             return $result;
 | 
        
           |  |  | 957 |         } else {
 | 
        
           |  |  | 958 |             $tmp =& new DB_result($this, $result);
 | 
        
           |  |  | 959 |             return $tmp;
 | 
        
           |  |  | 960 |         }
 | 
        
           |  |  | 961 |     }
 | 
        
           |  |  | 962 |   | 
        
           |  |  | 963 |     // }}}
 | 
        
           |  |  | 964 |     // {{{ executeEmulateQuery()
 | 
        
           |  |  | 965 |   | 
        
           |  |  | 966 |     /**
 | 
        
           |  |  | 967 |      * Emulates the execute statement, when not supported
 | 
        
           |  |  | 968 |      *
 | 
        
           |  |  | 969 |      * @param resource  $stmt  a DB statement resource returned from execute()
 | 
        
           |  |  | 970 |      * @param mixed  $data  array, string or numeric data to be used in
 | 
        
           |  |  | 971 |      *                      execution of the statement.  Quantity of items
 | 
        
           |  |  | 972 |      *                      passed must match quantity of placeholders in
 | 
        
           |  |  | 973 |      *                      query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 974 |      *                      parameters or 1 placeholder per array element.
 | 
        
           |  |  | 975 |      *
 | 
        
           |  |  | 976 |      * @return mixed a string containing the real query run when emulating
 | 
        
           |  |  | 977 |      *               prepare/execute.  A DB error code is returned on failure.
 | 
        
           |  |  | 978 |      *
 | 
        
           |  |  | 979 |      * @see DB_common::execute()
 | 
        
           |  |  | 980 |      * @access private
 | 
        
           |  |  | 981 |      */
 | 
        
           |  |  | 982 |     function executeEmulateQuery($stmt, $data = array())
 | 
        
           |  |  | 983 |     {
 | 
        
           |  |  | 984 |         if (!is_array($data)) {
 | 
        
           |  |  | 985 |             $data = array($data);
 | 
        
           |  |  | 986 |         }
 | 
        
           |  |  | 987 |   | 
        
           |  |  | 988 |         if (count($this->prepare_types[$stmt]) != count($data)) {
 | 
        
           |  |  | 989 |             $this->last_query = $this->prepared_queries[$stmt];
 | 
        
           |  |  | 990 |             return $this->raiseError(DB_ERROR_MISMATCH);
 | 
        
           |  |  | 991 |         }
 | 
        
           |  |  | 992 |   | 
        
           |  |  | 993 |         $realquery = $this->prepare_tokens[$stmt][0];
 | 
        
           |  |  | 994 |   | 
        
           |  |  | 995 |         $i = 0;
 | 
        
           |  |  | 996 |         foreach ($data as $value) {
 | 
        
           |  |  | 997 |             if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) {
 | 
        
           |  |  | 998 |                 $realquery .= $this->quoteSmart($value);
 | 
        
           |  |  | 999 |             } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) {
 | 
        
           |  |  | 1000 |                 $fp = @fopen($value, 'rb');
 | 
        
           |  |  | 1001 |                 if (!$fp) {
 | 
        
           |  |  | 1002 |                     return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
 | 
        
           |  |  | 1003 |                 }
 | 
        
           |  |  | 1004 |                 $realquery .= $this->quoteSmart(fread($fp, filesize($value)));
 | 
        
           |  |  | 1005 |                 fclose($fp);
 | 
        
           |  |  | 1006 |             } else {
 | 
        
           |  |  | 1007 |                 $realquery .= $value;
 | 
        
           |  |  | 1008 |             }
 | 
        
           |  |  | 1009 |   | 
        
           |  |  | 1010 |             $realquery .= $this->prepare_tokens[$stmt][++$i];
 | 
        
           |  |  | 1011 |         }
 | 
        
           |  |  | 1012 |   | 
        
           |  |  | 1013 |         return $realquery;
 | 
        
           |  |  | 1014 |     }
 | 
        
           |  |  | 1015 |   | 
        
           |  |  | 1016 |     // }}}
 | 
        
           |  |  | 1017 |     // {{{ executeMultiple()
 | 
        
           |  |  | 1018 |   | 
        
           |  |  | 1019 |     /**
 | 
        
           |  |  | 1020 |      * This function does several execute() calls on the same
 | 
        
           |  |  | 1021 |      * statement handle
 | 
        
           |  |  | 1022 |      *
 | 
        
           |  |  | 1023 |      * $data must be an array indexed numerically
 | 
        
           |  |  | 1024 |      * from 0, one execute call is done for every "row" in the array.
 | 
        
           |  |  | 1025 |      *
 | 
        
           |  |  | 1026 |      * If an error occurs during execute(), executeMultiple() does not
 | 
        
           |  |  | 1027 |      * execute the unfinished rows, but rather returns that error.
 | 
        
           |  |  | 1028 |      *
 | 
        
           |  |  | 1029 |      * @param resource $stmt query handle from prepare()
 | 
        
           |  |  | 1030 |      * @param array    $data numeric array containing the
 | 
        
           |  |  | 1031 |      *                       data to insert into the query
 | 
        
           |  |  | 1032 |      *
 | 
        
           |  |  | 1033 |      * @return mixed DB_OK or DB_Error
 | 
        
           |  |  | 1034 |      *
 | 
        
           |  |  | 1035 |      * @see DB_common::prepare(), DB_common::execute()
 | 
        
           |  |  | 1036 |      * @access public
 | 
        
           |  |  | 1037 |      */
 | 
        
           |  |  | 1038 |     function executeMultiple($stmt, $data)
 | 
        
           |  |  | 1039 |     {
 | 
        
           |  |  | 1040 |         foreach ($data as $value) {
 | 
        
           |  |  | 1041 |             $res =& $this->execute($stmt, $value);
 | 
        
           |  |  | 1042 |             if (DB::isError($res)) {
 | 
        
           |  |  | 1043 |                 return $res;
 | 
        
           |  |  | 1044 |             }
 | 
        
           |  |  | 1045 |         }
 | 
        
           |  |  | 1046 |         return DB_OK;
 | 
        
           |  |  | 1047 |     }
 | 
        
           |  |  | 1048 |   | 
        
           |  |  | 1049 |     // }}}
 | 
        
           |  |  | 1050 |     // {{{ freePrepared()
 | 
        
           |  |  | 1051 |   | 
        
           |  |  | 1052 |     /**
 | 
        
           |  |  | 1053 |      * Free the resource used in a prepared query
 | 
        
           |  |  | 1054 |      *
 | 
        
           |  |  | 1055 |      * @param $stmt The resurce returned by the prepare() function
 | 
        
           |  |  | 1056 |      * @see DB_common::prepare()
 | 
        
           |  |  | 1057 |      */
 | 
        
           |  |  | 1058 |     function freePrepared($stmt)
 | 
        
           |  |  | 1059 |     {
 | 
        
           |  |  | 1060 |         // Free the internal prepared vars
 | 
        
           |  |  | 1061 |         if (isset($this->prepare_tokens[$stmt])) {
 | 
        
           |  |  | 1062 |             unset($this->prepare_tokens[$stmt]);
 | 
        
           |  |  | 1063 |             unset($this->prepare_types[$stmt]);
 | 
        
           |  |  | 1064 |             unset($this->prepared_queries[$stmt]);
 | 
        
           |  |  | 1065 |             return true;
 | 
        
           |  |  | 1066 |         }
 | 
        
           |  |  | 1067 |         return false;
 | 
        
           |  |  | 1068 |     }
 | 
        
           |  |  | 1069 |   | 
        
           |  |  | 1070 |     // }}}
 | 
        
           |  |  | 1071 |     // {{{ modifyQuery()
 | 
        
           |  |  | 1072 |   | 
        
           |  |  | 1073 |     /**
 | 
        
           |  |  | 1074 |      * This method is used by backends to alter queries for various
 | 
        
           |  |  | 1075 |      * reasons
 | 
        
           |  |  | 1076 |      *
 | 
        
           |  |  | 1077 |      * It is defined here to assure that all implementations
 | 
        
           |  |  | 1078 |      * have this method defined.
 | 
        
           |  |  | 1079 |      *
 | 
        
           |  |  | 1080 |      * @param string $query  query to modify
 | 
        
           |  |  | 1081 |      *
 | 
        
           |  |  | 1082 |      * @return the new (modified) query
 | 
        
           |  |  | 1083 |      *
 | 
        
           |  |  | 1084 |      * @access private
 | 
        
           |  |  | 1085 |      */
 | 
        
           |  |  | 1086 |     function modifyQuery($query) {
 | 
        
           |  |  | 1087 |         return $query;
 | 
        
           |  |  | 1088 |     }
 | 
        
           |  |  | 1089 |   | 
        
           |  |  | 1090 |     // }}}
 | 
        
           |  |  | 1091 |     // {{{ modifyLimitQuery()
 | 
        
           |  |  | 1092 |   | 
        
           |  |  | 1093 |     /**
 | 
        
           |  |  | 1094 |      * This method is used by backends to alter limited queries
 | 
        
           |  |  | 1095 |      *
 | 
        
           |  |  | 1096 |      * @param string  $query query to modify
 | 
        
           |  |  | 1097 |      * @param integer $from  the row to start to fetching
 | 
        
           |  |  | 1098 |      * @param integer $count the numbers of rows to fetch
 | 
        
           |  |  | 1099 |      *
 | 
        
           |  |  | 1100 |      * @return the new (modified) query
 | 
        
           |  |  | 1101 |      *
 | 
        
           |  |  | 1102 |      * @access private
 | 
        
           |  |  | 1103 |      */
 | 
        
           |  |  | 1104 |     function modifyLimitQuery($query, $from, $count, $params = array())
 | 
        
           |  |  | 1105 |     {
 | 
        
           |  |  | 1106 |         return $query;
 | 
        
           |  |  | 1107 |     }
 | 
        
           |  |  | 1108 |   | 
        
           |  |  | 1109 |     // }}}
 | 
        
           |  |  | 1110 |     // {{{ query()
 | 
        
           |  |  | 1111 |   | 
        
           |  |  | 1112 |     /**
 | 
        
           |  |  | 1113 |      * Send a query to the database and return any results with a
 | 
        
           |  |  | 1114 |      * DB_result object
 | 
        
           |  |  | 1115 |      *
 | 
        
           |  |  | 1116 |      * The query string can be either a normal statement to be sent directly
 | 
        
           |  |  | 1117 |      * to the server OR if <var>$params</var> are passed the query can have
 | 
        
           |  |  | 1118 |      * placeholders and it will be passed through prepare() and execute().
 | 
        
           |  |  | 1119 |      *
 | 
        
           |  |  | 1120 |      * @param string $query  the SQL query or the statement to prepare
 | 
        
           |  |  | 1121 |      * @param mixed  $params array, string or numeric data to be used in
 | 
        
           |  |  | 1122 |      *                       execution of the statement.  Quantity of items
 | 
        
           |  |  | 1123 |      *                       passed must match quantity of placeholders in
 | 
        
           |  |  | 1124 |      *                       query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 1125 |      *                       parameters or 1 placeholder per array element.
 | 
        
           |  |  | 1126 |      *
 | 
        
           |  |  | 1127 |      * @return mixed  a DB_result object or DB_OK on success, a DB
 | 
        
           |  |  | 1128 |      *                error on failure
 | 
        
           |  |  | 1129 |      *
 | 
        
           |  |  | 1130 |      * @see DB_result, DB_common::prepare(), DB_common::execute()
 | 
        
           |  |  | 1131 |      * @access public
 | 
        
           |  |  | 1132 |      */
 | 
        
           |  |  | 1133 |     function &query($query, $params = array())
 | 
        
           |  |  | 1134 |     {
 | 
        
           |  |  | 1135 |         if (sizeof($params) > 0) {
 | 
        
           |  |  | 1136 |             $sth = $this->prepare($query);
 | 
        
           |  |  | 1137 |             if (DB::isError($sth)) {
 | 
        
           |  |  | 1138 |                 return $sth;
 | 
        
           |  |  | 1139 |             }
 | 
        
           |  |  | 1140 |             $ret =& $this->execute($sth, $params);
 | 
        
           |  |  | 1141 |             $this->freePrepared($sth);
 | 
        
           |  |  | 1142 |             return $ret;
 | 
        
           |  |  | 1143 |         } else {
 | 
        
           |  |  | 1144 |             $result = $this->simpleQuery($query);
 | 
        
           |  |  | 1145 |             if (DB::isError($result) || $result === DB_OK) {
 | 
        
           |  |  | 1146 |                 return $result;
 | 
        
           |  |  | 1147 |             } else {
 | 
        
           |  |  | 1148 |                 $tmp =& new DB_result($this, $result);
 | 
        
           |  |  | 1149 |                 return $tmp;
 | 
        
           |  |  | 1150 |             }
 | 
        
           |  |  | 1151 |         }
 | 
        
           |  |  | 1152 |     }
 | 
        
           |  |  | 1153 |   | 
        
           |  |  | 1154 |     // }}}
 | 
        
           |  |  | 1155 |     // {{{ limitQuery()
 | 
        
           |  |  | 1156 |   | 
        
           |  |  | 1157 |     /**
 | 
        
           |  |  | 1158 |      * Generates a limited query
 | 
        
           |  |  | 1159 |      *
 | 
        
           |  |  | 1160 |      * @param string  $query query
 | 
        
           |  |  | 1161 |      * @param integer $from  the row to start to fetching
 | 
        
           |  |  | 1162 |      * @param integer $count the numbers of rows to fetch
 | 
        
           |  |  | 1163 |      * @param mixed   $params array, string or numeric data to be used in
 | 
        
           |  |  | 1164 |      *                       execution of the statement.  Quantity of items
 | 
        
           |  |  | 1165 |      *                       passed must match quantity of placeholders in
 | 
        
           |  |  | 1166 |      *                       query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 1167 |      *                       parameters or 1 placeholder per array element.
 | 
        
           |  |  | 1168 |      *
 | 
        
           |  |  | 1169 |      * @return mixed a DB_Result object, DB_OK or a DB_Error
 | 
        
           |  |  | 1170 |      *
 | 
        
           |  |  | 1171 |      * @access public
 | 
        
           |  |  | 1172 |      */
 | 
        
           |  |  | 1173 |     function &limitQuery($query, $from, $count, $params = array())
 | 
        
           |  |  | 1174 |     {
 | 
        
           |  |  | 1175 |         $query = $this->modifyLimitQuery($query, $from, $count, $params);
 | 
        
           |  |  | 1176 |         if (DB::isError($query)){
 | 
        
           |  |  | 1177 |             return $query;
 | 
        
           |  |  | 1178 |         }
 | 
        
           |  |  | 1179 |         $result =& $this->query($query, $params);
 | 
        
           |  |  | 1180 |         if (is_a($result, 'DB_result')) {
 | 
        
           |  |  | 1181 |             $result->setOption('limit_from', $from);
 | 
        
           |  |  | 1182 |             $result->setOption('limit_count', $count);
 | 
        
           |  |  | 1183 |         }
 | 
        
           |  |  | 1184 |         return $result;
 | 
        
           |  |  | 1185 |     }
 | 
        
           |  |  | 1186 |   | 
        
           |  |  | 1187 |     // }}}
 | 
        
           |  |  | 1188 |     // {{{ getOne()
 | 
        
           |  |  | 1189 |   | 
        
           |  |  | 1190 |     /**
 | 
        
           |  |  | 1191 |      * Fetch the first column of the first row of data returned from
 | 
        
           |  |  | 1192 |      * a query
 | 
        
           |  |  | 1193 |      *
 | 
        
           |  |  | 1194 |      * Takes care of doing the query and freeing the results when finished.
 | 
        
           |  |  | 1195 |      *
 | 
        
           |  |  | 1196 |      * @param string $query  the SQL query
 | 
        
           |  |  | 1197 |      * @param mixed  $params array, string or numeric data to be used in
 | 
        
           |  |  | 1198 |      *                       execution of the statement.  Quantity of items
 | 
        
           |  |  | 1199 |      *                       passed must match quantity of placeholders in
 | 
        
           |  |  | 1200 |      *                       query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 1201 |      *                       parameters or 1 placeholder per array element.
 | 
        
           |  |  | 1202 |      *
 | 
        
           |  |  | 1203 |      * @return mixed  the returned value of the query.  DB_Error on failure.
 | 
        
           |  |  | 1204 |      *
 | 
        
           |  |  | 1205 |      * @access public
 | 
        
           |  |  | 1206 |      */
 | 
        
           |  |  | 1207 |     function &getOne($query, $params = array())
 | 
        
           |  |  | 1208 |     {
 | 
        
           |  |  | 1209 |         settype($params, 'array');
 | 
        
           |  |  | 1210 |         if (sizeof($params) > 0) {
 | 
        
           |  |  | 1211 |             $sth = $this->prepare($query);
 | 
        
           |  |  | 1212 |             if (DB::isError($sth)) {
 | 
        
           |  |  | 1213 |                 return $sth;
 | 
        
           |  |  | 1214 |             }
 | 
        
           |  |  | 1215 |             $res =& $this->execute($sth, $params);
 | 
        
           |  |  | 1216 |             $this->freePrepared($sth);
 | 
        
           |  |  | 1217 |         } else {
 | 
        
           |  |  | 1218 |             $res =& $this->query($query);
 | 
        
           |  |  | 1219 |         }
 | 
        
           |  |  | 1220 |   | 
        
           |  |  | 1221 |         if (DB::isError($res)) {
 | 
        
           |  |  | 1222 |             return $res;
 | 
        
           |  |  | 1223 |         }
 | 
        
           |  |  | 1224 |   | 
        
           |  |  | 1225 |         $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
 | 
        
           |  |  | 1226 |         $res->free();
 | 
        
           |  |  | 1227 |   | 
        
           |  |  | 1228 |         if ($err !== DB_OK) {
 | 
        
           |  |  | 1229 |             return $err;
 | 
        
           |  |  | 1230 |         }
 | 
        
           |  |  | 1231 |   | 
        
           |  |  | 1232 |         return $row[0];
 | 
        
           |  |  | 1233 |     }
 | 
        
           |  |  | 1234 |   | 
        
           |  |  | 1235 |     // }}}
 | 
        
           |  |  | 1236 |     // {{{ getRow()
 | 
        
           |  |  | 1237 |   | 
        
           |  |  | 1238 |     /**
 | 
        
           |  |  | 1239 |      * Fetch the first row of data returned from a query
 | 
        
           |  |  | 1240 |      *
 | 
        
           |  |  | 1241 |      * Takes care of doing the query and freeing the results when finished.
 | 
        
           |  |  | 1242 |      *
 | 
        
           |  |  | 1243 |      * @param string $query  the SQL query
 | 
        
           |  |  | 1244 |      * @param array  $params array to be used in execution of the statement.
 | 
        
           |  |  | 1245 |      *                       Quantity of array elements must match quantity
 | 
        
           |  |  | 1246 |      *                       of placeholders in query.  This function does
 | 
        
           |  |  | 1247 |      *                       NOT support scalars.
 | 
        
           |  |  | 1248 |      * @param int    $fetchmode  the fetch mode to use
 | 
        
           |  |  | 1249 |      *
 | 
        
           |  |  | 1250 |      * @return array the first row of results as an array indexed from
 | 
        
           |  |  | 1251 |      *               0, or a DB error code.
 | 
        
           |  |  | 1252 |      *
 | 
        
           |  |  | 1253 |      * @access public
 | 
        
           |  |  | 1254 |      */
 | 
        
           |  |  | 1255 |     function &getRow($query,
 | 
        
           |  |  | 1256 |                      $params = array(),
 | 
        
           |  |  | 1257 |                      $fetchmode = DB_FETCHMODE_DEFAULT)
 | 
        
           |  |  | 1258 |     {
 | 
        
           |  |  | 1259 |         // compat check, the params and fetchmode parameters used to
 | 
        
           |  |  | 1260 |         // have the opposite order
 | 
        
           |  |  | 1261 |         if (!is_array($params)) {
 | 
        
           |  |  | 1262 |             if (is_array($fetchmode)) {
 | 
        
           |  |  | 1263 |                 if ($params === null) {
 | 
        
           |  |  | 1264 |                     $tmp = DB_FETCHMODE_DEFAULT;
 | 
        
           |  |  | 1265 |                 } else {
 | 
        
           |  |  | 1266 |                     $tmp = $params;
 | 
        
           |  |  | 1267 |                 }
 | 
        
           |  |  | 1268 |                 $params = $fetchmode;
 | 
        
           |  |  | 1269 |                 $fetchmode = $tmp;
 | 
        
           |  |  | 1270 |             } elseif ($params !== null) {
 | 
        
           |  |  | 1271 |                 $fetchmode = $params;
 | 
        
           |  |  | 1272 |                 $params = array();
 | 
        
           |  |  | 1273 |             }
 | 
        
           |  |  | 1274 |         }
 | 
        
           |  |  | 1275 |   | 
        
           |  |  | 1276 |         if (sizeof($params) > 0) {
 | 
        
           |  |  | 1277 |             $sth = $this->prepare($query);
 | 
        
           |  |  | 1278 |             if (DB::isError($sth)) {
 | 
        
           |  |  | 1279 |                 return $sth;
 | 
        
           |  |  | 1280 |             }
 | 
        
           |  |  | 1281 |             $res =& $this->execute($sth, $params);
 | 
        
           |  |  | 1282 |             $this->freePrepared($sth);
 | 
        
           |  |  | 1283 |         } else {
 | 
        
           |  |  | 1284 |             $res =& $this->query($query);
 | 
        
           |  |  | 1285 |         }
 | 
        
           |  |  | 1286 |   | 
        
           |  |  | 1287 |         if (DB::isError($res)) {
 | 
        
           |  |  | 1288 |             return $res;
 | 
        
           |  |  | 1289 |         }
 | 
        
           |  |  | 1290 |   | 
        
           |  |  | 1291 |         $err = $res->fetchInto($row, $fetchmode);
 | 
        
           |  |  | 1292 |   | 
        
           |  |  | 1293 |         $res->free();
 | 
        
           |  |  | 1294 |   | 
        
           |  |  | 1295 |         if ($err !== DB_OK) {
 | 
        
           |  |  | 1296 |             return $err;
 | 
        
           |  |  | 1297 |         }
 | 
        
           |  |  | 1298 |   | 
        
           |  |  | 1299 |         return $row;
 | 
        
           |  |  | 1300 |     }
 | 
        
           |  |  | 1301 |   | 
        
           |  |  | 1302 |     // }}}
 | 
        
           |  |  | 1303 |     // {{{ getCol()
 | 
        
           |  |  | 1304 |   | 
        
           |  |  | 1305 |     /**
 | 
        
           |  |  | 1306 |      * Fetch a single column from a result set and return it as an
 | 
        
           |  |  | 1307 |      * indexed array
 | 
        
           |  |  | 1308 |      *
 | 
        
           |  |  | 1309 |      * @param string $query  the SQL query
 | 
        
           |  |  | 1310 |      * @param mixed  $col    which column to return (integer [column number,
 | 
        
           |  |  | 1311 |      *                       starting at 0] or string [column name])
 | 
        
           |  |  | 1312 |      * @param mixed  $params array, string or numeric data to be used in
 | 
        
           |  |  | 1313 |      *                       execution of the statement.  Quantity of items
 | 
        
           |  |  | 1314 |      *                       passed must match quantity of placeholders in
 | 
        
           |  |  | 1315 |      *                       query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 1316 |      *                       parameters or 1 placeholder per array element.
 | 
        
           |  |  | 1317 |      *
 | 
        
           |  |  | 1318 |      * @return array  an indexed array with the data from the first
 | 
        
           |  |  | 1319 |      *                row at index 0, or a DB error code
 | 
        
           |  |  | 1320 |      *
 | 
        
           |  |  | 1321 |      * @see DB_common::query()
 | 
        
           |  |  | 1322 |      * @access public
 | 
        
           |  |  | 1323 |      */
 | 
        
           |  |  | 1324 |     function &getCol($query, $col = 0, $params = array())
 | 
        
           |  |  | 1325 |     {
 | 
        
           |  |  | 1326 |         settype($params, 'array');
 | 
        
           |  |  | 1327 |         if (sizeof($params) > 0) {
 | 
        
           |  |  | 1328 |             $sth = $this->prepare($query);
 | 
        
           |  |  | 1329 |   | 
        
           |  |  | 1330 |             if (DB::isError($sth)) {
 | 
        
           |  |  | 1331 |                 return $sth;
 | 
        
           |  |  | 1332 |             }
 | 
        
           |  |  | 1333 |   | 
        
           |  |  | 1334 |             $res =& $this->execute($sth, $params);
 | 
        
           |  |  | 1335 |             $this->freePrepared($sth);
 | 
        
           |  |  | 1336 |         } else {
 | 
        
           |  |  | 1337 |             $res =& $this->query($query);
 | 
        
           |  |  | 1338 |         }
 | 
        
           |  |  | 1339 |   | 
        
           |  |  | 1340 |         if (DB::isError($res)) {
 | 
        
           |  |  | 1341 |             return $res;
 | 
        
           |  |  | 1342 |         }
 | 
        
           |  |  | 1343 |   | 
        
           |  |  | 1344 |         $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
 | 
        
           |  |  | 1345 |   | 
        
           |  |  | 1346 |         if (!is_array($row = $res->fetchRow($fetchmode))) {
 | 
        
           |  |  | 1347 |             $ret = array();
 | 
        
           |  |  | 1348 |         } else {
 | 
        
           |  |  | 1349 |             if (!array_key_exists($col, $row)) {
 | 
        
           |  |  | 1350 |                 $ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
 | 
        
           |  |  | 1351 |             } else {
 | 
        
           |  |  | 1352 |                 $ret = array($row[$col]);
 | 
        
           |  |  | 1353 |                 while (is_array($row = $res->fetchRow($fetchmode))) {
 | 
        
           |  |  | 1354 |                     $ret[] = $row[$col];
 | 
        
           |  |  | 1355 |                 }
 | 
        
           |  |  | 1356 |             }
 | 
        
           |  |  | 1357 |         }
 | 
        
           |  |  | 1358 |   | 
        
           |  |  | 1359 |         $res->free();
 | 
        
           |  |  | 1360 |   | 
        
           |  |  | 1361 |         if (DB::isError($row)) {
 | 
        
           |  |  | 1362 |             $ret = $row;
 | 
        
           |  |  | 1363 |         }
 | 
        
           |  |  | 1364 |   | 
        
           |  |  | 1365 |         return $ret;
 | 
        
           |  |  | 1366 |     }
 | 
        
           |  |  | 1367 |   | 
        
           |  |  | 1368 |     // }}}
 | 
        
           |  |  | 1369 |     // {{{ getAssoc()
 | 
        
           |  |  | 1370 |   | 
        
           |  |  | 1371 |     /**
 | 
        
           |  |  | 1372 |      * Fetch the entire result set of a query and return it as an
 | 
        
           |  |  | 1373 |      * associative array using the first column as the key
 | 
        
           |  |  | 1374 |      *
 | 
        
           |  |  | 1375 |      * If the result set contains more than two columns, the value
 | 
        
           |  |  | 1376 |      * will be an array of the values from column 2-n.  If the result
 | 
        
           |  |  | 1377 |      * set contains only two columns, the returned value will be a
 | 
        
           |  |  | 1378 |      * scalar with the value of the second column (unless forced to an
 | 
        
           |  |  | 1379 |      * array with the $force_array parameter).  A DB error code is
 | 
        
           |  |  | 1380 |      * returned on errors.  If the result set contains fewer than two
 | 
        
           |  |  | 1381 |      * columns, a DB_ERROR_TRUNCATED error is returned.
 | 
        
           |  |  | 1382 |      *
 | 
        
           |  |  | 1383 |      * For example, if the table "mytable" contains:
 | 
        
           |  |  | 1384 |      *
 | 
        
           |  |  | 1385 |      * <pre>
 | 
        
           |  |  | 1386 |      *  ID      TEXT       DATE
 | 
        
           |  |  | 1387 |      * --------------------------------
 | 
        
           |  |  | 1388 |      *  1       'one'      944679408
 | 
        
           |  |  | 1389 |      *  2       'two'      944679408
 | 
        
           |  |  | 1390 |      *  3       'three'    944679408
 | 
        
           |  |  | 1391 |      * </pre>
 | 
        
           |  |  | 1392 |      *
 | 
        
           |  |  | 1393 |      * Then the call getAssoc('SELECT id,text FROM mytable') returns:
 | 
        
           |  |  | 1394 |      * <pre>
 | 
        
           |  |  | 1395 |      *   array(
 | 
        
           |  |  | 1396 |      *     '1' => 'one',
 | 
        
           |  |  | 1397 |      *     '2' => 'two',
 | 
        
           |  |  | 1398 |      *     '3' => 'three',
 | 
        
           |  |  | 1399 |      *   )
 | 
        
           |  |  | 1400 |      * </pre>
 | 
        
           |  |  | 1401 |      *
 | 
        
           |  |  | 1402 |      * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
 | 
        
           |  |  | 1403 |      * <pre>
 | 
        
           |  |  | 1404 |      *   array(
 | 
        
           |  |  | 1405 |      *     '1' => array('one', '944679408'),
 | 
        
           |  |  | 1406 |      *     '2' => array('two', '944679408'),
 | 
        
           |  |  | 1407 |      *     '3' => array('three', '944679408')
 | 
        
           |  |  | 1408 |      *   )
 | 
        
           |  |  | 1409 |      * </pre>
 | 
        
           |  |  | 1410 |      *
 | 
        
           |  |  | 1411 |      * If the more than one row occurs with the same value in the
 | 
        
           |  |  | 1412 |      * first column, the last row overwrites all previous ones by
 | 
        
           |  |  | 1413 |      * default.  Use the $group parameter if you don't want to
 | 
        
           |  |  | 1414 |      * overwrite like this.  Example:
 | 
        
           |  |  | 1415 |      *
 | 
        
           |  |  | 1416 |      * <pre>
 | 
        
           |  |  | 1417 |      * getAssoc('SELECT category,id,name FROM mytable', false, null,
 | 
        
           |  |  | 1418 |      *          DB_FETCHMODE_ASSOC, true) returns:
 | 
        
           |  |  | 1419 |      *
 | 
        
           |  |  | 1420 |      *   array(
 | 
        
           |  |  | 1421 |      *     '1' => array(array('id' => '4', 'name' => 'number four'),
 | 
        
           |  |  | 1422 |      *                  array('id' => '6', 'name' => 'number six')
 | 
        
           |  |  | 1423 |      *            ),
 | 
        
           |  |  | 1424 |      *     '9' => array(array('id' => '4', 'name' => 'number four'),
 | 
        
           |  |  | 1425 |      *                  array('id' => '6', 'name' => 'number six')
 | 
        
           |  |  | 1426 |      *            )
 | 
        
           |  |  | 1427 |      *   )
 | 
        
           |  |  | 1428 |      * </pre>
 | 
        
           |  |  | 1429 |      *
 | 
        
           |  |  | 1430 |      * Keep in mind that database functions in PHP usually return string
 | 
        
           |  |  | 1431 |      * values for results regardless of the database's internal type.
 | 
        
           |  |  | 1432 |      *
 | 
        
           |  |  | 1433 |      * @param string  $query  the SQL query
 | 
        
           |  |  | 1434 |      * @param boolean $force_array  used only when the query returns
 | 
        
           |  |  | 1435 |      *                              exactly two columns.  If true, the values
 | 
        
           |  |  | 1436 |      *                              of the returned array will be one-element
 | 
        
           |  |  | 1437 |      *                              arrays instead of scalars.
 | 
        
           |  |  | 1438 |      * @param mixed   $params array, string or numeric data to be used in
 | 
        
           |  |  | 1439 |      *                        execution of the statement.  Quantity of items
 | 
        
           |  |  | 1440 |      *                        passed must match quantity of placeholders in
 | 
        
           |  |  | 1441 |      *                        query:  meaning 1 placeholder for non-array
 | 
        
           |  |  | 1442 |      *                        parameters or 1 placeholder per array element.
 | 
        
           |  |  | 1443 |      * @param int     $fetchmode  the fetch mode to use
 | 
        
           |  |  | 1444 |      * @param boolean $group  if true, the values of the returned array
 | 
        
           |  |  | 1445 |      *                        is wrapped in another array.  If the same
 | 
        
           |  |  | 1446 |      *                        key value (in the first column) repeats
 | 
        
           |  |  | 1447 |      *                        itself, the values will be appended to
 | 
        
           |  |  | 1448 |      *                        this array instead of overwriting the
 | 
        
           |  |  | 1449 |      *                        existing values.
 | 
        
           |  |  | 1450 |      *
 | 
        
           |  |  | 1451 |      * @return array  associative array with results from the query.
 | 
        
           |  |  | 1452 |      *                DB Error on failure.
 | 
        
           |  |  | 1453 |      *
 | 
        
           |  |  | 1454 |      * @access public
 | 
        
           |  |  | 1455 |      */
 | 
        
           |  |  | 1456 |     function &getAssoc($query, $force_array = false, $params = array(),
 | 
        
           |  |  | 1457 |                        $fetchmode = DB_FETCHMODE_DEFAULT, $group = false)
 | 
        
           |  |  | 1458 |     {
 | 
        
           |  |  | 1459 |         settype($params, 'array');
 | 
        
           |  |  | 1460 |         if (sizeof($params) > 0) {
 | 
        
           |  |  | 1461 |             $sth = $this->prepare($query);
 | 
        
           |  |  | 1462 |   | 
        
           |  |  | 1463 |             if (DB::isError($sth)) {
 | 
        
           |  |  | 1464 |                 return $sth;
 | 
        
           |  |  | 1465 |             }
 | 
        
           |  |  | 1466 |   | 
        
           |  |  | 1467 |             $res =& $this->execute($sth, $params);
 | 
        
           |  |  | 1468 |             $this->freePrepared($sth);
 | 
        
           |  |  | 1469 |         } else {
 | 
        
           |  |  | 1470 |             $res =& $this->query($query);
 | 
        
           |  |  | 1471 |         }
 | 
        
           |  |  | 1472 |   | 
        
           |  |  | 1473 |         if (DB::isError($res)) {
 | 
        
           |  |  | 1474 |             return $res;
 | 
        
           |  |  | 1475 |         }
 | 
        
           |  |  | 1476 |         if ($fetchmode == DB_FETCHMODE_DEFAULT) {
 | 
        
           |  |  | 1477 |             $fetchmode = $this->fetchmode;
 | 
        
           |  |  | 1478 |         }
 | 
        
           |  |  | 1479 |         $cols = $res->numCols();
 | 
        
           |  |  | 1480 |   | 
        
           |  |  | 1481 |         if ($cols < 2) {
 | 
        
           |  |  | 1482 |             $tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
 | 
        
           |  |  | 1483 |             return $tmp;
 | 
        
           |  |  | 1484 |         }
 | 
        
           |  |  | 1485 |   | 
        
           |  |  | 1486 |         $results = array();
 | 
        
           |  |  | 1487 |   | 
        
           |  |  | 1488 |         if ($cols > 2 || $force_array) {
 | 
        
           |  |  | 1489 |             // return array values
 | 
        
           |  |  | 1490 |             // XXX this part can be optimized
 | 
        
           |  |  | 1491 |             if ($fetchmode == DB_FETCHMODE_ASSOC) {
 | 
        
           |  |  | 1492 |                 while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) {
 | 
        
           |  |  | 1493 |                     reset($row);
 | 
        
           |  |  | 1494 |                     $key = current($row);
 | 
        
           |  |  | 1495 |                     unset($row[key($row)]);
 | 
        
           |  |  | 1496 |                     if ($group) {
 | 
        
           |  |  | 1497 |                         $results[$key][] = $row;
 | 
        
           |  |  | 1498 |                     } else {
 | 
        
           |  |  | 1499 |                         $results[$key] = $row;
 | 
        
           |  |  | 1500 |                     }
 | 
        
           |  |  | 1501 |                 }
 | 
        
           |  |  | 1502 |             } elseif ($fetchmode == DB_FETCHMODE_OBJECT) {
 | 
        
           |  |  | 1503 |                 while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) {
 | 
        
           |  |  | 1504 |                     $arr = get_object_vars($row);
 | 
        
           |  |  | 1505 |                     $key = current($arr);
 | 
        
           |  |  | 1506 |                     if ($group) {
 | 
        
           |  |  | 1507 |                         $results[$key][] = $row;
 | 
        
           |  |  | 1508 |                     } else {
 | 
        
           |  |  | 1509 |                         $results[$key] = $row;
 | 
        
           |  |  | 1510 |                     }
 | 
        
           |  |  | 1511 |                 }
 | 
        
           |  |  | 1512 |             } else {
 | 
        
           |  |  | 1513 |                 while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
 | 
        
           |  |  | 1514 |                     // we shift away the first element to get
 | 
        
           |  |  | 1515 |                     // indices running from 0 again
 | 
        
           |  |  | 1516 |                     $key = array_shift($row);
 | 
        
           |  |  | 1517 |                     if ($group) {
 | 
        
           |  |  | 1518 |                         $results[$key][] = $row;
 | 
        
           |  |  | 1519 |                     } else {
 | 
        
           |  |  | 1520 |                         $results[$key] = $row;
 | 
        
           |  |  | 1521 |                     }
 | 
        
           |  |  | 1522 |                 }
 | 
        
           |  |  | 1523 |             }
 | 
        
           |  |  | 1524 |             if (DB::isError($row)) {
 | 
        
           |  |  | 1525 |                 $results = $row;
 | 
        
           |  |  | 1526 |             }
 | 
        
           |  |  | 1527 |         } else {
 | 
        
           |  |  | 1528 |             // return scalar values
 | 
        
           |  |  | 1529 |             while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
 | 
        
           |  |  | 1530 |                 if ($group) {
 | 
        
           |  |  | 1531 |                     $results[$row[0]][] = $row[1];
 | 
        
           |  |  | 1532 |                 } else {
 | 
        
           |  |  | 1533 |                     $results[$row[0]] = $row[1];
 | 
        
           |  |  | 1534 |                 }
 | 
        
           |  |  | 1535 |             }
 | 
        
           |  |  | 1536 |             if (DB::isError($row)) {
 | 
        
           |  |  | 1537 |                 $results = $row;
 | 
        
           |  |  | 1538 |             }
 | 
        
           |  |  | 1539 |         }
 | 
        
           |  |  | 1540 |   | 
        
           |  |  | 1541 |         $res->free();
 | 
        
           |  |  | 1542 |   | 
        
           |  |  | 1543 |         return $results;
 | 
        
           |  |  | 1544 |     }
 | 
        
           |  |  | 1545 |   | 
        
           |  |  | 1546 |     // }}}
 | 
        
           |  |  | 1547 |     // {{{ getAll()
 | 
        
           |  |  | 1548 |   | 
        
           |  |  | 1549 |     /**
 | 
        
           |  |  | 1550 |      * Fetch all the rows returned from a query
 | 
        
           |  |  | 1551 |      *
 | 
        
           |  |  | 1552 |      * @param string $query  the SQL query
 | 
        
           |  |  | 1553 |      * @param array  $params array to be used in execution of the statement.
 | 
        
           |  |  | 1554 |      *                       Quantity of array elements must match quantity
 | 
        
           |  |  | 1555 |      *                       of placeholders in query.  This function does
 | 
        
           |  |  | 1556 |      *                       NOT support scalars.
 | 
        
           |  |  | 1557 |      * @param int    $fetchmode  the fetch mode to use
 | 
        
           |  |  | 1558 |      *
 | 
        
           |  |  | 1559 |      * @return array  an nested array.  DB error on failure.
 | 
        
           |  |  | 1560 |      *
 | 
        
           |  |  | 1561 |      * @access public
 | 
        
           |  |  | 1562 |      */
 | 
        
           |  |  | 1563 |     function &getAll($query,
 | 
        
           |  |  | 1564 |                      $params = array(),
 | 
        
           |  |  | 1565 |                      $fetchmode = DB_FETCHMODE_DEFAULT)
 | 
        
           |  |  | 1566 |     {
 | 
        
           |  |  | 1567 |         // compat check, the params and fetchmode parameters used to
 | 
        
           |  |  | 1568 |         // have the opposite order
 | 
        
           |  |  | 1569 |         if (!is_array($params)) {
 | 
        
           |  |  | 1570 |             if (is_array($fetchmode)) {
 | 
        
           |  |  | 1571 |                 if ($params === null) {
 | 
        
           |  |  | 1572 |                     $tmp = DB_FETCHMODE_DEFAULT;
 | 
        
           |  |  | 1573 |                 } else {
 | 
        
           |  |  | 1574 |                     $tmp = $params;
 | 
        
           |  |  | 1575 |                 }
 | 
        
           |  |  | 1576 |                 $params = $fetchmode;
 | 
        
           |  |  | 1577 |                 $fetchmode = $tmp;
 | 
        
           |  |  | 1578 |             } elseif ($params !== null) {
 | 
        
           |  |  | 1579 |                 $fetchmode = $params;
 | 
        
           |  |  | 1580 |                 $params = array();
 | 
        
           |  |  | 1581 |             }
 | 
        
           |  |  | 1582 |         }
 | 
        
           |  |  | 1583 |   | 
        
           |  |  | 1584 |         if (sizeof($params) > 0) {
 | 
        
           |  |  | 1585 |             $sth = $this->prepare($query);
 | 
        
           |  |  | 1586 |   | 
        
           |  |  | 1587 |             if (DB::isError($sth)) {
 | 
        
           |  |  | 1588 |                 return $sth;
 | 
        
           |  |  | 1589 |             }
 | 
        
           |  |  | 1590 |   | 
        
           |  |  | 1591 |             $res =& $this->execute($sth, $params);
 | 
        
           |  |  | 1592 |             $this->freePrepared($sth);
 | 
        
           |  |  | 1593 |         } else {
 | 
        
           |  |  | 1594 |             $res =& $this->query($query);
 | 
        
           |  |  | 1595 |         }
 | 
        
           |  |  | 1596 |   | 
        
           |  |  | 1597 |         if (DB::isError($res) || $res === DB_OK) {
 | 
        
           |  |  | 1598 |             return $res;
 | 
        
           |  |  | 1599 |         }
 | 
        
           |  |  | 1600 |   | 
        
           |  |  | 1601 |         $results = array();
 | 
        
           |  |  | 1602 |         while (DB_OK === $res->fetchInto($row, $fetchmode)) {
 | 
        
           |  |  | 1603 |             if ($fetchmode & DB_FETCHMODE_FLIPPED) {
 | 
        
           |  |  | 1604 |                 foreach ($row as $key => $val) {
 | 
        
           |  |  | 1605 |                     $results[$key][] = $val;
 | 
        
           |  |  | 1606 |                 }
 | 
        
           |  |  | 1607 |             } else {
 | 
        
           |  |  | 1608 |                 $results[] = $row;
 | 
        
           |  |  | 1609 |             }
 | 
        
           |  |  | 1610 |         }
 | 
        
           |  |  | 1611 |   | 
        
           |  |  | 1612 |         $res->free();
 | 
        
           |  |  | 1613 |   | 
        
           |  |  | 1614 |         if (DB::isError($row)) {
 | 
        
           |  |  | 1615 |             $tmp =& $this->raiseError($row);
 | 
        
           |  |  | 1616 |             return $tmp;
 | 
        
           |  |  | 1617 |         }
 | 
        
           |  |  | 1618 |         return $results;
 | 
        
           |  |  | 1619 |     }
 | 
        
           |  |  | 1620 |   | 
        
           |  |  | 1621 |     // }}}
 | 
        
           |  |  | 1622 |     // {{{ autoCommit()
 | 
        
           |  |  | 1623 |   | 
        
           |  |  | 1624 |     /**
 | 
        
           |  |  | 1625 |      * enable automatic Commit
 | 
        
           |  |  | 1626 |      *
 | 
        
           |  |  | 1627 |      * @param boolean $onoff
 | 
        
           |  |  | 1628 |      * @return mixed DB_Error
 | 
        
           |  |  | 1629 |      *
 | 
        
           |  |  | 1630 |      * @access public
 | 
        
           |  |  | 1631 |      */
 | 
        
           |  |  | 1632 |     function autoCommit($onoff=false)
 | 
        
           |  |  | 1633 |     {
 | 
        
           |  |  | 1634 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1635 |     }
 | 
        
           |  |  | 1636 |   | 
        
           |  |  | 1637 |     // }}}
 | 
        
           |  |  | 1638 |     // {{{ commit()
 | 
        
           |  |  | 1639 |   | 
        
           |  |  | 1640 |     /**
 | 
        
           |  |  | 1641 |      * starts a Commit
 | 
        
           |  |  | 1642 |      *
 | 
        
           |  |  | 1643 |      * @return mixed DB_Error
 | 
        
           |  |  | 1644 |      *
 | 
        
           |  |  | 1645 |      * @access public
 | 
        
           |  |  | 1646 |      */
 | 
        
           |  |  | 1647 |     function commit()
 | 
        
           |  |  | 1648 |     {
 | 
        
           |  |  | 1649 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1650 |     }
 | 
        
           |  |  | 1651 |   | 
        
           |  |  | 1652 |     // }}}
 | 
        
           |  |  | 1653 |     // {{{ rollback()
 | 
        
           |  |  | 1654 |   | 
        
           |  |  | 1655 |     /**
 | 
        
           |  |  | 1656 |      * starts a rollback
 | 
        
           |  |  | 1657 |      *
 | 
        
           |  |  | 1658 |      * @return mixed DB_Error
 | 
        
           |  |  | 1659 |      *
 | 
        
           |  |  | 1660 |      * @access public
 | 
        
           |  |  | 1661 |      */
 | 
        
           |  |  | 1662 |     function rollback()
 | 
        
           |  |  | 1663 |     {
 | 
        
           |  |  | 1664 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1665 |     }
 | 
        
           |  |  | 1666 |   | 
        
           |  |  | 1667 |     // }}}
 | 
        
           |  |  | 1668 |     // {{{ numRows()
 | 
        
           |  |  | 1669 |   | 
        
           |  |  | 1670 |     /**
 | 
        
           |  |  | 1671 |      * Returns the number of rows in a result object
 | 
        
           |  |  | 1672 |      *
 | 
        
           |  |  | 1673 |      * @param object DB_Result the result object to check
 | 
        
           |  |  | 1674 |      *
 | 
        
           |  |  | 1675 |      * @return mixed DB_Error or the number of rows
 | 
        
           |  |  | 1676 |      *
 | 
        
           |  |  | 1677 |      * @access public
 | 
        
           |  |  | 1678 |      */
 | 
        
           |  |  | 1679 |     function numRows($result)
 | 
        
           |  |  | 1680 |     {
 | 
        
           |  |  | 1681 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1682 |     }
 | 
        
           |  |  | 1683 |   | 
        
           |  |  | 1684 |     // }}}
 | 
        
           |  |  | 1685 |     // {{{ affectedRows()
 | 
        
           |  |  | 1686 |   | 
        
           |  |  | 1687 |     /**
 | 
        
           |  |  | 1688 |      * Returns the affected rows of a query
 | 
        
           |  |  | 1689 |      *
 | 
        
           |  |  | 1690 |      * @return mixed DB_Error or number of rows
 | 
        
           |  |  | 1691 |      *
 | 
        
           |  |  | 1692 |      * @access public
 | 
        
           |  |  | 1693 |      */
 | 
        
           |  |  | 1694 |     function affectedRows()
 | 
        
           |  |  | 1695 |     {
 | 
        
           |  |  | 1696 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1697 |     }
 | 
        
           |  |  | 1698 |   | 
        
           |  |  | 1699 |     // }}}
 | 
        
           |  |  | 1700 |     // {{{ errorNative()
 | 
        
           |  |  | 1701 |   | 
        
           |  |  | 1702 |     /**
 | 
        
           |  |  | 1703 |      * Returns an errormessage, provides by the database
 | 
        
           |  |  | 1704 |      *
 | 
        
           |  |  | 1705 |      * @return mixed DB_Error or message
 | 
        
           |  |  | 1706 |      *
 | 
        
           |  |  | 1707 |      * @access public
 | 
        
           |  |  | 1708 |      */
 | 
        
           |  |  | 1709 |     function errorNative()
 | 
        
           |  |  | 1710 |     {
 | 
        
           |  |  | 1711 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1712 |     }
 | 
        
           |  |  | 1713 |   | 
        
           |  |  | 1714 |     // }}}
 | 
        
           |  |  | 1715 |     // {{{ getSequenceName()
 | 
        
           |  |  | 1716 |   | 
        
           |  |  | 1717 |     /**
 | 
        
           |  |  | 1718 |      * Generate the name used inside the database for a sequence
 | 
        
           |  |  | 1719 |      *
 | 
        
           |  |  | 1720 |      * The createSequence() docblock contains notes about storing sequence
 | 
        
           |  |  | 1721 |      * names.
 | 
        
           |  |  | 1722 |      *
 | 
        
           |  |  | 1723 |      * @param string $sqn  the sequence's public name
 | 
        
           |  |  | 1724 |      *
 | 
        
           |  |  | 1725 |      * @return string  the sequence's name in the backend
 | 
        
           |  |  | 1726 |      *
 | 
        
           |  |  | 1727 |      * @see DB_common::createSequence(), DB_common::dropSequence(),
 | 
        
           |  |  | 1728 |      *      DB_common::nextID(), DB_common::setOption()
 | 
        
           |  |  | 1729 |      * @access private
 | 
        
           |  |  | 1730 |      */
 | 
        
           |  |  | 1731 |     function getSequenceName($sqn)
 | 
        
           |  |  | 1732 |     {
 | 
        
           |  |  | 1733 |         return sprintf($this->getOption('seqname_format'),
 | 
        
           |  |  | 1734 |                        preg_replace('/[^a-z0-9_.]/i', '_', $sqn));
 | 
        
           |  |  | 1735 |     }
 | 
        
           |  |  | 1736 |   | 
        
           |  |  | 1737 |     // }}}
 | 
        
           |  |  | 1738 |     // {{{ nextId()
 | 
        
           |  |  | 1739 |   | 
        
           |  |  | 1740 |     /**
 | 
        
           |  |  | 1741 |      * Returns the next free id in a sequence
 | 
        
           |  |  | 1742 |      *
 | 
        
           |  |  | 1743 |      * @param string  $seq_name  name of the sequence
 | 
        
           |  |  | 1744 |      * @param boolean $ondemand  when true, the seqence is automatically
 | 
        
           |  |  | 1745 |      *                           created if it does not exist
 | 
        
           |  |  | 1746 |      *
 | 
        
           |  |  | 1747 |      * @return int  the next id number in the sequence.  DB_Error if problem.
 | 
        
           |  |  | 1748 |      *
 | 
        
           |  |  | 1749 |      * @see DB_common::createSequence(), DB_common::dropSequence(),
 | 
        
           |  |  | 1750 |      *      DB_common::getSequenceName()
 | 
        
           |  |  | 1751 |      * @access public
 | 
        
           |  |  | 1752 |      */
 | 
        
           |  |  | 1753 |     function nextId($seq_name, $ondemand = true)
 | 
        
           |  |  | 1754 |     {
 | 
        
           |  |  | 1755 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1756 |     }
 | 
        
           |  |  | 1757 |   | 
        
           |  |  | 1758 |     // }}}
 | 
        
           |  |  | 1759 |     // {{{ createSequence()
 | 
        
           |  |  | 1760 |   | 
        
           |  |  | 1761 |     /**
 | 
        
           |  |  | 1762 |      * Creates a new sequence
 | 
        
           |  |  | 1763 |      *
 | 
        
           |  |  | 1764 |      * The name of a given sequence is determined by passing the string
 | 
        
           |  |  | 1765 |      * provided in the <var>$seq_name</var> argument through PHP's sprintf()
 | 
        
           |  |  | 1766 |      * function using the value from the <var>seqname_format</var> option as
 | 
        
           |  |  | 1767 |      * the sprintf()'s format argument.
 | 
        
           |  |  | 1768 |      *
 | 
        
           |  |  | 1769 |      * <var>seqname_format</var> is set via setOption().
 | 
        
           |  |  | 1770 |      *
 | 
        
           |  |  | 1771 |      * @param string $seq_name  name of the new sequence
 | 
        
           |  |  | 1772 |      *
 | 
        
           |  |  | 1773 |      * @return int  DB_OK on success.  A DB_Error object is returned if
 | 
        
           |  |  | 1774 |      *              problems arise.
 | 
        
           |  |  | 1775 |      *
 | 
        
           |  |  | 1776 |      * @see DB_common::dropSequence(), DB_common::getSequenceName(),
 | 
        
           |  |  | 1777 |      *      DB_common::nextID()
 | 
        
           |  |  | 1778 |      * @access public
 | 
        
           |  |  | 1779 |      */
 | 
        
           |  |  | 1780 |     function createSequence($seq_name)
 | 
        
           |  |  | 1781 |     {
 | 
        
           |  |  | 1782 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1783 |     }
 | 
        
           |  |  | 1784 |   | 
        
           |  |  | 1785 |     // }}}
 | 
        
           |  |  | 1786 |     // {{{ dropSequence()
 | 
        
           |  |  | 1787 |   | 
        
           |  |  | 1788 |     /**
 | 
        
           |  |  | 1789 |      * Deletes a sequence
 | 
        
           |  |  | 1790 |      *
 | 
        
           |  |  | 1791 |      * @param string $seq_name  name of the sequence to be deleted
 | 
        
           |  |  | 1792 |      *
 | 
        
           |  |  | 1793 |      * @return int  DB_OK on success.  DB_Error if problems.
 | 
        
           |  |  | 1794 |      *
 | 
        
           |  |  | 1795 |      * @see DB_common::createSequence(), DB_common::getSequenceName(),
 | 
        
           |  |  | 1796 |      *      DB_common::nextID()
 | 
        
           |  |  | 1797 |      * @access public
 | 
        
           |  |  | 1798 |      */
 | 
        
           |  |  | 1799 |     function dropSequence($seq_name)
 | 
        
           |  |  | 1800 |     {
 | 
        
           |  |  | 1801 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1802 |     }
 | 
        
           |  |  | 1803 |   | 
        
           |  |  | 1804 |     // }}}
 | 
        
           |  |  | 1805 |     // {{{ tableInfo()
 | 
        
           |  |  | 1806 |   | 
        
           |  |  | 1807 |     /**
 | 
        
           |  |  | 1808 |      * Returns information about a table or a result set
 | 
        
           |  |  | 1809 |      *
 | 
        
           |  |  | 1810 |      * The format of the resulting array depends on which <var>$mode</var>
 | 
        
           |  |  | 1811 |      * you select.  The sample output below is based on this query:
 | 
        
           |  |  | 1812 |      * <pre>
 | 
        
           |  |  | 1813 |      *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
 | 
        
           |  |  | 1814 |      *    FROM tblFoo
 | 
        
           |  |  | 1815 |      *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
 | 
        
           |  |  | 1816 |      * </pre>
 | 
        
           |  |  | 1817 |      *
 | 
        
           |  |  | 1818 |      * <ul>
 | 
        
           |  |  | 1819 |      * <li>
 | 
        
           |  |  | 1820 |      *
 | 
        
           |  |  | 1821 |      * <kbd>null</kbd> (default)
 | 
        
           |  |  | 1822 |      *   <pre>
 | 
        
           |  |  | 1823 |      *   [0] => Array (
 | 
        
           |  |  | 1824 |      *       [table] => tblFoo
 | 
        
           |  |  | 1825 |      *       [name] => fldId
 | 
        
           |  |  | 1826 |      *       [type] => int
 | 
        
           |  |  | 1827 |      *       [len] => 11
 | 
        
           |  |  | 1828 |      *       [flags] => primary_key not_null
 | 
        
           |  |  | 1829 |      *   )
 | 
        
           |  |  | 1830 |      *   [1] => Array (
 | 
        
           |  |  | 1831 |      *       [table] => tblFoo
 | 
        
           |  |  | 1832 |      *       [name] => fldPhone
 | 
        
           |  |  | 1833 |      *       [type] => string
 | 
        
           |  |  | 1834 |      *       [len] => 20
 | 
        
           |  |  | 1835 |      *       [flags] =>
 | 
        
           |  |  | 1836 |      *   )
 | 
        
           |  |  | 1837 |      *   [2] => Array (
 | 
        
           |  |  | 1838 |      *       [table] => tblBar
 | 
        
           |  |  | 1839 |      *       [name] => fldId
 | 
        
           |  |  | 1840 |      *       [type] => int
 | 
        
           |  |  | 1841 |      *       [len] => 11
 | 
        
           |  |  | 1842 |      *       [flags] => primary_key not_null
 | 
        
           |  |  | 1843 |      *   )
 | 
        
           |  |  | 1844 |      *   </pre>
 | 
        
           |  |  | 1845 |      *
 | 
        
           |  |  | 1846 |      * </li><li>
 | 
        
           |  |  | 1847 |      *
 | 
        
           |  |  | 1848 |      * <kbd>DB_TABLEINFO_ORDER</kbd>
 | 
        
           |  |  | 1849 |      *
 | 
        
           |  |  | 1850 |      *   <p>In addition to the information found in the default output,
 | 
        
           |  |  | 1851 |      *   a notation of the number of columns is provided by the
 | 
        
           |  |  | 1852 |      *   <samp>num_fields</samp> element while the <samp>order</samp>
 | 
        
           |  |  | 1853 |      *   element provides an array with the column names as the keys and
 | 
        
           |  |  | 1854 |      *   their location index number (corresponding to the keys in the
 | 
        
           |  |  | 1855 |      *   the default output) as the values.</p>
 | 
        
           |  |  | 1856 |      *
 | 
        
           |  |  | 1857 |      *   <p>If a result set has identical field names, the last one is
 | 
        
           |  |  | 1858 |      *   used.</p>
 | 
        
           |  |  | 1859 |      *
 | 
        
           |  |  | 1860 |      *   <pre>
 | 
        
           |  |  | 1861 |      *   [num_fields] => 3
 | 
        
           |  |  | 1862 |      *   [order] => Array (
 | 
        
           |  |  | 1863 |      *       [fldId] => 2
 | 
        
           |  |  | 1864 |      *       [fldTrans] => 1
 | 
        
           |  |  | 1865 |      *   )
 | 
        
           |  |  | 1866 |      *   </pre>
 | 
        
           |  |  | 1867 |      *
 | 
        
           |  |  | 1868 |      * </li><li>
 | 
        
           |  |  | 1869 |      *
 | 
        
           |  |  | 1870 |      * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>
 | 
        
           |  |  | 1871 |      *
 | 
        
           |  |  | 1872 |      *   <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more
 | 
        
           |  |  | 1873 |      *   dimensions to the array in which the table names are keys and
 | 
        
           |  |  | 1874 |      *   the field names are sub-keys.  This is helpful for queries that
 | 
        
           |  |  | 1875 |      *   join tables which have identical field names.</p>
 | 
        
           |  |  | 1876 |      *
 | 
        
           |  |  | 1877 |      *   <pre>
 | 
        
           |  |  | 1878 |      *   [num_fields] => 3
 | 
        
           |  |  | 1879 |      *   [ordertable] => Array (
 | 
        
           |  |  | 1880 |      *       [tblFoo] => Array (
 | 
        
           |  |  | 1881 |      *           [fldId] => 0
 | 
        
           |  |  | 1882 |      *           [fldPhone] => 1
 | 
        
           |  |  | 1883 |      *       )
 | 
        
           |  |  | 1884 |      *       [tblBar] => Array (
 | 
        
           |  |  | 1885 |      *           [fldId] => 2
 | 
        
           |  |  | 1886 |      *       )
 | 
        
           |  |  | 1887 |      *   )
 | 
        
           |  |  | 1888 |      *   </pre>
 | 
        
           |  |  | 1889 |      *
 | 
        
           |  |  | 1890 |      * </li>
 | 
        
           |  |  | 1891 |      * </ul>
 | 
        
           |  |  | 1892 |      *
 | 
        
           |  |  | 1893 |      * The <samp>flags</samp> element contains a space separated list
 | 
        
           |  |  | 1894 |      * of extra information about the field.  This data is inconsistent
 | 
        
           |  |  | 1895 |      * between DBMS's due to the way each DBMS works.
 | 
        
           |  |  | 1896 |      *   + <samp>primary_key</samp>
 | 
        
           |  |  | 1897 |      *   + <samp>unique_key</samp>
 | 
        
           |  |  | 1898 |      *   + <samp>multiple_key</samp>
 | 
        
           |  |  | 1899 |      *   + <samp>not_null</samp>
 | 
        
           |  |  | 1900 |      *
 | 
        
           |  |  | 1901 |      * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
 | 
        
           |  |  | 1902 |      * elements if <var>$result</var> is a table name.  The following DBMS's
 | 
        
           |  |  | 1903 |      * provide full information from queries:
 | 
        
           |  |  | 1904 |      *   + fbsql
 | 
        
           |  |  | 1905 |      *   + mysql
 | 
        
           |  |  | 1906 |      *
 | 
        
           |  |  | 1907 |      * If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp>
 | 
        
           |  |  | 1908 |      * turned on, the names of tables and fields will be lowercased.
 | 
        
           |  |  | 1909 |      *
 | 
        
           |  |  | 1910 |      * @param object|string  $result  DB_result object from a query or a
 | 
        
           |  |  | 1911 |      *                                string containing the name of a table.
 | 
        
           |  |  | 1912 |      *                                While this also accepts a query result
 | 
        
           |  |  | 1913 |      *                                resource identifier, this behavior is
 | 
        
           |  |  | 1914 |      *                                deprecated.
 | 
        
           |  |  | 1915 |      * @param int  $mode   either unused or one of the tableInfo modes:
 | 
        
           |  |  | 1916 |      *                     <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
 | 
        
           |  |  | 1917 |      *                     <kbd>DB_TABLEINFO_ORDER</kbd> or
 | 
        
           |  |  | 1918 |      *                     <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
 | 
        
           |  |  | 1919 |      *                     These are bitwise, so the first two can be
 | 
        
           |  |  | 1920 |      *                     combined using <kbd>|</kbd>.
 | 
        
           |  |  | 1921 |      * @return array  an associative array with the information requested.
 | 
        
           |  |  | 1922 |      *                If something goes wrong an error object is returned.
 | 
        
           |  |  | 1923 |      *
 | 
        
           |  |  | 1924 |      * @see DB_common::setOption()
 | 
        
           |  |  | 1925 |      * @access public
 | 
        
           |  |  | 1926 |      */
 | 
        
           |  |  | 1927 |     function tableInfo($result, $mode = null)
 | 
        
           |  |  | 1928 |     {
 | 
        
           |  |  | 1929 |         /*
 | 
        
           |  |  | 1930 |          * If the DB_<driver> class has a tableInfo() method, that one
 | 
        
           |  |  | 1931 |          * overrides this one.  But, if the driver doesn't have one,
 | 
        
           |  |  | 1932 |          * this method runs and tells users about that fact.
 | 
        
           |  |  | 1933 |          */
 | 
        
           |  |  | 1934 |         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
 | 
        
           |  |  | 1935 |     }
 | 
        
           |  |  | 1936 |   | 
        
           |  |  | 1937 |     // }}}
 | 
        
           |  |  | 1938 |     // {{{ getTables()
 | 
        
           |  |  | 1939 |   | 
        
           |  |  | 1940 |     /**
 | 
        
           |  |  | 1941 |      * @deprecated  Deprecated in release 1.2 or lower
 | 
        
           |  |  | 1942 |      */
 | 
        
           |  |  | 1943 |     function getTables()
 | 
        
           |  |  | 1944 |     {
 | 
        
           |  |  | 1945 |         return $this->getListOf('tables');
 | 
        
           |  |  | 1946 |     }
 | 
        
           |  |  | 1947 |   | 
        
           |  |  | 1948 |     // }}}
 | 
        
           |  |  | 1949 |     // {{{ getListOf()
 | 
        
           |  |  | 1950 |   | 
        
           |  |  | 1951 |     /**
 | 
        
           |  |  | 1952 |      * list internal DB info
 | 
        
           |  |  | 1953 |      * valid values for $type are db dependent,
 | 
        
           |  |  | 1954 |      * often: databases, users, view, functions
 | 
        
           |  |  | 1955 |      *
 | 
        
           |  |  | 1956 |      * @param string $type type of requested info
 | 
        
           |  |  | 1957 |      *
 | 
        
           |  |  | 1958 |      * @return mixed DB_Error or the requested data
 | 
        
           |  |  | 1959 |      *
 | 
        
           |  |  | 1960 |      * @access public
 | 
        
           |  |  | 1961 |      */
 | 
        
           |  |  | 1962 |     function getListOf($type)
 | 
        
           |  |  | 1963 |     {
 | 
        
           |  |  | 1964 |         $sql = $this->getSpecialQuery($type);
 | 
        
           |  |  | 1965 |         if ($sql === null) {                                // No support
 | 
        
           |  |  | 1966 |             return $this->raiseError(DB_ERROR_UNSUPPORTED);
 | 
        
           |  |  | 1967 |         } elseif (is_int($sql) || DB::isError($sql)) {      // Previous error
 | 
        
           |  |  | 1968 |             return $this->raiseError($sql);
 | 
        
           |  |  | 1969 |         } elseif (is_array($sql)) {                         // Already the result
 | 
        
           |  |  | 1970 |             return $sql;
 | 
        
           |  |  | 1971 |         }
 | 
        
           |  |  | 1972 |         return $this->getCol($sql);                         // Launch this query
 | 
        
           |  |  | 1973 |     }
 | 
        
           |  |  | 1974 |   | 
        
           |  |  | 1975 |     // }}}
 | 
        
           |  |  | 1976 |     // {{{ getSpecialQuery()
 | 
        
           |  |  | 1977 |   | 
        
           |  |  | 1978 |     /**
 | 
        
           |  |  | 1979 |      * Returns the query needed to get some backend info
 | 
        
           |  |  | 1980 |      *
 | 
        
           |  |  | 1981 |      * @param string $type What kind of info you want to retrieve
 | 
        
           |  |  | 1982 |      *
 | 
        
           |  |  | 1983 |      * @return string The SQL query string
 | 
        
           |  |  | 1984 |      *
 | 
        
           |  |  | 1985 |      * @access public
 | 
        
           |  |  | 1986 |      */
 | 
        
           |  |  | 1987 |     function getSpecialQuery($type)
 | 
        
           |  |  | 1988 |     {
 | 
        
           |  |  | 1989 |         return $this->raiseError(DB_ERROR_UNSUPPORTED);
 | 
        
           |  |  | 1990 |     }
 | 
        
           |  |  | 1991 |   | 
        
           |  |  | 1992 |     // }}}
 | 
        
           |  |  | 1993 |     // {{{ _rtrimArrayValues()
 | 
        
           |  |  | 1994 |   | 
        
           |  |  | 1995 |     /**
 | 
        
           |  |  | 1996 |      * Right trim all strings in an array
 | 
        
           |  |  | 1997 |      *
 | 
        
           |  |  | 1998 |      * @param array  $array  the array to be trimmed (passed by reference)
 | 
        
           |  |  | 1999 |      * @return void
 | 
        
           |  |  | 2000 |      * @access private
 | 
        
           |  |  | 2001 |      */
 | 
        
           |  |  | 2002 |     function _rtrimArrayValues(&$array)
 | 
        
           |  |  | 2003 |     {
 | 
        
           |  |  | 2004 |         foreach ($array as $key => $value) {
 | 
        
           |  |  | 2005 |             if (is_string($value)) {
 | 
        
           |  |  | 2006 |                 $array[$key] = rtrim($value);
 | 
        
           |  |  | 2007 |             }
 | 
        
           |  |  | 2008 |         }
 | 
        
           |  |  | 2009 |     }
 | 
        
           |  |  | 2010 |   | 
        
           |  |  | 2011 |     // }}}
 | 
        
           |  |  | 2012 |     // {{{ _convertNullArrayValuesToEmpty()
 | 
        
           |  |  | 2013 |   | 
        
           |  |  | 2014 |     /**
 | 
        
           |  |  | 2015 |      * Convert all null values in an array to empty strings
 | 
        
           |  |  | 2016 |      *
 | 
        
           |  |  | 2017 |      * @param array  $array  the array to be de-nullified (passed by reference)
 | 
        
           |  |  | 2018 |      * @return void
 | 
        
           |  |  | 2019 |      * @access private
 | 
        
           |  |  | 2020 |      */
 | 
        
           |  |  | 2021 |     function _convertNullArrayValuesToEmpty(&$array)
 | 
        
           |  |  | 2022 |     {
 | 
        
           |  |  | 2023 |         foreach ($array as $key => $value) {
 | 
        
           |  |  | 2024 |             if (is_null($value)) {
 | 
        
           |  |  | 2025 |                 $array[$key] = '';
 | 
        
           |  |  | 2026 |             }
 | 
        
           |  |  | 2027 |         }
 | 
        
           |  |  | 2028 |     }
 | 
        
           |  |  | 2029 |   | 
        
           |  |  | 2030 |     // }}}
 | 
        
           |  |  | 2031 | }
 | 
        
           |  |  | 2032 |   | 
        
           |  |  | 2033 | /*
 | 
        
           |  |  | 2034 |  * Local variables:
 | 
        
           |  |  | 2035 |  * tab-width: 4
 | 
        
           |  |  | 2036 |  * c-basic-offset: 4
 | 
        
           |  |  | 2037 |  * End:
 | 
        
           |  |  | 2038 |  */
 | 
        
           |  |  | 2039 |   | 
        
           |  |  | 2040 | ?>
 |