/** * Returns the index name. * * @return string */ public function getName() { $this->doNaming(); if ($this->table && ($database = $this->table->getDatabase())) { return substr($this->name, 0, $database->getMaxColumnNameLength()); } return $this->name; }
/** * @param Driver $driver * @param Table $table * @param Query $query * @param bool $asArray */ public function __construct(Driver $driver, Table $table, Query $query, $asArray = false) { $this->asArray = $asArray; $this->table = $table; $params = []; $this->tableName = $table->getName(); if (!$this->asArray) { $this->recordClasses = [$this->tableName => $table->getDatabase()->getClassMapper()->getClassForRecord($this->tableName)]; } $sql = $query->getRawSql(); if ($sql === null) { $sql = $driver->buildSQL($table, $query, $params); $this->fetchStyle = \PDO::FETCH_NUM; foreach ($table->getColumns() as $column) { if ($column->isPrimaryKey()) { $this->primaryKeyOrdinals[$this->tableName][$column->getOrdinal()] = true; } $this->columnOrdinalMap[$this->tableName][$column->getOrdinal()] = $column->getName(); } $offset = count($table->getColumns()); foreach ($query->getJoins() as $join) { if (isset($join['cardinality'])) { $joinedTableName = $join['table']; $joinedTable = $table->getDatabase()->getTable($joinedTableName); $this->joinedTables[$joinedTableName] = $joinedTable; if (!$this->asArray) { $this->recordClasses[$joinedTableName] = $joinedTable->getDatabase()->getClassMapper()->getClassForRecord($joinedTableName); } foreach ($joinedTable->getColumns() as $column) { if ($column->isPrimaryKey()) { $this->primaryKeyOrdinals[$joinedTableName][$offset + $column->getOrdinal()] = true; } $this->columnOrdinalMap[$joinedTableName][$offset + $column->getOrdinal()] = $column->getName(); } $this->cardinalities[$joinedTableName] = $join['cardinality']; if ($join['cardinality'] === Query::CARDINALITY_ONE_TO_MANY) { $this->properties[$joinedTableName] = $joinedTableName; } else { $this->properties[$joinedTableName] = array_keys($join['on']); } $offset += count($joinedTable->getColumns()); } } } else { $this->fetchStyle = \PDO::FETCH_ASSOC; $this->rawSql = true; } $this->result = $driver->query($sql, $params); $this->fetchNextRow(); }
/** * 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); } }
/** * Sets up the Column object based on the attributes that were passed to loadFromXML(). * @see parent::loadFromXML() */ protected function setupObject() { try { $dom = $this->getAttribute("domain"); if ($dom) { $this->getDomain()->copy($this->getTable()->getDatabase()->getDomain($dom)); } else { $type = strtoupper($this->getAttribute("type")); if ($type) { if ($platform = $this->getPlatform()) { $this->getDomain()->copy($this->getPlatform()->getDomainForType($type)); } else { // no platform - probably during tests $this->setDomain(new Domain($type)); } } else { if ($platform = $this->getPlatform()) { $this->getDomain()->copy($this->getPlatform()->getDomainForType(self::DEFAULT_TYPE)); } else { // no platform - probably during tests $this->setDomain(new Domain(self::DEFAULT_TYPE)); } } } $this->name = $this->getAttribute("name"); $this->phpName = $this->getAttribute("phpName"); $this->phpType = $this->getAttribute("phpType"); if ($this->getAttribute("prefix", null) !== null) { $this->namePrefix = $this->getAttribute("prefix"); } elseif ($this->getTable()->getAttribute('columnPrefix', null) !== null) { $this->namePrefix = $this->getTable()->getAttribute('columnPrefix'); } else { $this->namePrefix = ''; } // Accessor visibility if ($this->getAttribute('accessorVisibility', null) !== null) { $this->setAccessorVisibility($this->getAttribute('accessorVisibility')); } elseif ($this->getTable()->getAttribute('defaultAccessorVisibility', null) !== null) { $this->setAccessorVisibility($this->getTable()->getAttribute('defaultAccessorVisibility')); } elseif ($this->getTable()->getDatabase()->getAttribute('defaultAccessorVisibility', null) !== null) { $this->setAccessorVisibility($this->getTable()->getDatabase()->getAttribute('defaultAccessorVisibility')); } else { $this->setAccessorVisibility(self::DEFAULT_VISIBILITY); } // Mutator visibility if ($this->getAttribute('mutatorVisibility', null) !== null) { $this->setMutatorVisibility($this->getAttribute('mutatorVisibility')); } elseif ($this->getTable()->getAttribute('defaultMutatorVisibility', null) !== null) { $this->setMutatorVisibility($this->getTable()->getAttribute('defaultMutatorVisibility')); } elseif ($this->getTable()->getDatabase()->getAttribute('defaultMutatorVisibility', null) !== null) { $this->setMutatorVisibility($this->getTable()->getDatabase()->getAttribute('defaultMutatorVisibility')); } else { $this->setMutatorVisibility(self::DEFAULT_VISIBILITY); } $this->peerName = $this->getAttribute("peerName"); // retrieves the method for converting from specified name to a PHP name, defaulting to parent tables default method $this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->parentTable->getDatabase()->getDefaultPhpNamingMethod()); $this->isPrimaryString = $this->booleanValue($this->getAttribute("primaryString")); $this->isPrimaryKey = $this->booleanValue($this->getAttribute("primaryKey")); $this->isNodeKey = $this->booleanValue($this->getAttribute("nodeKey")); $this->nodeKeySep = $this->getAttribute("nodeKeySep", "."); $this->isNestedSetLeftKey = $this->booleanValue($this->getAttribute("nestedSetLeftKey")); $this->isNestedSetRightKey = $this->booleanValue($this->getAttribute("nestedSetRightKey")); $this->isTreeScopeKey = $this->booleanValue($this->getAttribute("treeScopeKey")); $this->isNotNull = $this->booleanValue($this->getAttribute("required"), false) || $this->isPrimaryKey; // primary keys are required //AutoIncrement/Sequences $this->isAutoIncrement = $this->booleanValue($this->getAttribute("autoIncrement")); $this->isLazyLoad = $this->booleanValue($this->getAttribute("lazyLoad")); // Add type, size information to associated Domain object $this->getDomain()->replaceSqlType($this->getAttribute("sqlType")); if (!$this->getAttribute("size") && $this->getDomain()->getType() == 'VARCHAR' && $this->hasPlatform() && !$this->getAttribute("sqlType") && !$this->getPlatform()->supportsVarcharWithoutSize()) { $size = 255; } else { $size = $this->getAttribute("size"); } $this->getDomain()->replaceSize($size); $this->getDomain()->replaceScale($this->getAttribute("scale")); $defval = $this->getAttribute("defaultValue", $this->getAttribute("default")); if ($defval !== null && strtolower($defval) !== 'null') { $this->getDomain()->setDefaultValue(new ColumnDefaultValue($defval, ColumnDefaultValue::TYPE_VALUE)); } elseif ($this->getAttribute("defaultExpr") !== null) { $this->getDomain()->setDefaultValue(new ColumnDefaultValue($this->getAttribute("defaultExpr"), ColumnDefaultValue::TYPE_EXPR)); } if ($this->getAttribute('valueSet', null) !== null) { $valueSet = explode(',', $this->getAttribute("valueSet")); $valueSet = array_map('trim', $valueSet); $this->valueSet = $valueSet; } $this->inheritanceType = $this->getAttribute("inheritance"); $this->isInheritance = $this->inheritanceType !== null && $this->inheritanceType !== "false"; // here we are only checking for 'false', so don't // use boleanValue() $this->description = $this->getAttribute("description"); } catch (Exception $e) { throw new EngineException("Error setting up column " . var_export($this->getAttribute("name"), true) . ": " . $e->getMessage()); } }
protected function getTableOptions(Table $table) { $dbVI = $table->getDatabase()->getVendorInfoForType('mysql'); $tableVI = $table->getVendorInfoForType('mysql'); $vi = $dbVI->getMergedVendorInfo($tableVI); $tableOptions = array(); $supportedOptions = array('Charset' => 'CHARACTER SET', 'Collate' => 'COLLATE', 'Checksum' => 'CHECKSUM', 'Pack_Keys' => 'PACK_KEYS', 'Delay_key_write' => 'DELAY_KEY_WRITE'); foreach ($supportedOptions as $name => $sqlName) { if ($vi->hasParameter($name)) { $tableOptions[] = sprintf('%s=%s', $sqlName, $this->quote($vi->getParameter($name))); } } return $tableOptions; }
/** * 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]); } } } }
/** * 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])); } } }
/** * Build SQL FROM clause * @param Query $query * @param Table $table * @param string &$columns * @return string */ protected function buildFromClause(Query $query, Table $table, &$columns) { $from = $table->getFullIdentifier(); foreach ($query->getJoins() as $join) { if ($join['type'] == 'left') { $from .= "\n\tLEFT JOIN "; } else { $from .= "\n\tINNER JOIN "; } $rightSideTable = $table->getDatabase()->getTable($join['table']); if (!empty($join['columns'])) { foreach ($join['columns'] as $columnName) { $column = $rightSideTable->getColumn($columnName); $columns .= ",\n\t{$column->getSQLExpression()}"; } } $from .= $rightSideTable->getFullIdentifier(); if (empty($join['alias'])) { $rightSideTableReference = $rightSideTable->getFullIdentifier(); } else { $rightSideTableReference = $join['alias']; $from .= ' AS ' . $join['alias']; } $on = ''; foreach ($join['on'] as $leftSide => $rightSide) { $on .= ' AND ' . $table->getFullIdentifier() . '.' . $leftSide . ' = ' . $rightSideTableReference . '.' . $rightSide; } $from .= "\n\t\tON (" . substr($on, 5) . ')'; } return $from; }
/** * 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); } }
protected function getTableOptions(Table $table) { $dbVI = $table->getDatabase()->getVendorInfoForType('mysql'); $tableVI = $table->getVendorInfoForType('mysql'); $vi = $dbVI->getMergedVendorInfo($tableVI); $tableOptions = array(); // List of supported table options // see http://dev.mysql.com/doc/refman/5.5/en/create-table.html $supportedOptions = array('AutoIncrement' => 'AUTO_INCREMENT', 'AvgRowLength' => 'AVG_ROW_LENGTH', 'Charset' => 'CHARACTER SET', 'Checksum' => 'CHECKSUM', 'Collate' => 'COLLATE', 'Connection' => 'CONNECTION', 'DataDirectory' => 'DATA DIRECTORY', 'Delay_key_write' => 'DELAY_KEY_WRITE', 'DelayKeyWrite' => 'DELAY_KEY_WRITE', 'IndexDirectory' => 'INDEX DIRECTORY', 'InsertMethod' => 'INSERT_METHOD', 'KeyBlockSize' => 'KEY_BLOCK_SIZE', 'MaxRows' => 'MAX_ROWS', 'MinRows' => 'MIN_ROWS', 'Pack_Keys' => 'PACK_KEYS', 'PackKeys' => 'PACK_KEYS', 'RowFormat' => 'ROW_FORMAT', 'Union' => 'UNION'); foreach ($supportedOptions as $name => $sqlName) { if ($vi->hasParameter($name)) { $tableOptions[] = sprintf('%s=%s', $sqlName, $this->quote($vi->getParameter($name))); } elseif ($vi->hasParameter($sqlName)) { $tableOptions[] = sprintf('%s=%s', $sqlName, $this->quote($vi->getParameter($sqlName))); } } return $tableOptions; }
/** * Returns the resolved foreign Table model object. * * @return Table */ public function getForeignTable() { if ($database = $this->parentTable->getDatabase()) { return $database->getTable($this->getForeignTableName()); } }
/** * Load foreign keys for this table. */ protected function addForeignKeys(Table $table) { $database = $table->getDatabase(); $stmt = $this->dbh->query("SELECT CONSTRAINT_NAME, DELETE_RULE, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'R' AND TABLE_NAME = '" . $table->getName() . "'"); $foreignKeys = array(); // local store to avoid duplicates while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $name = $row['CONSTRAINT_NAME']; $stmt2 = $this->dbh->query("SELECT CON.CONSTRAINT_NAME, CON.TABLE_NAME, COL.COLUMN_NAME FROM USER_CONS_COLUMNS COL, USER_CONSTRAINTS CON WHERE COL.CONSTRAINT_NAME = CON.CONSTRAINT_NAME AND COL.CONSTRAINT_NAME = '" . $row['R_CONSTRAINT_NAME'] . "'"); $foreignKeyCols = $stmt2->fetch(PDO::FETCH_ASSOC); if (!is_array($foreignKeyCols[0])) { $foreignRows[0] = $foreignKeyCols; } else { $foreignRows = $foreignKeyCols; } $stmt2 = $this->dbh->query("SELECT CON.CONSTRAINT_NAME, CON.TABLE_NAME, COL.COLUMN_NAME FROM USER_CONS_COLUMNS COL, USER_CONSTRAINTS CON WHERE COL.CONSTRAINT_NAME = CON.CONSTRAINT_NAME AND COL.CONSTRAINT_NAME = '" . $row['CONSTRAINT_NAME'] . "'"); $localKeyCols = $stmt2->fetch(PDO::FETCH_ASSOC); if (!is_array($localKeyCols[0])) { $localRows[0] = $localKeyCols; } else { $localRows = $localKeyCols; } print_r($foreignRows); $localColumns = array(); $foreignColumns = array(); $foreignTable = $database->getTable($foreignRows[0]["TABLE_NAME"]); foreach ($foreignRows as $foreignCol) { $foreignColumns[] = $foreignTable->getColumn($foreignCol["COLUMN_NAME"]); } foreach ($localRows as $localCol) { $localColumns[] = $table->getColumn($localCol['COLUMN_NAME']); } if (!isset($foreignKeys[$name])) { $fk = new ForeignKey($name); $fk->setForeignTableName($foreignTable->getName()); $fk->setOnDelete($row["DELETE_RULE"]); $fk->setOnUpdate($row["DELETE_RULE"]); $table->addForeignKey($fk); $foreignKeys[$name] = $fk; } for ($i = 0; $i < count($localColumns); $i++) { $foreignKeys[$name]->addReference($localColumns[$i], $foreignColumns[$i]); } } }