47require_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;
 
   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);
 
  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);
 
  185CREATE 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); 
const MDB2_ERROR_UNSUPPORTED
const MDB2_OK(!class_exists('PEAR'))
The method mapErrorCode in each MDB2_dbtype implementation maps native error codes to one of these.
An exception for terminatinating execution or to throw for unit testing.
createConstraint($table, $name, $definition)
create a constraint on a table
dropDatabase($name)
drop an existing database
createSequence($seq_name, $start=1)
create sequence
createDatabase($name)
create a new database
_makeAutoincrement($name, $table, $start=1)
add an autoincrement sequence + trigger
& getDBInstance()
Get the instance of MDB2 associated with the module instance.
isError($data, $code=null)
Tell whether a value is a PEAR error.
if(empty($password)) $table