Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   1  <?php
   2  /**
   3   * @version   v5.21.0  2021-02-27
   4   * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   5   * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   6   * Released under both BSD license and Lesser GPL library license.
   7   * Whenever there is any discrepancy between the two licenses,
   8   * the BSD license will take precedence.
   9   *
  10   * Set tabs to 4 for best viewing.
  11   *
  12   * PEAR DB Emulation Layer for ADODB.
  13   *
  14   * The following code is modelled on PEAR DB code by Stig Bakken <ssb@fast.no>	 	 	 	 	 	 	 	    |
  15   * and Tomas V.V.Cox <cox@idecnet.com>.	 Portions (c)1997-2002 The PHP Group.
  16   */
  17  
  18   /*
  19   We support:
  20  
  21   DB_Common
  22   ---------
  23   	 query - returns PEAR_Error on error
  24  	 limitQuery - return PEAR_Error on error
  25  	 prepare - does not return PEAR_Error on error
  26  	 execute - does not return PEAR_Error on error
  27  	 setFetchMode - supports ASSOC and ORDERED
  28  	 errorNative
  29  	 quote
  30  	 nextID
  31  	 disconnect
  32  
  33  	 getOne
  34  	 getAssoc
  35  	 getRow
  36  	 getCol
  37  	 getAll
  38  
  39   DB_Result
  40   ---------
  41   	 numRows - returns -1 if not supported
  42  	 numCols
  43  	 fetchInto - does not support passing of fetchmode
  44  	 fetchRows - does not support passing of fetchmode
  45  	 free
  46   */
  47  
  48  define('ADODB_PEAR',dirname(__FILE__));
  49  include_once "PEAR.php";
  50  include_once  ADODB_PEAR."/adodb-errorpear.inc.php";
  51  include_once  ADODB_PEAR."/adodb.inc.php";
  52  
  53  if (!defined('DB_OK')) {
  54  define("DB_OK",	 1);
  55  define("DB_ERROR",-1);
  56  
  57  /**
  58   * This is a special constant that tells DB the user hasn't specified
  59   * any particular get mode, so the default should be used.
  60   */
  61  
  62  define('DB_FETCHMODE_DEFAULT', 0);
  63  
  64  /**
  65   * Column data indexed by numbers, ordered from 0 and up
  66   */
  67  
  68  define('DB_FETCHMODE_ORDERED', 1);
  69  
  70  /**
  71   * Column data indexed by column names
  72   */
  73  
  74  define('DB_FETCHMODE_ASSOC', 2);
  75  
  76  /* for compatibility */
  77  
  78  define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
  79  define('DB_GETMODE_ASSOC',   DB_FETCHMODE_ASSOC);
  80  
  81  /**
  82   * these are constants for the tableInfo-function
  83   * they are bitwised or'ed. so if there are more constants to be defined
  84   * in the future, adjust DB_TABLEINFO_FULL accordingly
  85   */
  86  
  87  define('DB_TABLEINFO_ORDER', 1);
  88  define('DB_TABLEINFO_ORDERTABLE', 2);
  89  define('DB_TABLEINFO_FULL', 3);
  90  }
  91  
  92  /**
  93   * The main "DB" class is simply a container class with some static
  94   * methods for creating DB objects as well as some utility functions
  95   * common to all parts of DB.
  96   *
  97   */
  98  
  99  class DB
 100  {
 101  	 /**
 102  	  * Create a new DB object for the specified database type
 103  	  *
 104  	  * @param $type string database type, for example "mysql"
 105  	  *
 106  	  * @return object a newly created DB object, or a DB error code on
 107  	  * error
 108  	  */
 109  
 110  	function factory($type)
 111  	 {
 112  	 	 include_once(ADODB_DIR."/drivers/adodb-$type.inc.php");
 113  	 	 $obj = NewADOConnection($type);
 114  	 	 if (!is_object($obj)) $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
 115  	 	 return $obj;
 116  	 }
 117  
 118  	 /**
 119  	  * Create a new DB object and connect to the specified database
 120  	  *
 121  	  * @param $dsn mixed "data source name", see the DB::parseDSN
 122  	  * method for a description of the dsn format.  Can also be
 123  	  * specified as an array of the format returned by DB::parseDSN.
 124  	  *
 125  	  * @param $options mixed if boolean (or scalar), tells whether
 126  	  * this connection should be persistent (for backends that support
 127  	  * this).  This parameter can also be an array of options, see
 128  	  * DB_common::setOption for more information on connection
 129  	  * options.
 130  	  *
 131  	  * @return object a newly created DB connection object, or a DB
 132  	  * error object on error
 133  	  *
 134  	  * @see DB::parseDSN
 135  	  * @see DB::isError
 136  	  */
 137  	function connect($dsn, $options = false)
 138  	 {
 139  	 	 if (is_array($dsn)) {
 140  	 	 	 $dsninfo = $dsn;
 141  	 	 } else {
 142  	 	 	 $dsninfo = DB::parseDSN($dsn);
 143  	 	 }
 144  	 	 switch ($dsninfo["phptype"]) {
 145  	 	 	 case 'pgsql': 	 $type = 'postgres7'; break;
 146  	 	 	 case 'ifx':	 	 $type = 'informix9'; break;
 147  	 	 	 default: 	 	 $type = $dsninfo["phptype"]; break;
 148  	 	 }
 149  
 150  	 	 if (is_array($options) && isset($options["debug"]) &&
 151  	 	 	 $options["debug"] >= 2) {
 152  	 	 	 // expose php errors with sufficient debug level
 153  	 	 	  @include_once("adodb-$type.inc.php");
 154  	 	 } else {
 155  	 	 	  @include_once("adodb-$type.inc.php");
 156  	 	 }
 157  
 158  	 	 @$obj = NewADOConnection($type);
 159  	 	 if (!is_object($obj)) {
 160  	 	 	 $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
 161  	 	 	 return $obj;
 162  	 	 }
 163  	 	 if (is_array($options)) {
 164  	 	 	 foreach($options as $k => $v) {
 165  	 	 	 	 switch(strtolower($k)) {
 166  	 	 	 	 case 'persist':
 167  	 	 	 	 case 'persistent': 	 $persist = $v; break;
 168  	 	 	 	 #ibase
 169  	 	 	 	 case 'dialect': 	 $obj->dialect = $v; break;
 170  	 	 	 	 case 'charset':	 	 $obj->charset = $v; break;
 171  	 	 	 	 case 'buffers':	 	 $obj->buffers = $v; break;
 172  	 	 	 	 #ado
 173  	 	 	 	 case 'charpage':	 $obj->charPage = $v; break;
 174  	 	 	 	 #mysql
 175  	 	 	 	 case 'clientflags': $obj->clientFlags = $v; break;
 176  	 	 	 	 }
 177  	 	 	 }
 178  	 	 } else {
 179  	 	    	 $persist = false;
 180  	 	 }
 181  
 182  	 	 if (isset($dsninfo['socket'])) $dsninfo['hostspec'] .= ':'.$dsninfo['socket'];
 183  	 	 else if (isset($dsninfo['port'])) $dsninfo['hostspec'] .= ':'.$dsninfo['port'];
 184  
 185  	 	 if($persist) $ok = $obj->PConnect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
 186  	 	 else  $ok = $obj->Connect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
 187  
 188  	 	 if (!$ok) $obj = ADODB_PEAR_Error();
 189  	 	 return $obj;
 190  	 }
 191  
 192  	 /**
 193  	  * Return the DB API version
 194  	  *
 195  	  * @return int the DB API version number
 196  	  */
 197  	function apiVersion()
 198  	 {
 199  	 	 return 2;
 200  	 }
 201  
 202  	 /**
 203  	  * Tell whether a result code from a DB method is an error
 204  	  *
 205  	  * @param $value int result code
 206  	  *
 207  	  * @return bool whether $value is an error
 208  	  */
 209  	function isError($value)
 210  	 {
 211  	 	 if (!is_object($value)) return false;
 212  	 	 $class = strtolower(get_class($value));
 213  	 	 return $class == 'pear_error' || is_subclass_of($value, 'pear_error') ||
 214  	 	 	 	 $class == 'db_error' || is_subclass_of($value, 'db_error');
 215  	 }
 216  
 217  
 218  	 /**
 219  	  * Tell whether a result code from a DB method is a warning.
 220  	  * Warnings differ from errors in that they are generated by DB,
 221  	  * and are not fatal.
 222  	  *
 223  	  * @param $value mixed result value
 224  	  *
 225  	  * @return bool whether $value is a warning
 226  	  */
 227  	function isWarning($value)
 228  	 {
 229  	 	 return false;
 230  	 	 /*
 231  	 	 return is_object($value) &&
 232  	 	 	 (get_class( $value ) == "db_warning" ||
 233  	 	 	  is_subclass_of($value, "db_warning"));*/
 234  	 }
 235  
 236  	 /**
 237  	  * Parse a data source name
 238  	  *
 239  	  * @param $dsn string Data Source Name to be parsed
 240  	  *
 241  	  * @return array an associative array with the following keys:
 242  	  *
 243  	  *  phptype: Database backend used in PHP (mysql, odbc etc.)
 244  	  *  dbsyntax: Database used with regards to SQL syntax etc.
 245  	  *  protocol: Communication protocol to use (tcp, unix etc.)
 246  	  *  hostspec: Host specification (hostname[:port])
 247  	  *  database: Database to use on the DBMS server
 248  	  *  username: User name for login
 249  	  *  password: Password for login
 250  	  *
 251  	  * The format of the supplied DSN is in its fullest form:
 252  	  *
 253  	  *  phptype(dbsyntax)://username:password@protocol+hostspec/database
 254  	  *
 255  	  * Most variations are allowed:
 256  	  *
 257  	  *  phptype://username:password@protocol+hostspec:110//usr/db_file.db
 258  	  *  phptype://username:password@hostspec/database_name
 259  	  *  phptype://username:password@hostspec
 260  	  *  phptype://username@hostspec
 261  	  *  phptype://hostspec/database
 262  	  *  phptype://hostspec
 263  	  *  phptype(dbsyntax)
 264  	  *  phptype
 265  	  *
 266  	  * @author Tomas V.V.Cox <cox@idecnet.com>
 267  	  */
 268  	function parseDSN($dsn)
 269  	 {
 270  	 	 if (is_array($dsn)) {
 271  	 	 	 return $dsn;
 272  	 	 }
 273  
 274  	 	 $parsed = array(
 275  	 	 	 'phptype'  => false,
 276  	 	 	 'dbsyntax' => false,
 277  	 	 	 'protocol' => false,
 278  	 	 	 'hostspec' => false,
 279  	 	 	 'database' => false,
 280  	 	 	 'username' => false,
 281  	 	 	 'password' => false
 282  	 	 );
 283  
 284  	 	 // Find phptype and dbsyntax
 285  	 	 if (($pos = strpos($dsn, '://')) !== false) {
 286  	 	 	 $str = substr($dsn, 0, $pos);
 287  	 	 	 $dsn = substr($dsn, $pos + 3);
 288  	 	 } else {
 289  	 	 	 $str = $dsn;
 290  	 	 	 $dsn = NULL;
 291  	 	 }
 292  
 293  	 	 // Get phptype and dbsyntax
 294  	 	 // $str => phptype(dbsyntax)
 295  	 	 if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
 296  	 	 	 $parsed['phptype'] = $arr[1];
 297  	 	 	 $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
 298  	 	 } else {
 299  	 	 	 $parsed['phptype'] = $str;
 300  	 	 	 $parsed['dbsyntax'] = $str;
 301  	 	 }
 302  
 303  	 	 if (empty($dsn)) {
 304  	 	 	 return $parsed;
 305  	 	 }
 306  
 307  	 	 // Get (if found): username and password
 308  	 	 // $dsn => username:password@protocol+hostspec/database
 309  	 	 if (($at = strpos($dsn,'@')) !== false) {
 310  	 	 	 $str = substr($dsn, 0, $at);
 311  	 	 	 $dsn = substr($dsn, $at + 1);
 312  	 	 	 if (($pos = strpos($str, ':')) !== false) {
 313  	 	 	 	 $parsed['username'] = urldecode(substr($str, 0, $pos));
 314  	 	 	 	 $parsed['password'] = urldecode(substr($str, $pos + 1));
 315  	 	 	 } else {
 316  	 	 	 	 $parsed['username'] = urldecode($str);
 317  	 	 	 }
 318  	 	 }
 319  
 320  	 	 // Find protocol and hostspec
 321  	 	 // $dsn => protocol+hostspec/database
 322  	 	 if (($pos=strpos($dsn, '/')) !== false) {
 323  	 	 	 $str = substr($dsn, 0, $pos);
 324  	 	 	 $dsn = substr($dsn, $pos + 1);
 325  	 	 } else {
 326  	 	 	 $str = $dsn;
 327  	 	 	 $dsn = NULL;
 328  	 	 }
 329  
 330  	 	 // Get protocol + hostspec
 331  	 	 // $str => protocol+hostspec
 332  	 	 if (($pos=strpos($str, '+')) !== false) {
 333  	 	 	 $parsed['protocol'] = substr($str, 0, $pos);
 334  	 	 	 $parsed['hostspec'] = urldecode(substr($str, $pos + 1));
 335  	 	 } else {
 336  	 	 	 $parsed['hostspec'] = urldecode($str);
 337  	 	 }
 338  
 339  	 	 // Get database if any
 340  	 	 // $dsn => database
 341  	 	 if (!empty($dsn)) {
 342  	 	 	 $parsed['database'] = $dsn;
 343  	 	 }
 344  
 345  	 	 return $parsed;
 346  	 }
 347  
 348  	 /**
 349  	  * Load a PHP database extension if it is not loaded already.
 350  	  *
 351  	  * @access public
 352  	  *
 353  	  * @param $name the base name of the extension (without the .so or
 354  	  * .dll suffix)
 355  	  *
 356  	  * @return bool true if the extension was already or successfully
 357  	  * loaded, false if it could not be loaded
 358  	  */
 359  	function assertExtension($name)
 360  	 {
 361  	 	 if (function_exists('dl') && !extension_loaded($name)) {
 362  	 	 	 $dlext = (strncmp(PHP_OS,'WIN',3) === 0) ? '.dll' : '.so';
 363  	 	 	 @dl($name . $dlext);
 364  	 	 }
 365  	 	 if (!extension_loaded($name)) {
 366  	 	 	 return false;
 367  	 	 }
 368  	 	 return true;
 369  	 }
 370  }