예제 #1
0
 /**
  * @param Table $localTable
  * @param ForeignKeyConstraint $fkConstraint
  */
 public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
 {
     // Append the foreign key constraints SQL
     if ($this->_platform->supportsForeignKeyConstraints()) {
         $this->_createFkConstraintQueries = array_merge($this->_createFkConstraintQueries, (array) $this->_platform->getCreateForeignKeySQL($fkConstraint, $localTable->getQuotedName($this->_platform)));
     }
 }
 public function getCreateTableSQL(Table $table, array $columns, array $options = array())
 {
     $tableName = $table->getQuotedName($this->platform);
     $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
     if ($this->platform->supportsCommentOnStatement()) {
         foreach ($table->getColumns() as $column) {
             $comment = $this->getColumnComment($column);
             if (null !== $comment && '' !== $comment) {
                 $sql[] = $this->platform->getCommentOnColumnSQL($tableName, $column->getQuotedName($this->platform), $comment);
             }
         }
     }
     return $sql;
 }
예제 #3
0
 /**
  * @param \TYPO3\CMS\Core\Database\Schema\Parser\AST\CreateIndexDefinitionItem $item
  * @return \Doctrine\DBAL\Schema\Index
  * @throws \Doctrine\DBAL\Schema\SchemaException
  * @throws \InvalidArgumentException
  */
 protected function addIndex(CreateIndexDefinitionItem $item) : Index
 {
     $indexName = $item->indexName->getQuotedName();
     $columnNames = array_map(function (IndexColumnName $columnName) {
         if ($columnName->length) {
             return $columnName->columnName->getQuotedName() . '(' . $columnName->length . ')';
         }
         return $columnName->columnName->getQuotedName();
     }, $item->columnNames);
     if ($item->isPrimary) {
         $this->table->setPrimaryKey($columnNames);
         $index = $this->table->getPrimaryKey();
     } else {
         $index = GeneralUtility::makeInstance(Index::class, $indexName, $columnNames, $item->isUnique, $item->isPrimary);
         if ($item->isFulltext) {
             $index->addFlag('fulltext');
         } elseif ($item->isSpatial) {
             $index->addFlag('spatial');
         }
         $this->table = GeneralUtility::makeInstance(Table::class, $this->table->getQuotedName($this->platform), $this->table->getColumns(), array_merge($this->table->getIndexes(), [strtolower($indexName) => $index]), $this->table->getForeignKeys(), 0, $this->table->getOptions());
     }
     return $index;
 }
 /**
  * @param \Doctrine\DBAL\Schema\TableDiff $diff
  *
  * @return array|bool
  */
 private function getSimpleAlterTableSQL(TableDiff $diff)
 {
     // Suppress changes on integer type autoincrement columns.
     foreach ($diff->changedColumns as $oldColumnName => $columnDiff) {
         if (!$columnDiff->fromColumn instanceof Column || !$columnDiff->column instanceof Column || !$columnDiff->column->getAutoincrement() || !(string) $columnDiff->column->getType() === 'Integer') {
             continue;
         }
         if (!$columnDiff->hasChanged('type') && $columnDiff->hasChanged('unsigned')) {
             unset($diff->changedColumns[$oldColumnName]);
             continue;
         }
         $fromColumnType = (string) $columnDiff->fromColumn->getType();
         if ($fromColumnType === 'SmallInt' || $fromColumnType === 'BigInt') {
             unset($diff->changedColumns[$oldColumnName]);
         }
     }
     if (!empty($diff->renamedColumns) || !empty($diff->addedForeignKeys) || !empty($diff->addedIndexes) || !empty($diff->changedColumns) || !empty($diff->changedForeignKeys) || !empty($diff->changedIndexes) || !empty($diff->removedColumns) || !empty($diff->removedForeignKeys) || !empty($diff->removedIndexes) || !empty($diff->renamedIndexes)) {
         return false;
     }
     $table = new Table($diff->name);
     $sql = array();
     $tableSql = array();
     $columnSql = array();
     foreach ($diff->addedColumns as $column) {
         if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
             continue;
         }
         $field = array_merge(array('unique' => null, 'autoincrement' => null, 'default' => null), $column->toArray());
         $type = (string) $field['type'];
         switch (true) {
             case isset($field['columnDefinition']) || $field['autoincrement'] || $field['unique']:
             case $type == 'DateTime' && $field['default'] == $this->getCurrentTimestampSQL():
             case $type == 'Date' && $field['default'] == $this->getCurrentDateSQL():
             case $type == 'Time' && $field['default'] == $this->getCurrentTimeSQL():
                 return false;
         }
         $field['name'] = $column->getQuotedName($this);
         if (strtolower($field['type']) == 'string' && $field['length'] === null) {
             $field['length'] = 255;
         }
         $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ADD COLUMN ' . $this->getColumnDeclarationSQL($field['name'], $field);
     }
     if (!$this->onSchemaAlterTable($diff, $tableSql)) {
         if ($diff->newName !== false) {
             $newTable = new Identifier($diff->newName);
             $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' RENAME TO ' . $newTable->getQuotedName($this);
         }
     }
     return array_merge($sql, $tableSql, $columnSql);
 }
 /**
  * @group DBAL-177
  */
 public function testQuoteSchemaPrefixed()
 {
     $table = new Table("`test`.`test`");
     $this->assertEquals("test.test", $table->getName());
     $this->assertEquals("`test`.`test`", $table->getQuotedName(new \Doctrine\DBAL\Platforms\MySqlPlatform()));
 }
 /**
  * Drops and creates a new table.
  *
  * @param \Doctrine\DBAL\Schema\Table $table
  *
  * @return void
  */
 public function dropAndCreateTable(Table $table)
 {
     $this->tryMethod('dropTable', $table->getQuotedName($this->_platform));
     $this->createTable($table);
 }
예제 #7
0
 /**
  * @param \Doctrine\DBAL\Schema\TableDiff $diff
  *
  * @return array|bool
  */
 private function getSimpleAlterTableSQL(TableDiff $diff)
 {
     if (!empty($diff->renamedColumns) || !empty($diff->addedForeignKeys) || !empty($diff->addedIndexes) || !empty($diff->changedColumns) || !empty($diff->changedForeignKeys) || !empty($diff->changedIndexes) || !empty($diff->removedColumns) || !empty($diff->removedForeignKeys) || !empty($diff->removedIndexes)) {
         return false;
     }
     $table = new Table($diff->name);
     $sql = array();
     $tableSql = array();
     $columnSql = array();
     foreach ($diff->addedColumns as $column) {
         if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
             continue;
         }
         $field = array_merge(array('unique' => null, 'autoincrement' => null, 'default' => null), $column->toArray());
         $type = (string) $field['type'];
         switch (true) {
             case isset($field['columnDefinition']) || $field['autoincrement'] || $field['unique']:
             case $type == 'DateTime' && $field['default'] == $this->getCurrentTimestampSQL():
             case $type == 'Date' && $field['default'] == $this->getCurrentDateSQL():
             case $type == 'Time' && $field['default'] == $this->getCurrentTimeSQL():
                 return false;
         }
         $field['name'] = $column->getQuotedName($this);
         if (strtolower($field['type']) == 'string' && $field['length'] === null) {
             $field['length'] = 255;
         }
         $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ADD COLUMN ' . $this->getColumnDeclarationSQL($field['name'], $field);
     }
     if (!$this->onSchemaAlterTable($diff, $tableSql)) {
         if ($diff->newName !== false) {
             $newTable = new Table($diff->newName);
             $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' RENAME TO ' . $newTable->getQuotedName($this);
         }
     }
     return array_merge($sql, $tableSql, $columnSql);
 }
예제 #8
0
 /**
  * @param AbstractPlatform $platform The platform to use for retrieving this table diff's name.
  *
  * @return \Doctrine\DBAL\Schema\Identifier
  */
 public function getName(AbstractPlatform $platform)
 {
     return new Identifier($this->fromTable instanceof Table ? $this->fromTable->getQuotedName($platform) : $this->name);
 }
예제 #9
0
 /**
  * @param TableConfiguration $tableConfig
  * @param Table              $table
  * @param array              $harvestedValues
  *
  * @return QueryBuilder
  */
 private function createSelectQueryBuilder(TableConfiguration $tableConfig, Table $table, $harvestedValues = array())
 {
     $qb = $this->connectionHandler->getConnection()->createQueryBuilder()->select('*')->from($table->getQuotedName($this->connectionHandler->getPlatform()), 't');
     $this->addFiltersToSelectQuery($qb, $tableConfig, $harvestedValues);
     if ($tableConfig->getLimit() != null) {
         $qb->setMaxResults($tableConfig->getLimit());
     }
     if ($tableConfig->getOrderBy() != null) {
         $qb->add('orderBy', $tableConfig->getOrderBy());
     }
     return $qb;
 }
 /**
  * @param Table $table
  */
 public function acceptTable(Table $table)
 {
     $this->_tables[] = $this->_platform->getDropTableSQL($table->getQuotedName($this->_platform));
 }
예제 #11
0
 /**
  * Dumps the contents of a single table.
  *
  * @param Table              $table
  * @param TableConfiguration $tableConfig
  */
 private function dumpTableContent(Table $table, TableConfiguration $tableConfig)
 {
     // Ensure connection is still open (to prevent for example "MySQL server has gone" errors)
     $this->connectionHandler->reconnectIfNecessary();
     // The PDO instance is used to quote the dumped values.
     $pdo = $this->connectionHandler->getPdo();
     $tableName = $table->getName();
     $quotedTableName = $table->getQuotedName($this->connectionHandler->getPlatform());
     $insertColumns = null;
     $harvestColumns = $tableConfig->getColumnsToHarvest();
     // The buffer is used to create combined SQL statements.
     $maxBufferSize = $this->context->getConfig()->getOutputConfig()->getRowsPerStatement();
     $bufferCount = 0;
     // number of rows in buffer
     $buffer = array();
     // array to buffer rows
     $rowCount = $this->dataLoader->countRows($tableConfig, $table, $this->harvestedValues);
     $result = $this->dataLoader->executeSelectQuery($tableConfig, $table, $this->harvestedValues);
     $this->logger->info(sprintf('Dumping table %s (%d rows)', $table->getName(), $rowCount));
     $progress = $this->context->getProgressBarHelper()->createProgressBar($rowCount, OutputInterface::VERBOSITY_VERY_VERBOSE);
     foreach ($result as $row) {
         /*
          * The following code (in this loop) will be executed for each dumped row!
          * Performance in this place is essential!
          */
         foreach ($harvestColumns as $harvestColumn) {
             if (!isset($row[$harvestColumn])) {
                 throw new InvalidArgumentException(sprintf('Trying to collect value of column %s in table %s which does not exist.', $harvestColumn, $tableName));
             }
             $this->harvestedValues[$tableName][$harvestColumn][] = $row[$harvestColumn];
         }
         // Quote all values in the row.
         $context = $row;
         foreach ($row as $key => $value) {
             $value = $this->dataConverter->convert($tableName . '.' . $key, $value, $context);
             if (is_null($value)) {
                 $value = 'NULL';
             } else {
                 $value = $pdo->quote($value);
             }
             $row[$key] = $value;
         }
         if ($insertColumns === null) {
             // As custom queries can be defined to select the data, the column order in the insert statement
             // depends on the actual result set.
             $insertColumns = $this->extractInsertColumns(array_keys($row));
         }
         $buffer[] = '(' . implode(', ', $row) . ')';
         $bufferCount++;
         if ($bufferCount >= $maxBufferSize) {
             $query = 'INSERT INTO ' . $quotedTableName . ' (' . $insertColumns . ')' . ' VALUES ' . implode(', ', $buffer) . ';';
             $this->dumpOutput->writeln($query);
             $progress->advance($bufferCount);
             $buffer = array();
             $bufferCount = 0;
         }
     }
     if ($bufferCount > 0) {
         // Dump the final buffer.
         $query = 'INSERT INTO ' . $quotedTableName . ' (' . $insertColumns . ')' . ' VALUES ' . implode(', ', $buffer) . ';';
         $this->dumpOutput->writeln($query);
     }
     $progress->finish();
 }
예제 #12
0
 /**
  * {@inheritDoc}
  * Gets the SQL statement(s) to create a table with the specified name, columns and constraints
  * on this platform.
  *
  * @param Table $table The name of the table.
  * @param integer $createFlags
  *
  * @return array The sequence of SQL statements.
  */
 public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
 {
     if (!is_int($createFlags)) {
         $msg = "Second argument of CratePlatform::getCreateTableSQL() has to be integer.";
         throw new \InvalidArgumentException($msg);
     }
     if (count($table->getColumns()) === 0) {
         throw DBALException::noColumnsSpecifiedForTable($table->getName());
     }
     $tableName = $table->getQuotedName($this);
     $options = $table->getOptions();
     $options['uniqueConstraints'] = array();
     $options['indexes'] = array();
     $options['primary'] = array();
     if (($createFlags & self::CREATE_INDEXES) > 0) {
         foreach ($table->getIndexes() as $index) {
             /* @var $index Index */
             if ($index->isPrimary()) {
                 $platform = $this;
                 $options['primary'] = array_map(function ($columnName) use($table, $platform) {
                     return $table->getColumn($columnName)->getQuotedName($platform);
                 }, $index->getColumns());
                 $options['primary_index'] = $index;
             } else {
                 $options['indexes'][$index->getName()] = $index;
             }
         }
     }
     $columnSql = array();
     $columns = array();
     foreach ($table->getColumns() as $column) {
         if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) {
             $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
             $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
             $columnSql = array_merge($columnSql, $eventArgs->getSql());
             if ($eventArgs->isDefaultPrevented()) {
                 continue;
             }
         }
         $columns[$column->getQuotedName($this)] = $this->prepareColumnData($column, $options['primary']);
     }
     if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
         $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
         $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
         if ($eventArgs->isDefaultPrevented()) {
             return array_merge($eventArgs->getSql(), $columnSql);
         }
     }
     $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
     if ($this->supportsCommentOnStatement()) {
         foreach ($table->getColumns() as $column) {
             if ($this->getColumnComment($column)) {
                 $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getName(), $this->getColumnComment($column));
             }
         }
     }
     return array_merge($sql, $columnSql);
 }
예제 #13
0
 /**
  * @group DBAL-64
  */
 public function testQuotedTableName()
 {
     $table = new Table("`bar`");
     $mysqlPlatform = new \Doctrine\DBAL\Platforms\MySqlPlatform();
     $sqlitePlatform = new \Doctrine\DBAL\Platforms\SqlitePlatform();
     $this->assertEquals('bar', $table->getName());
     $this->assertEquals('`bar`', $table->getQuotedName($mysqlPlatform));
     $this->assertEquals('"bar"', $table->getQuotedName($sqlitePlatform));
 }
예제 #14
0
 /**
  * Gathers the table alteration SQL for a given column diff.
  *
  * @param Table      $table      The table to gather the SQL for.
  * @param ColumnDiff $columnDiff The column diff to evaluate.
  * @param array      $sql        The sequence of table alteration statements to fill.
  * @param array      $queryParts The sequence of column alteration clauses to fill.
  */
 private function gatherAlterColumnSQL(Table $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts)
 {
     $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff);
     if (empty($alterColumnClauses)) {
         return;
     }
     // If we have a single column alteration, we can append the clause to the main query.
     if (count($alterColumnClauses) === 1) {
         $queryParts[] = current($alterColumnClauses);
         return;
     }
     // We have multiple alterations for the same column,
     // so we need to trigger a complete ALTER TABLE statement
     // for each ALTER COLUMN clause.
     foreach ($alterColumnClauses as $alterColumnClause) {
         $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ' . $alterColumnClause;
     }
 }
예제 #15
0
 /**
  * Returns the quoted representation of the referenced table name
  * the foreign key constraint is associated with.
  *
  * But only if it was defined with one or the referenced table name
  * is a keyword reserved by the platform.
  * Otherwise the plain unquoted value as inserted is returned.
  *
  * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform The platform to use for quotation.
  *
  * @return string
  */
 public function getQuotedForeignTableName(AbstractPlatform $platform)
 {
     return $this->_foreignTableName->getQuotedName($platform);
 }
예제 #16
0
 /**
  * Gets the SQL statement(s) to create a table with the specified name, columns and constraints
  * on this platform.
  *
  * @param string $table The name of the table.
  * @param int $createFlags
  * @return array The sequence of SQL statements.
  */
 public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
 {
     if (!is_int($createFlags)) {
         throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.");
     }
     if (count($table->getColumns()) == 0) {
         throw DBALException::noColumnsSpecifiedForTable($table->getName());
     }
     $tableName = $table->getQuotedName($this);
     $options = $table->getOptions();
     $options['uniqueConstraints'] = array();
     $options['indexes'] = array();
     $options['primary'] = array();
     if (($createFlags & self::CREATE_INDEXES) > 0) {
         foreach ($table->getIndexes() as $index) {
             /* @var $index Index */
             if ($index->isPrimary()) {
                 $options['primary'] = $index->getColumns();
             } else {
                 $options['indexes'][$index->getName()] = $index;
             }
         }
     }
     $columnSql = array();
     $columns = array();
     foreach ($table->getColumns() as $column) {
         /* @var \Doctrine\DBAL\Schema\Column $column */
         if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) {
             $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
             $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
             $columnSql = array_merge($columnSql, $eventArgs->getSql());
             if ($eventArgs->isDefaultPrevented()) {
                 continue;
             }
         }
         $columnData = array();
         $columnData['name'] = $column->getQuotedName($this);
         $columnData['type'] = $column->getType();
         $columnData['length'] = $column->getLength();
         $columnData['notnull'] = $column->getNotNull();
         $columnData['fixed'] = $column->getFixed();
         $columnData['unique'] = false;
         // TODO: what do we do about this?
         $columnData['version'] = $column->hasPlatformOption("version") ? $column->getPlatformOption('version') : false;
         if (strtolower($columnData['type']) == "string" && $columnData['length'] === null) {
             $columnData['length'] = 255;
         }
         $columnData['unsigned'] = $column->getUnsigned();
         $columnData['precision'] = $column->getPrecision();
         $columnData['scale'] = $column->getScale();
         $columnData['default'] = $column->getDefault();
         $columnData['columnDefinition'] = $column->getColumnDefinition();
         $columnData['autoincrement'] = $column->getAutoincrement();
         $columnData['comment'] = $this->getColumnComment($column);
         if (in_array($column->getName(), $options['primary'])) {
             $columnData['primary'] = true;
         }
         $columns[$columnData['name']] = $columnData;
     }
     if (($createFlags & self::CREATE_FOREIGNKEYS) > 0) {
         $options['foreignKeys'] = array();
         foreach ($table->getForeignKeys() as $fkConstraint) {
             $options['foreignKeys'][] = $fkConstraint;
         }
     }
     if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
         $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
         $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
         if ($eventArgs->isDefaultPrevented()) {
             return array_merge($eventArgs->getSql(), $columnSql);
         }
     }
     $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
     if ($this->supportsCommentOnStatement()) {
         foreach ($table->getColumns() as $column) {
             if ($this->getColumnComment($column)) {
                 $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getName(), $this->getColumnComment($column));
             }
         }
     }
     return array_merge($sql, $columnSql);
 }
예제 #17
0
    public function testQuotedTableNames()
    {
        $table = new Table('"test"');
        $table->addColumn('"id"', 'integer', array('autoincrement' => true));
        // assert tabel
        $this->assertTrue($table->isQuoted());
        $this->assertEquals('test', $table->getName());
        $this->assertEquals('"test"', $table->getQuotedName($this->_platform));
        $sql = $this->_platform->getCreateTableSQL($table);
        $this->assertEquals('CREATE TABLE "test" ("id" NUMBER(10) NOT NULL)', $sql[0]);
        $this->assertEquals('CREATE SEQUENCE "test_SEQ" START WITH 1 MINVALUE 1 INCREMENT BY 1', $sql[2]);
        $createTriggerStatement = <<<EOD
CREATE TRIGGER "test_AI_PK"
   BEFORE INSERT
   ON "test"
   FOR EACH ROW
DECLARE
   last_Sequence NUMBER;
   last_InsertID NUMBER;
BEGIN
   SELECT "test_SEQ".NEXTVAL INTO :NEW."id" FROM DUAL;
   IF (:NEW."id" IS NULL OR :NEW."id" = 0) THEN
      SELECT "test_SEQ".NEXTVAL INTO :NEW."id" FROM DUAL;
   ELSE
      SELECT NVL(Last_Number, 0) INTO last_Sequence
        FROM User_Sequences
       WHERE Sequence_Name = 'test_SEQ';
      SELECT :NEW."id" INTO last_InsertID FROM DUAL;
      WHILE (last_InsertID > last_Sequence) LOOP
         SELECT "test_SEQ".NEXTVAL INTO last_Sequence FROM DUAL;
      END LOOP;
   END IF;
END;
EOD;
        $this->assertEquals($createTriggerStatement, $sql[3]);
    }