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