grammar.php 2.53 KB
Newer Older
1 2 3 4 5 6 7 8
<?php namespace Laravel\Database\Schema\Grammars;

use Laravel\Fluent;
use Laravel\Database\Schema\Table;

abstract class Grammar extends \Laravel\Database\Grammar {

	/**
9
	 * Generate the SQL statement for creating a foreign key.
10
	 *
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
	 * @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);

		$sql = "ALTER TABLE $table ADD CONSTRAINT $name ";

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
		$sql .= "FOREIGN KEY ($foreign) REFERENCES $on ($referenced)";

		// Finally we will check for any "on delete" or "on update" options for
		// the foreign key. These control the behavior of the constraint when
		// an update or delete statement is run against the record.
		if ( ! is_null($command->on_delete))
		{
			$sql .= " ON DELETE {$command->on_delete}";
		}

		if ( ! is_null($command->on_update))
		{
			$sql .= " ON UPDATE {$command->on_update}";
		}

		return $sql;
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
	}

	/**
	 * Drop a constraint from the table.
	 *
	 * @param  Table   $table
	 * @param  Fluent  $fluent
	 * @return string
	 */
	protected function drop_constraint(Table $table, Fluent $command)
	{
		return "ALTER TABLE ".$this->wrap($table)." DROP CONSTRAINT ".$command->name;
	}

	/**
66 67 68 69 70 71 72 73 74 75
	 * Wrap a value in keyword identifiers.
	 *
	 * @param  Table|string  $value
	 * @return string
	 */
	public function wrap($value)
	{
		// This method is primarily for convenience so we can just pass a
		// column or table instance into the wrap method without sending
		// in the name each time we need to wrap one of these objects.
76 77 78 79 80
		if ($value instanceof Table)
		{
			return $this->wrap_table($value->name);
		}
		elseif ($value instanceof Fluent)
81 82 83 84 85 86 87
		{
			$value = $value->name;
		}

		return parent::wrap($value);
	}

88
	/**
89
	 * Get the appropriate data type definition for the column.
90 91 92 93
	 *
	 * @param  Fluent  $column
	 * @return string
	 */
94
	protected function type(Fluent $column)
95
	{
96
		return $this->{'type_'.$column->type}($column);
97 98
	}

99
}