Example #1
0
 public function actionUpdate()
 {
     $isSubmitted = false;
     $sql = false;
     $foreignKey = ForeignKey::model()->findBySql('SELECT * FROM KEY_COLUMN_USAGE ' . 'WHERE TABLE_SCHEMA = :tableSchema ' . 'AND TABLE_NAME = :tableName ' . 'AND COLUMN_NAME = :columnName ' . 'AND REFERENCED_TABLE_SCHEMA IS NOT NULL', array('tableSchema' => $this->schema, 'tableName' => $this->table, 'columnName' => $this->column));
     if (!$foreignKey) {
         $foreignKey = new ForeignKey();
         $foreignKey->TABLE_SCHEMA = $this->schema;
         $foreignKey->TABLE_NAME = $this->table;
         $foreignKey->COLUMN_NAME = $this->column;
     }
     if (isset($_POST['ForeignKey'])) {
         $foreignKey->attributes = $_POST['ForeignKey'];
         if ($foreignKey->getReferences() && ($sql = $foreignKey->save())) {
             $isSubmitted = true;
         } elseif (!$foreignKey->getReferences() && ($sql = $foreignKey->delete())) {
             $isSubmitted = true;
         }
     }
     CHtml::generateRandomIdPrefix();
     // Column data
     $columns = array('' => '');
     $tables = Table::model()->findAllByAttributes(array('TABLE_SCHEMA' => $this->schema));
     foreach ($tables as $table) {
         if (StorageEngine::check($table->ENGINE, StorageEngine::SUPPORTS_FOREIGN_KEYS)) {
             $columns[$table->TABLE_NAME] = array();
             foreach ($table->columns as $column) {
                 $columns[$table->TABLE_NAME][$this->schema . '.' . $table->TABLE_NAME . '.' . $column->COLUMN_NAME] = $column->COLUMN_NAME;
             }
         }
     }
     // "On-Actions"
     $onActions = array('' => '', 'CASCADE' => 'CASCADE', 'SET NULL' => 'SET NULL', 'NO ACTION' => 'NO ACTION', 'RESTRICT' => 'RESTRICT');
     $this->render('form', array('foreignKey' => $foreignKey, 'columns' => $columns, 'onActions' => $onActions, 'sql' => $sql, 'isSubmitted' => $isSubmitted));
 }
 /**
  * Adds the method that returns the referrer fkey collection.
  * @param      string &$script The script will be modified in this method.
  */
 protected function addRefFKGet(&$script, ForeignKey $refFK)
 {
     $table = $this->getTable();
     $tblFK = $refFK->getTable();
     $peerClassname = $this->getStubPeerBuilder()->getClassname();
     $fkPeerBuilder = $this->getNewPeerBuilder($refFK->getTable());
     $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
     $collName = $this->getRefFKCollVarName($refFK);
     $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK);
     $className = $fkPeerBuilder->getObjectClassname();
     $script .= "\n\t/**\n\t * Gets an array of {$className} objects which contain a foreign key that references this object.\n\t *\n\t * If this collection has already been initialized with an identical Criteria, it returns the collection.\n\t * Otherwise if this " . $this->getObjectClassname() . " has previously been saved, it will retrieve\n\t * related {$relCol} from storage. If this " . $this->getObjectClassname() . " is new, it will return\n\t * an empty collection or the current collection, the criteria is ignored on a new object.\n\t *\n\t * @param      PropelPDO \$con\n\t * @param      Criteria \$criteria\n\t * @return     array {$className}[]\n\t * @throws     PropelException\n\t */\n\tpublic function get{$relCol}(\$criteria = null, PropelPDO \$con = null, array \$selectedColumns = null)\n\t{";
     $script .= "\n\t\tif (\$criteria === null) {\n\t\t\t\$criteria = new Criteria({$peerClassname}::DATABASE_NAME);\n\t\t}\n\t\telseif (\$criteria instanceof Criteria)\n\t\t{\n\t\t\t\$criteria = clone \$criteria;\n\t\t}\n\n\t\tif (\$this->{$collName} === null) {\n\t\t\tif (\$this->isNew()) {\n\t\t\t   \$this->{$collName} = array();\n\t\t\t} else {\n";
     foreach ($refFK->getLocalColumns() as $colFKName) {
         // $colFKName is local to the referring table (i.e. foreign to this table)
         $lfmap = $refFK->getLocalForeignMapping();
         $localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
         $colFK = $refFK->getTable()->getColumn($colFKName);
         $clo = strtolower($localColumn->getName());
         $script .= "\n\t\t\t\t\$criteria->add(" . $fkPeerBuilder->getColumnConstant($colFK) . ", \$this->{$clo});\n";
     }
     // end foreach ($fk->getForeignColumns()
     $script .= "\n        if (null !== \$selectedColumns) {\n          " . $fkPeerBuilder->getPeerClassname() . "::setSelectedColumns(\$selectedColumns);\n        }\n\t\t\t\t" . $fkPeerBuilder->getPeerClassname() . "::addSelectColumns(\$criteria);\n\t\t\t\t\$this->{$collName} = " . $fkPeerBuilder->getPeerClassname() . "::doSelect(\$criteria, \$con);\n\t\t\t}\n\t\t} else {\n\t\t\t// criteria has no effect for a new object\n\t\t\tif (!\$this->isNew()) {\n\t\t\t\t// the following code is to determine if a new query is\n\t\t\t\t// called for.  If the criteria is the same as the last\n\t\t\t\t// one, just return the collection.\n";
     foreach ($refFK->getLocalColumns() as $colFKName) {
         // $colFKName is local to the referring table (i.e. foreign to this table)
         $lfmap = $refFK->getLocalForeignMapping();
         $localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
         $colFK = $refFK->getTable()->getColumn($colFKName);
         $clo = strtolower($localColumn->getName());
         $script .= "\n\n\t\t\t\t\$criteria->add(" . $fkPeerBuilder->getColumnConstant($colFK) . ", \$this->{$clo});\n";
     }
     // foreach ($fk->getForeignColumns()
     $script .= "\n        if (null !== \$selectedColumns) {\n          " . $fkPeerBuilder->getPeerClassname() . "::setSelectedColumns(\$selectedColumns);\n        }\n\t\t\t\t" . $fkPeerBuilder->getPeerClassname() . "::addSelectColumns(\$criteria);\n\t\t\t\tif (!isset(\$this->{$lastCriteriaName}) || !\$this->" . $lastCriteriaName . "->equals(\$criteria)) {\n\t\t\t\t\t\$this->{$collName} = " . $fkPeerBuilder->getPeerClassname() . "::doSelect(\$criteria, \$con);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\$this->{$lastCriteriaName} = \$criteria;\n\t\treturn \$this->{$collName};\n\t}\n";
 }
Example #3
0
 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);
 }
Example #4
0
 public function init()
 {
     if (empty($this->related_name)) {
         $this->setOption('related_name', $this->metadata->getDbTableName());
     }
     parent::init();
 }
Example #5
0
 /**
  * Shows the table structure
  */
 public function actionStructure()
 {
     $table = $this->loadTable();
     if (!$table instanceof Table) {
         $response = new AjaxResponse();
         $response->addNotification("error", Yii::t("core", "tableLoadErrorTitle", array("{table}" => $this->table)), Yii::t("core", "tableLoadErrorMessage", array("{table}" => $this->table)));
         $response->executeJavaScript("sideBar.loadTables(schema)");
         $this->sendJSON($response);
     }
     // Constraints
     if (StorageEngine::check($table->ENGINE, StorageEngine::SUPPORTS_FOREIGN_KEYS)) {
         $foreignKeys = array();
         $sql = 'SELECT * FROM KEY_COLUMN_USAGE ' . 'WHERE TABLE_SCHEMA = :tableSchema ' . 'AND TABLE_NAME = :tableName ' . 'AND REFERENCED_TABLE_SCHEMA IS NOT NULL';
         $table->foreignKeys = ForeignKey::model()->findAllBySql($sql, array('tableSchema' => $table->TABLE_SCHEMA, 'tableName' => $table->TABLE_NAME));
         foreach ($table->foreignKeys as $key) {
             $foreignKeys[] = $key->COLUMN_NAME;
         }
     } else {
         $foreignKeys = false;
     }
     // Indices
     $sql = 'SELECT * FROM STATISTICS ' . 'WHERE TABLE_SCHEMA = :tableSchema ' . 'AND TABLE_NAME = :tableName ' . 'GROUP BY INDEX_NAME ' . 'ORDER BY INDEX_NAME = \'PRIMARY\' DESC, INDEX_NAME';
     $table->indices = Index::model()->findAllBySql($sql, array('tableSchema' => $table->TABLE_SCHEMA, 'tableName' => $table->TABLE_NAME));
     foreach ($table->indices as $index) {
         $index->columns = IndexColumn::model()->findAllByAttributes(array('TABLE_SCHEMA' => $table->TABLE_SCHEMA, 'TABLE_NAME' => $table->TABLE_NAME, 'INDEX_NAME' => $index->INDEX_NAME));
     }
     // Indices (seperate for each column)
     $indicesRaw = Index::model()->findAllByAttributes(array('TABLE_SCHEMA' => $table->TABLE_SCHEMA, 'TABLE_NAME' => $table->TABLE_NAME));
     // Triggers
     $table->triggers = Trigger::model()->findAllByAttributes(array('EVENT_OBJECT_SCHEMA' => $table->TABLE_SCHEMA, 'EVENT_OBJECT_TABLE' => $table->TABLE_NAME));
     $this->render('structure', array('table' => $table, 'canAlter' => Yii::app()->user->privileges->checkTable($table->TABLE_SCHEMA, $table->TABLE_NAME, 'ALTER'), 'foreignKeys' => $foreignKeys, 'indicesRaw' => $indicesRaw));
 }
Example #6
0
 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 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);
 }
Example #9
0
 private function __construct($sql)
 {
     preg_match('/^CREATE TABLE (?<name>[^\\s\\(]+) \\((?<defs>.*)\\)\\s*$/is', $sql, $matches);
     $this->m_name = $matches['name'];
     $defs = array_map('trim', preg_split('/,[\\t ]*[\\r\\n]/', $matches['defs']));
     $this->m_columns = [];
     $this->m_foreign = [];
     $this->m_unique = [];
     $constraints = [];
     foreach ($defs as $def) {
         if (count($constraints) || ($matched = self::match('(?:CONSTRAINT|PRIMARY|UNIQUE|FOREIGN|CHECK)\\b', $def, $m))) {
             if (isset($matched) && !$matched) {
                 throw new \Exception('Failed to parse start of constraint');
             }
             // table constraint
             // check for optional constraint name
             $constraintName = NULL;
             if (self::match('CONSTRAINT (?<name>' . Column::R_NAME . ')', $def, $m)) {
                 $constraintName = $m['name'];
                 $def = ltrim(substr($def, strlen($m[0])));
             }
             if ($uniqueKey = UniqueKey::parse($constraintName, $def)) {
                 $this->m_unique[] = $uniqueKey;
             } else {
                 if ($foreignKey = ForeignKey::parse($constraintName, $def)) {
                     $this->m_foreign[$foreignKey->localField()] = $foreignKey;
                 } else {
                     throw new \Exception('Failed to parse constraint');
                 }
             }
         } else {
             $column = Column::parse($def);
             $this->m_columns[$column->name()] = $column;
         }
     }
 }
Example #10
0
 /**
  * Gets the "RelatedBy*" suffix (if needed) that is attached to method and variable names.
  *
  * The related by suffix is based on the local columns of the foreign key.  If there is more than
  * one column in a table that points to the same foreign table, then a 'RelatedByLocalColName' suffix
  * will be appended.
  *
  * @return     string
  */
 protected function getRelatedBySuffix(ForeignKey $fk, $columnCheck = false)
 {
     $relCol = "";
     foreach ($fk->getLocalColumns() as $columnName) {
         $column = $fk->getTable()->getColumn($columnName);
         if (!$column) {
             throw new Exception("Could not fetch column: {$columnName} in table " . $fk->getTable()->getName());
         }
         if (count($column->getTable()->getForeignKeysReferencingTable($fk->getForeignTableName())) > 1 || $fk->getForeignTableName() == $fk->getTable()->getName()) {
             // if there are seeral foreign keys that point to the same table
             // then we need to generate methods like getAuthorRelatedByColName()
             // instead of just getAuthor().  Currently we are doing the same
             // for self-referential foreign keys, to avoid confusion.
             $relCol .= $column->getPhpName();
         }
     }
     #var_dump($fk->getForeignTableName() . ' - ' .$fk->getTableName() . ' - ' . $this->getTable()->getName());
     #$fk->getForeignTableName() != $this->getTable()->getName() &&
     // @todo comment on it
     if ($columnCheck && !$relCol && $fk->getTable()->getColumn($fk->getForeignTableName())) {
         foreach ($fk->getLocalColumns() as $columnName) {
             $column = $fk->getTable()->getColumn($columnName);
             $relCol .= $column->getPhpName();
         }
     }
     if ($relCol != "") {
         $relCol = "RelatedBy" . $relCol;
     }
     return $relCol;
 }
 /**
  * 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 getReferrerVersionsColumn(ForeignKey $fk)
 {
     $fkTableName = $fk->getTable()->getName();
     $fkIdsColumnName = $fkTableName . '_versions';
     return $this->versionTable->getColumn($fkIdsColumnName);
 }
 public function getForeignKeyDDL(ForeignKey $fk)
 {
     $pattern = "\n-- SQLite does not support foreign keys; this is just for reference\n-- FOREIGN KEY (%s) REFERENCES %s (%s)\n";
     return sprintf($pattern, $this->getColumnListDDL($fk->getLocalColumns()), $fk->getForeignTableName(), $this->getColumnListDDL($fk->getForeignColumns()));
 }
Example #14
0
 /**
  * Criar a ForeignKey da Associação.
  * @param $column
  * @param $other_table
  * @param null $name
  * @param null $other_key
  * @return \Illuminate\Support\Fluent
  */
 public function foreignAssociation($column, $other_table, $name = null, $other_key = null)
 {
     $name = is_null($name) ? ForeignKey::makeName($this->table, $column) : $name;
     $other_key = is_null($other_key) ? self::keyAttr() : $other_key;
     $fk = $this->foreign($column, $name);
     $fk->on($other_table);
     $fk->references($other_key);
     return $fk;
 }
Example #15
0
 /**
  * Load foreign keys for this table.
  */
 protected function addForeignKeys(Table $table)
 {
     $database = $table->getDatabase();
     $stmt = $this->dbh->query("SELECT ccu1.TABLE_NAME, ccu1.COLUMN_NAME, ccu2.TABLE_NAME AS FK_TABLE_NAME, ccu2.COLUMN_NAME AS FK_COLUMN_NAME\n            FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu1 INNER JOIN\n            INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc1 ON tc1.CONSTRAINT_NAME = ccu1.CONSTRAINT_NAME AND\n            CONSTRAINT_TYPE = 'Foreign Key' INNER JOIN\n            INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1 ON rc1.CONSTRAINT_NAME = tc1.CONSTRAINT_NAME INNER JOIN\n            INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu2 ON ccu2.CONSTRAINT_NAME = rc1.UNIQUE_CONSTRAINT_NAME\n            WHERE (ccu1.table_name = '" . $table->getName() . "')");
     $foreignKeys = array();
     // local store to avoid duplicates
     while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
         $lcol = $row['COLUMN_NAME'];
         $ftbl = $row['FK_TABLE_NAME'];
         $fcol = $row['FK_COLUMN_NAME'];
         $foreignTable = $database->getTable($ftbl);
         $foreignColumn = $foreignTable->getColumn($fcol);
         $localColumn = $table->getColumn($lcol);
         if (!isset($foreignKeys[$name])) {
             $fk = new ForeignKey($name);
             $fk->setForeignTableCommonName($foreignTable->getCommonName());
             $fk->setForeignSchemaName($foreignTable->getSchema());
             //$fk->setOnDelete($fkactions['ON DELETE']);
             //$fk->setOnUpdate($fkactions['ON UPDATE']);
             $table->addForeignKey($fk);
             $foreignKeys[$name] = $fk;
         }
         $foreignKeys[$name]->addReference($localColumn, $foreignColumn);
     }
 }
 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 getForeignKeyDDL(ForeignKey $fk)
 {
     if ($fk->isSkipSql()) {
         return;
     }
     $pattern = 'CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)';
     $script = sprintf($pattern, $this->quoteIdentifier($fk->getName()), $this->getColumnListDDL($fk->getLocalColumns()), $this->quoteIdentifier($fk->getForeignTableName()), $this->getColumnListDDL($fk->getForeignColumns()));
     if ($fk->hasOnUpdate() && $fk->getOnUpdate() != ForeignKey::SETNULL) {
         $script .= ' ON UPDATE ' . $fk->getOnUpdate();
     }
     if ($fk->hasOnDelete() && $fk->getOnDelete() != ForeignKey::SETNULL) {
         $script .= ' ON DELETE ' . $fk->getOnDelete();
     }
     return $script;
 }
Example #18
0
 /**
  * Adds the method that adds an object into the referrer fkey collection.
  * @param      string &$script The script will be modified in this method.
  */
 protected function addCrossFKAdd(&$script, ForeignKey $refFK, ForeignKey $crossFK)
 {
     $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
     $collName = $this->getCrossFKVarName($crossFK);
     $tblFK = $refFK->getTable();
     $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
     $className = $joinedTableObjectBuilder->getObjectClassname();
     $foreignObjectName = '$' . $tblFK->getStudlyPhpName();
     $crossObjectName = '$' . $crossFK->getForeignTable()->getStudlyPhpName();
     $crossObjectClassName = $this->getNewObjectBuilder($crossFK->getForeignTable())->getObjectClassname();
     $script .= "\n\t/**\n\t * Associate a " . $crossObjectClassName . " object to this object\n\t * through the " . $tblFK->getName() . " cross reference table.\n\t *\n\t * @param      " . $crossObjectClassName . " " . $crossObjectName . " The {$className} object to relate\n\t * @return     void\n\t */\n\tpublic function add" . $this->getFKPhpNameAffix($crossFK, $plural = false) . "(" . $crossObjectName . ")\n\t{\n\t\tif (\$this->" . $collName . " === null) {\n\t\t\t\$this->init" . $relCol . "();\n\t\t}\n\t\tif (!\$this->" . $collName . "->contains(" . $crossObjectName . ")) { // only add it if the **same** object is not already associated\n\t\t\t" . $foreignObjectName . " = new " . $className . "();\n\t\t\t" . $foreignObjectName . "->set" . $this->getFKPhpNameAffix($crossFK, $plural = false) . "(" . $crossObjectName . ");\n\t\t\t\$this->add" . $this->getRefFKPhpNameAffix($refFK, $plural = false) . "(" . $foreignObjectName . ");\n\n\t\t\t\$this->" . $collName . "[]= " . $crossObjectName . ";\n\t\t}\n\t}\n";
 }
 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));
 }
Example #20
0
 /**
  * Load foreign keys for this table.
  */
 protected function addForeignKeys(Table $table)
 {
     $database = $table->getDatabase();
     $stmt = $this->dbh->query("SHOW CREATE TABLE `" . $table->getName() . "`");
     $row = $stmt->fetch(PDO::FETCH_NUM);
     $foreignKeys = array();
     // local store to avoid duplicates
     // Get the information on all the foreign keys
     $regEx = '/CONSTRAINT `([^`]+)` FOREIGN KEY \\((.+)\\) REFERENCES `([^`]*)` \\((.+)\\)(.*)/';
     if (preg_match_all($regEx, $row[1], $matches)) {
         $tmpArray = array_keys($matches[0]);
         foreach ($tmpArray as $curKey) {
             $name = $matches[1][$curKey];
             $rawlcol = $matches[2][$curKey];
             $ftbl = $matches[3][$curKey];
             $rawfcol = $matches[4][$curKey];
             $fkey = $matches[5][$curKey];
             $lcols = array();
             foreach (preg_split('/`, `/', $rawlcol) as $piece) {
                 $lcols[] = trim($piece, '` ');
             }
             $fcols = array();
             foreach (preg_split('/`, `/', $rawfcol) as $piece) {
                 $fcols[] = trim($piece, '` ');
             }
             //typical for mysql is RESTRICT
             $fkactions = array('ON DELETE' => ForeignKey::RESTRICT, 'ON UPDATE' => ForeignKey::RESTRICT);
             if ($fkey) {
                 //split foreign key information -> search for ON DELETE and afterwords for ON UPDATE action
                 foreach (array_keys($fkactions) as $fkaction) {
                     $result = NULL;
                     preg_match('/' . $fkaction . ' (' . ForeignKey::CASCADE . '|' . ForeignKey::SETNULL . ')/', $fkey, $result);
                     if ($result && is_array($result) && isset($result[1])) {
                         $fkactions[$fkaction] = $result[1];
                     }
                 }
             }
             $localColumns = array();
             $foreignColumns = array();
             $foreignTable = $database->getTable($ftbl);
             foreach ($fcols as $fcol) {
                 $foreignColumns[] = $foreignTable->getColumn($fcol);
             }
             foreach ($lcols as $lcol) {
                 $localColumns[] = $table->getColumn($lcol);
             }
             if (!isset($foreignKeys[$name])) {
                 $fk = new ForeignKey($name);
                 $fk->setForeignTableName($foreignTable->getName());
                 $fk->setOnDelete($fkactions['ON DELETE']);
                 $fk->setOnUpdate($fkactions['ON UPDATE']);
                 $table->addForeignKey($fk);
                 $foreignKeys[$name] = $fk;
             }
             for ($i = 0; $i < count($localColumns); $i++) {
                 $foreignKeys[$name]->addReference($localColumns[$i], $foreignColumns[$i]);
             }
         }
     }
 }
Example #21
0
 /**
  * @param $columns
  * @param $referencedTable
  * @param array $referencedColumns
  * @param array $options
  * @return $this
  */
 public function addForeignKey($columns, $referencedTable, $referencedColumns = ['id'], $options = [])
 {
     $foreignKey = new ForeignKey();
     if (!is_array($referencedColumns)) {
         $referencedColumns = array($referencedColumns);
     }
     $foreignKey->setReferenceColumns($referencedColumns);
     if ($referencedTable instanceof Table) {
         $foreignKey->setReferenceTable($referencedTable);
     } else {
         $foreignKey->setReferenceTable(new Table($referencedTable, [], $this->mapper));
     }
     $foreignKey->setColumns($columns);
     $foreignKey->setOptions($options);
     $this->foreignKeys[] = $foreignKey;
     return $this;
 }
Example #22
0
 /**
  * A utility function to create a new foreign key
  * from attrib and add it to this table.
  */
 public function addForeignKey($fkdata)
 {
     if ($fkdata instanceof ForeignKey) {
         $fk = $fkdata;
         $fk->setTable($this);
         $this->foreignKeys[] = $fk;
         if ($this->foreignTableNames === null) {
             $this->foreignTableNames = array();
         }
         if (!in_array($fk->getForeignTableName(), $this->foreignTableNames)) {
             $this->foreignTableNames[] = $fk->getForeignTableName();
         }
         return $fk;
     } else {
         $fk = new ForeignKey();
         $fk->setTable($this);
         $fk->loadFromXML($fkdata);
         return $this->addForeignKey($fk);
     }
 }
Example #23
0
 /**
  * @param string $stmt
  * @return $this
  */
 public function parse($stmt)
 {
     $lines = array_map('trim', explode(PHP_EOL, $stmt));
     $this->first = array_shift($lines);
     $last = array_pop($lines);
     //remove AUTO_INCREMENT bit from raw statement
     $this->last = preg_replace('/AUTO_INCREMENT=\\d+ ?/', '', $last);
     $this->statement = str_replace($last, $this->last, $stmt);
     if ($this->name === null) {
         if (!preg_match('/`([^`]+)/', $this->first, $match)) {
             throw new \RuntimeException(sprintf('Unable to extract name from %s (looked at line %s)', $stmt, $lines[0]));
         }
         $this->name = $match[1];
     }
     foreach ($lines as $ln) {
         if (mb_substr($ln, -1) == ',') {
             $ln = mb_substr($ln, 0, -1);
         }
         //field lines start with back-tick
         switch ($ln[0]) {
             case '`':
                 $field = new Field($ln);
                 $this->fields[$field->getName()] = $field;
                 break;
             case 'P':
                 $this->primary = new Primary($ln);
                 break;
             case 'S':
                 //spatial
             //spatial
             case 'U':
                 //unique
             //unique
             case 'F':
                 //fulltext
             //fulltext
             case 'I':
                 //index
             //index
             case 'K':
                 //Key
                 $idx = new Index($ln);
                 $this->indexes[$idx->getName()] = $idx;
                 break;
             case 'C':
                 $constraint = new ForeignKey($ln);
                 $this->constraints[$constraint->getName()] = $constraint;
                 break;
             default:
                 throw new \LogicException(sprintf('Unable to parse line %s in %s', $ln, $stmt));
         }
     }
     return $this;
 }
Example #24
0
 public function getForeignKeyDDL(ForeignKey $fk)
 {
     if ($fk->isSkipSql()) {
         return;
     }
     $pattern = "CONSTRAINT %s\r\n    FOREIGN KEY (%s) REFERENCES %s (%s)";
     $script = sprintf($pattern, $this->quoteIdentifier($fk->getName()), $this->getColumnListDDL($fk->getLocalColumns()), $this->quoteIdentifier($fk->getForeignTableName()), $this->getColumnListDDL($fk->getForeignColumns()));
     if ($fk->hasOnDelete()) {
         $script .= "\r\n    ON DELETE " . $fk->getOnDelete();
     }
     return $script;
 }
Example #25
0
 /**
  * Load foreign keys for this table.
  */
 protected function addForeignKeys(Table $table, $oid, $version)
 {
     $database = $table->getDatabase();
     $stmt = $this->dbh->prepare("SELECT\n                                          conname,\n                                          confupdtype,\n                                          confdeltype,\n                                          CASE nl.nspname WHEN 'public' THEN cl.relname ELSE nl.nspname||'.'||cl.relname END as fktab,\n                                          array_agg(DISTINCT a2.attname) AS fkcols,\n                                          CASE nr.nspname WHEN 'public' THEN cr.relname ELSE nr.nspname||'.'||cr.relname END as reftab,\n                                          array_agg(DISTINCT a1.attname) AS refcols\n                                    FROM pg_constraint ct\n                                         JOIN pg_class cl ON cl.oid=conrelid\n                                         JOIN pg_class cr ON cr.oid=confrelid\n                                         JOIN pg_namespace nl ON nl.oid = cl.relnamespace\n                                         JOIN pg_namespace nr ON nr.oid = cr.relnamespace\n                                         LEFT JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = ct.confrelid\n                                         LEFT JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = ct.conrelid\n                                    WHERE\n                                         contype='f'\n                                         AND conrelid = ?\n                                          AND a2.attnum = ANY (ct.conkey)\n                                          AND a1.attnum = ANY (ct.confkey)\n                                    GROUP BY conname, confupdtype, confdeltype, fktab, reftab\n                                    ORDER BY conname");
     $stmt->bindValue(1, $oid);
     $stmt->execute();
     $foreignKeys = array();
     // local store to avoid duplicates
     while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
         $name = $row['conname'];
         $local_table = $row['fktab'];
         $local_columns = explode(',', trim($row['fkcols'], '{}'));
         $foreign_table = $row['reftab'];
         $foreign_columns = explode(',', trim($row['refcols'], '{}'));
         // On Update
         switch ($row['confupdtype']) {
             case 'c':
                 $onupdate = ForeignKey::CASCADE;
                 break;
             case 'd':
                 $onupdate = ForeignKey::SETDEFAULT;
                 break;
             case 'n':
                 $onupdate = ForeignKey::SETNULL;
                 break;
             case 'r':
                 $onupdate = ForeignKey::RESTRICT;
                 break;
             default:
             case 'a':
                 //NOACTION is the postgresql default
                 $onupdate = ForeignKey::NONE;
                 break;
         }
         // On Delete
         switch ($row['confdeltype']) {
             case 'c':
                 $ondelete = ForeignKey::CASCADE;
                 break;
             case 'd':
                 $ondelete = ForeignKey::SETDEFAULT;
                 break;
             case 'n':
                 $ondelete = ForeignKey::SETNULL;
                 break;
             case 'r':
                 $ondelete = ForeignKey::RESTRICT;
                 break;
             default:
             case 'a':
                 //NOACTION is the postgresql default
                 $ondelete = ForeignKey::NONE;
                 break;
         }
         $foreignTable = $database->getTable($foreign_table);
         $localTable = $database->getTable($local_table);
         if (!isset($foreignKeys[$name])) {
             $fk = new ForeignKey($name);
             $fk->setForeignTableCommonName($foreignTable->getCommonName());
             $fk->setForeignSchemaName($foreignTable->getSchema());
             $fk->setOnDelete($ondelete);
             $fk->setOnUpdate($onupdate);
             $table->addForeignKey($fk);
             $foreignKeys[$name] = $fk;
         }
         for ($i = 0; $i < count($local_columns); $i++) {
             $foreignKeys[$name]->addReference($localTable->getColumn($local_columns[$i]), $foreignTable->getColumn($foreign_columns[$i]));
         }
     }
 }
 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 getDropForeignKeyDDL(ForeignKey $fk)
 {
     if ($fk->isSkipSql()) {
         return;
     }
     $pattern = "\nALTER TABLE %s DROP FOREIGN KEY %s;\n";
     return sprintf($pattern, $this->quoteIdentifier($fk->getTable()->getName()), $this->quoteIdentifier($fk->getName()));
 }
Example #28
0
 /**
  * @param		string &$script The script will be modified in this method.
  * @param		ForeignKey $refFK
  * @param		ForeignKey $crossFK
  */
 protected function addCrossFKDoAdd(&$script, ForeignKey $refFK, ForeignKey $crossFK)
 {
     $relatedObjectClassName = $this->getFKPhpNameAffix($crossFK, $plural = false);
     // lcfirst() doesn't exist in PHP < 5.3
     $lowerRelatedObjectClassName = $relatedObjectClassName;
     $lowerRelatedObjectClassName[0] = strtolower($lowerRelatedObjectClassName[0]);
     $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
     $className = $joinedTableObjectBuilder->getObjectClassname();
     $tblFK = $refFK->getTable();
     $foreignObjectName = '$' . $tblFK->getStudlyPhpName();
     $script .= "\n\t/**\n\t * @param\t{$relatedObjectClassName} \${$lowerRelatedObjectClassName} The {$lowerRelatedObjectClassName} object to add.\n\t */\n\tprotected function doAdd{$relatedObjectClassName}(\${$lowerRelatedObjectClassName})\n\t{\n\t\t{$foreignObjectName} = new {$className}();\n\t\t{$foreignObjectName}->set{$relatedObjectClassName}(\${$lowerRelatedObjectClassName});\n\t\t\$this->add{$className}({$foreignObjectName});\n\t}\n";
 }
 /**
  * Load foreign keys for this table.
  */
 protected function addForeignKeys(Table $table, $oid, $version)
 {
     $database = $table->getDatabase();
     $stmt = $this->dbh->prepare("SELECT\n\t\t\t\t\t\t\t\t          conname,\n\t\t\t\t\t\t\t\t          confupdtype,\n\t\t\t\t\t\t\t\t          confdeltype,\n\t\t\t\t\t\t\t\t          CASE nl.nspname WHEN 'public' THEN cl.relname ELSE nl.nspname||'.'||cl.relname END as fktab,\n\t\t\t\t\t\t\t\t          a2.attname as fkcol,\n\t\t\t\t\t\t\t\t          CASE nr.nspname WHEN 'public' THEN cr.relname ELSE nr.nspname||'.'||cr.relname END as reftab,\n\t\t\t\t\t\t\t\t          a1.attname as refcol\n\t\t\t\t\t\t\t\t    FROM pg_constraint ct\n\t\t\t\t\t\t\t\t         JOIN pg_class cl ON cl.oid=conrelid\n\t\t\t\t\t\t\t\t         JOIN pg_class cr ON cr.oid=confrelid\n\t\t\t\t\t\t\t\t         JOIN pg_namespace nl ON nl.oid = cl.relnamespace\n\t\t\t\t\t\t\t\t         JOIN pg_namespace nr ON nr.oid = cr.relnamespace\n\t\t\t\t\t\t\t\t         LEFT JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = ct.confrelid\n\t\t\t\t\t\t\t\t         LEFT JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = ct.conrelid\n\t\t\t\t\t\t\t\t    WHERE\n\t\t\t\t\t\t\t\t         contype='f'\n\t\t\t\t\t\t\t\t         AND conrelid = ?\n\t\t\t\t\t\t\t\t         AND a2.attnum = ct.conkey[1]\n\t\t\t\t\t\t\t\t         AND a1.attnum = ct.confkey[1]\n\t\t\t\t\t\t\t\t    ORDER BY conname");
     $stmt->bindValue(1, $oid);
     $stmt->execute();
     $foreignKeys = array();
     // local store to avoid duplicates
     while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
         $name = $row['conname'];
         $local_table = $row['fktab'];
         $local_column = $row['fkcol'];
         $foreign_table = $row['reftab'];
         $foreign_column = $row['refcol'];
         // On Update
         switch ($row['confupdtype']) {
             case 'c':
                 $onupdate = ForeignKey::CASCADE;
                 break;
             case 'd':
                 $onupdate = ForeignKey::SETDEFAULT;
                 break;
             case 'n':
                 $onupdate = ForeignKey::SETNULL;
                 break;
             case 'r':
                 $onupdate = ForeignKey::RESTRICT;
                 break;
             default:
             case 'a':
                 //NOACTION is the postgresql default
                 $onupdate = ForeignKey::NONE;
                 break;
         }
         // On Delete
         switch ($row['confdeltype']) {
             case 'c':
                 $ondelete = ForeignKey::CASCADE;
                 break;
             case 'd':
                 $ondelete = ForeignKey::SETDEFAULT;
                 break;
             case 'n':
                 $ondelete = ForeignKey::SETNULL;
                 break;
             case 'r':
                 $ondelete = ForeignKey::RESTRICT;
                 break;
             default:
             case 'a':
                 //NOACTION is the postgresql default
                 $ondelete = ForeignKey::NONE;
                 break;
         }
         $foreignTable = $database->getTable($foreign_table);
         $foreignColumn = $foreignTable->getColumn($foreign_column);
         $localTable = $database->getTable($local_table);
         $localColumn = $localTable->getColumn($local_column);
         if (!isset($foreignKeys[$name])) {
             $fk = new ForeignKey($name);
             $fk->setForeignTableName($foreignTable->getName());
             $fk->setOnDelete($ondelete);
             $fk->setOnUpdate($onupdate);
             $table->addForeignKey($fk);
             $foreignKeys[$name] = $fk;
         }
         $foreignKeys[$name]->addReference($localColumn, $foreignColumn);
     }
 }
Example #30
0
 /**
  * Adds the method that remove an object from the referrer fkey collection.
  * @param string $script The script will be modified in this method.
  */
 protected function addCrossFKRemove(&$script, ForeignKey $refFK, ForeignKey $crossFK)
 {
     $relCol = $this->getFKPhpNameAffix($crossFK, $plural = true);
     $collName = 'coll' . $relCol;
     $tblFK = $refFK->getTable();
     $joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
     $className = $joinedTableObjectBuilder->getObjectClassname();
     $lowerRelCol = $relCol;
     $lowerRelCol[0] = strtolower($lowerRelCol[0]);
     $M2MScheduledForDeletion = $lowerRelCol . "ScheduledForDeletion";
     $crossObjectName = '$' . $crossFK->getForeignTable()->getStudlyPhpName();
     $crossObjectClassName = $this->getNewObjectBuilder($crossFK->getForeignTable())->getObjectClassname();
     $relatedObjectClassName = $this->getFKPhpNameAffix($crossFK, $plural = false);
     $script .= "\n    /**\n     * Remove a {$crossObjectClassName} object to this object\n     * through the {$tblFK->getName()} cross reference table.\n     *\n     * @param {$crossObjectClassName} {$crossObjectName} The {$className} object to relate\n     * @return void\n     */\n    public function remove{$relatedObjectClassName}({$crossObjectClassName} {$crossObjectName})\n    {\n        if (\$this->get{$relCol}()->contains({$crossObjectName})) {\n            \$this->{$collName}->remove(\$this->{$collName}->search({$crossObjectName}));\n            if (null === \$this->{$M2MScheduledForDeletion}) {\n                \$this->{$M2MScheduledForDeletion} = clone \$this->{$collName};\n                \$this->{$M2MScheduledForDeletion}->clear();\n            }\n            \$this->{$M2MScheduledForDeletion}[]= {$crossObjectName};\n        }\n    }\n";
 }