ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilDBOracle.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
5include_once ("./Services/Database/classes/MDB2/class.ilDB.php");
6
18class ilDBOracle extends ilDB
19{
20 const CLOB_BUFFER_SIZE = 2000;
22
23
24 public function loadModule($module) {
25 // TODO: Implement loadModule() method.
26 }
27
28
32 function getDSN()
33 {
34 // TODO: check if there is another solution.
35 // This works with 11g
36 if(!isset($GLOBALS['_MDB2_dsninfo_default']['charset']) or
37 $GLOBALS['_MDB2_dsninfo_default']['charset'] != 'utf8')
38 {
39 $GLOBALS['_MDB2_dsninfo_default']['charset'] = 'utf8';
40 }
41
42 return array('phptype' => 'oci8',
43 'hostspec' => $this->getDBHost(),
44 'username' => $this->getDBUser(),
45 'password' => $this->getDBPassword(),
46 'port' => $this->getDBPort(),
47 'service' => $this->getDBName()
48 );
49
50 //return "oci8://".$this->getDBUser().":".$this->getDBPassword()."@".
51 // $this->getDBHost()."/?service=".$this->getDBName();
52 }
53
57 function getDBType()
58 {
59 return "oracle";
60 }
61
62 public function getDBVersion()
63 {
64 $query = 'SELECT * FROM v$version';
65 $res = $this->db->query($query);
66
68 {
69 return parent::getDBVersion();
70 }
72 return isset($row['banner']) ? $row['banner'] : parent::getDBVersion();
73 }
74
78 static function getReservedWords()
79 {
80 // version: 10g
81 // url: http://download-west.oracle.com/docs/cd/B14117_01/server.101/b10759/ap_keywd.htm#g691972
82 return array(
83 "ACCESS", "ADD", "ALL", "ALTER", "AND", "ANY", "AS", "ASC",
84 "AUDIT", "BETWEEN", "BY", "CHAR", "CHECK", "CLUSTER", "COLUMN",
85 "COMMENT", "COMPRESS", "CONNECT", "CREATE", "CURRENT", "DATE",
86 "DECIMAL", "DEFAULT", "DELETE", "DESC", "DISTINCT", "DROP", "ELSE",
87 "EXCLUSIVE", "EXISTS", "FILE", "FLOAT", "FOR", "FROM", "GRANT", "GROUP",
88 "HAVING", "IDENTIFIED", "IMMEDIATE", "IN", "INCREMENT", "INDEX", "INITIAL",
89 "INSERT", "INTEGER", "INTERSECT", "INTO", "IS", "LEVEL", "LIKE", "LOCK", "LONG",
90 "MAXEXTENTS", "MINUS", "MLSLABEL", "MODE", "MODIFY", "NOAUDIT", "NOCOMPRESS", "NOT",
91 "NOWAIT", "NULL", "NUMBER", "OF", "OFFLINE", "ON", "ONLINE","OPTION",
92 "OR", "ORDER", "PCTFREE", "PRIOR", "PRIVILEGES", "PUBLIC", "RAW", "RENAME",
93 "RESOURCE", "REVOKE", "ROW", "ROWID", "ROWNUM", "ROWS", "SELECT", "SESSION", "SET",
94 "SHARE", "SIZE", "SMALLINT", "START", "SUCCESSFUL", "SYNONYM", "SYSDATE","TABLE",
95 "THEN", "TO", "TRIGGER", "UID", "UNION", "UNIQUE", "UPDATE", "USER","VALIDATE",
96 "VALUES", "VARCHAR", "VARCHAR2", "VIEW", "WHENEVER", "WHERE", "WITH"
97 );
98 }
99
103 function doConnect()
104 {
105 $this->db = MDB2::connect($this->getDSN(),
106 array("use_transactions" => true));
107 }
108
112 function initConnection()
113 {
114 $GLOBALS['_MDB2_dsninfo_default']['charset'] = 'utf8';
115 $this->query("ALTER SESSION SET nls_length_semantics='CHAR'");
116 $this->query("ALTER SESSION SET NLS_SORT = binary_ci");
117 }
118
119/* function manipulate($sql)
120 {
121//echo "1";
122//if (!is_int(strpos($sql, "frm_thread_access")))
123//{
124//echo "2";
125 return parent::manipulate($sql);
126//}
127//echo "3";
128 }*/
129
134 function now()
135 {
136 return "LOCALTIMESTAMP";
137 }
138
142 function fromUnixtime($a_expr, $a_to_text = true)
143 {
144 if (!$a_to_text)
145 {
146 return "TO_DATE('19700101000000','YYYYMMDDHH24MISS') ".
147 "+ NUMTODSINTERVAL(".$a_expr.", 'SECOND')";
148 }
149 else
150 {
151 return "to_char(TO_DATE('19700101000000','YYYYMMDDHH24MISS') ".
152 "+ NUMTODSINTERVAL(".$a_expr.", 'SECOND'), 'yyyy-mm-dd hh24:mi:ss')";
153 }
154 }
155
159 function unixTimestamp()
160 {
161 // sysdate should respect database time zone
162 // current_date would respect session time zone
163 return "ROUND((sysdate - to_date('01-JAN-1970','DD-MON-YYYY')) * (86400))";
164 }
165
169 function constraintName($a_table, $a_constraint)
170 {
171 return $a_table."_".$a_constraint;
172 }
173
178 {
179 return "pk";
180 }
181
186 {
187 return false;
188 }
189
197 function replace($a_table, $a_pk_columns, $a_other_columns)
198 {
199 $a_columns = array_merge($a_pk_columns, $a_other_columns);
200 $fields = array();
201 $field_values = array();
202 $placeholders = array();
203 $types = array();
204 $values = array();
205 $lobs = false;
206 $lob = array();
207 $val_field = array();
208 $a = array();
209 $b = array();
210 foreach ($a_columns as $k => $col)
211 {
212 if($col[0] == 'clob' or $col[0] == 'blob')
213 {
214 $val_field[] = $this->quote($col[1], 'text')." ".$k;
215 }
216 else
217 {
218 $val_field[] = $this->quote($col[1], $col[0])." ".$k;
219 }
220 $fields[] = $k;
221 $placeholders[] = "%s";
222 $placeholders2[] = ":$k";
223 $types[] = $col[0];
224
225 // integer auto-typecast (this casts bool values to integer)
226 if ($col[0] == 'integer' && !is_null($col[1]))
227 {
228 $col[1] = (int) $col[1];
229 }
230
231 $values[] = $col[1];
232 $field_values[$k] = $col[1];
233 if ($col[0] == "blob" || $col[0] == "clob")
234 {
235 $lobs = true;
236 $lob[$k] = $k;
237 }
238 $a[] = "a.".$k;
239 $b[] = "b.".$k;
240 }
241 $abpk = array();
242 $aboc = array();
243 $delwhere = array();
244 foreach ($a_pk_columns as $k => $col)
245 {
246 $abpk[] = "a.".$k." = b.".$k;
247 $delwhere[] = $k." = ".$this->quote($col[1], $col[0]);
248 }
249 foreach ($a_other_columns as $k => $col)
250 {
251 $aboc[] = "a.".$k." = b.".$k;
252 }
253 if ($lobs) // delete/insert
254 {
255 $this->manipulate("DELETE FROM ".$a_table." WHERE ".
256 implode ($delwhere, " AND ")
257 );
258 $this->insert($a_table, $a_columns);
259
260 //$r = $this->db->extended->autoExecute($a_table, $field_values, MDB2_AUTOQUERY_INSERT, null, $types);
261 $this->handleError($r, "replace, delete/insert(".$a_table.")");
262 }
263 else // if no lobs are used, use manipulate
264 {
265 $q = "MERGE INTO ".$a_table." a ".
266 "USING (SELECT ".implode($val_field, ", ")." ".
267 "FROM DUAL) b ON (".implode($abpk, " AND ").") ".
268 "WHEN MATCHED THEN UPDATE SET ".implode($aboc, ", ")." ".
269 "WHEN NOT MATCHED THEN INSERT (".implode($a, ",").") VALUES (".implode($b, ",").")";
270 $r = $this->manipulate($q);
271 }
272 return $r;
273 }
274
282 public function locate($a_needle,$a_string,$a_start_pos = 1)
283 {
284 $locate = ' INSTR( ';
285 $locate .= ('SUBSTR('.$a_string.',0,'.self::CLOB_BUFFER_SIZE.')');
286 $locate .= ',';
287 $locate .= $a_needle;
288 $locate .= ',';
289 $locate .= $a_start_pos;
290 $locate .= ') ';
291 return $locate;
292 }
293
305 public function like($a_col, $a_type, $a_value = "?", $case_insensitive = true)
306 {
307 if($a_type == 'text')
308 {
309 return parent::like($a_col,$a_type,$a_value,$case_insensitive);
310 }
311
312 if (!in_array($a_type, array("text", "clob", "blob")))
313 {
314 $this->raisePearError("Like: Invalid column type '".$a_type."'.", $this->error_class->FATAL);
315 }
316 if ($a_value == "?")
317 {
318 if ($case_insensitive)
319 {
320 return "UPPER(SUBSTR(".$a_col.",0,".self::CLOB_BUFFER_SIZE.")) LIKE(UPPER(?))";
321 }
322 else
323 {
324 return "SUBSTR(".$a_col .",0,".self::CLOB_BUFFER_SIZE.") LIKE(?)";
325 }
326 }
327 else
328 {
329 if ($case_insensitive)
330 {
331 return " UPPER(SUBSTR(".$a_col.",0,".self::CLOB_BUFFER_SIZE.")) LIKE(UPPER(".$this->quote($a_value, 'text')."))";
332 }
333 else
334 {
335 return " SUBSTR(".$a_col.",0,".self::CLOB_BUFFER_SIZE.") LIKE(".$this->quote($a_value, 'text').")";
336 }
337 }
338 }
339
346 public function concat(array $a_values, $a_allow_null = true)
347 {
348 if(count($a_values) <= 2)
349 {
350 return parent::concat($a_values,false);
351 }
352
353 $first = true;
354 foreach($a_values as $field_info)
355 {
356 if(!$first)
357 {
358 $concat_value = parent::concat(
359 array(
360 array($concat_value,$concat_type),
361 array($field_info[0],$field_info[1])),
362 false
363 );
364 }
365 else
366 {
367 $first = false;
368 $concat_value = $field_info[0];
369 $concat_type = $field_info[1];
370 }
371 }
372 return $concat_value;
373 }
374
389 function in($a_field, $a_values, $negate = false, $a_type = "")
390 {
391 if(count($a_values) <= self::LIMIT_EXPRESSIONS_IN_LIST)
392 {
393 return parent::in($a_field,$a_values,$negate,$a_type);
394 }
395
396 $first = true;
397 $concat = $negate ? ' AND ' : ' OR ';
398 $in = '(';
399 do
400 {
401 if(!$first)
402 {
403 $in .= $concat;
404
405 }
406 $first = false;
407
408 $spliced = array_splice($a_values, 0, self::LIMIT_EXPRESSIONS_IN_LIST);
409 $in .= parent::in($a_field, $spliced, $negate, $a_type);
410
411 }
412 while($a_values);
413
414 return $in." ) ";
415 }
416
417
428 public function lockTables($a_tables)
429 {
430 global $ilLog;
431
432 $locks = array();
433
434 $counter = 0;
435 foreach($a_tables as $table)
436 {
437 $lock = 'LOCK TABLE ';
438
439 $lock .= ($table['name'].' ');
440
441 switch($table['type'])
442 {
444 $lock .= ' IN SHARE MODE ';
445 break;
446
448 $lock .= ' IN EXCLUSIVE MODE ';
449 break;
450 }
451
452 $locks[] = $lock;
453 }
454
455 // @TODO use and store a unique identifier to allow nested lock/unlocks
456 $this->db->beginTransaction();
457 foreach($locks as $lock)
458 {
459 $this->db->query($lock);
460 $ilLog->write(__METHOD__.': '.$lock);
461 }
462 return true;
463 }
464
470 public function unlockTables()
471 {
472 $this->db->commit();
473 }
474
480 function dropPrimaryKey($a_table)
481 {
482 // oracle 10: dropping constraint may not drop attached index
483 // http://www.orafaq.com/forum/t/59807/0/
484
485 $query = "ALTER TABLE ".$a_table." DROP PRIMARY KEY DROP INDEX";
486 $res = $this->db->query($query);
487
488 return $this->handleError($res, "dropPrimaryKey(".$a_table.")");
489 }
490
491
492 public function setStorageEngine($storage_engine) {
493 unset($storage_engine);
494 }
495
496
497 public function getStorageEngine() {
498 return null;
499 }
500
501
502 public function dropFulltextIndex($a_table, $a_name) {
503 return false;
504 }
505}
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
An exception for terminatinating execution or to throw for unit testing.
isError($data, $code=null)
Tell whether a value is a MDB2 error.
Definition: MDB2.php:599
& connect($dsn, $options=false)
Create a new MDB2 connection object and connect to the specified database.
Definition: MDB2.php:436
Oracle Database Wrapper.
concat(array $a_values, $a_allow_null=true)
CONCAT for oracle allows only the concatenation of two values.
setStorageEngine($storage_engine)
initConnection()
Initialize the database connection.
supportsFulltext()
Is fulltext index supported?
getDSN()
Get DSN.
dropPrimaryKey($a_table)
Drop a primary key from a table.
constraintName($a_table, $a_constraint)
Constraint names must be "globally" unique in oracle.
locate($a_needle, $a_string, $a_start_pos=1)
Create locate string.
loadModule($module)
like($a_col, $a_type, $a_value="?", $case_insensitive=true)
Provisional LIKE support for oracle CLOB's Uses SUBSTR to reduce the length.
fromUnixtime($a_expr, $a_to_text=true)
fromUnixtime (makes timestamp out of unix timestamp)
lockTables($a_tables)
Lock table.
dropFulltextIndex($a_table, $a_name)
const CLOB_BUFFER_SIZE
getDBType()
Get DB Type.
static getReservedWords()
Get reserved words.
doConnect()
Standard way to connect to db.
unixTimestamp()
Unix timestamp.
replace($a_table, $a_pk_columns, $a_other_columns)
Replace into method.
getDBVersion()
Get DB version.
unlockTables()
Unlock tables.
getPrimaryKeyIdentifier()
Primary key identifier.
in($a_field, $a_values, $negate=false, $a_type="")
Overwritten implementation of $ilDB->in to avoid ORA-01795 (maximum number of expressions in a list i...
const LIMIT_EXPRESSIONS_IN_LIST
Database Wrapper.
Definition: class.ilDB.php:30
manipulate($sql)
Data manipulation.
getDBPort()
Get database port.
Definition: class.ilDB.php:103
handleError($a_res, $a_info="", $a_level="")
Handle MDB2 Errors.
Definition: class.ilDB.php:423
getDBUser()
Get database user.
Definition: class.ilDB.php:83
getDBName()
Get database name.
Definition: class.ilDB.php:163
query($sql, $a_handle_error=true)
Query.
insert($a_table, $a_columns)
Convenient method for standard insert statements, example field array:
raisePearError($a_message, $a_level="")
Raise an error.
Definition: class.ilDB.php:459
getDBPassword()
Get database password.
Definition: class.ilDB.php:143
getDBHost()
Get database host.
Definition: class.ilDB.php:123
quote($a_query, $a_type=null)
Wrapper for quote method.
$counter
$r
Definition: example_031.php:79
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
$a_type
Definition: workflow.php:93