5 require_once(
'base/Ego_Sql_Abstract.php');
19 private $_queryHandle;
23 private $_mode=OCI_DEFAULT;
31 @oci_free_statement($this->_lobStm);
32 unset($this->_lobStm);
34 if ($this->_queryHandle)
37 @oci_free_statement($this->_queryHandle);
38 unset($this->_queryHandle);
45 function connect($database=
'', $host=
'', $user=
'', $password=
'', $charset=
'AL32UTF8')
47 if (func_num_args()==0)
49 if ($GLOBALS[
'egotec_conf'][
'oci']) {
50 $GLOBALS[
'egotec_conf'][
'db'] = $GLOBALS[
'egotec_conf'][
'oci'];
55 $this->_user = strtoupper($GLOBALS[
'egotec_conf'][
'db'][
'user']);
57 $this->_dbHandle = oci_pconnect(
58 $GLOBALS[
'egotec_conf'][
'db'][
'user'],
59 $GLOBALS[
'egotec_conf'][
'db'][
'password'],
60 $GLOBALS[
'egotec_conf'][
'db'][
'database'],
64 $this->_user = strtoupper($GLOBALS[
'egotec_conf'][
'db'][
'user']);
67 $this->_dbHandle = oci_connect($user, $password, $database, $charset);
68 $this->_user = strtoupper($user);
69 if ( !$this->_dbHandle )
71 $this->_dbHandle = oci_connect($host, $user, $password, $database);
72 $this->_user = strtoupper($host);
74 if ( !$this->_dbHandle )
87 function query($query, $appendCurrent =
false)
90 if (strpos($query,
'LEFT(')!==
false) {
91 $query = preg_replace(
'#left\((.*?),(.*?)\)#i',
'substr($1,0,$2)', $query);
96 $this->currentQuery .= $query;
98 $this->currentQuery = $query;
100 $this->currentBind = array();
101 $this->_queryHandle = oci_parse($this->_dbHandle, $query);
102 if ($this->_queryHandle===
false || !@oci_execute($this->_queryHandle, $this->_mode))
106 oci_set_prefetch($this->_queryHandle, 100);
107 if (!$this->_transaction) {
108 oci_commit($this->_dbHandle);
110 $this->_currentRow = -1;
111 return $this->_queryHandle;
120 private function _prepare($query)
122 $this->currentBind = array();
124 while (($pos=strpos($query,
'?'))!==
false)
126 $query = substr($query, 0, $pos).
':'.($index++).substr($query, $pos+1);
128 $this->currentQuery = $query;
129 return oci_parse($this->_dbHandle, $query);
139 private function _execute($queryHandle, $values, $blobs=array())
141 $this->currentBind = $values;
143 foreach ($values as $key => $val)
145 oci_bind_by_name($queryHandle,
':'.$index++, $values[$key]);
149 if (!@oci_execute($queryHandle, $this->_mode))
153 if (!$this->_transaction)
155 oci_commit($this->_dbHandle);
158 $descriptors = array();
159 foreach ($blobs as $key => $val)
161 $descriptors[$key] = oci_new_descriptor($this->_dbHandle, OCI_D_LOB);
162 oci_bind_by_name($queryHandle,
':'.$index++, $descriptors[$key], -1, OCI_B_CLOB);
164 if (!oci_execute($queryHandle, OCI_DEFAULT))
168 foreach ($blobs as $key => $val)
170 $descriptors[$key]->write($val);
172 if (!$this->_transaction)
174 oci_commit($this->_dbHandle);
176 foreach ($descriptors as $descriptor)
181 $error = oci_error($queryHandle);
182 if (!$queryHandle || $error)
186 $this->_currentRow = -1;
204 $this->
query(
'DROP TABLE "'.strtoupper($table).
'"');
214 if (!$this->_queryHandle)
216 return $this->Record =
null;
218 $this->_currentRow++;
219 if ($this->_limit<0 || $this->_limit--)
221 $this->Record = oci_fetch_assoc($this->_queryHandle);
224 foreach ($this->Record as $key => $val)
228 $this->Record[$key] = $val->load();
233 oci_bind_by_name($this->_lobStm,
':'.$this->_lobStmId, $this->Record[strtoupper($this->_lobStmId)]);
234 oci_execute($this->_lobStm, $this->_mode);
235 $lob_record = oci_fetch_assoc($this->_lobStm);
238 return $this->Record = array();
240 foreach ($lob_record as $key=>$val)
244 $this->Record[$key] = $val->load();
248 return $this->Record = array_change_key_case($this->Record);
251 return $this->Record =
null;
261 if ($this->_queryHandle)
263 $GLOBALS[
'stats'][
'db_select']++;
264 $query =
'SELECT COUNT(*) FROM ('.$this->currentQuery.
')';
265 $statement = oci_parse($this->_dbHandle, $query);
266 if ($this->currentBind)
268 foreach ($this->currentBind as $key => $val)
270 oci_bind_by_name($statement, $key, $this->currentBind[$key]);
273 oci_execute($statement, $this->_mode);
274 $row = oci_fetch_row($statement);
275 oci_free_statement($statement);
292 if ($query[
'bitand']) {
293 if (empty($query[
'where'])) {
294 $query[
'where'] =
'1=1';
296 foreach ($query[
'bitand'] as $bit) {
297 $query[
'where'] .=
' AND BITAND('.$bit[0].
', '.$bit[1].
') = '.$bit[2];
300 return 'SELECT '.($query[
'distinct']?
'DISTINCT ':
'')
301 .($query[
'fields']?:
'*').(isset($query[
'fields2'])&&!empty($query[
'fields2'])?
','.(is_array($query[
'fields2'])?implode(
',',$query[
'fields2']):$query[
'fields2']):
'')
302 .
"\nFROM ".($query[
'table']?:$query[
'from'])
303 .($query[
'table2']?($query[
'table']?
',':
'').$query[
'table2']:
'')
304 .($query[
'inner']?
' INNER JOIN '.(is_array($query[
'inner'])?
305 implode(
' INNER JOIN ', $query[
'inner']):$query[
'inner']):
'')
306 .($query[
'join']?
"\nLEFT JOIN ".(is_array($query[
'join'])?
307 implode(
"\nLEFT JOIN ", $query[
'join']):$query[
'join']):
'')
308 .($query[
'where']?
"\nWHERE ".$query[
'where']:
'')
309 .($query[
'group']?
"\nGROUP BY ".$query[
'group']:
'')
310 .($query[
'having']?
' HAVING '.$query[
'having']:
'')
311 .($query[
'order']?
"\nORDER BY ".$query[
'order']:
'');
324 if ($query[
'field_as'])
326 foreach ($query[
'field_as'] as $k=>$v)
328 if ($query[
'field_as_bitand'][$k]) {
329 foreach ($query[
'field_as_bitand'][$k] as $bit) {
330 $v .=
' AND BITAND('.$bit[0].
','.$bit[1].
')='.$bit[2];
333 $query[
'fields2'][] =
'('.$v.
') AS '.$k;
335 unset($query[
'field_as']);
338 unset($this->_lobStm);
339 if (($query[
'fields']==
'id' || substr($query[
'fields'], 0, 3)==
'id,') && $query[
'table'])
341 $tables = explode(
',', $query[
'table']);
342 $query[
'fields'] = $tables[
sizeof($tables)-1].
'.*';
344 if ($query[
'fields'] && $query[
'fields'][strlen($query[
'fields'])-5]==
'_'
345 && substr($query[
'fields'], strlen($query[
'fields'])-2)==
'.*')
347 $lob_table = substr($query[
'fields'], 0, strlen($query[
'fields'])-2);
348 $query[
'fields'] = $lob_table.
'.id,'.$lob_table.
'.name,'.$lob_table.
'.title,'.$lob_table.
'.url,'.$lob_table.
'.short,'.
349 $lob_table.
'.a_date,'.$lob_table.
'.c_date,'.$lob_table.
'.m_date,'.$lob_table.
'.a_user,'.$lob_table.
'.c_user,'.$lob_table.
'.m_user,'.
350 $lob_table.
'.type,'.$lob_table.
'.children_order,'.$lob_table.
'.order_field,'.
351 $lob_table.
'.nav_hide,'.$lob_table.
'.inactive,'.$lob_table.
'.cache,'.$lob_table.
'.release_from,'.$lob_table.
'.release_until,'.
352 $lob_table.
'.workflow,'.$lob_table.
'.workflow_state,'.$lob_table.
'.deleted';
353 $lob_query =
'select content, extra from '.$lob_table.
' where id=:id';
354 $this->_lobStm = oci_parse($this->_dbHandle, $lob_query);
355 $this->_lobStmId =
'id';
358 strpos($query[
'fields'],
'egotec_user.*')===0 ||
359 ( $query[
'union'] && $query[
'union'][0][
'fields']==
'egotec_user.*' )
361 $lob_table=
'egotec_user';
364 for($i=0; $i<
sizeof($query[
'union']); $i++)
366 $query[
'union'][$i][
'fields'] = $lob_table.
'.user_id,'.$lob_table.
'.username,'.
367 $lob_table.
'.email,'.$lob_table.
'.sid,'.
368 $lob_table.
'.multiple_login,'.$lob_table.
'.last_login,'.$lob_table.
'.no_admin,'.$lob_table.
'.user_c_date';
371 $add_fields = substr($query[
'fields'], strlen(
'egotec_user.*'));
372 $query[
'fields'] = $lob_table.
'.user_id,'.$lob_table.
'.username,'.
373 $lob_table.
'.email,'.$lob_table.
'.sid,'.
374 $lob_table.
'.multiple_login,'.$lob_table.
'.last_login,'.$lob_table.
'.no_admin,'.$lob_table.
'.user_c_date'.
377 $lob_query =
'select extra from '.$lob_table.
' where user_id=:user_id';
378 $this->_lobStm = oci_parse($this->_dbHandle, $lob_query);
379 $this->_lobStmId =
'user_id';
382 $query[
'where'] = str_replace(
"\\'",
"''", $query[
'where']);
384 $this->_cached =
false;
388 $order = $query[
'order'];
389 unset($query[
'order']);
390 if (!$query[
'fields'] || $query[
'fields']==
'*' || $query[
'fields']==$query[
'table'].
'.*')
392 $order = str_replace(
393 array(
'id',
'name',
'a_date',
'c_date',
'type',
'order_field',
'workflow_state'),
394 array(0, 2, 6, 7, 10, 12, 19),
398 $fields = $query[
'fields'].($query[
'fields2']?(is_array($query[
'fields2'])?implode(
',',$query[
'fields2']):
','.$query[
'fields2']):
'');
399 $fields = preg_replace(
'#\(SELECT.*?\) AS ([^,]+)#ims',
"\\1", $fields);
400 $fields = explode(
',', $fields);
401 array_unshift($fields,
'#####');
402 $order = str_replace(array_values($fields), array_keys($fields), $order);
404 foreach ($query[
'union'] as $union)
406 $union_join = $union[
'join'];
407 $union = array_merge($query, $union);
408 $union[
'join'] = $union_join?$union_join:array();
409 $union[
'where'] = $query[
'where']?
'('.$query[
'where'].
') AND ('.$union[
'where'].
')':$union[
'where'];
410 $union[
'join'] = $query[
'join']?array_merge_recursive($query[
'join'], $union[
'join']):$union[
'join'];
413 $s = implode(
"\nUNION\n", $unions).($order?
"\nORDER BY ".$order:
'');
420 foreach ($query[
'bind'] as $k=>$v)
422 $s = str_replace(
':'.$k, (!in_array($k, [
'name',
'path',
's',
'u',
'username',
'dir']) && is_numeric($v))?$v:
'\''.str_replace(array(
'\\',
'\''), array(
'\\\\',
'\'\
''), $v).
'\'', $s);
424 $return = $this->
query($s);
426 $return = $this->
query($s);
431 $limit = explode(
',', $query[
'limit']);
432 if (
sizeof($limit)>1)
437 if (!oci_fetch($this->_queryHandle))
439 unset($this->_queryHandle);
445 $this->_limit = $limit[1];
447 $this->_limit = $limit[0];
455 function delete($query)
457 assert($query[
'table']||$query[
'from']);
459 .($query[
'fields']?$query[
'fields'].
' ':
'')
461 .($query[
'table']?$query[
'table']:$query[
'from'])
462 .($query[
'inner']?
' INNER JOIN '.(is_array($query[
'inner'])?
463 implode(
' INNER JOIN ', $query[
'inner']):$query[
'inner']):
'')
464 .($query[
'join']?
' LEFT JOIN '.(is_array($query[
'join'])?
465 implode(
' LEFT JOIN ', $query[
'join']):$query[
'join']):
'')
466 .($query[
'where']?
' WHERE '.$query[
'where']:
'');
469 foreach ($query[
'bind'] as $k=>$v)
471 $s = str_replace(
':'.$k, ($k!=
'name' && $k!=
'u' && $k!=
's' && $k !=
'dir' && is_numeric($v))?$v:
'\''.str_replace(array(
'\\',
'\''), array(
'\\\\',
'\'\
''), $v).
'\'', $s);
474 return $this->
query($s);
497 if (isset($query[
'key']))
499 $query[
'set'] = array_combine($query[
'key'], $query[
'val']);
504 if (isset($query[
'set']))
506 foreach ($query[
'set'] as $k => $v)
512 $keys[] = strtoupper($k);
513 $names[] =
'EMPTY_CLOB()';
518 $keys[] = strtoupper($k);
523 if ($query[
'replace'])
525 if (empty($query[
'primary'])) {
526 $query[
'primary'] = array_keys($this->
getPrimary($query[
'table']));
529 foreach ($keys as $key)
531 if (in_array(strtolower($key), $query[
'primary']))
533 $val = $query[
'set'][strtolower($key)];
534 $where[] = $key.
'='.(strtolower($key)!=
'dir' && is_numeric($val)?$val:
"'$val'");
537 $this->
delete(array(
'table' => $query[
'table'],
'where' => implode(
' AND ', $where)));
539 $insert_table = $query[
'table'].
'-'.
sizeof($keys).
'-'.$query[
'replace'];
540 if ($this->_insertTable != $insert_table) {
541 $this->currentQuery = $query;
542 $s =
'INSERT INTO '.$query[
'table'].
' ("'.implode(
'","', $keys).
'") VALUES ('.implode(
',', $names).
')';
544 $s.=
' RETURNING '.implode(
',', array_keys($blobs)).
' INTO ?'.str_repeat(
',?',
sizeof($blobs)-1);
546 $this->_insertstmt = $this->_prepare($s);
547 $this->_insertTable = $insert_table;
549 $this->currentQuery = print_r($query,
true);
550 return $this->_execute($this->_insertstmt, $values, $blobs);
561 if (isset($query[
'key']))
563 $query[
'set'] = array_combine($query[
'key'], $query[
'val']);
568 if (isset($query[
'set']))
570 foreach ($query[
'set'] as $k => $v)
576 $set2[] = $k.
'=EMPTY_CLOB()';
585 if (isset($query[
'set_f']))
587 foreach ($query[
'set_f'] as $k => $v)
592 $set = array_merge($set, $set2);
593 $s =
'UPDATE '.$query[
'table'].
' SET '.implode(
',', $set).($query[
'where']?
' WHERE '.$query[
'where']:
'');
596 $s.=
' RETURNING '.implode(
',', array_keys($blobs)).
' INTO ?'.str_repeat(
',?',
sizeof($blobs)-1);
600 foreach ($query[
'bind'] as $k=>$v)
602 $s = str_replace(
':'.$k, ($k!=
'name' && $k!=
'u' && $k!=
's' && $k!=
'dir' && is_numeric($v))?$v:
'\''.str_replace(array(
'\\',
'\''), array(
'\\\\',
'\'\
''), $v).
'\'', $s);
605 $this->_queryHandle = $this->_prepare($s);
606 return $this->_execute($this->_queryHandle, $values, $blobs);
609 private function _changeType($type)
611 $type = str_replace(
'/*bin*/',
'', $type);
612 $type_array = explode(
' ', $type);
614 switch ($type_array[0])
624 $type =
'varchar2(255)';
627 $type =
'varchar2(500)';
630 $type =
'varchar2(3900)';
651 function createTable($table, $struct, $drop_flag=
true, $notexists_flag=
false)
655 $this->
query(
'DROP TABLE '.strtoupper($table));
665 foreach ($struct as $name => $type)
667 $key = explode(
' ', $name);
668 $type = $this->_changeType($type);
671 $query[] =
'"'.$name.
'" '.$type;
673 $val = preg_replace(
'/\([^)]+\)/',
'', $type);
675 if ($table==
'egotec_url' && $key[0]==
'PRIMARY') {
682 $query[] =
'PRIMARY KEY ("'.str_replace(
',',
'","', $val).
'")';
685 $index_name = $table.
'_'.$key[1];
686 if (strlen($index_name)>24)
688 $index_name_array = explode(
'_', $index_name);
689 $index_name_short =
'';
690 $part_length = (integer)(24/
sizeof($index_name_array));
691 foreach ($index_name_array as $index_name_part)
693 $index_name_short.= substr($index_name_part, 0, $part_length);
695 $index_name = $index_name_short.substr(md5($index_name), 0, 24-strlen($index_name_short));
697 $index[] =
'CREATE INDEX '.$index_name.
' ON '.$table.
' ("'.str_replace(
',',
'","', $val).
'") NOLOGGING';
700 $query[] =
'UNIQUE ("'.$type.
'")';
704 $s = strtoupper(
'create table '.$table.
' ('.implode(
',', $query).
')');
706 foreach ($index as $query)
708 $this->
query(strtoupper($query));
715 foreach ($struct as $name => $type)
717 $key = explode(
' ', $name);
718 $type = $this->_changeType($type);
721 $query[] =
'ADD '.$name.
' '.$type;
726 $query[] =
'ADD PRIMARY KEY ('.$type.
')';
729 $query[] =
'ADD KEY '.$key[1].
' ('.$type.
')';
732 $query[] =
'ADD UNIQUE KEY '.$key[1].
' ('.$type.
')';
735 if ($key[1] == $key[2]) {
736 $query[] =
'MODIFY '.$key[1].
' ('.$type.
')';
738 $query[] =
'RENAME '.$key[1].
' TO '.$key[2];
743 foreach ($query as $q) {
744 $q =
'ALTER TABLE '.$table.
' '.$q;
753 private function _halt()
755 if ($this->_queryHandle)
757 $error = oci_error($this->_queryHandle);
759 $error = oci_error();
761 $error_str = print_r($error,
true);
770 oci_commit($this->_dbHandle);
771 $this->_transaction =
true;
779 $this->_transaction =
false;
780 oci_commit($this->_dbHandle);
788 if ($this->_transaction) {
789 oci_rollback($this->_dbHandle);
790 $this->_transaction =
false;
808 if (!$table)
return array();
809 $table = strtoupper($table);
810 $stmt = $this->
query(
"SELECT COLUMN_NAME, DATA_TYPE FROM user_tab_columns WHERE TABLE_NAME ='$table'");
812 while($record = oci_fetch_assoc($stmt))
814 $type = strtolower($record[
'DATA_TYPE']);
820 $type =
'varchar(255)';
827 'field' => strtolower($record[
'COLUMN_NAME']),
831 oci_free_statement($stmt);
864 'table' =>
'all_tables',
865 'where' =>
'table_name=:table',
867 'table' => strtoupper($table)
883 'fields' =>
'cols.column_name,cols2.data_type',
884 'table' =>
'all_constraints cons, all_cons_columns cols, all_tab_columns cols2',
885 'where' =>
'cols.table_name=\''.strtoupper($table).
'\' '.
886 'AND cons.constraint_type=\
'P\' '.
887 'AND cons.constraint_name = cols.constraint_name '.
888 'AND cons.owner = cols.owner '.
889 'AND cols2.table_name=cols.table_name AND cols2.column_name=cols.column_name',
890 'order' =>
'cols.position'
893 while ($db->nextRecord())
895 if (strpos($db->Record[
'data_type'],
'INT')!==
false || $db->Record[
'data_type']==
'NUMBER')
901 $primary[strtolower($db->Record[
'column_name'])] = $type;
913 require_once(
'base/Ego_System.php');
915 $s =
'ANALYZE TABLE '.$table.
' COMPUTE STATISTICS';
916 $handle = oci_parse($this->_dbHandle, $s);
917 oci_execute($handle);
949 'table' =>
'all_tables',
950 'where' =>
"TABLE_NAME LIKE :whatnames",
952 'whatnames' => strtoupper($like.
'%')
964 'table' =>
'all_tables'
968 $all_table = array();
972 $all_table[$count++] = array_pop($this->Record);
982 $this->
query($this->currentQuery);
990 return oci_server_version($this->_dbHandle);
select($query, $cache=false)
alterTable($table, $struct)
createTable($table, $struct, $drop_flag=true, $notexists_flag=false)
connect($database='', $host='', $user='', $password='', $charset='AL32UTF8')
query($query, $appendCurrent=false)
static eternalCache($active, $clear=true)