[ Index ]
 

Code source de PHP PEAR 1.4.5

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

title

Body

[fermer]

/ -> MDB.php (source)

   1  <?php
   2  // +----------------------------------------------------------------------+
   3  // | PHP Version 4                                                        |
   4  // +----------------------------------------------------------------------+
   5  // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
   6  // | Stig. S. Bakken, Lukas Smith                                         |
   7  // | All rights reserved.                                                 |
   8  // +----------------------------------------------------------------------+
   9  // | MDB is a merge of PEAR DB and Metabases that provides a unified DB   |
  10  // | API as well as database abstraction for PHP applications.            |
  11  // | This LICENSE is in the BSD license style.                            |
  12  // |                                                                      |
  13  // | Redistribution and use in source and binary forms, with or without   |
  14  // | modification, are permitted provided that the following conditions   |
  15  // | are met:                                                             |
  16  // |                                                                      |
  17  // | Redistributions of source code must retain the above copyright       |
  18  // | notice, this list of conditions and the following disclaimer.        |
  19  // |                                                                      |
  20  // | Redistributions in binary form must reproduce the above copyright    |
  21  // | notice, this list of conditions and the following disclaimer in the  |
  22  // | documentation and/or other materials provided with the distribution. |
  23  // |                                                                      |
  24  // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25  // | Lukas Smith nor the names of his contributors may be used to endorse |
  26  // | or promote products derived from this software without specific prior|
  27  // | written permission.                                                  |
  28  // |                                                                      |
  29  // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30  // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31  // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32  // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33  // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34  // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35  // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36  // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37  // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38  // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39  // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40  // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41  // +----------------------------------------------------------------------+
  42  // | Author: Lukas Smith <smith@backendmedia.com>                         |
  43  // +----------------------------------------------------------------------+
  44  //
  45  // $Id: MDB.php,v 1.59.4.12 2004/02/28 10:37:54 quipo Exp $
  46  //
  47  require_once ('PEAR.php');
  48  
  49  /**
  50   * The method mapErrorCode in each MDB_dbtype implementation maps
  51   * native error codes to one of these.
  52   *
  53   * If you add an error code here, make sure you also add a textual
  54   * version of it in MDB::errorMessage().
  55   */
  56  
  57  define('MDB_OK',                         1);
  58  define('MDB_ERROR',                     -1);
  59  define('MDB_ERROR_SYNTAX',              -2);
  60  define('MDB_ERROR_CONSTRAINT',          -3);
  61  define('MDB_ERROR_NOT_FOUND',           -4);
  62  define('MDB_ERROR_ALREADY_EXISTS',      -5);
  63  define('MDB_ERROR_UNSUPPORTED',         -6);
  64  define('MDB_ERROR_MISMATCH',            -7);
  65  define('MDB_ERROR_INVALID',             -8);
  66  define('MDB_ERROR_NOT_CAPABLE',         -9);
  67  define('MDB_ERROR_TRUNCATED',          -10);
  68  define('MDB_ERROR_INVALID_NUMBER',     -11);
  69  define('MDB_ERROR_INVALID_DATE',       -12);
  70  define('MDB_ERROR_DIVZERO',            -13);
  71  define('MDB_ERROR_NODBSELECTED',       -14);
  72  define('MDB_ERROR_CANNOT_CREATE',      -15);
  73  define('MDB_ERROR_CANNOT_DELETE',      -16);
  74  define('MDB_ERROR_CANNOT_DROP',        -17);
  75  define('MDB_ERROR_NOSUCHTABLE',        -18);
  76  define('MDB_ERROR_NOSUCHFIELD',        -19);
  77  define('MDB_ERROR_NEED_MORE_DATA',     -20);
  78  define('MDB_ERROR_NOT_LOCKED',         -21);
  79  define('MDB_ERROR_VALUE_COUNT_ON_ROW', -22);
  80  define('MDB_ERROR_INVALID_DSN',        -23);
  81  define('MDB_ERROR_CONNECT_FAILED',     -24);
  82  define('MDB_ERROR_EXTENSION_NOT_FOUND',-25);
  83  define('MDB_ERROR_NOSUCHDB',           -26);
  84  define('MDB_ERROR_ACCESS_VIOLATION',   -27);
  85  define('MDB_ERROR_CANNOT_REPLACE',     -28);
  86  define('MDB_ERROR_CONSTRAINT_NOT_NULL',-29);
  87  define('MDB_ERROR_DEADLOCK',           -30);
  88  define('MDB_ERROR_CANNOT_ALTER',       -31);
  89  define('MDB_ERROR_MANAGER',            -32);
  90  define('MDB_ERROR_MANAGER_PARSE',      -33);
  91  define('MDB_ERROR_LOADMODULE',         -34);
  92  define('MDB_ERROR_INSUFFICIENT_DATA',  -35);
  93  /**
  94   * This is a special constant that tells DB the user hasn't specified
  95   * any particular get mode, so the default should be used.
  96   */
  97  
  98  define('MDB_FETCHMODE_DEFAULT', 0);
  99  
 100  /**
 101   * Column data indexed by numbers, ordered from 0 and up
 102   */
 103  
 104  define('MDB_FETCHMODE_ORDERED',  1);
 105  
 106  /**
 107   * Column data indexed by column names
 108   */
 109  
 110  define('MDB_FETCHMODE_ASSOC',    2);
 111  
 112  /**
 113   * For multi-dimensional results: normally the first level of arrays
 114   * is the row number, and the second level indexed by column number or name.
 115   * MDB_FETCHMODE_FLIPPED switches this order, so the first level of arrays
 116   * is the column name, and the second level the row number.
 117   */
 118  
 119  define('MDB_FETCHMODE_FLIPPED',  4);
 120  
 121  /**
 122   * These are constants for the tableInfo-function
 123   * they are bitwised or'ed. so if there are more constants to be defined
 124   * in the future, adjust MDB_TABLEINFO_FULL accordingly
 125   */
 126  
 127  define('MDB_TABLEINFO_ORDER',      1);
 128  define('MDB_TABLEINFO_ORDERTABLE', 2);
 129  define('MDB_TABLEINFO_FULL',       3);
 130  
 131  /**
 132   * These are constants for each of the supported datatypes
 133   */
 134  
 135  define('MDB_TYPE_TEXT'      , 0);
 136  define('MDB_TYPE_BOOLEAN'   , 1);
 137  define('MDB_TYPE_INTEGER'   , 2);
 138  define('MDB_TYPE_DECIMAL'   , 3);
 139  define('MDB_TYPE_FLOAT'     , 4);
 140  define('MDB_TYPE_DATE'      , 5);
 141  define('MDB_TYPE_TIME'      , 6);
 142  define('MDB_TYPE_TIMESTAMP' , 7);
 143  define('MDB_TYPE_CLOB'      , 8);
 144  define('MDB_TYPE_BLOB'      , 9);
 145  
 146  /**
 147   * These are global variables that are used to track the various class instances
 148   */
 149  
 150  $GLOBALS['_MDB_lobs'] = array();
 151  $GLOBALS['_MDB_databases'] = array();
 152  
 153  /**
 154   * The main 'MDB' class is simply a container class with some static
 155   * methods for creating DB objects as well as some utility functions
 156   * common to all parts of DB.
 157   *
 158   * The object model of DB is as follows (indentation means inheritance):
 159   *
 160   * MDB          The main DB class.  This is simply a utility class
 161   *              with some 'static' methods for creating MDB objects as
 162   *              well as common utility functions for other MDB classes.
 163   *
 164   * MDB_common   The base for each DB implementation.  Provides default
 165   * |            implementations (in OO lingo virtual methods) for
 166   * |            the actual DB implementations as well as a bunch of
 167   * |            query utility functions.
 168   * |
 169   * +-MDB_mysql  The DB implementation for MySQL. Inherits MDB_Common.
 170   *              When calling MDB::factory or MDB::connect for MySQL
 171   *              connections, the object returned is an instance of this
 172   *              class.
 173   * +-MDB_pgsql  The DB implementation for PostGreSQL. Inherits MDB_Common.
 174   *              When calling MDB::factory or MDB::connect for PostGreSQL
 175   *              connections, the object returned is an instance of this
 176   *              class.
 177   *
 178   * MDB_Date     This class provides several method to convert from and to
 179   *              MDB timestamps.
 180   *
 181   * MDB_Manager  This class handles the xml schema management.
 182   *
 183   * @package  MDB
 184   * @version  $Id: MDB.php,v 1.59.4.12 2004/02/28 10:37:54 quipo Exp $
 185   * @category Database
 186   * @author   Lukas Smith <smith@backendmedia.com>
 187   */
 188  class MDB
 189  {
 190      // }}}
 191      // {{{ setOptions()
 192  
 193      /**
 194       * set option array in an exiting database object
 195       *
 196       * @param   object  $db       MDB object
 197       * @param   mixed   $options  An associative array of option names and
 198       *                            their values.
 199       * @access  public
 200       */
 201      function setOptions(&$db, $options)
 202      {
 203          if(is_array($options)) {
 204              foreach($options as $option => $value) {
 205                  $test = $db->setOption($option, $value);
 206                  if(MDB::isError($test)) {
 207                      return $test;
 208                  }
 209              }
 210          } else {
 211              $db->setOption('persistent', $options);
 212          }
 213          $include_lob = $db->getOption('includelob');
 214          if(!MDB::isError($include_lob) && $include_lob) {
 215              $db->loadLob('load at start');
 216          }
 217          $includemanager = $db->getOption('includemanager');
 218          if(!MDB::isError($includemanager) && $includemanager) {
 219              $db->loadManager('load at start');
 220          }
 221          $debug = $db->getOption('debug');
 222          if(!MDB::isError($debug) && $debug) {
 223              $db->captureDebugOutput(TRUE);
 224          }
 225      }
 226  
 227      // }}}
 228      // {{{ factory()
 229  
 230      /**
 231       * Create a new DB connection object for the specified database
 232       * type
 233       * IMPORTANT: In order for MDB to work properly it is necessary that
 234       * you make sure that you work with a reference of the original
 235       * object instead of a copy (this is a PHP4 quirk).
 236       *
 237       * For example:
 238       *     $mdb =& MDB::factory($dsn);
 239       *          ^^
 240       * And not:
 241       *     $mdb = MDB::factory($dsn);
 242       *          ^^
 243       *
 244       * @param   string  $type   database type, for example 'mysql'
 245       * @return  mixed   a newly created MDB connection object, or a MDB
 246       *                  error object on error
 247       * @access  public
 248       */
 249      function &factory($type)
 250      {
 251          $class_name = "MDB_$type";
 252  
 253          @include_once("MDB/$type}.php");
 254  
 255          @$db =& new $class_name;
 256  
 257          return($db);
 258      }
 259  
 260      // }}}
 261      // {{{ connect()
 262  
 263      /**
 264       * Create a new MDB connection object and connect to the specified
 265       * database
 266       *
 267       * IMPORTANT: In order for MDB to work properly it is necessary that
 268       * you make sure that you work with a reference of the original
 269       * object instead of a copy (this is a PHP4 quirk).
 270       *
 271       * For example:
 272       *     $mdb =& MDB::connect($dsn);
 273       *          ^^
 274       * And not:
 275       *     $mdb = MDB::connect($dsn);
 276       *          ^^
 277       *
 278       * @param   mixed   $dsn      'data source name', see the MDB::parseDSN
 279       *                            method for a description of the dsn format.
 280       *                            Can also be specified as an array of the
 281       *                            format returned by MDB::parseDSN.
 282       * @param   mixed   $options  An associative array of option names and
 283       *                            their values.
 284       * @return  mixed   a newly created MDB connection object, or a MDB
 285       *                  error object on error
 286       * @access  public
 287       * @see     MDB::parseDSN
 288       */
 289      function &connect($dsn, $options = FALSE)
 290      {
 291          $dsninfo = MDB::parseDSN($dsn);
 292          if(isset($dsninfo['phptype'])) {
 293              $type          = $dsninfo['phptype'];
 294              $class_name    = 'MDB_'.$type;
 295              $include       = 'MDB/'.$type.'.php';
 296          } else {
 297              return(PEAR::raiseError(NULL, MDB_ERROR_NOT_FOUND,
 298                  NULL, NULL, 'no RDBMS driver specified',
 299                  'MDB_Error', TRUE));
 300          }
 301  
 302          if(is_array($options)
 303              && isset($options['debug'])
 304              && $options['debug'] >= 2
 305          ) {
 306              // expose php errors with sufficient debug level
 307              @include_once($include);
 308          } else {
 309              include_once($include);
 310          }
 311  
 312          if(!class_exists($class_name)) {
 313              $error = PEAR::raiseError(NULL, MDB_ERROR_NOT_FOUND, NULL, NULL,
 314                  'Unable to include the '.$include.' file', 'MDB_Error', TRUE);
 315              return($error);
 316          }
 317  
 318          @$db =& new $class_name();
 319  
 320          $db->setDSN($dsninfo);
 321  
 322          MDB::setOptions($db, $options);
 323  
 324          if(isset($dsninfo['database'])) {
 325              $err = $db->connect();
 326              if (MDB::isError($err)) {
 327                  $dsn = $db->getDSN();
 328                  $err->addUserInfo($dsn);
 329                  return($err);
 330              }
 331          }
 332          return($db);
 333      }
 334  
 335      // }}}
 336      // {{{ connect()
 337  
 338      /**
 339       * Returns a MDB connection with the requested DSN.
 340       * A newnew MDB connection object is only created if no object with the
 341       * reuested DSN exists yet.
 342       *
 343       * IMPORTANT: In order for MDB to work properly it is necessary that
 344       * you make sure that you work with a reference of the original
 345       * object instead of a copy (this is a PHP4 quirk).
 346       *
 347       * For example:
 348       *     $mdb =& MDB::sngleton($dsn);
 349       *          ^^
 350       * And not:
 351       *     $mdb = MDB::singleton($dsn);
 352       *          ^^
 353       *
 354       * @param   mixed   $dsn      'data source name', see the MDB::parseDSN
 355       *                            method for a description of the dsn format.
 356       *                            Can also be specified as an array of the
 357       *                            format returned by MDB::parseDSN.
 358       * @param   mixed   $options  An associative array of option names and
 359       *                            their values.
 360       * @return  mixed   a newly created MDB connection object, or a MDB
 361       *                  error object on error
 362       * @access  public
 363       * @see     MDB::parseDSN
 364       */
 365      function &singleton($dsn = NULL, $options = FALSE)
 366      {
 367          if ($dsn) {
 368              $dsninfo = MDB::parseDSN($dsn);
 369              $dsninfo_default = array(
 370                  'phptype' => NULL,
 371                  'username' => NULL,
 372                  'password' => NULL,
 373                  'hostspec' => NULL,
 374                  'database' => NULL,
 375              );
 376              $dsninfo = array_merge($dsninfo_default, $dsninfo);
 377              $keys = array_keys($GLOBALS['_MDB_databases']);
 378              for ($i=0, $j=count($keys); $i<$j; ++$i) {
 379                  $tmp_dsn = $GLOBALS['_MDB_databases'][$keys[$i]]->getDSN('array');
 380                  if ($dsninfo['phptype'] == $tmp_dsn['phptype']
 381                      && $dsninfo['username'] == $tmp_dsn['username']
 382                      && $dsninfo['password'] == $tmp_dsn['password']
 383                      && $dsninfo['hostspec'] == $tmp_dsn['hostspec']
 384                      && $dsninfo['database'] == $tmp_dsn['database'])
 385                  {
 386                      MDB::setOptions($GLOBALS['_MDB_databases'][$keys[$i]], $options);
 387                      return $GLOBALS['_MDB_databases'][$keys[$i]];
 388                  }
 389              }
 390          } else {
 391              if (is_array($GLOBALS['_MDB_databases'])
 392                  && reset($GLOBALS['_MDB_databases'])
 393              ) {
 394                  $db =& $GLOBALS['_MDB_databases'][key($GLOBALS['_MDB_databases'])];
 395                  return $db;
 396              }
 397          }
 398          $db =& MDB::connect($dsn, $options);
 399          return $db;
 400      }
 401  
 402      // }}}
 403      // {{{ loadFile()
 404  
 405      /**
 406       * load a file (like 'Date.php' or 'Manager.php')
 407       *
 408       * @return $file    name of the file to be included from the MDB dir without
 409       *                  the '.php' extension (like 'Date' or 'Manager')
 410       * @access public
 411       */
 412      function loadFile($file)
 413      {
 414          @include_once('MDB/'.$file.'.php');
 415      }
 416  
 417      // }}}
 418      // {{{ apiVersion()
 419  
 420      /**
 421       * Return the MDB API version
 422       *
 423       * @return int     the MDB API version number
 424       * @access public
 425       */
 426      function apiVersion()
 427      {
 428          return(1);
 429      }
 430  
 431      // }}}
 432      // {{{ isError()
 433  
 434      /**
 435       * Tell whether a result code from a MDB method is an error
 436       *
 437       * @param   int       $value  result code
 438       * @return  boolean   whether $value is an MDB_Error
 439       * @access public
 440       */
 441      function isError($value)
 442      {
 443          return is_a($value, 'MDB_Error');
 444      }
 445  
 446      // }}}
 447      // {{{ isConnection()
 448      /**
 449       * Tell whether a value is a MDB connection
 450       *
 451       * @param mixed $value value to test
 452       *
 453       * @return bool whether $value is a MDB connection
 454       *
 455       * @access public
 456       */
 457      function isConnection($value)
 458      {
 459          return is_a($value, 'MDB_Common');
 460      }
 461  
 462      // }}}
 463      // {{{ isManip()
 464  
 465      /**
 466       * Tell whether a query is a data manipulation query (insert,
 467       * update or delete) or a data definition query (create, drop,
 468       * alter, grant, revoke).
 469       *
 470       * @param   string   $query the query
 471       * @return  boolean  whether $query is a data manipulation query
 472       * @access public
 473       */
 474      function isManip($query)
 475      {
 476          $manips = 'INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|
 477                    ALTER|GRANT|REVOKE|LOCK|UNLOCK|ROLLBACK|COMMIT';
 478          if (preg_match('/^\s*"?('.$manips.')\s+/i', $query)) {
 479              return(TRUE);
 480          }
 481          return(FALSE);
 482      }
 483  
 484      // }}}
 485      // {{{ errorMessage()
 486  
 487      /**
 488       * Return a textual error message for a MDB error code
 489       *
 490       * @param   int     $value error code
 491       * @return  string  error message, or false if the error code was
 492       *                  not recognized
 493       * @access public
 494       */
 495      function errorMessage($value)
 496      {
 497          static $errorMessages;
 498          if (!isset($errorMessages)) {
 499              $errorMessages = array(
 500                  MDB_ERROR                    => 'unknown error',
 501                  MDB_ERROR_ALREADY_EXISTS     => 'already exists',
 502                  MDB_ERROR_CANNOT_CREATE      => 'can not create',
 503                  MDB_ERROR_CANNOT_ALTER       => 'can not alter',
 504                  MDB_ERROR_CANNOT_REPLACE     => 'can not replace',
 505                  MDB_ERROR_CANNOT_DELETE      => 'can not delete',
 506                  MDB_ERROR_CANNOT_DROP        => 'can not drop',
 507                  MDB_ERROR_CONSTRAINT         => 'constraint violation',
 508                  MDB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
 509                  MDB_ERROR_DIVZERO            => 'division by zero',
 510                  MDB_ERROR_INVALID            => 'invalid',
 511                  MDB_ERROR_INVALID_DATE       => 'invalid date or time',
 512                  MDB_ERROR_INVALID_NUMBER     => 'invalid number',
 513                  MDB_ERROR_MISMATCH           => 'mismatch',
 514                  MDB_ERROR_NODBSELECTED       => 'no database selected',
 515                  MDB_ERROR_NOSUCHFIELD        => 'no such field',
 516                  MDB_ERROR_NOSUCHTABLE        => 'no such table',
 517                  MDB_ERROR_NOT_CAPABLE        => 'MDB backend not capable',
 518                  MDB_ERROR_NOT_FOUND          => 'not found',
 519                  MDB_ERROR_NOT_LOCKED         => 'not locked',
 520                  MDB_ERROR_SYNTAX             => 'syntax error',
 521                  MDB_ERROR_UNSUPPORTED        => 'not supported',
 522                  MDB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
 523                  MDB_ERROR_INVALID_DSN        => 'invalid DSN',
 524                  MDB_ERROR_CONNECT_FAILED     => 'connect failed',
 525                  MDB_OK                       => 'no error',
 526                  MDB_ERROR_NEED_MORE_DATA     => 'insufficient data supplied',
 527                  MDB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
 528                  MDB_ERROR_NOSUCHDB           => 'no such database',
 529                  MDB_ERROR_ACCESS_VIOLATION   => 'insufficient permissions',
 530                  MDB_ERROR_MANAGER            => 'MDB_manager error',
 531                  MDB_ERROR_MANAGER_PARSE      => 'MDB_manager schema parse error',
 532                  MDB_ERROR_LOADMODULE         => 'Error while including on demand module',
 533                  MDB_ERROR_TRUNCATED          => 'truncated',
 534                  MDB_ERROR_DEADLOCK           => 'deadlock detected',
 535              );
 536          }
 537  
 538          if (MDB::isError($value)) {
 539              $value = $value->getCode();
 540          }
 541  
 542          return(isset($errorMessages[$value]) ?
 543             $errorMessages[$value] : $errorMessages[MDB_ERROR]);
 544      }
 545  
 546      // }}}
 547      // {{{ parseDSN()
 548  
 549      /**
 550       * Parse a data source name
 551       *
 552       * A array with the following keys will be returned:
 553       *  phptype: Database backend used in PHP (mysql, odbc etc.)
 554       *  dbsyntax: Database used with regards to SQL syntax etc.
 555       *  protocol: Communication protocol to use (tcp, unix etc.)
 556       *  hostspec: Host specification (hostname[:port])
 557       *  database: Database to use on the DBMS server
 558       *  username: User name for login
 559       *  password: Password for login
 560       *
 561       * The format of the supplied DSN is in its fullest form:
 562       *
 563       *  phptype(dbsyntax)://username:password@protocol+hostspec/database
 564       *
 565       * Most variations are allowed:
 566       *
 567       *  phptype://username:password@protocol+hostspec:110//usr/db_file.db
 568       *  phptype://username:password@hostspec/database_name
 569       *  phptype://username:password@hostspec
 570       *  phptype://username@hostspec
 571       *  phptype://hostspec/database
 572       *  phptype://hostspec
 573       *  phptype(dbsyntax)
 574       *  phptype
 575       *
 576       * @param   string  $dsn Data Source Name to be parsed
 577       * @return  array   an associative array
 578       * @access public
 579       * @author Tomas V.V.Cox <cox@idecnet.com>
 580       */
 581      function parseDSN($dsn)
 582      {
 583          if (is_array($dsn)) {
 584              return($dsn);
 585          }
 586  
 587          $parsed = array(
 588              'phptype'  => FALSE,
 589              'dbsyntax' => FALSE,
 590              'username' => FALSE,
 591              'password' => FALSE,
 592              'protocol' => FALSE,
 593              'hostspec' => FALSE,
 594              'port'     => FALSE,
 595              'socket'   => FALSE,
 596              'database' => FALSE
 597          );
 598  
 599          // Find phptype and dbsyntax
 600          if (($pos = strpos($dsn, '://')) !== FALSE) {
 601              $str = substr($dsn, 0, $pos);
 602              $dsn = substr($dsn, $pos + 3);
 603          } else {
 604              $str = $dsn;
 605              $dsn = NULL;
 606          }
 607  
 608          // Get phptype and dbsyntax
 609          // $str => phptype(dbsyntax)
 610          if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
 611              $parsed['phptype']  = $arr[1];
 612              $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
 613          } else {
 614              $parsed['phptype']  = $str;
 615              $parsed['dbsyntax'] = $str;
 616          }
 617  
 618          if (empty($dsn)) {
 619              return($parsed);
 620          }
 621  
 622          // Get (if found): username and password
 623          // $dsn => username:password@protocol+hostspec/database
 624          if (($at = strrpos($dsn,'@')) !== FALSE) {
 625              $str = substr($dsn, 0, $at);
 626              $dsn = substr($dsn, $at + 1);
 627              if (($pos = strpos($str, ':')) !== FALSE) {
 628                  $parsed['username'] = rawurldecode(substr($str, 0, $pos));
 629                  $parsed['password'] = rawurldecode(substr($str, $pos + 1));
 630              } else {
 631                  $parsed['username'] = rawurldecode($str);
 632              }
 633          }
 634  
 635          // Find protocol and hostspec
 636  
 637          // $dsn => proto(proto_opts)/database
 638          if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
 639              $proto       = $match[1];
 640              $proto_opts  = (!empty($match[2])) ? $match[2] : FALSE;
 641              $dsn         = $match[3];
 642  
 643          // $dsn => protocol+hostspec/database (old format)
 644          } else {
 645              if (strpos($dsn, '+') !== FALSE) {
 646                  list($proto, $dsn) = explode('+', $dsn, 2);
 647              }
 648              if (strpos($dsn, '/') !== FALSE) {
 649                  list($proto_opts, $dsn) = explode('/', $dsn, 2);
 650              } else {
 651                  $proto_opts = $dsn;
 652                  $dsn = NULL;
 653              }
 654          }
 655  
 656          // process the different protocol options
 657          $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
 658          $proto_opts = rawurldecode($proto_opts);
 659          if ($parsed['protocol'] == 'tcp') {
 660              if (strpos($proto_opts, ':') !== FALSE) {
 661                  list($parsed['hostspec'], $parsed['port']) =
 662                                                       explode(':', $proto_opts);
 663              } else {
 664                  $parsed['hostspec'] = $proto_opts;
 665              }
 666          } elseif ($parsed['protocol'] == 'unix') {
 667              $parsed['socket'] = $proto_opts;
 668          }
 669  
 670          // Get dabase if any
 671          // $dsn => database
 672          if (!empty($dsn)) {
 673              // /database
 674              if (($pos = strpos($dsn, '?')) === FALSE) {
 675                  $parsed['database'] = $dsn;
 676              // /database?param1=value1&param2=value2
 677              } else {
 678                  $parsed['database'] = substr($dsn, 0, $pos);
 679                  $dsn = substr($dsn, $pos + 1);
 680                  if (strpos($dsn, '&') !== FALSE) {
 681                      $opts = explode('&', $dsn);
 682                  } else { // database?param1=value1
 683                      $opts = array($dsn);
 684                  }
 685                  foreach ($opts as $opt) {
 686                      list($key, $value) = explode('=', $opt);
 687                      if (!isset($parsed[$key])) { // don't allow params overwrite
 688                          $parsed[$key] = rawurldecode($value);
 689                      }
 690                  }
 691              }
 692          }
 693  
 694          return($parsed);
 695      }
 696  }
 697  
 698  /**
 699   * MDB_Error implements a class for reporting portable database error
 700   * messages.
 701   *
 702   * @package MDB
 703   * @category Database
 704   * @author  Stig Bakken <ssb@fast.no>
 705   */
 706  class MDB_Error extends PEAR_Error
 707  {
 708  
 709      // }}}
 710      // {{{ constructor
 711  
 712      /**
 713       * MDB_Error constructor.
 714       *
 715       * @param mixed   $code      MDB error code, or string with error message.
 716       * @param integer $mode      what 'error mode' to operate in
 717       * @param integer $level     what error level to use for
 718       *                           $mode & PEAR_ERROR_TRIGGER
 719       * @param smixed  $debuginfo additional debug info, such as the last query
 720       */
 721      function MDB_Error($code = MDB_ERROR, $mode = PEAR_ERROR_RETURN,
 722                $level = E_USER_NOTICE, $debuginfo = NULL)
 723      {
 724          if (is_int($code)) {
 725              $this->PEAR_Error('MDB Error: '.MDB::errorMessage($code), $code,
 726                  $mode, $level, $debuginfo);
 727          } else {
 728              $this->PEAR_Error("MDB Error: $code", MDB_ERROR, $mode, $level,
 729                  $debuginfo);
 730          }
 731      }
 732  }
 733  ?>


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