schema.php 4.27 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<?php namespace Laravel\Database;

use Laravel\Fluent;
use Laravel\Database as DB;

class Schema {

	/**
	 * Begin a fluent schema operation on a database table.
	 *
	 * @param  string   $table
	 * @param  Closure  $callback
	 * @return void
	 */
	public static function table($table, $callback)
	{
		call_user_func($callback, $table = new Schema\Table($table));

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
		return static::execute($table);
	}

	/**
	 * Create a new database table schema.
	 *
	 * @param  string   $table
	 * @param  Closure  $callback
	 * @return void
	 */
	public static function create($table, $callback)
	{
		$table = new Schema\Table($table);

		// To indicate that the table is new and needs to be created, we'll run
		// the "create" command on the table instance. This tells schema it is
		// not simply a column modification operation.
		$table->create();

		call_user_func($callback, $table);

		return static::execute($table);
	}

	/**
	 * Drop a database table from the schema.
	 *
	 * @param  string  $table
Taylor Otwell committed
47
	 * @param  string  $connection
48 49
	 * @return void
	 */
Taylor Otwell committed
50
	public static function drop($table, $connection = null)
51 52 53
	{
		$table = new Schema\Table($table);

Taylor Otwell committed
54 55
		$table->on($connection);

56 57 58 59
		// To indicate that the table needs to be dropped, we will run the
		// "drop" command on the table instance and pass the instance to
		// the execute method as calling a Closure isn't needed.
		$table->drop();
60 61 62 63 64 65 66 67 68 69 70 71

		return static::execute($table);
	}

	/**
	 * Execute the given schema operation against the database.
	 *
	 * @param  Schema\Table  $table
	 * @return void
	 */
	public static function execute($table)
	{
72 73 74 75 76
		// The implications method is responsible for finding any fluently
		// defined indexes on the schema table and adding the explicit
		// commands that are needed to tbe schema instance.
		static::implications($table);

77 78 79 80
		foreach ($table->commands as $command)
		{
			$connection = DB::connection($table->connection);

81
			$grammar = static::grammar($connection);
82

83 84 85
			// Each grammar has a function that corresponds to the command type and
			// is for building that command's SQL. This lets the SQL syntax builds
			// stay granular across various database systems.
86 87 88 89
			if (method_exists($grammar, $method = $command->type))
			{
				$statements = $grammar->$method($table, $command);

90 91 92
				// Once we have the statements, we will cast them to an array even
				// though not all of the commands return an array just in case it
				// needs multiple queries to complete.
93 94
				foreach ((array) $statements as $statement)
				{
95
					$connection->query($statement);
96 97 98 99 100 101 102 103 104 105 106 107 108
				}
			}
		}
	}

	/**
	 * Add any implicit commands to the schema table operation.
	 *
	 * @param   Schema\Table  $table
	 * @return  void
	 */
	protected static function implications($table)
	{
Taylor Otwell committed
109 110 111
		// If the developer has specified columns for the table and the table is
		// not being created, we'll assume they simply want to add the columns
		// to the table and generate the add command.
112 113 114 115 116 117 118
		if (count($table->columns) > 0 and ! $table->creating())
		{
			$command = new Fluent(array('type' => 'add'));

			array_unshift($table->commands, $command);
		}

Taylor Otwell committed
119 120 121
		// For some extra syntax sugar, we'll check for any implicit indexes
		// on the table since the developer may specify the index type on
		// the fluent column declaration for convenience.
122 123 124 125
		foreach ($table->columns as $column)
		{
			foreach (array('primary', 'unique', 'fulltext', 'index') as $key)
			{
126
				if (isset($column->$key))
127
				{
128 129 130 131 132 133 134 135
					if ($column->$key === true)
					{
						$table->$key($column->name);
					}
					else
					{
						$table->$key($column->name, $column->$key);
					}
136 137 138 139 140 141 142 143
				}
			}
		}
	}

	/**
	 * Create the appropriate schema grammar for the driver.
	 *
144
	 * @param  Connection  $connection
145 146
	 * @return Grammar
	 */
147
	public static function grammar(Connection $connection)
148
	{
149 150
		$driver = $connection->driver();

151 152 153 154 155
		if (isset(\Laravel\Database::$registrar[$driver]))
		{
			return \Laravel\Database::$registrar[$driver]['schema']();
		}

156 157 158
		switch ($driver)
		{
			case 'mysql':
159
				return new Schema\Grammars\MySQL($connection);
160 161

			case 'pgsql':
162
				return new Schema\Grammars\Postgres($connection);
163 164

			case 'sqlsrv':
165
				return new Schema\Grammars\SQLServer($connection);
166 167

			case 'sqlite':
168
				return new Schema\Grammars\SQLite($connection);
169 170 171 172 173 174
		}

		throw new \Exception("Schema operations not supported for [$driver].");
	}

}