protected function relateI18nTableToMainTable() { $table = $this->getTable(); $i18nTable = $this->i18nTable; $pks = $this->getTable()->getPrimaryKey(); if (count($pks) > 1) { throw new EngineException('The i18n behavior does not support tables with composite primary keys'); } foreach ($pks as $column) { if (!$i18nTable->hasColumn($column->getName())) { $column = clone $column; $column->setAutoIncrement(false); $i18nTable->addColumn($column); } } if (in_array($table->getName(), $i18nTable->getForeignTableNames())) { return; } $fk = new ForeignKey(); $fk->setForeignTableCommonName($table->getCommonName()); $fk->setForeignSchemaName($table->getSchema()); $fk->setDefaultJoin('LEFT JOIN'); $fk->setOnDelete(ForeignKey::CASCADE); $fk->setOnUpdate(ForeignKey::NONE); foreach ($pks as $column) { $fk->addReference($column->getName(), $column->getName()); } $i18nTable->addForeignKey($fk); }
public function modifyTable() { $parentTable = $this->getParentTable(); if (count($parentTable->getPrimaryKey()) > 1) { throw new RuntimeException('Equal nest works only with a single primary key for the parent table'); } $parentTablePrimaryKey = $parentTable->getPrimaryKey(); if (!$this->getTable()->hasColumn($this->getReferenceColumn1Name())) { $this->getTable()->addColumn(array('name' => $this->getReferenceColumn1Name(), 'primaryKey' => 'true', 'type' => $parentTablePrimaryKey[0]->getType())); $fk = new ForeignKey(); $fk->setName($this->getReferenceColumn1Name()); $fk->setForeignTableCommonName($this->getParentTable()->getCommonName()); $fk->setOnDelete(ForeignKey::CASCADE); $fk->setOnUpdate(null); $fk->addReference($this->getReferenceColumn1Name(), $parentTablePrimaryKey[0]->getName()); $this->getTable()->addForeignKey($fk); } if (!$this->getTable()->hasColumn($this->getReferenceColumn2Name())) { $this->getTable()->addColumn(array('name' => $this->getReferenceColumn2Name(), 'primaryKey' => 'true', 'type' => $parentTablePrimaryKey[0]->getType())); $fk = new ForeignKey(); $fk->setName($this->getReferenceColumn2Name()); $fk->setForeignTableCommonName($this->getParentTable()->getCommonName()); $fk->setOnDelete(ForeignKey::CASCADE); $fk->setOnUpdate(null); $fk->addReference($this->getReferenceColumn2Name(), $parentTablePrimaryKey[0]->getName()); $this->getTable()->addForeignKey($fk); } if (!$parentTable->hasBehavior('equal_nest_parent')) { $parentBehavior = new EqualNestParentBehavior(); $parentBehavior->setName('equal_nest_parent'); $parentBehavior->addParameter(array('name' => 'middle_table', 'value' => $this->getTable()->getName())); $parentTable->addBehavior($parentBehavior); } $this->parentBehavior = $parentTable->getBehavior('equal_nest_parent'); }
private function addRelation($oLocalColumn, $oUsersTable, $oUsersId) { $oFk = new ForeignKey(); $oFk->setTable($this->getTable()); $oFk->setForeignTableCommonName($oUsersTable->getName()); if (!$oFk->isMatchedByInverseFK()) { $oFk->setOnDelete(ForeignKey::SETNULL); $oFk->setOnUpdate(null); $oFk->addReference($oLocalColumn, $oUsersId); $this->getTable()->addForeignKey($oFk); } }
protected function addVersionTable() { $table = $this->getTable(); $database = $table->getDatabase(); $versionTableName = $this->getParameter('version_table') ? $this->getParameter('version_table') : $table->getName() . '_version'; if (!$database->hasTable($versionTableName)) { // create the version table $versionTable = $database->addTable(array('name' => $versionTableName, 'phpName' => $this->getVersionTablePhpName(), 'package' => $table->getPackage(), 'schema' => $table->getSchema(), 'namespace' => $table->getNamespace() ? '\\' . $table->getNamespace() : null)); // every behavior adding a table should re-execute database behaviors foreach ($database->getBehaviors() as $behavior) { $behavior->modifyDatabase(); } // copy all the columns foreach ($table->getColumns() as $column) { $columnInVersionTable = clone $column; if ($columnInVersionTable->hasReferrers()) { $columnInVersionTable->clearReferrers(); } if ($columnInVersionTable->isAutoincrement()) { $columnInVersionTable->setAutoIncrement(false); } $versionTable->addColumn($columnInVersionTable); } // create the foreign key $fk = new ForeignKey(); $fk->setForeignTableCommonName($table->getCommonName()); $fk->setForeignSchemaName($table->getSchema()); $fk->setOnDelete('CASCADE'); $fk->setOnUpdate(null); $tablePKs = $table->getPrimaryKey(); foreach ($versionTable->getPrimaryKey() as $key => $column) { $fk->addReference($column, $tablePKs[$key]); } $versionTable->addForeignKey($fk); // add the version column to the primary key $versionTable->getColumn($this->getParameter('version_column'))->setPrimaryKey(true); $this->versionTable = $versionTable; } else { $this->versionTable = $database->getTable($versionTableName); } }
protected function relateDelegateToMainTable($delegateTable, $mainTable) { $pks = $mainTable->getPrimaryKey(); foreach ($pks as $column) { $mainColumnName = $column->getName(); if (!$delegateTable->hasColumn($mainColumnName)) { $column = clone $column; $column->setAutoIncrement(false); $delegateTable->addColumn($column); } } // Add a one-to-one fk $fk = new ForeignKey(); $fk->setForeignTableCommonName($mainTable->getCommonName()); $fk->setForeignSchemaName($mainTable->getSchema()); $fk->setDefaultJoin('LEFT JOIN'); $fk->setOnDelete(ForeignKey::CASCADE); $fk->setOnUpdate(ForeignKey::NONE); foreach ($pks as $column) { $fk->addReference($column->getName(), $column->getName()); } $delegateTable->addForeignKey($fk); }
public function testColumnIsFKAndPK() { $column = new Column(); $column->setName('id'); $column->setPrimaryKey(true); $column->setAutoIncrement(true); $column->setType('integer'); $table = new Table(); $table->setCommonName('table_one'); $table->addColumn($column); $db = new Database(); $db->setName('MultipleTables'); $db->addTable($table); $column = new Column(); $column->setName('id'); $column->setPrimaryKey(true); $column->setAutoIncrement(true); $column->setType('integer'); $c2 = new Column(); $c2->setPrimaryKey(true); $c2->setName('foreign_id'); $c2->setType('integer'); $table = new Table(); $table->setCommonName('table_two'); $table->addColumn($column); $table->addColumn($c2); $fk = new ForeignKey(); $fk->setName('FK_1'); $fk->addReference('foreign_id', 'id'); $fk->setForeignTableCommonName('table_one'); $table->addForeignKey($fk); $db->addTable($table); $expected = implode("\n", array('digraph G {', 'nodetable_one [label="{<table>table_one|<cols>id (integer) [PK]\\l}", shape=record];', 'nodetable_two [label="{<table>table_two|<cols>id (integer) [PK]\\lforeign_id (integer) [FK] [PK]\\l}", shape=record];', 'nodetable_two:cols -> nodetable_one:table [label="foreign_id=id"];', '}', '')); $this->assertEquals($expected, PropelDotGenerator::create($db)); }
/** * Load foreign keys for this table. * * @param Table $table The Table model class to add FKs to */ protected function addForeignKeys(Table $table) { // local store to avoid duplicates $foreignKeys = array(); $stmt = $this->dbh->query("SELECT CONSTRAINT_NAME, DELETE_RULE, R_CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'R' AND TABLE_NAME = '" . $table->getName() . "'"); /* @var stmt PDOStatement */ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { // Local reference $stmt2 = $this->dbh->query("SELECT COLUMN_NAME FROM USER_CONS_COLUMNS WHERE CONSTRAINT_NAME = '" . $row['CONSTRAINT_NAME'] . "' AND TABLE_NAME = '" . $table->getName() . "'"); /* @var stmt2 PDOStatement */ $localReferenceInfo = $stmt2->fetch(PDO::FETCH_ASSOC); // Foreign reference $stmt2 = $this->dbh->query("SELECT TABLE_NAME, COLUMN_NAME FROM USER_CONS_COLUMNS WHERE CONSTRAINT_NAME = '" . $row['R_CONSTRAINT_NAME'] . "'"); $foreignReferenceInfo = $stmt2->fetch(PDO::FETCH_ASSOC); if (!isset($foreignKeys[$row["CONSTRAINT_NAME"]])) { $fk = new ForeignKey($row["CONSTRAINT_NAME"]); $fk->setForeignTableCommonName($foreignReferenceInfo['TABLE_NAME']); $onDelete = $row["DELETE_RULE"] == 'NO ACTION' ? 'NONE' : $row["DELETE_RULE"]; $fk->setOnDelete($onDelete); $fk->setOnUpdate($onDelete); $fk->addReference(array("local" => $localReferenceInfo['COLUMN_NAME'], "foreign" => $foreignReferenceInfo['COLUMN_NAME'])); $table->addForeignKey($fk); $foreignKeys[$row["CONSTRAINT_NAME"]] = $fk; } } }
public function testCompareModifiedFks() { $db1 = new Database(); $db1->setPlatform($this->platform); $c1 = new Column('Foo'); $c2 = new Column('Bar'); $fk1 = new ForeignKey(); $fk1->addReference($c1, $c2); $t1 = new Table('Baz'); $t1->addForeignKey($fk1); $db1->addTable($t1); $t1->doNaming(); $db2 = new Database(); $db2->setPlatform($this->platform); $c3 = new Column('Foo'); $c4 = new Column('Bar2'); $fk2 = new ForeignKey(); $fk2->addReference($c3, $c4); $t2 = new Table('Baz'); $t2->addForeignKey($fk2); $db2->addTable($t2); $t2->doNaming(); $tc = new PropelTableComparator(); $tc->setFromTable($t1); $tc->setToTable($t2); $nbDiffs = $tc->compareForeignKeys(); $tableDiff = $tc->getTableDiff(); $this->assertEquals(1, $nbDiffs); $this->assertEquals(1, count($tableDiff->getModifiedFks())); $this->assertEquals(array('Baz_FK_1' => array($fk1, $fk2)), $tableDiff->getModifiedFks()); }
public function modifyTable() { $table = $this->getTable(); $parentTable = $this->getParentTable(); if ($this->isCopyData()) { // tell the parent table that it has a descendant if (!$parentTable->hasBehavior('concrete_inheritance_parent')) { $parentBehavior = new ConcreteInheritanceParentBehavior(); $parentBehavior->setName('concrete_inheritance_parent'); $parentBehavior->addParameter(array('name' => 'descendant_column', 'value' => $this->getParameter('descendant_column'))); $parentTable->addBehavior($parentBehavior); // The parent table's behavior modifyTable() must be executed before this one $parentBehavior->getTableModifier()->modifyTable(); $parentBehavior->setTableModified(true); } } // Add the columns of the parent table foreach ($parentTable->getColumns() as $column) { if ($column->getName() == $this->getParameter('descendant_column')) { continue; } if ($table->containsColumn($column->getName())) { continue; } $copiedColumn = clone $column; if ($column->isAutoIncrement() && $this->isCopyData()) { $copiedColumn->setAutoIncrement(false); } $table->addColumn($copiedColumn); if ($column->isPrimaryKey() && $this->isCopyData()) { $fk = new ForeignKey(); $fk->setForeignTableCommonName($column->getTable()->getCommonName()); $fk->setForeignSchemaName($column->getTable()->getSchema()); $fk->setOnDelete('CASCADE'); $fk->setOnUpdate(null); $fk->addReference($copiedColumn, $column); $fk->isParentChild = true; $table->addForeignKey($fk); } } // add the foreign keys of the parent table foreach ($parentTable->getForeignKeys() as $fk) { $copiedFk = clone $fk; $copiedFk->setName(''); $copiedFk->setRefPhpName(''); $this->getTable()->addForeignKey($copiedFk); } // add the validators of the parent table foreach ($parentTable->getValidators() as $validator) { $copiedValidator = clone $validator; $this->getTable()->addValidator($copiedValidator); } // add the indices of the parent table foreach ($parentTable->getIndices() as $index) { $copiedIndex = clone $index; $copiedIndex->setName(''); $this->getTable()->addIndex($copiedIndex); } // add the unique indices of the parent table foreach ($parentTable->getUnices() as $unique) { $copiedUnique = clone $unique; $copiedUnique->setName(''); $this->getTable()->addUnique($copiedUnique); } // add the Behaviors of the parent table foreach ($parentTable->getBehaviors() as $behavior) { if ($behavior->getName() == 'concrete_inheritance_parent' || $behavior->getName() == 'concrete_inheritance') { continue; } $copiedBehavior = clone $behavior; $copiedBehavior->setTableModified(false); $this->getTable()->addBehavior($copiedBehavior); } }
public function providerForTestGetForeignKeysDDL() { $table1 = new Table('foo'); $column1 = new Column('bar_id'); $column1->getDomain()->copy(new Domain('FOOTYPE')); $table1->addColumn($column1); $table2 = new Table('bar'); $column2 = new Column('id'); $column2->getDomain()->copy(new Domain('BARTYPE')); $table2->addColumn($column2); $fk = new ForeignKey('foo_bar_FK'); $fk->setForeignTableCommonName('bar'); $fk->addReference($column1, $column2); $fk->setOnDelete('CASCADE'); $table1->addForeignKey($fk); $column3 = new Column('baz_id'); $column3->getDomain()->copy(new Domain('BAZTYPE')); $table1->addColumn($column3); $table3 = new Table('baz'); $column4 = new Column('id'); $column4->getDomain()->copy(new Domain('BAZTYPE')); $table3->addColumn($column4); $fk = new ForeignKey('foo_baz_FK'); $fk->setForeignTableCommonName('baz'); $fk->addReference($column3, $column4); $fk->setOnDelete('SETNULL'); $table1->addForeignKey($fk); return array(array($table1)); }
protected function createTaggingTable() { $table = $this->getTable(); $database = $table->getDatabase(); $pks = $this->getTable()->getPrimaryKey(); if (count($pks) > 1) { throw new EngineException('The Taggable behavior does not support tables with composite primary keys'); } $taggingTableName = $this->getTaggingTableName(); if ($database->hasTable($taggingTableName)) { $this->taggingTable = $database->getTable($taggingTableName); } else { $this->taggingTable = $database->addTable(array('name' => $taggingTableName, 'phpName' => $this->replaceTokens($this->getParameter('tagging_table_phpname')), 'package' => $table->getPackage(), 'schema' => $table->getSchema(), 'namespace' => '\\' . $table->getNamespace())); // every behavior adding a table should re-execute database behaviors // see bug 2188 http://www.propelorm.org/changeset/2188 foreach ($database->getBehaviors() as $behavior) { $behavior->modifyDatabase(); } } if ($this->taggingTable->hasColumn('tag_id')) { $tagFkColumn = $this->taggingTable->getColumn('tag_id'); } else { $tagFkColumn = $this->taggingTable->addColumn(array('name' => 'tag_id', 'type' => PropelTypes::INTEGER, 'primaryKey' => 'true')); } if ($this->taggingTable->hasColumn($table->getName() . '_id')) { $objFkColumn = $this->taggingTable->getColumn($table->getName() . '_id'); } else { $objFkColumn = $this->taggingTable->addColumn(array('name' => $table->getName() . '_id', 'type' => PropelTypes::INTEGER, 'primaryKey' => 'true')); } $this->taggingTable->setIsCrossRef(true); $fkTag = new ForeignKey(); $fkTag->setForeignTableCommonName($this->tagTable->getCommonName()); $fkTag->setForeignSchemaName($this->tagTable->getSchema()); $fkTag->setOnDelete(ForeignKey::CASCADE); $fkTag->setOnUpdate(ForeignKey::CASCADE); $tagColumn = $this->tagTable->getColumn('id'); $fkTag->addReference($tagFkColumn->getName(), $tagColumn->getName()); $this->taggingTable->addForeignKey($fkTag); $fkObj = new ForeignKey(); $fkObj->setForeignTableCommonName($this->getTable()->getCommonName()); $fkObj->setForeignSchemaName($this->getTable()->getSchema()); $fkObj->setOnDelete(ForeignKey::CASCADE); $fkObj->setOnUpdate(ForeignKey::CASCADE); foreach ($pks as $column) { $fkObj->addReference($objFkColumn->getName(), $column->getName()); } $this->taggingTable->addForeignKey($fkObj); }
public function testCompareSort() { $c1 = new Column('Foo'); $c2 = new Column('Bar'); $c3 = new Column('Baz'); $c4 = new Column('Faz'); $fk1 = new ForeignKey(); $fk1->addReference($c1, $c3); $fk1->addReference($c2, $c4); $t1 = new Table('Baz'); $t1->addForeignKey($fk1); $fk2 = new ForeignKey(); $fk2->addReference($c2, $c4); $fk2->addReference($c1, $c3); $t2 = new Table('Baz'); $t2->addForeignKey($fk2); $this->assertFalse(PropelForeignKeyComparator::computeDiff($fk1, $fk2)); }
public function testCompareOnDelete() { $c1 = new Column('Foo'); $c2 = new Column('Bar'); $fk1 = new ForeignKey(); $fk1->addReference($c1, $c2); $fk1->setOnDelete(ForeignKey::SETNULL); $t1 = new Table('Baz'); $t1->addForeignKey($fk1); $c3 = new Column('Foo'); $c4 = new Column('Bar'); $fk2 = new ForeignKey(); $fk2->addReference($c3, $c4); $fk2->setOnDelete(ForeignKey::RESTRICT); $t2 = new Table('Baz'); $t2->addForeignKey($fk2); $this->assertTrue(PropelForeignKeyComparator::computeDiff($fk1, $fk2)); }