PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Illuminate/Database/Schema/Blueprint.php

https://github.com/Fale/framework
PHP | 622 lines | 243 code | 71 blank | 308 comment | 9 complexity | 8310e6e52d1beceb5a4488d02997289c MD5 | raw file
  1. <?php namespace Illuminate\Database\Schema;
  2. use Closure;
  3. use Illuminate\Support\Fluent;
  4. use Illuminate\Database\Connection;
  5. use Illuminate\Database\Schema\Grammars\Grammar;
  6. class Blueprint {
  7. /**
  8. * The table the blueprint describes.
  9. *
  10. * @var string
  11. */
  12. protected $table;
  13. /**
  14. * The columns that should be added to the table.
  15. *
  16. * @var array
  17. */
  18. protected $columns = array();
  19. /**
  20. * The commands that should be run for the table.
  21. *
  22. * @var array
  23. */
  24. protected $commands = array();
  25. /**
  26. * Create a new schema blueprint.
  27. *
  28. * @param string $table
  29. * @param Closure $callback
  30. * @return void
  31. */
  32. public function __construct($table, Closure $callback = null)
  33. {
  34. $this->table = $table;
  35. if ( ! is_null($callback)) $callback($this);
  36. }
  37. /**
  38. * Execute the blueprint against the database.
  39. *
  40. * @param Illuminate\Database\Connection $connection
  41. * @param Illuminate\Database\Schema\Grammars\Grammar $grammar
  42. * @return void
  43. */
  44. public function build(Connection $connection, Grammar $grammar)
  45. {
  46. foreach ($this->toSql($grammar) as $statement)
  47. {
  48. $connection->statement($statement);
  49. }
  50. }
  51. /**
  52. * Get the raw SQL statements for the blueprint.
  53. *
  54. * @param Illuminate\Database\Schema\Grammars\Grammar $grammar
  55. * @return array
  56. */
  57. public function toSql(Grammar $grammar)
  58. {
  59. $this->addImpliedCommands();
  60. $statements = array();
  61. // Each type of command has a corresponding compiler function on the schema
  62. // grammar which is used to build the necessary SQL statements to build
  63. // the blueprint element, so we'll just call that compilers function.
  64. foreach ($this->commands as $command)
  65. {
  66. $method = 'compile'.ucfirst($command->name);
  67. if (method_exists($grammar, $method))
  68. {
  69. if ( ! is_null($sql = $grammar->$method($this, $command)))
  70. {
  71. $statements = array_merge($statements, (array) $sql);
  72. }
  73. }
  74. }
  75. return $statements;
  76. }
  77. /**
  78. * Add the commands that are implied by the blueprint.
  79. *
  80. * @return void
  81. */
  82. protected function addImpliedCommands()
  83. {
  84. if (count($this->columns) > 0 and ! $this->creating())
  85. {
  86. array_unshift($this->commands, $this->createCommand('add'));
  87. }
  88. $this->addFluentIndexes();
  89. }
  90. /**
  91. * Add the index commands fluently specified on columns.
  92. *
  93. * @return void
  94. */
  95. protected function addFluentIndexes()
  96. {
  97. foreach ($this->columns as $column)
  98. {
  99. foreach (array('primary', 'unique', 'index') as $index)
  100. {
  101. // If the index has been specified on the given column, but is simply
  102. // equal to "true" (boolean), no name has been specified for this
  103. // index, so we will simply call the index methods without one.
  104. if ($column->$index === true)
  105. {
  106. $this->$index($column->name);
  107. continue 2;
  108. }
  109. // If the index has been specified on the column and it is something
  110. // other than boolean true, we will assume a name was provided on
  111. // the index specification, and pass in the name to the method.
  112. elseif (isset($column->$index))
  113. {
  114. $this->$index($column->name, $column->$index);
  115. continue 2;
  116. }
  117. }
  118. }
  119. }
  120. /**
  121. * Determine if the blueprint has a create command.
  122. *
  123. * @return bool
  124. */
  125. protected function creating()
  126. {
  127. foreach ($this->commands as $command)
  128. {
  129. if ($command->name == 'create') return true;
  130. }
  131. return false;
  132. }
  133. /**
  134. * Indicate that the table needs to be created.
  135. *
  136. * @return Illuminate\Support\Fluent
  137. */
  138. public function create()
  139. {
  140. return $this->addCommand('create');
  141. }
  142. /**
  143. * Indicate that the table should be dropped.
  144. *
  145. * @return Illuminate\Support\Fluent
  146. */
  147. public function drop()
  148. {
  149. return $this->addCommand('drop');
  150. }
  151. /**
  152. * Indicate that the table should be dropped if it exists.
  153. *
  154. * @return Illuminate\Support\Fluent
  155. */
  156. public function dropIfExists()
  157. {
  158. return $this->addCommand('dropIfExists');
  159. }
  160. /**
  161. * Indicate that the given columns should be dropped.
  162. *
  163. * @param string|array $columns
  164. * @return Illuminate\Support\Fluent
  165. */
  166. public function dropColumn($columns)
  167. {
  168. $columns = (array) $columns;
  169. return $this->addCommand('dropColumn', compact('columns'));
  170. }
  171. /**
  172. * Indicate that the given columns should be dropped.
  173. *
  174. * @param dynamic
  175. * @return Illuminate\Support\Fluent
  176. */
  177. public function dropColumns()
  178. {
  179. return $this->dropColumn(func_get_args());
  180. }
  181. /**
  182. * Indicate that the given primary key should be dropped.
  183. *
  184. * @param string|array $index
  185. * @return Illuminate\Support\Fluent
  186. */
  187. public function dropPrimary($index = null)
  188. {
  189. return $this->dropIndexCommand('dropPrimary', $index);
  190. }
  191. /**
  192. * Indicate that the given unique key should be dropped.
  193. *
  194. * @param string|array $index
  195. * @return Illuminate\Support\Fluent
  196. */
  197. public function dropUnique($index)
  198. {
  199. return $this->dropIndexCommand('dropUnique', $index);
  200. }
  201. /**
  202. * Indicate that the given index should be dropped.
  203. *
  204. * @param string|array $index
  205. * @return Illuminate\Support\Fluent
  206. */
  207. public function dropIndex($index)
  208. {
  209. return $this->dropIndexCommand('dropIndex', $index);
  210. }
  211. /**
  212. * Indicate that the given foreign key should be dropped.
  213. *
  214. * @param string $index
  215. * @return Illuminate\Support\Fluent
  216. */
  217. public function dropForeign($index)
  218. {
  219. return $this->dropIndexCommand('dropForeign', $index);
  220. }
  221. /**
  222. * Rename the table to a given name.
  223. *
  224. * @param string $to
  225. * @return Illuminate\Support\Fluent
  226. */
  227. public function rename($to)
  228. {
  229. return $this->addCommand('rename', compact('to'));
  230. }
  231. /**
  232. * Specify the primary key(s) for the table.
  233. *
  234. * @param string|array $columns
  235. * @param string $name
  236. * @return Illuminate\Support\Fluent
  237. */
  238. public function primary($columns, $name = null)
  239. {
  240. return $this->indexCommand('primary', $columns, $name);
  241. }
  242. /**
  243. * Specify a unique index for the table.
  244. *
  245. * @param string|array $columns
  246. * @param string $name
  247. * @return Illuminate\Support\Fluent
  248. */
  249. public function unique($columns, $name = null)
  250. {
  251. return $this->indexCommand('unique', $columns, $name);
  252. }
  253. /**
  254. * Specify an index for the table.
  255. *
  256. * @param string|array $columns
  257. * @param string $name
  258. * @return Illuminate\Support\Fluent
  259. */
  260. public function index($columns, $name = null)
  261. {
  262. return $this->indexCommand('index', $columns, $name);
  263. }
  264. /**
  265. * Specify a foreign key for the table.
  266. *
  267. * @param string|array $columns
  268. * @param string $name
  269. * @return Illuminate\Support\Fluent
  270. */
  271. public function foreign($columns, $name = null)
  272. {
  273. return $this->indexCommand('foreign', $columns, $name);
  274. }
  275. /**
  276. * Create a new auto-incrementing column on the table.
  277. *
  278. * @param string $column
  279. * @return Illuminate\Support\Fluent
  280. */
  281. public function increments($column)
  282. {
  283. return $this->unsignedInteger($column, true);
  284. }
  285. /**
  286. * Create a new string column on the table.
  287. *
  288. * @param string $column
  289. * @param int $length
  290. * @return Illuminate\Support\Fluent
  291. */
  292. public function string($column, $length = 255)
  293. {
  294. return $this->addColumn('string', $column, compact('length'));
  295. }
  296. /**
  297. * Create a new text column on the table.
  298. *
  299. * @param string $column
  300. * @return Illuminate\Support\Fluent
  301. */
  302. public function text($column)
  303. {
  304. return $this->addColumn('text', $column);
  305. }
  306. /**
  307. * Create a new integer column on the table.
  308. *
  309. * @param string $column
  310. * @param bool $autoIncrement
  311. * @param bool $unsigned
  312. * @return Illuminate\Support\Fluent
  313. */
  314. public function integer($column, $autoIncrement = false, $unsigned = false)
  315. {
  316. return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
  317. }
  318. /**
  319. * Create a new unsigned integer column on the table.
  320. *
  321. * @param string $column
  322. * @param bool $autoIncrement
  323. * @param bool $unsigned
  324. * @return Illuminate\Support\Fluent
  325. */
  326. public function unsignedInteger($column, $autoIncrement = false)
  327. {
  328. return $this->integer($column, $autoIncrement, true);
  329. }
  330. /**
  331. * Create a new float column on the table.
  332. *
  333. * @param string $column
  334. * @param int $total
  335. * @param int $places
  336. * @return Illuminate\Support\Fluent
  337. */
  338. public function float($column, $total = 8, $places = 2)
  339. {
  340. return $this->addColumn('float', $column, compact('total', 'places'));
  341. }
  342. /**
  343. * Create a new decimal column on the table.
  344. *
  345. * @param string $column
  346. * @param int $total
  347. * @param int $places
  348. * @return Illuminate\Support\Fluent
  349. */
  350. public function decimal($column, $total = 8, $places = 2)
  351. {
  352. return $this->addColumn('decimal', $column, compact('total', 'places'));
  353. }
  354. /**
  355. * Create a new boolean column on the table.
  356. *
  357. * @param string $column
  358. * @return Illuminate\Support\Fluent
  359. */
  360. public function boolean($column)
  361. {
  362. return $this->addColumn('boolean', $column);
  363. }
  364. /**
  365. * Create a new enum column on the table.
  366. *
  367. * @param string $column
  368. * @param array $allowed
  369. * @return Illuminate\Support\Fluent
  370. */
  371. public function enum($column, array $allowed)
  372. {
  373. return $this->addColumn('enum', $column, compact('allowed'));
  374. }
  375. /**
  376. * Create a new date column on the table.
  377. *
  378. * @param string $column
  379. * @return Illuminate\Support\Fluent
  380. */
  381. public function date($column)
  382. {
  383. return $this->addColumn('date', $column);
  384. }
  385. /**
  386. * Create a new date-time column on the table.
  387. *
  388. * @param string $column
  389. * @return Illuminate\Support\Fluent
  390. */
  391. public function dateTime($column)
  392. {
  393. return $this->addColumn('dateTime', $column);
  394. }
  395. /**
  396. * Create a new time column on the table.
  397. *
  398. * @param string $column
  399. * @return Illuminate\Support\Fluent
  400. */
  401. public function time($column)
  402. {
  403. return $this->addColumn('time', $column);
  404. }
  405. /**
  406. * Create a new timestamp column on the table.
  407. *
  408. * @param string $column
  409. * @return Illuminate\Support\Fluent
  410. */
  411. public function timestamp($column)
  412. {
  413. return $this->addColumn('timestamp', $column);
  414. }
  415. /**
  416. * Add creation and update timestamps to the table.
  417. *
  418. * @return void
  419. */
  420. public function timestamps()
  421. {
  422. $this->timestamp('created_at');
  423. $this->timestamp('updated_at');
  424. }
  425. /**
  426. * Create a new binary column on the table.
  427. *
  428. * @param string $column
  429. * @return Illuminate\Support\Fluent
  430. */
  431. public function binary($column)
  432. {
  433. return $this->addColumn('binary', $column);
  434. }
  435. /**
  436. * Create a new drop index command on the blueprint.
  437. *
  438. * @param string $type
  439. * @param string|array $index
  440. * @return Illuminate\Support\Fluent
  441. */
  442. protected function dropIndexCommand($type, $index)
  443. {
  444. $columns = array();
  445. // If the given "index" is actually an array of columns, the developer means
  446. // to drop an index merely by specifying the columns involved without the
  447. // conventional name, so we will built the index name from the columns.
  448. if (is_array($index))
  449. {
  450. $columns = $index;
  451. $index = null;
  452. }
  453. return $this->indexCommand($type, $columns, $index);
  454. }
  455. /**
  456. * Add a new index command to the blueprint.
  457. *
  458. * @param string $type
  459. * @param string|array $columns
  460. * @param string $index
  461. * @return Illuminate\Support\Fluent
  462. */
  463. protected function indexCommand($type, $columns, $index)
  464. {
  465. $columns = (array) $columns;
  466. // If no name was specified for this index, we will create one using a basic
  467. // convention of the table name, followed by the columns, followed by an
  468. // index type, such as primary or index, which makes the index unique.
  469. if (is_null($index))
  470. {
  471. $index = $this->createIndexName($type, $columns);
  472. }
  473. return $this->addCommand($type, compact('index', 'columns'));
  474. }
  475. /**
  476. * Create a default index name for the table.
  477. *
  478. * @param string $type
  479. * @param array $columns
  480. * @return string
  481. */
  482. protected function createIndexName($type, array $columns)
  483. {
  484. $table = str_replace(array('-', '.'), '_', $this->table);
  485. return strtolower($table.'_'.implode('_', $columns).'_'.$type);
  486. }
  487. /**
  488. * Add a new column to the blueprint.
  489. *
  490. * @param string $type
  491. * @param string $name
  492. * @param array $parameters
  493. * @return Illuminate\Support\Fluent
  494. */
  495. protected function addColumn($type, $name, array $parameters = array())
  496. {
  497. $attributes = array_merge(compact('type', 'name'), $parameters);
  498. $this->columns[] = $column = new Fluent($attributes);
  499. return $column;
  500. }
  501. /**
  502. * Add a new command to the blueprint.
  503. *
  504. * @param string $name
  505. * @param array $parameters
  506. * @return Illuminate\Support\Fluent
  507. */
  508. protected function addCommand($name, array $parameters = array())
  509. {
  510. $this->commands[] = $command = $this->createCommand($name, $parameters);
  511. return $command;
  512. }
  513. /**
  514. * Create a new Fluent command.
  515. *
  516. * @param string $name
  517. * @param array $parameters
  518. * @return Illuminate\Support\Fluent
  519. */
  520. protected function createCommand($name, array $parameters = array())
  521. {
  522. return new Fluent(array_merge(compact('name'), $parameters));
  523. }
  524. /**
  525. * Get the table the blueprint describes.
  526. *
  527. * @return string
  528. */
  529. public function getTable()
  530. {
  531. return $this->table;
  532. }
  533. /**
  534. * Get the columns that should be added.
  535. *
  536. * @return array
  537. */
  538. public function getColumns()
  539. {
  540. return $this->columns;
  541. }
  542. /**
  543. * Get the commands on the blueprint.
  544. *
  545. * @return array
  546. */
  547. public function getCommands()
  548. {
  549. return $this->commands;
  550. }
  551. }