1: <?php namespace Laravel\Database;
2:
3: use Closure;
4: use Laravel\Fluent;
5: use Laravel\Database as DB;
6:
7: class Schema {
8:
9: /**
10: * Begin a fluent schema operation on a database table.
11: *
12: * @param string $table
13: * @param Closure $callback
14: * @return void
15: */
16: public static function table($table, $callback)
17: {
18: call_user_func($callback, $table = new Schema\Table($table));
19:
20: return static::execute($table);
21: }
22:
23: /**
24: * Create a new database table schema.
25: *
26: * @param string $table
27: * @param Closure $callback
28: * @return void
29: */
30: public static function create($table, $callback)
31: {
32: $table = new Schema\Table($table);
33:
34: // To indicate that the table is new and needs to be created, we'll run
35: // the "create" command on the table instance. This tells schema it is
36: // not simply a column modification operation.
37: $table->create();
38:
39: call_user_func($callback, $table);
40:
41: return static::execute($table);
42: }
43:
44: /**
45: * Rename a database table in the schema.
46: *
47: * @param string $table
48: * @param string $new_name
49: * @return void
50: */
51: public static function rename($table, $new_name)
52: {
53: $table = new Schema\Table($table);
54:
55: // To indicate that the table needs to be renamed, we will run the
56: // "rename" command on the table instance and pass the instance to
57: // the execute method as calling a Closure isn't needed.
58: $table->rename($new_name);
59:
60: return static::execute($table);
61: }
62:
63: /**
64: * Drop a database table from the schema.
65: *
66: * @param string $table
67: * @param string $connection
68: * @return void
69: */
70: public static function drop($table, $connection = null)
71: {
72: $table = new Schema\Table($table);
73:
74: $table->on($connection);
75:
76: // To indicate that the table needs to be dropped, we will run the
77: // "drop" command on the table instance and pass the instance to
78: // the execute method as calling a Closure isn't needed.
79: $table->drop();
80:
81: return static::execute($table);
82: }
83:
84: /**
85: * Execute the given schema operation against the database.
86: *
87: * @param Schema\Table $table
88: * @return void
89: */
90: public static function execute($table)
91: {
92: // The implications method is responsible for finding any fluently
93: // defined indexes on the schema table and adding the explicit
94: // commands that are needed for the schema instance.
95: static::implications($table);
96:
97: foreach ($table->commands as $command)
98: {
99: $connection = DB::connection($table->connection);
100:
101: $grammar = static::grammar($connection);
102:
103: // Each grammar has a function that corresponds to the command type and
104: // is for building that command's SQL. This lets the SQL syntax builds
105: // stay granular across various database systems.
106: if (method_exists($grammar, $method = $command->type))
107: {
108: $statements = $grammar->$method($table, $command);
109:
110: // Once we have the statements, we will cast them to an array even
111: // though not all of the commands return an array just in case it
112: // needs multiple queries to complete.
113: foreach ((array) $statements as $statement)
114: {
115: $connection->query($statement);
116: }
117: }
118: }
119: }
120:
121: /**
122: * Add any implicit commands to the schema table operation.
123: *
124: * @param Schema\Table $table
125: * @return void
126: */
127: protected static function implications($table)
128: {
129: // If the developer has specified columns for the table and the table is
130: // not being created, we'll assume they simply want to add the columns
131: // to the table and generate the add command.
132: if (count($table->columns) > 0 and ! $table->creating())
133: {
134: $command = new Fluent(array('type' => 'add'));
135:
136: array_unshift($table->commands, $command);
137: }
138:
139: // For some extra syntax sugar, we'll check for any implicit indexes
140: // on the table since the developer may specify the index type on
141: // the fluent column declaration for convenience.
142: foreach ($table->columns as $column)
143: {
144: foreach (array('primary', 'unique', 'fulltext', 'index') as $key)
145: {
146: if (isset($column->$key))
147: {
148: if ($column->$key === true)
149: {
150: $table->$key($column->name);
151: }
152: else
153: {
154: $table->$key($column->name, $column->$key);
155: }
156: }
157: }
158: }
159: }
160:
161: /**
162: * Create the appropriate schema grammar for the driver.
163: *
164: * @param Connection $connection
165: * @return Grammar
166: */
167: public static function grammar(Connection $connection)
168: {
169: $driver = $connection->driver();
170:
171: if (isset(\Laravel\Database::$registrar[$driver]))
172: {
173: return \Laravel\Database::$registrar[$driver]['schema']();
174: }
175:
176: switch ($driver)
177: {
178: case 'mysql':
179: return new Schema\Grammars\MySQL($connection);
180:
181: case 'pgsql':
182: return new Schema\Grammars\Postgres($connection);
183:
184: case 'sqlsrv':
185: return new Schema\Grammars\SQLServer($connection);
186:
187: case 'sqlite':
188: return new Schema\Grammars\SQLite($connection);
189: }
190:
191: throw new \Exception("Schema operations not supported for [$driver].");
192: }
193:
194: }
195: