Example #1
0
 /**
  * @dataProvider provideTableSpecificAttributes
  *
  */
 public function testCreateDefaultUniqueIndexName($tableName, $maxColumnNameLength, $indexName)
 {
     $table = $this->getTableMock($tableName, array('common_name' => $tableName, 'unices' => array(new Unique(), new Unique()), 'database' => $this->getDatabaseMock('bookstore', array('platform' => $this->getPlatformMock(true, array('max_column_name_length' => $maxColumnNameLength))))));
     $index = new Unique();
     $index->setTable($table);
     $this->assertTrue($index->isUnique());
     $this->assertSame($indexName, $index->getName());
 }
Example #2
0
 public function testCompareType()
 {
     $c1 = new Column('Foo');
     $i1 = new Index('Foo_Index');
     $i1->addColumn($c1);
     $c2 = new Column('Foo');
     $i2 = new Unique('Foo_Index');
     $i2->addColumn($c2);
     $this->assertTrue(IndexComparator::computeDiff($i1, $i2));
 }
Example #3
0
 /**
  * Adds a unique constraint to the table to enforce uniqueness of the slug_column
  *
  * @param Table $table
  */
 protected function addUniqueConstraint(Table $table)
 {
     $unique = new Unique($this->getColumnForParameter('slug_column'));
     $unique->setName($table->getCommonName() . '_slug');
     $unique->addColumn($table->getColumn($this->getParameter('slug_column')));
     if ($this->getParameter('scope_column')) {
         $unique->addColumn($table->getColumn($this->getParameter('scope_column')));
     }
     $table->addUnique($unique);
 }
 /**
  * @dataProvider provideTableSpecificAttributes
  *
  */
 public function testCreateDefaultUniqueIndexName($tableName, $maxColumnNameLength, $indexName)
 {
     $database = $this->getDatabaseMock('bookstore');
     $database->expects($this->any())->method('getMaxColumnNameLength')->will($this->returnValue($maxColumnNameLength));
     $table = $this->getTableMock($tableName, ['common_name' => $tableName, 'unices' => [new Unique(), new Unique()], 'database' => $database]);
     $index = new Unique();
     $index->setTable($table);
     $this->assertTrue($index->isUnique());
     $this->assertSame($indexName, $index->getName());
 }
Example #5
0
 /**
  * Add the slug_column to the current table
  */
 public function modifyTable()
 {
     if (!$this->getTable()->containsColumn($this->getParameter('slug_column'))) {
         $this->getTable()->addColumn(array('name' => $this->getParameter('slug_column'), 'type' => 'VARCHAR', 'size' => 255));
         // add a unique to column
         $unique = new Unique($this->getColumnForParameter('slug_column'));
         $unique->setName($this->getTable()->getCommonName() . '_slug');
         $unique->addColumn($this->getTable()->getColumn($this->getParameter('slug_column')));
         $this->getTable()->addUnique($unique);
     }
 }
 /**
  * Adds all columns, indexes, constraints and additional tables.
  */
 public function modifyTable()
 {
     $table = $this->getTable();
     $tableName = $table->getName();
     $foreignTableName = $this->getForeignTable();
     // enable reload on insert to force the model to load the trigger generated id(s)
     $table->setReloadOnInsert(true);
     $foreignIdColumnName = $foreignTableName . '_id';
     $compositeKeyColumnName = $foreignTableName . '_' . $tableName . '_id';
     if ($table->hasBehavior('concrete_inheritance')) {
         // we're a child in a concrete inheritance
         $parentTableName = $table->getBehavior('concrete_inheritance')->getParameter('extends');
         $parentTable = $table->getDatabase()->getTable($parentTableName);
         if ($parentTable->hasBehavior('\\' . __CLASS__)) {
             //we're a child of a concrete inheritance structure, so we're going to skip this
             //round here because this behavior has also been attached by the parent table.
             return;
         }
     }
     if ($table->hasColumn($foreignIdColumnName)) {
         $foreignIdColumn = $table->getColumn($foreignIdColumnName);
     } else {
         $foreignIdColumn = $table->addColumn(array('name' => $foreignIdColumnName, 'type' => 'integer', 'required' => true));
         $compositeKeyForeignKeyName = $tableName . '_FK_' . $foreignIdColumnName;
         $foreignKey = new ForeignKey($compositeKeyForeignKeyName);
         $foreignKey->addReference($foreignIdColumnName, 'id');
         $foreignKey->setForeignTableCommonName($foreignTableName);
         $foreignKey->setOnUpdate(ForeignKey::CASCADE);
         $foreignKey->setOnDelete(ForeignKey::CASCADE);
         $table->addForeignKey($foreignKey);
     }
     if ($table->hasColumn($compositeKeyColumnName)) {
         $compositeKeyColumn = $table->getColumn($compositeKeyColumnName);
     } else {
         $compositeKeyColumn = $table->addColumn(array('name' => $compositeKeyColumnName, 'type' => 'integer', 'required' => false));
     }
     $index = new Unique($tableName . '_UQ_' . $foreignIdColumnName . '_' . $compositeKeyColumnName);
     $index->addColumn($foreignIdColumn);
     $index->addColumn($compositeKeyColumn);
     $table->addUnique($index);
     $database = $table->getDatabase();
     $sequenceTableName = sprintf('%s_sequence', $foreignTableName);
     if (!$database->hasTable($sequenceTableName)) {
         $sequenceTable = $database->addTable(array('name' => $sequenceTableName, 'package' => $table->getPackage(), 'schema' => $table->getSchema(), 'namespace' => $table->getNamespace() ? '\\' . $table->getNamespace() : null, 'skipSql' => $table->isSkipSql()));
         $sequenceTable->addColumn(array('name' => 'table_name', 'type' => 'varchar', 'size' => 32, 'required' => true, 'primaryKey' => true));
         $sequenceTable->addColumn(array('name' => $foreignIdColumnName, 'type' => 'integer', 'required' => true, 'primaryKey' => true));
         $sequenceTable->addColumn(array('name' => $foreignTableName . '_max_sequence_id', 'type' => 'integer', 'required' => false, 'default' => null));
     }
 }
Example #7
0
 /**
  * Add the slug_column to the current table
  */
 public function modifyTable()
 {
     $table = $this->getTable();
     if (!$table->hasColumn($this->getParameter('slug_column'))) {
         $table->addColumn(array('name' => $this->getParameter('slug_column'), 'type' => 'VARCHAR', 'size' => 255, 'required' => false));
         // add a unique to column
         $unique = new Unique($this->getColumnForParameter('slug_column'));
         $unique->setName($table->getCommonName() . '_slug');
         $unique->addColumn($table->getColumn($this->getParameter('slug_column')));
         if ($this->getParameter('scope_column')) {
             $unique->addColumn($table->getColumn($this->getParameter('scope_column')));
         }
         $table->addUnique($unique);
     }
 }
 public function getUniqueDDL(Unique $unique)
 {
     return sprintf('UNIQUE INDEX %s (%s)', $this->quoteIdentifier($unique->getName()), $this->getIndexColumnListDDL($unique));
 }
Example #9
0
 /**
  * Adds a new Unique index to the list of unique indices and set the
  * parent table of the column to the current table.
  *
  * @param  Unique|array $unique
  * @return Unique
  */
 public function addUnique($unique)
 {
     if ($unique instanceof Unique) {
         $unique->setTable($this);
         $unique->getName();
         // we call this method so that the name is created now if it doesn't already exist.
         $this->unices[] = $unique;
         return $unique;
     }
     $unik = new Unique();
     $unik->loadMapping($unique);
     return $this->addUnique($unik);
 }
 /**
  * Unfortunately, SQLite does not support composite pks where one is AUTOINCREMENT,
  * so we have to flag both as NOT NULL and create a UNIQUE constraint.
  *
  * @param Table $table
  */
 public function normalizeTable(Table $table)
 {
     if (count($pks = $table->getPrimaryKey()) > 1 && $table->hasAutoIncrementPrimaryKey()) {
         foreach ($pks as $pk) {
             //no pk can be NULL, as usual
             $pk->setNotNull(true);
             //in SQLite the column with the AUTOINCREMENT MUST be a primary key, too.
             if (!$pk->isAutoIncrement()) {
                 //for all other sub keys we remove it, since we create a UNIQUE constraint over all primary keys.
                 $pk->setPrimaryKey(false);
             }
         }
         //search if there is already a UNIQUE constraint over the primary keys
         $pkUniqueExist = false;
         foreach ($table->getUnices() as $unique) {
             $allPk = false;
             foreach ($unique->getColumns() as $columnName) {
                 $allPk &= $table->getColumn($columnName)->isPrimaryKey();
             }
             if ($allPk) {
                 //there's already a unique constraint with the composite pk
                 $pkUniqueExist = true;
                 break;
             }
         }
         //there is none, let's create it
         if (!$pkUniqueExist) {
             $unique = new Unique();
             foreach ($pks as $pk) {
                 $unique->addColumn($pk);
             }
             $table->addUnique($unique);
         }
     }
     parent::normalizeTable($table);
 }
Example #11
0
 public function getUniqueDDL(Unique $unique)
 {
     return sprintf('CONSTRAINT %s UNIQUE (%s)', $this->quoteIdentifier($unique->getName()), $this->getColumnListDDL($unique->getColumnObjects()));
 }
Example #12
0
 public function startElement($parser, $name, $attributes)
 {
     $parentTag = $this->peekCurrentSchemaTag();
     if (false === $parentTag) {
         switch ($name) {
             case 'database':
                 if ($this->isExternalSchema()) {
                     $this->currentPackage = isset($attributes['package']) ? $attributes['package'] : null;
                     if (null === $this->currentPackage) {
                         $this->currentPackage = $this->defaultPackage;
                     }
                 } else {
                     $this->currDB = $this->schema->addDatabase($attributes);
                 }
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('database' === $parentTag) {
         switch ($name) {
             case 'external-schema':
                 $xmlFile = isset($attributes['filename']) ? $attributes['filename'] : null;
                 // 'referenceOnly' attribute is valid in the main schema XML file only,
                 // and it's ignored in the nested external-schemas
                 if (!$this->isExternalSchema()) {
                     $isForRefOnly = isset($attributes['referenceOnly']) ? $attributes['referenceOnly'] : null;
                     $this->isForReferenceOnly = null !== $isForRefOnly ? 'true' === strtolower($isForRefOnly) : true;
                     // defaults to TRUE
                 }
                 if ('/' !== $xmlFile[0]) {
                     $xmlFile = realpath(dirname($this->currentXmlFile) . DIRECTORY_SEPARATOR . $xmlFile);
                     if (!file_exists($xmlFile)) {
                         throw new SchemaException(sprintf('Unknown include external "%s"', $xmlFile));
                     }
                 }
                 $this->parseFile($xmlFile);
                 break;
             case 'domain':
                 $this->currDB->addDomain($attributes);
                 break;
             case 'table':
                 if (!isset($attributes['schema']) && $this->currDB->getSchema() && $this->currDB->getPlatform()->supportsSchemas() && false === strpos($attributes['name'], $this->currDB->getPlatform()->getSchemaDelimiter())) {
                     $attributes['schema'] = $this->currDB->getSchema();
                 }
                 $this->currTable = $this->currDB->addTable($attributes);
                 if ($this->isExternalSchema()) {
                     $this->currTable->setForReferenceOnly($this->isForReferenceOnly);
                     $this->currTable->setPackage($this->currentPackage);
                 }
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currDB->addVendorInfo($attributes);
                 break;
             case 'behavior':
                 $this->currBehavior = $this->currDB->addBehavior($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('table' === $parentTag) {
         switch ($name) {
             case 'column':
                 $this->currColumn = $this->currTable->addColumn($attributes);
                 break;
             case 'foreign-key':
                 $this->currFK = $this->currTable->addForeignKey($attributes);
                 break;
             case 'index':
                 $this->currIndex = new Index();
                 $this->currIndex->setTable($this->currTable);
                 $this->currIndex->loadMapping($attributes);
                 break;
             case 'unique':
                 $this->currUnique = new Unique();
                 $this->currUnique->setTable($this->currTable);
                 $this->currUnique->loadMapping($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currTable->addVendorInfo($attributes);
                 break;
             case 'id-method-parameter':
                 $this->currTable->addIdMethodParameter($attributes);
                 break;
             case 'behavior':
                 $this->currBehavior = $this->currTable->addBehavior($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('column' === $parentTag) {
         switch ($name) {
             case 'inheritance':
                 $this->currColumn->addInheritance($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currColumn->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('foreign-key' === $parentTag) {
         switch ($name) {
             case 'reference':
                 $this->currFK->addReference($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currUnique->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('index' === $parentTag) {
         switch ($name) {
             case 'index-column':
                 $this->currIndex->addColumn($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currIndex->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('unique' === $parentTag) {
         switch ($name) {
             case 'unique-column':
                 $this->currUnique->addColumn($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currUnique->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ($parentTag == 'behavior') {
         switch ($name) {
             case 'parameter':
                 $this->currBehavior->addParameter($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('vendor' === $parentTag) {
         switch ($name) {
             case 'parameter':
                 $this->currVendorObject->setParameter($attributes['name'], $attributes['value']);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } else {
         // it must be an invalid tag
         $this->_throwInvalidTagException($parser, $name);
     }
     $this->pushCurrentSchemaTag($name);
 }
Example #13
0
 /**
  * Adds a new Unique to the Unique list and set the
  * parent table of the column to the current table
  */
 public function addUnique($unqdata)
 {
     if ($unqdata instanceof Unique) {
         $unique = $unqdata;
         $unique->setTable($this);
         $unique->getName();
         // we call this method so that the name is created now if it doesn't already exist.
         $this->unices[] = $unique;
         return $unique;
     } else {
         $unique = new Unique($this);
         $unique->loadFromXML($unqdata);
         return $this->addUnique($unique);
     }
 }
Example #14
0
$fkPostTag->setForeignTableCommonName('blog_post');
$fkPostTag->setPhpName('Post');
$fkPostTag->setDefaultJoin('Criteria::LEFT_JOIN');
$fkPostTag->setOnDelete('CASCADE');
$fkTagPost = new ForeignKey('fk_tag_has_posts');
$fkTagPost->addReference('tag_id', 'id');
$fkTagPost->setForeignTableCommonName('blog_tag');
$fkTagPost->setPhpName('Tag');
$fkTagPost->setDefaultJoin('Criteria::LEFT_JOIN');
$fkTagPost->setOnDelete('CASCADE');
/* Regular Indexes */
$pageContentFulltextIdx = new Index('page_content_fulltext_idx');
$pageContentFulltextIdx->setColumns([['name' => 'content']]);
$pageContentFulltextIdx->addVendorInfo(new VendorInfo('mysql', ['Index_type' => 'FULLTEXT']));
/* Unique Indexes */
$authorUsernameUnique = new Unique('author_password_unique_idx');
$authorUsernameUnique->setColumns([['name' => 'username', 'size' => '8']]);
/* Behaviors */
$timestampableBehavior = new TimestampableBehavior();
$timestampableBehavior->setName('timestampable');
$sluggableBehavior = new SluggableBehavior();
$sluggableBehavior->setName('sluggable');
/* Tables */
$table1 = new Table('blog_post');
$table1->setDescription('The list of posts');
$table1->setNamespace('Blog');
$table1->setPackage('Acme.Blog');
$table1->addColumns([$column11, $column12, $column13, $column14, $column15, $column16, $column17]);
$table1->addForeignKeys([$fkAuthorPost, $fkCategoryPost]);
$table1->addBehavior($timestampableBehavior);
$table1->addBehavior($sluggableBehavior);
 /**
  * Normalizes a table for the current platform. Very important for the TableComparator to not
  * generate useless diffs.
  * Useful for checking needed definitions/structures. E.g. Unique Indexes for ForeignKey columns,
  * which the most Platforms requires but which is not always explicitly defined in the table model.
  *
  * @param Table $table The table object which gets modified.
  */
 public function normalizeTable(Table $table)
 {
     if ($table->hasForeignKeys()) {
         foreach ($table->getForeignKeys() as $fk) {
             if ($fk->getForeignTable() && !$fk->getForeignTable()->isUnique($fk->getForeignColumnObjects())) {
                 $unique = new Unique();
                 $unique->setColumns($fk->getForeignColumnObjects());
                 $fk->getForeignTable()->addUnique($unique);
             }
         }
     }
     if (!$this->supportsIndexSize() && $table->getIndices()) {
         // when the plafform does not support index sizes we reset it
         foreach ($table->getIndices() as $index) {
             $index->resetColumnsSize();
         }
     }
     foreach ($table->getColumns() as $column) {
         if ($column->getSize() && ($defaultSize = $this->getDefaultTypeSize($column->getType()))) {
             if (null === $column->getScale() && intval($column->getSize()) === $defaultSize) {
                 $column->setSize(null);
             }
         }
     }
 }
Example #16
0
 /**
  * Builds the DDL SQL for a Unique constraint object.
  *
  * @param      Unique $unique
  * @return     string
  */
 public function getUniqueDDL(Unique $unique)
 {
     return sprintf('UNIQUE (%s)', $this->getColumnListDDL($unique->getColumns()));
 }
 public function providerForTestGetUniqueDDL()
 {
     $table = new Table('foo');
     $table->setIdentifierQuoting(true);
     $column1 = new Column('bar1');
     $column1->getDomain()->copy(new Domain('FOOTYPE'));
     $table->addColumn($column1);
     $column2 = new Column('bar2');
     $column2->getDomain()->copy(new Domain('BARTYPE'));
     $table->addColumn($column2);
     $index = new Unique('babar');
     $index->addColumn($column1);
     $index->addColumn($column2);
     $table->addUnique($index);
     return array(array($index));
 }
 /**
  * Normalizes a table for the current platform. Very important for the TableComparator to not
  * generate useless diffs.
  * Useful for checking needed definitions/structures. E.g. Unique Indexes for ForeignKey columns,
  * which the most Platforms requires but which is not always explicitly defined in the table model.
  *
  * @param Table $table The table object which gets modified.
  */
 public function normalizeTable(Table $table)
 {
     if ($table->hasForeignKeys()) {
         foreach ($table->getForeignKeys() as $fk) {
             if (!$fk->getForeignTable()->isUnique($fk->getForeignColumnObjects())) {
                 $unique = new Unique();
                 $unique->setColumns($fk->getForeignColumnObjects());
                 $fk->getForeignTable()->addUnique($unique);
             }
         }
     }
 }
 public function testCompareModifiedIndices()
 {
     $t1 = new Table();
     $c1 = new Column('Foo');
     $c1->getDomain()->copy($this->platform->getDomainForType('VARCHAR'));
     $c1->getDomain()->replaceSize(255);
     $c1->setNotNull(false);
     $t1->addColumn($c1);
     $i1 = new Index('Foo_Index');
     $i1->addColumn($c1);
     $t1->addIndex($i1);
     $t2 = new Table();
     $c2 = new Column('Foo');
     $c2->getDomain()->copy($this->platform->getDomainForType('DOUBLE'));
     $c2->getDomain()->replaceScale(2);
     $c2->getDomain()->replaceSize(3);
     $c2->setNotNull(true);
     $c2->getDomain()->setDefaultValue(new ColumnDefaultValue(123, ColumnDefaultValue::TYPE_VALUE));
     $t2->addColumn($c2);
     $i2 = new Unique('Foo_Index');
     $i2->addColumn($c2);
     $t2->addIndex($i2);
     $tc = new PropelTableComparator();
     $tc->setFromTable($t1);
     $tc->setToTable($t2);
     $nbDiffs = $tc->compareIndices();
     $tableDiff = $tc->getTableDiff();
     $this->assertEquals(1, $nbDiffs);
     $this->assertEquals(1, count($tableDiff->getModifiedIndices()));
     $this->assertEquals(array('Foo_Index' => array($i1, $i2)), $tableDiff->getModifiedIndices());
 }
Example #20
0
 /**
  * Builds the DDL SQL for a Unique constraint object. MS SQL Server CONTRAINT specific
  *
  * @param  Unique $unique
  * @return string
  */
 public function getUniqueDDL(Unique $unique)
 {
     $pattern = 'CONSTRAINT %s UNIQUE NONCLUSTERED (%s) ON [PRIMARY]';
     return sprintf($pattern, $this->quoteIdentifier($unique->getName()), $this->getColumnListDDL($unique->getColumnObjects()));
 }