47 require_once 
'MDB2/Driver/Manager/Common.php';
 
   75         if (!$db->options[
'emulate_database']) {
 
   77                 'database creation is only supported if the "emulate_database" option is enabled', __FUNCTION__);
 
   80         $username = $db->options[
'database_name_prefix'].$name;
 
   81         $password = $db->dsn[
'password'] ? $db->dsn[
'password'] : $name;
 
   82         $tablespace = $db->options[
'default_tablespace']
 
   83             ? 
' DEFAULT TABLESPACE '.$db->options[
'default_tablespace'] : 
'';
 
   85         $query = 
'CREATE USER '.$username.
' IDENTIFIED BY '.$password.$tablespace;
 
   90         $query = 
'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO '.$username;
 
   93             $query = 
'DROP USER '.$username.
' CASCADE';
 
   94             $result2 = $db->standaloneQuery(
$query, null, 
true);
 
   96                 return $db->raiseError($result2, null, null,
 
   97                     'could not setup the database user', __FUNCTION__);
 
  122         if (!$db->options[
'emulate_database']) {
 
  124                 'database dropping is only supported if the "emulate_database" option is enabled', __FUNCTION__);
 
  127         $username = $db->options[
'database_name_prefix'].$name;
 
  128         return $db->standaloneQuery(
'DROP USER '.$username.
' CASCADE', null, 
true);
 
  151         $table = strtoupper($table);
 
  152         $index_name  = $table . 
'_AI_PK';
 
  155             'fields' => array($name => 
true),
 
  159             return $db->raiseError(
$result, null, null,
 
  160                 'primary key for autoincrement PK could not be created', __FUNCTION__);
 
  163         if (is_null($start)) {
 
  164             $db->beginTransaction();
 
  165             $query = 
'SELECT MAX(' . $db->quoteIdentifier($name, 
true) . 
') FROM ' . $db->quoteIdentifier($table, 
true);
 
  166             $start = $this->db->queryOne(
$query, 
'integer');
 
  177             return $db->raiseError(
$result, null, null,
 
  178                 'sequence for autoincrement PK could not be created', __FUNCTION__);
 
  180         $sequence_name = $db->getSequenceName($table);
 
  181         $trigger_name  = $db->quoteIdentifier($table . 
'_AI_PK', 
true);
 
  182         $table = $db->quoteIdentifier($table, 
true);
 
  183         $name  = $db->quoteIdentifier($name, 
true);
 
  185 CREATE TRIGGER '.$trigger_name.
' 
  190    last_Sequence NUMBER; 
  191    last_InsertID NUMBER; 
  193    SELECT '.$sequence_name.
'.NEXTVAL INTO :NEW.'.$name.
' FROM DUAL; 
  194    IF (:NEW.'.$name.
' IS NULL OR :NEW.'.$name.
' = 0) THEN 
  195       SELECT '.$sequence_name.
'.NEXTVAL INTO :NEW.'.$name.
' FROM DUAL; 
  197       SELECT NVL(Last_Number, 0) INTO last_Sequence 
  199        WHERE UPPER(Sequence_Name) = UPPER(\''.$sequence_name.
'\');
 
  200       SELECT :NEW.
'.$name.' INTO last_InsertID FROM DUAL;
 
  201       WHILE (last_InsertID > last_Sequence) LOOP
 
  202          SELECT 
'.$sequence_name.'.NEXTVAL INTO last_Sequence FROM DUAL;
 
  207         return $db->exec($trigger_sql); 
  211     // {{{ _dropAutoincrement() 
  220     function _dropAutoincrement($table) 
  222         $db =& $this->getDBInstance(); 
  223         if (PEAR::isError($db)) { 
  227         $table = strtoupper($table); 
  228         $trigger_name = $table . '_AI_PK
'; 
  229         $trigger_name_quoted = $db->quote($trigger_name, 'text
'); 
  230         $query = 'SELECT trigger_name FROM user_triggers
'; 
  231         $query.= ' WHERE trigger_name=
'.$trigger_name_quoted.' OR trigger_name=
'.strtoupper($trigger_name_quoted); 
  232         $trigger = $db->queryOne($query); 
  233         if (PEAR::isError($trigger)) { 
  238             $trigger_name  = $db->quoteIdentifier($table . '_AI_PK
', true); 
  239             $trigger_sql = 'DROP TRIGGER 
' . $trigger_name; 
  240             $result = $db->exec($trigger_sql); 
  241             if (PEAR::isError($result)) { 
  242                 return $db->raiseError($result, null, null, 
  243                     'trigger 
for autoincrement PK could not be dropped
', __FUNCTION__); 
  246             $result = $this->dropSequence($table); 
  247             if (PEAR::isError($result)) { 
  248                 return $db->raiseError($result, null, null, 
  249                     'sequence 
for autoincrement PK could not be dropped
', __FUNCTION__); 
  252             $index_name = $table . '_AI_PK
'; 
  253             $result = $this->dropConstraint($table, $index_name); 
  254             if (PEAR::isError($result)) { 
  255                 return $db->raiseError($result, null, null, 
  256                     'primary key 
for autoincrement PK could not be dropped
', __FUNCTION__); 
  264     // {{{ _getTemporaryTableQuery() 
  273     function _getTemporaryTableQuery() 
  275         return 'GLOBAL TEMPORARY
'; 
  316     function createTable($name, $fields, $options = array()) 
  318         $db =& $this->getDBInstance(); 
  319         if (PEAR::isError($db)) { 
  322         $db->beginNestedTransaction(); 
  323         $result = parent::createTable($name, $fields, $options); 
  324         if (!PEAR::isError($result)) { 
  325             foreach ($fields as $field_name => $field) { 
  326                 if (!empty($field['autoincrement
'])) { 
  327                     $result = $this->_makeAutoincrement($field_name, $name); 
  331         $db->completeNestedTransaction(); 
  345     function dropTable($name) 
  347         $db =& $this->getDBInstance(); 
  348         if (PEAR::isError($db)) { 
  351         $db->beginNestedTransaction(); 
  352         $result = $this->_dropAutoincrement($name); 
  353         if (!PEAR::isError($result)) { 
  354             $result = parent::dropTable($name); 
  356         $db->completeNestedTransaction(); 
  453     function alterTable($name, $changes, $check) 
  455         $db =& $this->getDBInstance(); 
  456         if (PEAR::isError($db)) { 
  460         foreach ($changes as $change_name => $change) { 
  461             switch ($change_name) { 
  469                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null, 
  470                     'change type 
"'.$change_name.'" not yet supported
', __FUNCTION__); 
  478         $name = $db->quoteIdentifier($name, true); 
  480         if (!empty($changes['add
']) && is_array($changes['add
'])) { 
  482             foreach ($changes['add
'] as $field_name => $field) { 
  483                 $fields[] = $db->getDeclaration($field['type
'], $field_name, $field); 
  485             $result = $db->exec("ALTER TABLE $name ADD (". implode(', 
', $fields).')
'); 
  486             if (PEAR::isError($result)) { 
  491         if (!empty($changes['change
']) && is_array($changes['change
'])) { 
  493             foreach ($changes['change
'] as $field_name => $field) { 
  494                 $fields[] = $field_name. ' ' . $db->getDeclaration($field['definition
']['type
'], '', $field['definition
']); 
  496             $result = $db->exec("ALTER TABLE $name MODIFY (". implode(', 
', $fields).')
'); 
  497             if (PEAR::isError($result)) { 
  502         if (!empty($changes['rename
']) && is_array($changes['rename
'])) { 
  503             foreach ($changes['rename
'] as $field_name => $field) { 
  504                 $field_name = $db->quoteIdentifier($field_name, true); 
  505                 //$query = "ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name
']); 
  506                                 // Disabled case sensitive renaming smeyer 
  507                 $query = "ALTER TABLE $name RENAME COLUMN $field_name TO ".$field['name
']; 
  508                 $result = $db->exec($query); 
  509                 if (PEAR::isError($result)) { 
  515         if (!empty($changes['remove']) && is_array($changes['remove'])) { 
  517             foreach ($changes['remove'] as $field_name => $field) { 
  518                 $fields[] = $db->quoteIdentifier($field_name, true); 
  520             $result = $db->exec("ALTER TABLE $name DROP COLUMN ". implode(', 
', $fields)); 
  521             if (PEAR::isError($result)) { 
  526         if (!empty($changes['name
'])) { 
  527             $change_name = $db->quoteIdentifier($changes['name
'], true); 
  528             $result = $db->exec("ALTER TABLE $name RENAME TO ".$change_name); 
  529             if (PEAR::isError($result)) { 
  538     // {{{ listDatabases() 
  546     function listDatabases() 
  548         $db =& $this->getDBInstance(); 
  549         if (PEAR::isError($db)) { 
  553         if (!$db->options['emulate_database
']) { 
  554             return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, 
  555                 'database listing is only supported 
if the 
"emulate_database" option is enabled
', __FUNCTION__); 
  558         if ($db->options['database_name_prefix
']) { 
  559             $query = 'SELECT SUBSTR(username, 
'; 
  560             $query.= (strlen($db->options['database_name_prefix
'])+1); 
  561             $query.= ") FROM sys.dba_users WHERE username LIKE '"; 
  562             $query.= $db->options['database_name_prefix']."%
'"; 
  564             $query = 'SELECT username FROM sys.dba_users
'; 
  566         $result2 = $db->standaloneQuery($query, array('text
'), false); 
  567         if (PEAR::isError($result2)) { 
  570         $result = $result2->fetchCol(); 
  571         if (PEAR::isError($result)) { 
  574         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  575             && $db->options['field_case
'] == CASE_LOWER 
  577             $result = array_map(($db->options['field_case
'] == CASE_LOWER ? 'strtolower
' : 'strtoupper
'), $result); 
  594         $db =& $this->getDBInstance(); 
  595         if (PEAR::isError($db)) { 
  599         if ($db->options['emulate_database
'] && $db->options['database_name_prefix
']) { 
  600             $query = 'SELECT SUBSTR(username, 
'; 
  601             $query.= (strlen($db->options['database_name_prefix
'])+1); 
  602             $query.= ") FROM sys.dba_users WHERE username NOT LIKE '"; 
  603             $query.= $db->options['database_name_prefix']."%
'"; 
  605             $query = 'SELECT username FROM sys.dba_users
'; 
  607         return $db->queryCol($query); 
  621         $db =& $this->getDBInstance(); 
  622         if (PEAR::isError($db)) { 
  626         $query = 'SELECT view_name FROM sys.user_views
'; 
  627         $result = $db->queryCol($query); 
  628         if (PEAR::isError($result)) { 
  631         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  632             && $db->options['field_case
'] == CASE_LOWER 
  634             $result = array_map(($db->options['field_case
'] == CASE_LOWER ? 'strtolower
' : 'strtoupper
'), $result); 
  640     // {{{ listFunctions() 
  648     function listFunctions() 
  650         $db =& $this->getDBInstance(); 
  651         if (PEAR::isError($db)) { 
  655         $query = "SELECT name FROM sys.user_source WHERE line = 1 AND type = 'FUNCTION
'"; 
  656         $result = $db->queryCol($query); 
  657         if (PEAR::isError($result)) { 
  660         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  661             && $db->options['field_case
'] == CASE_LOWER 
  663             $result = array_map(($db->options['field_case
'] == CASE_LOWER ? 'strtolower
' : 'strtoupper
'), $result); 
  677     function listTables() 
  679         $db =& $this->getDBInstance(); 
  680         if (PEAR::isError($db)) { 
  684         $query = 'SELECT table_name FROM sys.user_tables
'; 
  685         $result = $db->queryCol($query); 
  686         if (PEAR::isError($result)) { 
  689         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  690             && $db->options['field_case
'] == CASE_LOWER 
  692             $result = array_map(($db->options['field_case
'] == CASE_LOWER ? 'strtolower
' : 'strtoupper
'), $result); 
  698     // {{{ listTableFields() 
  707     function listTableFields($table) 
  709         $db =& $this->getDBInstance(); 
  710         if (PEAR::isError($db)) { 
  714         $table = $db->quote($table, 'text
'); 
  715         $query = 'SELECT column_name FROM user_tab_columns
'; 
  716         $query.= ' WHERE table_name=
'.$table.' OR table_name=
'.strtoupper($table).' ORDER BY column_id
'; 
  717         $result = $db->queryCol($query); 
  718         if (PEAR::isError($result)) { 
  721         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  722             && $db->options['field_case
'] == CASE_LOWER 
  724             $result = array_map(($db->options['field_case
'] == CASE_LOWER ? 'strtolower
' : 'strtoupper
'), $result); 
  730     // {{{ listTableIndexes() 
  739     function listTableIndexes($table) 
  741         $db =& $this->getDBInstance(); 
  742         if (PEAR::isError($db)) { 
  746         $table = $db->quote($table, 'text
'); 
  747         $query = 'SELECT index_name name FROM user_indexes
'; 
  748         $query.= ' WHERE (table_name=
'.$table.' OR table_name=
'.strtoupper($table); 
  749         $query.= ') AND generated=
' .$db->quote('N
', 'text
'); 
  750         $indexes = $db->queryCol($query, 'text
'); 
  751         if (PEAR::isError($indexes)) { 
  756         foreach ($indexes as $index) { 
  757             $index = $this->_fixIndexName($index); 
  758             if (!empty($index)) { 
  759                 $result[$index] = true; 
  763         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  764             && $db->options['field_case
'] == CASE_LOWER 
  766             $result = array_change_key_case($result, $db->options['field_case
']); 
  768         return array_keys($result); 
  772     // {{{ listTableConstraints() 
  781     function listTableConstraints($table) 
  783         $db =& $this->getDBInstance(); 
  784         if (PEAR::isError($db)) { 
  788         $table = $db->quote($table, 'text
'); 
  789         $query = 'SELECT constraint_name name FROM user_constraints
'; 
  790         $query.= ' WHERE table_name=
'.$table.' OR table_name=
'.strtoupper($table); 
  791         $constraints = $db->queryCol($query); 
  792         if (PEAR::isError($constraints)) { 
  797         foreach ($constraints as $constraint) { 
  798             $constraint = $this->_fixIndexName($constraint); 
  799             if (!empty($constraint)) { 
  800                 $result[$constraint] = true; 
  804         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE 
  805             && $db->options['field_case
'] == CASE_LOWER 
  807             $result = array_change_key_case($result, $db->options['field_case
']); 
  809         return array_keys($result); 
  813     // {{{ createSequence() 
  824     function createSequence($seq_name, $start = 1) 
  826         $db =& $this->getDBInstance(); 
  827         if (PEAR::isError($db)) { 
  831         $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true); 
  832         $query = "CREATE SEQUENCE $sequence_name START WITH $start INCREMENT BY 1 NOCACHE"; 
  833         $query.= ($start < 1 ? " MINVALUE $start" : ''); 
  834         return $db->exec($query); 
  838     // {{{ dropSequence() 
  848     function dropSequence($seq_name) 
  850         $db =& $this->getDBInstance(); 
  851         if (PEAR::isError($db)) { 
  855         $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true); 
  856         return $db->exec("DROP SEQUENCE $sequence_name"); 
  860     // {{{ listSequences() 
  868     function listSequences() 
  870         $db =& $this->getDBInstance(); 
  871         if (PEAR::isError($db)) { 
  875         $query = "SELECT sequence_name FROM sys.user_sequences"; 
  876         $table_names = $db->queryCol($query); 
  877         if (PEAR::isError($table_names)) { 
  881         foreach ($table_names as $table_name) { 
  882             $result[] = $this->_fixSequenceName($table_name); 
  884         if ($db->options['portability
'] & MDB2_PORTABILITY_FIX_CASE) { 
  885             $result = array_map(($db->options['field_case
'] == CASE_LOWER ? 'strtolower
' : 'strtoupper
'), $result);