1: <?php namespace Laravel\Database\Schema;
2:
3: use Laravel\Fluent;
4:
5: class Table {
6:
7: /**
8: * The database table name.
9: *
10: * @var string
11: */
12: public $name;
13:
14: /**
15: * The database connection that should be used.
16: *
17: * @var string
18: */
19: public $connection;
20:
21: /**
22: * The engine that should be used for the table.
23: *
24: * @var string
25: */
26: public $engine;
27:
28: /**
29: * The columns that should be added to the table.
30: *
31: * @var array
32: */
33: public $columns = array();
34:
35: /**
36: * The commands that should be executed on the table.
37: *
38: * @var array
39: */
40: public $commands = array();
41:
42: /**
43: * The registered custom macros.
44: *
45: * @var array
46: */
47: public static $macros = array();
48:
49: /**
50: * Registers a custom macro.
51: *
52: * @param string $name
53: * @param Closure $macro
54: * @return void
55: */
56: public static function macro($name, $macro)
57: {
58: static::$macros[$name] = $macro;
59: }
60:
61: /**
62: * Create a new schema table instance.
63: *
64: * @param string $name
65: * @return void
66: */
67: public function __construct($name)
68: {
69: $this->name = $name;
70: }
71:
72: /**
73: * Indicate that the table should be created.
74: *
75: * @return Fluent
76: */
77: public function create()
78: {
79: return $this->command(__FUNCTION__);
80: }
81:
82: /**
83: * Create a new primary key on the table.
84: *
85: * @param string|array $columns
86: * @param string $name
87: * @return Fluent
88: */
89: public function primary($columns, $name = null)
90: {
91: return $this->key(__FUNCTION__, $columns, $name);
92: }
93:
94: /**
95: * Create a new unique index on the table.
96: *
97: * @param string|array $columns
98: * @param string $name
99: * @return Fluent
100: */
101: public function unique($columns, $name = null)
102: {
103: return $this->key(__FUNCTION__, $columns, $name);
104: }
105:
106: /**
107: * Create a new full-text index on the table.
108: *
109: * @param string|array $columns
110: * @param string $name
111: * @return Fluent
112: */
113: public function fulltext($columns, $name = null)
114: {
115: return $this->key(__FUNCTION__, $columns, $name);
116: }
117:
118: /**
119: * Create a new index on the table.
120: *
121: * @param string|array $columns
122: * @param string $name
123: * @return Fluent
124: */
125: public function index($columns, $name = null)
126: {
127: return $this->key(__FUNCTION__, $columns, $name);
128: }
129:
130: /**
131: * Add a foreign key constraint to the table.
132: *
133: * @param string|array $columns
134: * @param string $name
135: * @return Fluent
136: */
137: public function foreign($columns, $name = null)
138: {
139: return $this->key(__FUNCTION__, $columns, $name);
140: }
141:
142: /**
143: * Create a command for creating any index.
144: *
145: * @param string $type
146: * @param string|array $columns
147: * @param string $name
148: * @return Fluent
149: */
150: public function key($type, $columns, $name)
151: {
152: $columns = (array) $columns;
153:
154: // If no index name was specified, we will concatenate the columns and
155: // append the index type to the name to generate a unique name for
156: // the index that can be used when dropping indexes.
157: if (is_null($name))
158: {
159: $name = str_replace(array('-', '.'), '_', $this->name);
160:
161: $name = $name.'_'.implode('_', $columns).'_'.$type;
162: }
163:
164: return $this->command($type, compact('name', 'columns'));
165: }
166:
167: /**
168: * Rename the database table.
169: *
170: * @param string $name
171: * @return Fluent
172: */
173: public function rename($name)
174: {
175: return $this->command(__FUNCTION__, compact('name'));
176: }
177:
178: /**
179: * Drop the database table.
180: *
181: * @return Fluent
182: */
183: public function drop()
184: {
185: return $this->command(__FUNCTION__);
186: }
187:
188: /**
189: * Drop a column from the table.
190: *
191: * @param string|array $columns
192: * @return void
193: */
194: public function drop_column($columns)
195: {
196: return $this->command(__FUNCTION__, array('columns' => (array) $columns));
197: }
198:
199: /**
200: * Drop a primary key from the table.
201: *
202: * @param string $name
203: * @return void
204: */
205: public function drop_primary($name = null)
206: {
207: return $this->drop_key(__FUNCTION__, $name);
208: }
209:
210: /**
211: * Drop a unique index from the table.
212: *
213: * @param string $name
214: * @return void
215: */
216: public function drop_unique($name)
217: {
218: return $this->drop_key(__FUNCTION__, $name);
219: }
220:
221: /**
222: * Drop a full-text index from the table.
223: *
224: * @param string $name
225: * @return void
226: */
227: public function drop_fulltext($name)
228: {
229: return $this->drop_key(__FUNCTION__, $name);
230: }
231:
232: /**
233: * Drop an index from the table.
234: *
235: * @param string $name
236: * @return void
237: */
238: public function drop_index($name)
239: {
240: return $this->drop_key(__FUNCTION__, $name);
241: }
242:
243: /**
244: * Drop a foreign key constraint from the table.
245: *
246: * @param string $name
247: * @return void
248: */
249: public function drop_foreign($name)
250: {
251: return $this->drop_key(__FUNCTION__, $name);
252: }
253:
254: /**
255: * Create a command to drop any type of index.
256: *
257: * @param string $type
258: * @param string $name
259: * @return Fluent
260: */
261: protected function drop_key($type, $name)
262: {
263: return $this->command($type, compact('name'));
264: }
265:
266: /**
267: * Add an auto-incrementing integer to the table.
268: *
269: * @param string $name
270: * @return Fluent
271: */
272: public function increments($name)
273: {
274: return $this->integer($name, true);
275: }
276:
277: /**
278: * Add a string column to the table.
279: *
280: * @param string $name
281: * @param int $length
282: * @return Fluent
283: */
284: public function string($name, $length = 200)
285: {
286: return $this->column(__FUNCTION__, compact('name', 'length'));
287: }
288:
289: /**
290: * Add an integer column to the table.
291: *
292: * @param string $name
293: * @param bool $increment
294: * @return Fluent
295: */
296: public function integer($name, $increment = false)
297: {
298: return $this->column(__FUNCTION__, compact('name', 'increment'));
299: }
300:
301: /**
302: * Add a float column to the table.
303: *
304: * @param string $name
305: * @return Fluent
306: */
307: public function float($name)
308: {
309: return $this->column(__FUNCTION__, compact('name'));
310: }
311:
312: /**
313: * Add a decimal column to the table.
314: *
315: * @param string $name
316: * @param int $precision
317: * @param int $scale
318: * @return Fluent
319: */
320: public function decimal($name, $precision, $scale)
321: {
322: return $this->column(__FUNCTION__, compact('name', 'precision', 'scale'));
323: }
324:
325: /**
326: * Add a boolean column to the table.
327: *
328: * @param string $name
329: * @return Fluent
330: */
331: public function boolean($name)
332: {
333: return $this->column(__FUNCTION__, compact('name'));
334: }
335:
336: /**
337: * Create date-time columns for creation and update timestamps.
338: *
339: * @return void
340: */
341: public function timestamps()
342: {
343: $this->date('created_at');
344:
345: $this->date('updated_at');
346: }
347:
348: /**
349: * Add a date-time column to the table.
350: *
351: * @param string $name
352: * @return Fluent
353: */
354: public function date($name)
355: {
356: return $this->column(__FUNCTION__, compact('name'));
357: }
358:
359: /**
360: * Add a timestamp column to the table.
361: *
362: * @param string $name
363: * @return Fluent
364: */
365: public function timestamp($name)
366: {
367: return $this->column(__FUNCTION__, compact('name'));
368: }
369:
370: /**
371: * Add a text column to the table.
372: *
373: * @param string $name
374: * @return Fluent
375: */
376: public function text($name)
377: {
378: return $this->column(__FUNCTION__, compact('name'));
379: }
380:
381: /**
382: * Add a blob column to the table.
383: *
384: * @param string $name
385: * @return Fluent
386: */
387: public function blob($name)
388: {
389: return $this->column(__FUNCTION__, compact('name'));
390: }
391:
392: /**
393: * Set the database connection for the table operation.
394: *
395: * @param string $connection
396: * @return void
397: */
398: public function on($connection)
399: {
400: $this->connection = $connection;
401: }
402:
403: /**
404: * Determine if the schema table has a creation command.
405: *
406: * @return bool
407: */
408: public function creating()
409: {
410: return ! is_null(array_first($this->commands, function($key, $value)
411: {
412: return $value->type == 'create';
413: }));
414: }
415:
416: /**
417: * Create a new fluent command instance.
418: *
419: * @param string $type
420: * @param array $parameters
421: * @return Fluent
422: */
423: protected function command($type, $parameters = array())
424: {
425: $parameters = array_merge(compact('type'), $parameters);
426:
427: return $this->commands[] = new Fluent($parameters);
428: }
429:
430: /**
431: * Create a new fluent column instance.
432: *
433: * @param string $type
434: * @param array $parameters
435: * @return Fluent
436: */
437: protected function column($type, $parameters = array())
438: {
439: $parameters = array_merge(compact('type'), $parameters);
440:
441: return $this->columns[] = new Fluent($parameters);
442: }
443:
444: /**
445: * Dynamically handle calls to custom macros.
446: *
447: * @param string $method
448: * @param array $parameters
449: * @return mixed
450: */
451: public function __call($method, $parameters)
452: {
453: if (isset(static::$macros[$method]))
454: {
455: array_unshift($parameters, $this);
456: return call_user_func_array(static::$macros[$method], $parameters);
457: }
458:
459: throw new \Exception("Method [$method] does not exist.");
460: }
461:
462: }
463: