예제 #1
0
 /**
  * Applies the differences defined in $dbSchemaDiff to the database referenced by $db.
  *
  * This method uses {@link convertDiffToDDL} to create SQL for the
  * differences and then executes the returned SQL statements on the
  * database handler $db.
  *
  * @todo check for failed transaction
  *
  * @param ezcDbHandler    $db
  * @param ezcDbSchemaDiff $dbSchemaDiff
  */
 public function applyDiffToDb(ezcDbHandler $db, ezcDbSchemaDiff $dbSchemaDiff)
 {
     $db->beginTransaction();
     foreach ($this->convertDiffToDDL($dbSchemaDiff) as $query) {
         $db->exec($query);
     }
     $db->commit();
 }
예제 #2
0
 /**
  * Performs changing field in Oracle table.
  * (workaround for "ALTER TABLE table MODIFY field fieldType AUTO_INCREMENT " that not alowed in Oracle ).
  * 
  * @param ezcDbHandler    $db
  * @param string          $tableName
  * @param string          $autoIncrementFieldName
  * @param string          $autoIncrementFieldType
  */
 private function addAutoIncrementField($db, $tableName, $autoIncrementFieldName, $autoIncrementFieldType)
 {
     // fetching field info from Oracle, getting column position of autoincrement field
     // @apichange This code piece would become orphan, with the new
     // implementation. We still need it to drop the old sequences.
     // Remove until --END-- to not take care of them.
     $resultArray = $db->query("SELECT   a.column_name AS field, " . "         a.column_id AS field_pos " . "FROM     user_tab_columns a " . "WHERE    a.table_name = '{$tableName}' AND a.column_name = '{$autoIncrementFieldName}'" . "ORDER BY a.column_id");
     $resultArray->setFetchMode(PDO::FETCH_ASSOC);
     if (count($resultArray) != 1) {
         return;
     }
     $result = $resultArray->fetch();
     $fieldPos = $result['field_pos'];
     // emulation of autoincrement through adding sequence, trigger and constraint
     $oldName = ezcDbSchemaOracleHelper::generateSuffixCompositeIdentName($tableName, $fieldPos, "seq");
     $oldNameTrigger = ezcDbSchemaOracleHelper::generateSuffixCompositeIdentName($tableName, $fieldPos, "trg");
     $sequence = $db->query("SELECT sequence_name FROM user_sequences WHERE sequence_name = '{$oldName}'")->fetchAll();
     if (count($sequence) > 0) {
         // assuming that if the seq exists, the trigger exists too
         $db->query("DROP SEQUENCE \"{$oldName}\"");
         $db->query("DROP TRIGGER \"{$oldNameTrigger}\"");
     }
     // --END--
     // New sequence names, using field names
     $newName = ezcDbSchemaOracleHelper::generateSuffixCompositeIdentName($tableName, $fieldPos, "seq");
     $newNameTrigger = ezcDbSchemaOracleHelper::generateSuffixCompositeIdentName($tableName, $fieldPos, "seq");
     // Emulation of autoincrement through adding sequence, trigger and constraint
     $sequences = $db->query("SELECT sequence_name FROM user_sequences WHERE sequence_name = '{$newName}'")->fetchAll();
     if (count($sequences) > 0) {
         $db->query("DROP SEQUENCE \"{$newName}\"");
     }
     $db->exec("CREATE SEQUENCE \"{$newName}\" start with 1 increment by 1 nomaxvalue");
     $db->exec("CREATE OR REPLACE TRIGGER \"{$newNameTrigger}\" " . "before insert on \"{$tableName}\" for each row " . "begin " . "select \"{$newName}\".nextval into :new.\"{$autoIncrementFieldName}\" from dual; " . "end;");
     $constraintName = ezcDbSchemaOracleHelper::generateSuffixedIdentName(array($tableName), "pkey");
     $constraint = $db->query("SELECT constraint_name FROM user_cons_columns WHERE constraint_name = '{$constraintName}'")->fetchAll();
     if (count($constraint) > 0) {
         $db->query("ALTER TABLE \"{$tableName}\" DROP CONSTRAINT \"{$constraintName}\"");
     }
     $db->exec("ALTER TABLE \"{$tableName}\" ADD CONSTRAINT \"{$constraintName}\" PRIMARY KEY ( \"{$autoIncrementFieldName}\" )");
     $this->context['skip_primary'] = true;
 }
예제 #3
0
 /**
  * Sets up opened connection according to options.
  */
 private function setupConnection()
 {
     $requiredMode = $this->options->quoteIdentifier;
     if ($requiredMode == ezcDbMssqlOptions::QUOTES_GUESS) {
         $result = parent::query("SELECT sessionproperty('QUOTED_IDENTIFIER')");
         $rows = $result->fetchAll();
         $mode = (int) $rows[0][0];
         if ($mode == 0) {
             $this->identifierQuoteChars = array('start' => '[', 'end' => ']');
         } else {
             $this->identifierQuoteChars = array('start' => '"', 'end' => '"');
         }
     } else {
         if ($requiredMode == ezcDbMssqlOptions::QUOTES_COMPLIANT) {
             parent::exec('SET QUOTED_IDENTIFIER ON');
             $this->identifierQuoteChars = array('start' => '"', 'end' => '"');
         } else {
             if ($requiredMode == ezcDbMssqlOptions::QUOTES_LEGACY) {
                 parent::exec('SET QUOTED_IDENTIFIER OFF');
                 $this->identifierQuoteChars = array('start' => '[', 'end' => ']');
             }
         }
     }
 }
예제 #4
0
 /**
  * Drop specified temporary table
  * in a portable way.
  *
  * Developers should use this method instead of dropping temporary
  * tables with the appropriate SQL queries
  * to maintain inter-DBMS portability.
  *
  * @see createTemporaryTable()
  *
  * @param   string  $tableName Name of temporary table to drop.
  * @return void
  */
 public function dropTemporaryTable($tableName)
 {
     $this->db->exec("DROP TABLE {$tableName}");
 }
예제 #5
0
 /**
  * Performs droping field from SQLite table using temporary table
  * (workaround for "ALTER TABLE table DROP field" that not alowed in SQLite ).
  *
  * @param ezcDbHandler    $db
  * @param string          $tableName
  * @param string          $dropFieldName
  */
 private function dropField($db, $tableName, $dropFieldName)
 {
     $tmpTableName = $tableName . '_ezcbackup';
     $resultArray = $db->query("PRAGMA TABLE_INFO( {$tableName} )");
     $resultArray->setFetchMode(PDO::FETCH_NUM);
     $fieldsDefinitions = array();
     $fieldsList = array();
     foreach ($resultArray as $row) {
         $fieldSql = array();
         $fieldSql[] = "'{$row[1]}'";
         // name
         if ($row[1] == $dropFieldName) {
             continue;
             // don't include droped fileld in temporary table
         }
         $fieldSql[] = $row[2];
         // type
         if ($row[3] == '99') {
             $fieldSql[] = 'NOT NULL';
         }
         $fieldDefault = null;
         if ($row[4] != '') {
             $fieldSql[] = "DEFAULT '{$row[4]}'";
         }
         if ($row[5] == '1') {
             $fieldSql[] = 'PRIMARY KEY AUTOINCREMENT';
         }
         // FIXME: unsigned needs to be implemented
         $fieldUnsigned = false;
         $fieldsDefinitions[] = join(' ', $fieldSql);
         $fieldsList[] = $fieldSql[0];
     }
     $fields = join(', ', $fieldsDefinitions);
     $tmpTableCreateSql = "CREATE TEMPORARY TABLE '{$tmpTableName}'( {$fields}  );";
     $newTableCreateSql = "CREATE TABLE '{$tableName}'( {$fields} )";
     if (count($fieldsList) > 0) {
         $db->exec($tmpTableCreateSql);
         $db->exec("INSERT INTO '{$tmpTableName}' SELECT " . join(', ', $fieldsList) . " FROM '{$tableName}';");
         $db->exec("DROP TABLE '{$tableName}';");
         $db->exec($newTableCreateSql);
         $db->exec("INSERT INTO '{$tableName}' SELECT " . join(', ', $fieldsList) . " FROM '{$tmpTableName}';");
         $db->exec("DROP TABLE '{$tmpTableName}';");
     } else {
         throw new ezcDbSchemaDropAllColumnsException("Trying to delete all columns in table: {$tableName}");
     }
 }
예제 #6
0
 /**
  * Performs adding field in PostgreSQL table.
  * ( workaround for "ALTER TABLE table ADD field fieldDefinition NOT NULL" 
  * that not alowed in PostgreSQL 7.x but works in PostgreSQL 8.x ).
  * 
  * @param ezcDbHandler    $db
  * @param string          $tableName
  * @param string          $fieldName
  * @param string          $fieldType
  *
  */
 private function addField(ezcDbHandler $db, $tableName, $fieldName, $fieldType)
 {
     $db->exec("ALTER TABLE \"{$tableName}\" ADD \"{$fieldName}\" {$fieldType}");
     $db->exec("ALTER TABLE \"{$tableName}\" ALTER \"{$fieldName}\" SET NOT NULL");
 }