Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403]

   1  <?php
   2  /**
   3   * Oracle data driver
   4   *
   5   * @deprecated Use oci8 driver instead
   6   *
   7   * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
   8   *
   9   * @package ADOdb
  10   * @link https://adodb.org Project's web site and documentation
  11   * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
  12   *
  13   * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
  14   * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
  15   * any later version. This means you can use it in proprietary products.
  16   * See the LICENSE.md file distributed with this source code for details.
  17   * @license BSD-3-Clause
  18   * @license LGPL-2.1-or-later
  19   *
  20   * @copyright 2000-2013 John Lim
  21   * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
  22   */
  23  
  24  // security - hide paths
  25  if (!defined('ADODB_DIR')) die();
  26  
  27  class ADODB_oracle extends ADOConnection {
  28  	 var $databaseType = "oracle";
  29  	 var $replaceQuote = "''"; // string to use to replace quotes
  30  	 var $concat_operator='||';
  31  	 var $_curs;
  32  	 var $_initdate = true; // init date to YYYY-MM-DD
  33  	 var $metaTablesSQL = 'select table_name from cat';
  34  	 var $metaColumnsSQL = "select cname,coltype,width from col where tname='%s' order by colno";
  35  	 var $sysDate = "TO_DATE(TO_CHAR(SYSDATE,'YYYY-MM-DD'),'YYYY-MM-DD')";
  36  	 var $sysTimeStamp = 'SYSDATE';
  37  	 var $connectSID = true;
  38  
  39  	 // format and return date string in database date format
  40  	function DBDate($d, $isfld = false)
  41  	 {
  42  	 	 if (is_string($d)) $d = ADORecordSet::UnixDate($d);
  43  	 	 if (is_object($d)) $ds = $d->format($this->fmtDate);
  44  	 	 else $ds = adodb_date($this->fmtDate,$d);
  45  	 	 return 'TO_DATE('.$ds.",'YYYY-MM-DD')";
  46  	 }
  47  
  48  	 // format and return date string in database timestamp format
  49  	function DBTimeStamp($ts, $isfld = false)
  50  	 {
  51  
  52  	 	 if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
  53  	 	 if (is_object($ts)) $ds = $ts->format($this->fmtDate);
  54  	 	 else $ds = adodb_date($this->fmtTimeStamp,$ts);
  55  	 	 return 'TO_DATE('.$ds.",'RRRR-MM-DD, HH:MI:SS AM')";
  56  	 }
  57  
  58  
  59  	function BindDate($d)
  60  	 {
  61  	 	 $d = ADOConnection::DBDate($d);
  62  	 	 if (strncmp($d,"'",1)) return $d;
  63  
  64  	 	 return substr($d,1,strlen($d)-2);
  65  	 }
  66  
  67  	function BindTimeStamp($d)
  68  	 {
  69  	 	 $d = ADOConnection::DBTimeStamp($d);
  70  	 	 if (strncmp($d,"'",1)) return $d;
  71  
  72  	 	 return substr($d,1,strlen($d)-2);
  73  	 }
  74  
  75  
  76  
  77  	function BeginTrans()
  78  	 {
  79  	 	  $this->autoCommit = false;
  80  	 	  ora_commitoff($this->_connectionID);
  81  	 	  return true;
  82  	 }
  83  
  84  
  85  	function CommitTrans($ok=true)
  86  	 {
  87  	 	    if (!$ok) return $this->RollbackTrans();
  88  	 	    $ret = ora_commit($this->_connectionID);
  89  	 	    ora_commiton($this->_connectionID);
  90  	 	    return $ret;
  91  	 }
  92  
  93  
  94  	function RollbackTrans()
  95  	 {
  96  	 	 $ret = ora_rollback($this->_connectionID);
  97  	 	 ora_commiton($this->_connectionID);
  98  	 	 return $ret;
  99  	 }
 100  
 101  
 102  	 /* there seems to be a bug in the oracle extension -- always returns ORA-00000 - no error */
 103  	function ErrorMsg()
 104   	 {
 105          if ($this->_errorMsg !== false) return $this->_errorMsg;
 106  
 107          if (is_resource($this->_curs)) $this->_errorMsg = @ora_error($this->_curs);
 108   	 	 if (empty($this->_errorMsg)) $this->_errorMsg = @ora_error($this->_connectionID);
 109  	 	 return $this->_errorMsg;
 110  	 }
 111  
 112  
 113  	function ErrorNo()
 114  	 {
 115  	 	 if ($this->_errorCode !== false) return $this->_errorCode;
 116  
 117  	 	 if (is_resource($this->_curs)) $this->_errorCode = @ora_errorcode($this->_curs);
 118  	 	 if (empty($this->_errorCode)) $this->_errorCode = @ora_errorcode($this->_connectionID);
 119          return $this->_errorCode;
 120  	 }
 121  
 122  
 123  
 124  	 	 // returns true or false
 125  		function _connect($argHostname, $argUsername, $argPassword, $argDatabasename, $mode=0)
 126  	 	 {
 127  	 	 	 if (!function_exists('ora_plogon')) return null;
 128  
 129              // <G. Giunta 2003/03/03/> Reset error messages before connecting
 130              $this->_errorMsg = false;
 131  	 	     $this->_errorCode = false;
 132  
 133              // G. Giunta 2003/08/13 - This looks danegrously suspicious: why should we want to set
 134              // the oracle home to the host name of remote DB?
 135  //	 	 	 if ($argHostname) putenv("ORACLE_HOME=$argHostname");
 136  
 137  	 	 	 if($argHostname) { // code copied from version submitted for oci8 by Jorma Tuomainen <jorma.tuomainen@ppoy.fi>
 138  	 	 	 	 if (empty($argDatabasename)) $argDatabasename = $argHostname;
 139  	 	 	 	 else {
 140  	 	 	 	 	 if(strpos($argHostname,":")) {
 141  	 	 	 	 	 	 $argHostinfo=explode(":",$argHostname);
 142  	 	 	 	 	 	 $argHostname=$argHostinfo[0];
 143  	 	 	 	 	 	 $argHostport=$argHostinfo[1];
 144  	 	 	 	 	 } else {
 145  	 	 	 	 	 	 $argHostport="1521";
 146  	 	 	 	 	 }
 147  
 148  
 149  	 	 	 	 	 if ($this->connectSID) {
 150  	 	 	 	 	 	 $argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
 151  	 	 	 	 	 	 .")(PORT=$argHostport))(CONNECT_DATA=(SID=$argDatabasename)))";
 152  	 	 	 	 	 } else
 153  	 	 	 	 	 	 $argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
 154  	 	 	 	 	 	 .")(PORT=$argHostport))(CONNECT_DATA=(SERVICE_NAME=$argDatabasename)))";
 155  	 	 	 	 }
 156  
 157  	 	 	 }
 158  
 159  	 	 	 if ($argDatabasename) $argUsername .= "@$argDatabasename";
 160  
 161  	 	 //if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
 162  	 	 	 if ($mode == 1)
 163  	 	 	 	 $this->_connectionID = ora_plogon($argUsername,$argPassword);
 164  	 	 	 else
 165  	 	 	 	 $this->_connectionID = ora_logon($argUsername,$argPassword);
 166  	 	 	 if ($this->_connectionID === false) return false;
 167  	 	 	 if ($this->autoCommit) ora_commiton($this->_connectionID);
 168  	 	 	 if ($this->_initdate) {
 169  	 	 	 	 $rs = $this->_query("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD'");
 170  	 	 	 	 if ($rs) ora_close($rs);
 171  	 	 	 }
 172  
 173  	 	 	 return true;
 174  	 	 }
 175  
 176  
 177  	 	 // returns true or false
 178  		function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
 179  	 	 {
 180  	 	 	 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, 1);
 181  	 	 }
 182  
 183  
 184  	 	 // returns query ID if successful, otherwise false
 185  		function _query($sql,$inputarr=false)
 186  	 	 {
 187              // <G. Giunta 2003/03/03/> Reset error messages before executing
 188              $this->_errorMsg = false;
 189  	 	     $this->_errorCode = false;
 190  
 191  	 	 	 $curs = ora_open($this->_connectionID);
 192  
 193  	 	  	 if ($curs === false) return false;
 194  	 	 	 $this->_curs = $curs;
 195  	 	 	 if (!ora_parse($curs,$sql)) return false;
 196  	 	 	 if (ora_exec($curs)) return $curs;
 197              // <G. Giunta 2004/03/03> before we close the cursor, we have to store the error message
 198              // that we can obtain ONLY from the cursor (and not from the connection)
 199              $this->_errorCode = @ora_errorcode($curs);
 200              $this->_errorMsg = @ora_error($curs);
 201              // </G. Giunta 2004/03/03>
 202  	 	  	 @ora_close($curs);
 203  	 	 	 return false;
 204  	 	 }
 205  
 206  
 207  	 	 // returns true or false
 208  		function _close()
 209  	 	 {
 210  	 	 	 return @ora_logoff($this->_connectionID);
 211  	 	 }
 212  
 213  
 214  
 215  }
 216  
 217  
 218  /*--------------------------------------------------------------------------------------
 219  	 	  Class Name: Recordset
 220  --------------------------------------------------------------------------------------*/
 221  
 222  class ADORecordset_oracle extends ADORecordSet {
 223  
 224  	 var $databaseType = "oracle";
 225  	 var $bind = false;
 226  
 227  	function __construct($queryID,$mode=false)
 228  	 {
 229  
 230  	 	 if ($mode === false) {
 231  	 	 	 global $ADODB_FETCH_MODE;
 232  	 	 	 $mode = $ADODB_FETCH_MODE;
 233  	 	 }
 234  	 	 $this->fetchMode = $mode;
 235  
 236  	 	 $this->_queryID = $queryID;
 237  
 238  	 	 $this->_inited = true;
 239  	 	 $this->fields = array();
 240  	 	 if ($queryID) {
 241  	 	 	 $this->_currentRow = 0;
 242  	 	 	 $this->EOF = !$this->_fetch();
 243  	 	 	 @$this->_initrs();
 244  	 	 } else {
 245  	 	 	 $this->_numOfRows = 0;
 246  	 	 	 $this->_numOfFields = 0;
 247  	 	 	 $this->EOF = true;
 248  	 	 }
 249  
 250  	 	 return $this->_queryID;
 251  	 }
 252  
 253  
 254  
 255  	    /*	 	 Returns: an object containing field information.
 256  	 	 	    Get column information in the Recordset object. fetchField() can be used in order to obtain information about
 257  	 	 	    fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
 258  	 	 	    fetchField() is retrieved.	 	 */
 259  
 260  	   function FetchField($fieldOffset = -1)
 261  	    {
 262  	 	 	 $fld = new ADOFieldObject;
 263  	 	 	 $fld->name = ora_columnname($this->_queryID, $fieldOffset);
 264  	 	 	 $fld->type = ora_columntype($this->_queryID, $fieldOffset);
 265  	 	 	 $fld->max_length = ora_columnsize($this->_queryID, $fieldOffset);
 266  	 	 	 return $fld;
 267  	    }
 268  
 269  	 /* Use associative array to get fields array */
 270  	function Fields($colname)
 271  	 {
 272  	 	 if (!$this->bind) {
 273  	 	 	 $this->bind = array();
 274  	 	 	 for ($i=0; $i < $this->_numOfFields; $i++) {
 275  	 	 	 	 $o = $this->FetchField($i);
 276  	 	 	 	 $this->bind[strtoupper($o->name)] = $i;
 277  	 	 	 }
 278  	 	 }
 279  
 280  	 	  return $this->fields[$this->bind[strtoupper($colname)]];
 281  	 }
 282  
 283     function _initrs()
 284     {
 285  	 	    $this->_numOfRows = -1;
 286  	 	    $this->_numOfFields = @ora_numcols($this->_queryID);
 287     }
 288  
 289  
 290     function _seek($row)
 291     {
 292  	 	    return false;
 293     }
 294  
 295     function _fetch($ignore_fields=false) {
 296  // should remove call by reference, but ora_fetch_into requires it in 4.0.3pl1
 297  	 	 if ($this->fetchMode & ADODB_FETCH_ASSOC)
 298  	 	 	 return @ora_fetch_into($this->_queryID,$this->fields,ORA_FETCHINTO_NULLS|ORA_FETCHINTO_ASSOC);
 299     	 	 else
 300  	 	 	 return @ora_fetch_into($this->_queryID,$this->fields,ORA_FETCHINTO_NULLS);
 301     }
 302  
 303     /*	 	 close() only needs to be called if you are worried about using too much memory while your script
 304  	 	    is running. All associated result memory for the specified result identifier will automatically be freed.	 	 */
 305  
 306     function _close()
 307  {
 308  	 	    return @ora_close($this->_queryID);
 309     }
 310  
 311  	function MetaType($t, $len = -1, $fieldobj = false)
 312  	 {
 313  	 	 if (is_object($t)) {
 314  	 	 	 $fieldobj = $t;
 315  	 	 	 $t = $fieldobj->type;
 316  	 	 	 $len = $fieldobj->max_length;
 317  	 	 }
 318  
 319  	 	 switch (strtoupper($t)) {
 320  	 	 case 'VARCHAR':
 321  	 	 case 'VARCHAR2':
 322  	 	 case 'CHAR':
 323  	 	 case 'VARBINARY':
 324  	 	 case 'BINARY':
 325  	 	 	 	 if ($len <= $this->blobSize) return 'C';
 326  	 	 case 'LONG':
 327  	 	 case 'LONG VARCHAR':
 328  	 	 case 'CLOB':
 329  	 	 return 'X';
 330  	 	 case 'LONG RAW':
 331  	 	 case 'LONG VARBINARY':
 332  	 	 case 'BLOB':
 333  	 	 	 	 return 'B';
 334  
 335  	 	 case 'DATE': return 'D';
 336  
 337  	 	 //case 'T': return 'T';
 338  
 339  	 	 case 'BIT': return 'L';
 340  	 	 case 'INT':
 341  	 	 case 'SMALLINT':
 342  	 	 case 'INTEGER': return 'I';
 343  	 	 default: return 'N';
 344  	 	 }
 345  	 }
 346  }