/** * @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()); }
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)); }
/** * 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()); }
/** * 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)); } }
/** * 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)); }
/** * 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); }
public function getUniqueDDL(Unique $unique) { return sprintf('CONSTRAINT %s UNIQUE (%s)', $this->quoteIdentifier($unique->getName()), $this->getColumnListDDL($unique->getColumnObjects())); }
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); }
/** * 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); } }
$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); } } } }
/** * 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()); }
/** * 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())); }