diff --git a/laravel/database/schema/grammars/mysql.php b/laravel/database/schema/grammars/mysql.php index 595c1dd8..7fa9f148 100644 --- a/laravel/database/schema/grammars/mysql.php +++ b/laravel/database/schema/grammars/mysql.php @@ -197,6 +197,39 @@ protected function key(Table $table, Fluent $command, $type) return 'ALTER TABLE '.$this->wrap($table)." ADD {$type} {$name}({$keys})"; } + /** + * Generate the SQL statement for creating a foreign key. + * + * @param Table $table + * @param Command $command + * @return string + */ + public function foreign(Table $table, Fluent $command) + { + $name = $command->name; + + // We need to wrap both of the table names in quoted identifiers to protect + // against any possible keyword collisions, both the table on which the + // command is being executed and the referenced table are wrapped. + $table = $this->wrap($table); + + $on = $this->wrap($command->on); + + // Next we need to columnize both the command table's columns as well as + // the columns referenced by the foreign key. We'll cast the referenced + // columns to an array since they aren't by the fluent command. + $foreign = $this->columnize($command->columns); + + $referenced = $this->columnize((array) $command->references); + + // Finally we can built the SQL. This should be the same for all database + // platforms we support, but we'll just keep it in the grammars since + // adding foreign keys using ALTER isn't supported by SQLite. + $sql = "ALTER TABLE $table ADD CONSTRAINT $name "; + + die($sql .= "FOREIGN KEY ($foreign) REFERENCES $on ($referenced)"); + } + /** * Generate the SQL statement for a drop table command. * diff --git a/laravel/database/schema/grammars/postgres.php b/laravel/database/schema/grammars/postgres.php index b974efc9..30bfa2f6 100644 --- a/laravel/database/schema/grammars/postgres.php +++ b/laravel/database/schema/grammars/postgres.php @@ -194,6 +194,39 @@ protected function key(Table $table, Fluent $command, $unique = false) return $create." INDEX {$command->name} ON ".$this->wrap($table)." ({$columns})"; } + /** + * Generate the SQL statement for creating a foreign key. + * + * @param Table $table + * @param Command $command + * @return string + */ + public function foreign(Table $table, Fluent $command) + { + $name = $command->name; + + // We need to wrap both of the table names in quoted identifiers to protect + // against any possible keyword collisions, both the table on which the + // command is being executed and the referenced table are wrapped. + $table = $this->wrap($table); + + $on = $this->wrap($command->on); + + // Next we need to columnize both the command table's columns as well as + // the columns referenced by the foreign key. We'll cast the referenced + // columns to an array since they aren't by the fluent command. + $foreign = $this->columnize($command->columns); + + $referenced = $this->columnize((array) $command->references); + + // Finally we can built the SQL. This should be the same for all database + // platforms we support, but we'll just keep it in the grammars since + // adding foreign keys using ALTER isn't supported by SQLite. + $sql = "ALTER TABLE $table ADD CONSTRAINT $name "; + + die($sql .= "FOREIGN KEY ($foreign) REFERENCES $on ($referenced)"); + } + /** * Generate the SQL statement for a drop table command. * diff --git a/laravel/database/schema/grammars/sqlserver.php b/laravel/database/schema/grammars/sqlserver.php index 6cf1bffb..2f8824da 100644 --- a/laravel/database/schema/grammars/sqlserver.php +++ b/laravel/database/schema/grammars/sqlserver.php @@ -212,6 +212,39 @@ protected function key(Table $table, Fluent $command, $unique = false) return $create." INDEX {$command->name} ON ".$this->wrap($table)." ({$columns})"; } + /** + * Generate the SQL statement for creating a foreign key. + * + * @param Table $table + * @param Command $command + * @return string + */ + public function foreign(Table $table, Fluent $command) + { + $name = $command->name; + + // We need to wrap both of the table names in quoted identifiers to protect + // against any possible keyword collisions, both the table on which the + // command is being executed and the referenced table are wrapped. + $table = $this->wrap($table); + + $on = $this->wrap($command->on); + + // Next we need to columnize both the command table's columns as well as + // the columns referenced by the foreign key. We'll cast the referenced + // columns to an array since they aren't by the fluent command. + $foreign = $this->columnize($command->columns); + + $referenced = $this->columnize((array) $command->references); + + // Finally we can built the SQL. This should be the same for all database + // platforms we support, but we'll just keep it in the grammars since + // adding foreign keys using ALTER isn't supported by SQLite. + $sql = "ALTER TABLE $table ADD CONSTRAINT $name "; + + die($sql .= "FOREIGN KEY ($foreign) REFERENCES $on ($referenced)"); + } + /** * Generate the SQL statement for a drop table command. * diff --git a/laravel/database/schema/table.php b/laravel/database/schema/table.php index 4af83422..006ba390 100644 --- a/laravel/database/schema/table.php +++ b/laravel/database/schema/table.php @@ -108,6 +108,17 @@ public function index($columns, $name = null) return $this->key(__FUNCTION__, $columns, $name); } + /** + * Add a foreign key constraint to the table. + * + * @param string|array $columns + * @param string $name + */ + public function foreign($columns, $name = null) + { + return $this->key(__FUNCTION__, $columns, $name); + } + /** * Create a command for creating any index. *