/vendor/laravel/framework/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php

https://gitlab.com/ealexis.t/trends · PHP · 796 lines · 315 code · 89 blank · 392 comment · 19 complexity · 88ed941eee280221356e7dd81cc3342f MD5 · raw file

  1. <?php
  2. namespace Illuminate\Database\Schema\Grammars;
  3. use Illuminate\Support\Fluent;
  4. use Illuminate\Database\Connection;
  5. use Illuminate\Database\Schema\Blueprint;
  6. class MySqlGrammar extends Grammar
  7. {
  8. /**
  9. * The possible column modifiers.
  10. *
  11. * @var array
  12. */
  13. protected $modifiers = [
  14. 'VirtualAs', 'StoredAs', 'Unsigned', 'Charset', 'Collate', 'Nullable',
  15. 'Default', 'Increment', 'Comment', 'After', 'First',
  16. ];
  17. /**
  18. * The possible column serials.
  19. *
  20. * @var array
  21. */
  22. protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
  23. /**
  24. * Compile the query to determine the list of tables.
  25. *
  26. * @return string
  27. */
  28. public function compileTableExists()
  29. {
  30. return 'select * from information_schema.tables where table_schema = ? and table_name = ?';
  31. }
  32. /**
  33. * Compile the query to determine the list of columns.
  34. *
  35. * @return string
  36. */
  37. public function compileColumnExists()
  38. {
  39. return 'select column_name from information_schema.columns where table_schema = ? and table_name = ?';
  40. }
  41. /**
  42. * Compile a create table command.
  43. *
  44. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  45. * @param \Illuminate\Support\Fluent $command
  46. * @param \Illuminate\Database\Connection $connection
  47. * @return string
  48. */
  49. public function compileCreate(Blueprint $blueprint, Fluent $command, Connection $connection)
  50. {
  51. $columns = implode(', ', $this->getColumns($blueprint));
  52. $sql = $blueprint->temporary ? 'create temporary' : 'create';
  53. $sql .= ' table '.$this->wrapTable($blueprint)." ($columns)";
  54. // Once we have the primary SQL, we can add the encoding option to the SQL for
  55. // the table. Then, we can check if a storage engine has been supplied for
  56. // the table. If so, we will add the engine declaration to the SQL query.
  57. $sql = $this->compileCreateEncoding($sql, $connection, $blueprint);
  58. if (isset($blueprint->engine)) {
  59. $sql .= ' engine = '.$blueprint->engine;
  60. } elseif (! is_null($engine = $connection->getConfig('engine'))) {
  61. $sql .= ' engine = '.$engine;
  62. }
  63. return $sql;
  64. }
  65. /**
  66. * Append the character set specifications to a command.
  67. *
  68. * @param string $sql
  69. * @param \Illuminate\Database\Connection $connection
  70. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  71. * @return string
  72. */
  73. protected function compileCreateEncoding($sql, Connection $connection, Blueprint $blueprint)
  74. {
  75. if (isset($blueprint->charset)) {
  76. $sql .= ' default character set '.$blueprint->charset;
  77. } elseif (! is_null($charset = $connection->getConfig('charset'))) {
  78. $sql .= ' default character set '.$charset;
  79. }
  80. if (isset($blueprint->collation)) {
  81. $sql .= ' collate '.$blueprint->collation;
  82. } elseif (! is_null($collation = $connection->getConfig('collation'))) {
  83. $sql .= ' collate '.$collation;
  84. }
  85. return $sql;
  86. }
  87. /**
  88. * Compile an add column command.
  89. *
  90. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  91. * @param \Illuminate\Support\Fluent $command
  92. * @return string
  93. */
  94. public function compileAdd(Blueprint $blueprint, Fluent $command)
  95. {
  96. $table = $this->wrapTable($blueprint);
  97. $columns = $this->prefixArray('add', $this->getColumns($blueprint));
  98. return 'alter table '.$table.' '.implode(', ', $columns);
  99. }
  100. /**
  101. * Compile a primary key command.
  102. *
  103. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  104. * @param \Illuminate\Support\Fluent $command
  105. * @return string
  106. */
  107. public function compilePrimary(Blueprint $blueprint, Fluent $command)
  108. {
  109. $command->name(null);
  110. return $this->compileKey($blueprint, $command, 'primary key');
  111. }
  112. /**
  113. * Compile a unique key command.
  114. *
  115. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  116. * @param \Illuminate\Support\Fluent $command
  117. * @return string
  118. */
  119. public function compileUnique(Blueprint $blueprint, Fluent $command)
  120. {
  121. return $this->compileKey($blueprint, $command, 'unique');
  122. }
  123. /**
  124. * Compile a plain index key command.
  125. *
  126. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  127. * @param \Illuminate\Support\Fluent $command
  128. * @return string
  129. */
  130. public function compileIndex(Blueprint $blueprint, Fluent $command)
  131. {
  132. return $this->compileKey($blueprint, $command, 'index');
  133. }
  134. /**
  135. * Compile an index creation command.
  136. *
  137. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  138. * @param \Illuminate\Support\Fluent $command
  139. * @param string $type
  140. * @return string
  141. */
  142. protected function compileKey(Blueprint $blueprint, Fluent $command, $type)
  143. {
  144. $columns = $this->columnize($command->columns);
  145. $table = $this->wrapTable($blueprint);
  146. $index = $this->wrap($command->index);
  147. return "alter table {$table} add {$type} {$index}($columns)";
  148. }
  149. /**
  150. * Compile a drop table command.
  151. *
  152. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  153. * @param \Illuminate\Support\Fluent $command
  154. * @return string
  155. */
  156. public function compileDrop(Blueprint $blueprint, Fluent $command)
  157. {
  158. return 'drop table '.$this->wrapTable($blueprint);
  159. }
  160. /**
  161. * Compile a drop table (if exists) command.
  162. *
  163. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  164. * @param \Illuminate\Support\Fluent $command
  165. * @return string
  166. */
  167. public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
  168. {
  169. return 'drop table if exists '.$this->wrapTable($blueprint);
  170. }
  171. /**
  172. * Compile a drop column command.
  173. *
  174. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  175. * @param \Illuminate\Support\Fluent $command
  176. * @return string
  177. */
  178. public function compileDropColumn(Blueprint $blueprint, Fluent $command)
  179. {
  180. $columns = $this->prefixArray('drop', $this->wrapArray($command->columns));
  181. $table = $this->wrapTable($blueprint);
  182. return 'alter table '.$table.' '.implode(', ', $columns);
  183. }
  184. /**
  185. * Compile a drop primary key command.
  186. *
  187. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  188. * @param \Illuminate\Support\Fluent $command
  189. * @return string
  190. */
  191. public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
  192. {
  193. return 'alter table '.$this->wrapTable($blueprint).' drop primary key';
  194. }
  195. /**
  196. * Compile a drop unique key command.
  197. *
  198. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  199. * @param \Illuminate\Support\Fluent $command
  200. * @return string
  201. */
  202. public function compileDropUnique(Blueprint $blueprint, Fluent $command)
  203. {
  204. $table = $this->wrapTable($blueprint);
  205. $index = $this->wrap($command->index);
  206. return "alter table {$table} drop index {$index}";
  207. }
  208. /**
  209. * Compile a drop index command.
  210. *
  211. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  212. * @param \Illuminate\Support\Fluent $command
  213. * @return string
  214. */
  215. public function compileDropIndex(Blueprint $blueprint, Fluent $command)
  216. {
  217. $table = $this->wrapTable($blueprint);
  218. $index = $this->wrap($command->index);
  219. return "alter table {$table} drop index {$index}";
  220. }
  221. /**
  222. * Compile a drop foreign key command.
  223. *
  224. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  225. * @param \Illuminate\Support\Fluent $command
  226. * @return string
  227. */
  228. public function compileDropForeign(Blueprint $blueprint, Fluent $command)
  229. {
  230. $table = $this->wrapTable($blueprint);
  231. $index = $this->wrap($command->index);
  232. return "alter table {$table} drop foreign key {$index}";
  233. }
  234. /**
  235. * Compile a rename table command.
  236. *
  237. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  238. * @param \Illuminate\Support\Fluent $command
  239. * @return string
  240. */
  241. public function compileRename(Blueprint $blueprint, Fluent $command)
  242. {
  243. $from = $this->wrapTable($blueprint);
  244. return "rename table {$from} to ".$this->wrapTable($command->to);
  245. }
  246. /**
  247. * Compile the command to enable foreign key constraints.
  248. *
  249. * @return string
  250. */
  251. public function compileEnableForeignKeyConstraints()
  252. {
  253. return 'SET FOREIGN_KEY_CHECKS=1;';
  254. }
  255. /**
  256. * Compile the command to disable foreign key constraints.
  257. *
  258. * @return string
  259. */
  260. public function compileDisableForeignKeyConstraints()
  261. {
  262. return 'SET FOREIGN_KEY_CHECKS=0;';
  263. }
  264. /**
  265. * Create the column definition for a char type.
  266. *
  267. * @param \Illuminate\Support\Fluent $column
  268. * @return string
  269. */
  270. protected function typeChar(Fluent $column)
  271. {
  272. return "char({$column->length})";
  273. }
  274. /**
  275. * Create the column definition for a string type.
  276. *
  277. * @param \Illuminate\Support\Fluent $column
  278. * @return string
  279. */
  280. protected function typeString(Fluent $column)
  281. {
  282. return "varchar({$column->length})";
  283. }
  284. /**
  285. * Create the column definition for a text type.
  286. *
  287. * @param \Illuminate\Support\Fluent $column
  288. * @return string
  289. */
  290. protected function typeText(Fluent $column)
  291. {
  292. return 'text';
  293. }
  294. /**
  295. * Create the column definition for a medium text type.
  296. *
  297. * @param \Illuminate\Support\Fluent $column
  298. * @return string
  299. */
  300. protected function typeMediumText(Fluent $column)
  301. {
  302. return 'mediumtext';
  303. }
  304. /**
  305. * Create the column definition for a long text type.
  306. *
  307. * @param \Illuminate\Support\Fluent $column
  308. * @return string
  309. */
  310. protected function typeLongText(Fluent $column)
  311. {
  312. return 'longtext';
  313. }
  314. /**
  315. * Create the column definition for a big integer type.
  316. *
  317. * @param \Illuminate\Support\Fluent $column
  318. * @return string
  319. */
  320. protected function typeBigInteger(Fluent $column)
  321. {
  322. return 'bigint';
  323. }
  324. /**
  325. * Create the column definition for a integer type.
  326. *
  327. * @param \Illuminate\Support\Fluent $column
  328. * @return string
  329. */
  330. protected function typeInteger(Fluent $column)
  331. {
  332. return 'int';
  333. }
  334. /**
  335. * Create the column definition for a medium integer type.
  336. *
  337. * @param \Illuminate\Support\Fluent $column
  338. * @return string
  339. */
  340. protected function typeMediumInteger(Fluent $column)
  341. {
  342. return 'mediumint';
  343. }
  344. /**
  345. * Create the column definition for a tiny integer type.
  346. *
  347. * @param \Illuminate\Support\Fluent $column
  348. * @return string
  349. */
  350. protected function typeTinyInteger(Fluent $column)
  351. {
  352. return 'tinyint';
  353. }
  354. /**
  355. * Create the column definition for a small integer type.
  356. *
  357. * @param \Illuminate\Support\Fluent $column
  358. * @return string
  359. */
  360. protected function typeSmallInteger(Fluent $column)
  361. {
  362. return 'smallint';
  363. }
  364. /**
  365. * Create the column definition for a float type.
  366. *
  367. * @param \Illuminate\Support\Fluent $column
  368. * @return string
  369. */
  370. protected function typeFloat(Fluent $column)
  371. {
  372. return $this->typeDouble($column);
  373. }
  374. /**
  375. * Create the column definition for a double type.
  376. *
  377. * @param \Illuminate\Support\Fluent $column
  378. * @return string
  379. */
  380. protected function typeDouble(Fluent $column)
  381. {
  382. if ($column->total && $column->places) {
  383. return "double({$column->total}, {$column->places})";
  384. }
  385. return 'double';
  386. }
  387. /**
  388. * Create the column definition for a decimal type.
  389. *
  390. * @param \Illuminate\Support\Fluent $column
  391. * @return string
  392. */
  393. protected function typeDecimal(Fluent $column)
  394. {
  395. return "decimal({$column->total}, {$column->places})";
  396. }
  397. /**
  398. * Create the column definition for a boolean type.
  399. *
  400. * @param \Illuminate\Support\Fluent $column
  401. * @return string
  402. */
  403. protected function typeBoolean(Fluent $column)
  404. {
  405. return 'tinyint(1)';
  406. }
  407. /**
  408. * Create the column definition for an enum type.
  409. *
  410. * @param \Illuminate\Support\Fluent $column
  411. * @return string
  412. */
  413. protected function typeEnum(Fluent $column)
  414. {
  415. return "enum('".implode("', '", $column->allowed)."')";
  416. }
  417. /**
  418. * Create the column definition for a json type.
  419. *
  420. * @param \Illuminate\Support\Fluent $column
  421. * @return string
  422. */
  423. protected function typeJson(Fluent $column)
  424. {
  425. return 'json';
  426. }
  427. /**
  428. * Create the column definition for a jsonb type.
  429. *
  430. * @param \Illuminate\Support\Fluent $column
  431. * @return string
  432. */
  433. protected function typeJsonb(Fluent $column)
  434. {
  435. return 'json';
  436. }
  437. /**
  438. * Create the column definition for a date type.
  439. *
  440. * @param \Illuminate\Support\Fluent $column
  441. * @return string
  442. */
  443. protected function typeDate(Fluent $column)
  444. {
  445. return 'date';
  446. }
  447. /**
  448. * Create the column definition for a date-time type.
  449. *
  450. * @param \Illuminate\Support\Fluent $column
  451. * @return string
  452. */
  453. protected function typeDateTime(Fluent $column)
  454. {
  455. return 'datetime';
  456. }
  457. /**
  458. * Create the column definition for a date-time type.
  459. *
  460. * @param \Illuminate\Support\Fluent $column
  461. * @return string
  462. */
  463. protected function typeDateTimeTz(Fluent $column)
  464. {
  465. return 'datetime';
  466. }
  467. /**
  468. * Create the column definition for a time type.
  469. *
  470. * @param \Illuminate\Support\Fluent $column
  471. * @return string
  472. */
  473. protected function typeTime(Fluent $column)
  474. {
  475. return 'time';
  476. }
  477. /**
  478. * Create the column definition for a time type.
  479. *
  480. * @param \Illuminate\Support\Fluent $column
  481. * @return string
  482. */
  483. protected function typeTimeTz(Fluent $column)
  484. {
  485. return 'time';
  486. }
  487. /**
  488. * Create the column definition for a timestamp type.
  489. *
  490. * @param \Illuminate\Support\Fluent $column
  491. * @return string
  492. */
  493. protected function typeTimestamp(Fluent $column)
  494. {
  495. if ($column->useCurrent) {
  496. return 'timestamp default CURRENT_TIMESTAMP';
  497. }
  498. return 'timestamp';
  499. }
  500. /**
  501. * Create the column definition for a timestamp type.
  502. *
  503. * @param \Illuminate\Support\Fluent $column
  504. * @return string
  505. */
  506. protected function typeTimestampTz(Fluent $column)
  507. {
  508. if ($column->useCurrent) {
  509. return 'timestamp default CURRENT_TIMESTAMP';
  510. }
  511. return 'timestamp';
  512. }
  513. /**
  514. * Create the column definition for a binary type.
  515. *
  516. * @param \Illuminate\Support\Fluent $column
  517. * @return string
  518. */
  519. protected function typeBinary(Fluent $column)
  520. {
  521. return 'blob';
  522. }
  523. /**
  524. * Create the column definition for a uuid type.
  525. *
  526. * @param \Illuminate\Support\Fluent $column
  527. * @return string
  528. */
  529. protected function typeUuid(Fluent $column)
  530. {
  531. return 'char(36)';
  532. }
  533. /**
  534. * Create the column definition for an IP address type.
  535. *
  536. * @param \Illuminate\Support\Fluent $column
  537. * @return string
  538. */
  539. protected function typeIpAddress(Fluent $column)
  540. {
  541. return 'varchar(45)';
  542. }
  543. /**
  544. * Create the column definition for a MAC address type.
  545. *
  546. * @param \Illuminate\Support\Fluent $column
  547. * @return string
  548. */
  549. protected function typeMacAddress(Fluent $column)
  550. {
  551. return 'varchar(17)';
  552. }
  553. /**
  554. * Get the SQL for a generated virtual column modifier.
  555. *
  556. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  557. * @param \Illuminate\Support\Fluent $column
  558. * @return string|null
  559. */
  560. protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
  561. {
  562. if (! is_null($column->virtualAs)) {
  563. return " as ({$column->virtualAs})";
  564. }
  565. }
  566. /**
  567. * Get the SQL for a generated stored column modifier.
  568. *
  569. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  570. * @param \Illuminate\Support\Fluent $column
  571. * @return string|null
  572. */
  573. protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
  574. {
  575. if (! is_null($column->storedAs)) {
  576. return " as ({$column->storedAs}) stored";
  577. }
  578. }
  579. /**
  580. * Get the SQL for an unsigned column modifier.
  581. *
  582. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  583. * @param \Illuminate\Support\Fluent $column
  584. * @return string|null
  585. */
  586. protected function modifyUnsigned(Blueprint $blueprint, Fluent $column)
  587. {
  588. if ($column->unsigned) {
  589. return ' unsigned';
  590. }
  591. }
  592. /**
  593. * Get the SQL for a character set column modifier.
  594. *
  595. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  596. * @param \Illuminate\Support\Fluent $column
  597. * @return string|null
  598. */
  599. protected function modifyCharset(Blueprint $blueprint, Fluent $column)
  600. {
  601. if (! is_null($column->charset)) {
  602. return ' character set '.$column->charset;
  603. }
  604. }
  605. /**
  606. * Get the SQL for a collation column modifier.
  607. *
  608. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  609. * @param \Illuminate\Support\Fluent $column
  610. * @return string|null
  611. */
  612. protected function modifyCollate(Blueprint $blueprint, Fluent $column)
  613. {
  614. if (! is_null($column->collation)) {
  615. return ' collate '.$column->collation;
  616. }
  617. }
  618. /**
  619. * Get the SQL for a nullable column modifier.
  620. *
  621. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  622. * @param \Illuminate\Support\Fluent $column
  623. * @return string|null
  624. */
  625. protected function modifyNullable(Blueprint $blueprint, Fluent $column)
  626. {
  627. return $column->nullable ? ' null' : ' not null';
  628. }
  629. /**
  630. * Get the SQL for a default column modifier.
  631. *
  632. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  633. * @param \Illuminate\Support\Fluent $column
  634. * @return string|null
  635. */
  636. protected function modifyDefault(Blueprint $blueprint, Fluent $column)
  637. {
  638. if (! is_null($column->default)) {
  639. return ' default '.$this->getDefaultValue($column->default);
  640. }
  641. }
  642. /**
  643. * Get the SQL for an auto-increment column modifier.
  644. *
  645. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  646. * @param \Illuminate\Support\Fluent $column
  647. * @return string|null
  648. */
  649. protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
  650. {
  651. if (in_array($column->type, $this->serials) && $column->autoIncrement) {
  652. return ' auto_increment primary key';
  653. }
  654. }
  655. /**
  656. * Get the SQL for a "first" column modifier.
  657. *
  658. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  659. * @param \Illuminate\Support\Fluent $column
  660. * @return string|null
  661. */
  662. protected function modifyFirst(Blueprint $blueprint, Fluent $column)
  663. {
  664. if (! is_null($column->first)) {
  665. return ' first';
  666. }
  667. }
  668. /**
  669. * Get the SQL for an "after" column modifier.
  670. *
  671. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  672. * @param \Illuminate\Support\Fluent $column
  673. * @return string|null
  674. */
  675. protected function modifyAfter(Blueprint $blueprint, Fluent $column)
  676. {
  677. if (! is_null($column->after)) {
  678. return ' after '.$this->wrap($column->after);
  679. }
  680. }
  681. /**
  682. * Get the SQL for a "comment" column modifier.
  683. *
  684. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  685. * @param \Illuminate\Support\Fluent $column
  686. * @return string|null
  687. */
  688. protected function modifyComment(Blueprint $blueprint, Fluent $column)
  689. {
  690. if (! is_null($column->comment)) {
  691. return ' comment "'.$column->comment.'"';
  692. }
  693. }
  694. /**
  695. * Wrap a single string in keyword identifiers.
  696. *
  697. * @param string $value
  698. * @return string
  699. */
  700. protected function wrapValue($value)
  701. {
  702. if ($value === '*') {
  703. return $value;
  704. }
  705. return '`'.str_replace('`', '``', $value).'`';
  706. }
  707. }