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

https://gitlab.com/Pasantias/pasantiasASLG · PHP · 625 lines · 239 code · 79 blank · 307 comment · 8 complexity · 0d0b8ffd255593d89fcafee4ff3533ef 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 SQLiteGrammar extends Grammar
  7. {
  8. /**
  9. * The possible column modifiers.
  10. *
  11. * @var array
  12. */
  13. protected $modifiers = ['Nullable', 'Default', 'Increment'];
  14. /**
  15. * The columns available as serials.
  16. *
  17. * @var array
  18. */
  19. protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
  20. /**
  21. * Compile the query to determine if a table exists.
  22. *
  23. * @return string
  24. */
  25. public function compileTableExists()
  26. {
  27. return "select * from sqlite_master where type = 'table' and name = ?";
  28. }
  29. /**
  30. * Compile the query to determine the list of columns.
  31. *
  32. * @param string $table
  33. * @return string
  34. */
  35. public function compileColumnExists($table)
  36. {
  37. return 'pragma table_info('.str_replace('.', '__', $table).')';
  38. }
  39. /**
  40. * Compile a create table command.
  41. *
  42. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  43. * @param \Illuminate\Support\Fluent $command
  44. * @return string
  45. */
  46. public function compileCreate(Blueprint $blueprint, Fluent $command)
  47. {
  48. $columns = implode(', ', $this->getColumns($blueprint));
  49. $sql = $blueprint->temporary ? 'create temporary' : 'create';
  50. $sql .= ' table '.$this->wrapTable($blueprint)." ($columns";
  51. // SQLite forces primary keys to be added when the table is initially created
  52. // so we will need to check for a primary key commands and add the columns
  53. // to the table's declaration here so they can be created on the tables.
  54. $sql .= (string) $this->addForeignKeys($blueprint);
  55. $sql .= (string) $this->addPrimaryKeys($blueprint);
  56. return $sql.')';
  57. }
  58. /**
  59. * Get the foreign key syntax for a table creation statement.
  60. *
  61. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  62. * @return string|null
  63. */
  64. protected function addForeignKeys(Blueprint $blueprint)
  65. {
  66. $sql = '';
  67. $foreigns = $this->getCommandsByName($blueprint, 'foreign');
  68. // Once we have all the foreign key commands for the table creation statement
  69. // we'll loop through each of them and add them to the create table SQL we
  70. // are building, since SQLite needs foreign keys on the tables creation.
  71. foreach ($foreigns as $foreign) {
  72. $sql .= $this->getForeignKey($foreign);
  73. if (! is_null($foreign->onDelete)) {
  74. $sql .= " on delete {$foreign->onDelete}";
  75. }
  76. if (! is_null($foreign->onUpdate)) {
  77. $sql .= " on update {$foreign->onUpdate}";
  78. }
  79. }
  80. return $sql;
  81. }
  82. /**
  83. * Get the SQL for the foreign key.
  84. *
  85. * @param \Illuminate\Support\Fluent $foreign
  86. * @return string
  87. */
  88. protected function getForeignKey($foreign)
  89. {
  90. $on = $this->wrapTable($foreign->on);
  91. // We need to columnize the columns that the foreign key is being defined for
  92. // so that it is a properly formatted list. Once we have done this, we can
  93. // return the foreign key SQL declaration to the calling method for use.
  94. $columns = $this->columnize($foreign->columns);
  95. $onColumns = $this->columnize((array) $foreign->references);
  96. return ", foreign key($columns) references $on($onColumns)";
  97. }
  98. /**
  99. * Get the primary key syntax for a table creation statement.
  100. *
  101. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  102. * @return string|null
  103. */
  104. protected function addPrimaryKeys(Blueprint $blueprint)
  105. {
  106. $primary = $this->getCommandByName($blueprint, 'primary');
  107. if (! is_null($primary)) {
  108. $columns = $this->columnize($primary->columns);
  109. return ", primary key ({$columns})";
  110. }
  111. }
  112. /**
  113. * Compile alter table commands for adding columns.
  114. *
  115. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  116. * @param \Illuminate\Support\Fluent $command
  117. * @return array
  118. */
  119. public function compileAdd(Blueprint $blueprint, Fluent $command)
  120. {
  121. $table = $this->wrapTable($blueprint);
  122. $columns = $this->prefixArray('add column', $this->getColumns($blueprint));
  123. $statements = [];
  124. foreach ($columns as $column) {
  125. $statements[] = 'alter table '.$table.' '.$column;
  126. }
  127. return $statements;
  128. }
  129. /**
  130. * Compile a unique key command.
  131. *
  132. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  133. * @param \Illuminate\Support\Fluent $command
  134. * @return string
  135. */
  136. public function compileUnique(Blueprint $blueprint, Fluent $command)
  137. {
  138. $columns = $this->columnize($command->columns);
  139. $table = $this->wrapTable($blueprint);
  140. return "create unique index {$command->index} on {$table} ({$columns})";
  141. }
  142. /**
  143. * Compile a plain index key command.
  144. *
  145. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  146. * @param \Illuminate\Support\Fluent $command
  147. * @return string
  148. */
  149. public function compileIndex(Blueprint $blueprint, Fluent $command)
  150. {
  151. $columns = $this->columnize($command->columns);
  152. $table = $this->wrapTable($blueprint);
  153. return "create index {$command->index} on {$table} ({$columns})";
  154. }
  155. /**
  156. * Compile a foreign key command.
  157. *
  158. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  159. * @param \Illuminate\Support\Fluent $command
  160. * @return string
  161. */
  162. public function compileForeign(Blueprint $blueprint, Fluent $command)
  163. {
  164. // Handled on table creation...
  165. }
  166. /**
  167. * Compile a drop table command.
  168. *
  169. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  170. * @param \Illuminate\Support\Fluent $command
  171. * @return string
  172. */
  173. public function compileDrop(Blueprint $blueprint, Fluent $command)
  174. {
  175. return 'drop table '.$this->wrapTable($blueprint);
  176. }
  177. /**
  178. * Compile a drop table (if exists) command.
  179. *
  180. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  181. * @param \Illuminate\Support\Fluent $command
  182. * @return string
  183. */
  184. public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
  185. {
  186. return 'drop table if exists '.$this->wrapTable($blueprint);
  187. }
  188. /**
  189. * Compile a drop column command.
  190. *
  191. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  192. * @param \Illuminate\Support\Fluent $command
  193. * @param \Illuminate\Database\Connection $connection
  194. * @return array
  195. */
  196. public function compileDropColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
  197. {
  198. $schema = $connection->getDoctrineSchemaManager();
  199. $tableDiff = $this->getDoctrineTableDiff($blueprint, $schema);
  200. foreach ($command->columns as $name) {
  201. $column = $connection->getDoctrineColumn($blueprint->getTable(), $name);
  202. $tableDiff->removedColumns[$name] = $column;
  203. }
  204. return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);
  205. }
  206. /**
  207. * Compile a drop unique key command.
  208. *
  209. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  210. * @param \Illuminate\Support\Fluent $command
  211. * @return string
  212. */
  213. public function compileDropUnique(Blueprint $blueprint, Fluent $command)
  214. {
  215. return "drop index {$command->index}";
  216. }
  217. /**
  218. * Compile a drop index command.
  219. *
  220. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  221. * @param \Illuminate\Support\Fluent $command
  222. * @return string
  223. */
  224. public function compileDropIndex(Blueprint $blueprint, Fluent $command)
  225. {
  226. return "drop index {$command->index}";
  227. }
  228. /**
  229. * Compile a rename table command.
  230. *
  231. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  232. * @param \Illuminate\Support\Fluent $command
  233. * @return string
  234. */
  235. public function compileRename(Blueprint $blueprint, Fluent $command)
  236. {
  237. $from = $this->wrapTable($blueprint);
  238. return "alter table {$from} rename to ".$this->wrapTable($command->to);
  239. }
  240. /**
  241. * Create the column definition for a char type.
  242. *
  243. * @param \Illuminate\Support\Fluent $column
  244. * @return string
  245. */
  246. protected function typeChar(Fluent $column)
  247. {
  248. return 'varchar';
  249. }
  250. /**
  251. * Create the column definition for a string type.
  252. *
  253. * @param \Illuminate\Support\Fluent $column
  254. * @return string
  255. */
  256. protected function typeString(Fluent $column)
  257. {
  258. return 'varchar';
  259. }
  260. /**
  261. * Create the column definition for a text type.
  262. *
  263. * @param \Illuminate\Support\Fluent $column
  264. * @return string
  265. */
  266. protected function typeText(Fluent $column)
  267. {
  268. return 'text';
  269. }
  270. /**
  271. * Create the column definition for a medium text type.
  272. *
  273. * @param \Illuminate\Support\Fluent $column
  274. * @return string
  275. */
  276. protected function typeMediumText(Fluent $column)
  277. {
  278. return 'text';
  279. }
  280. /**
  281. * Create the column definition for a long text type.
  282. *
  283. * @param \Illuminate\Support\Fluent $column
  284. * @return string
  285. */
  286. protected function typeLongText(Fluent $column)
  287. {
  288. return 'text';
  289. }
  290. /**
  291. * Create the column definition for a integer type.
  292. *
  293. * @param \Illuminate\Support\Fluent $column
  294. * @return string
  295. */
  296. protected function typeInteger(Fluent $column)
  297. {
  298. return 'integer';
  299. }
  300. /**
  301. * Create the column definition for a big integer type.
  302. *
  303. * @param \Illuminate\Support\Fluent $column
  304. * @return string
  305. */
  306. protected function typeBigInteger(Fluent $column)
  307. {
  308. return 'integer';
  309. }
  310. /**
  311. * Create the column definition for a medium integer type.
  312. *
  313. * @param \Illuminate\Support\Fluent $column
  314. * @return string
  315. */
  316. protected function typeMediumInteger(Fluent $column)
  317. {
  318. return 'integer';
  319. }
  320. /**
  321. * Create the column definition for a tiny integer type.
  322. *
  323. * @param \Illuminate\Support\Fluent $column
  324. * @return string
  325. */
  326. protected function typeTinyInteger(Fluent $column)
  327. {
  328. return 'integer';
  329. }
  330. /**
  331. * Create the column definition for a small integer type.
  332. *
  333. * @param \Illuminate\Support\Fluent $column
  334. * @return string
  335. */
  336. protected function typeSmallInteger(Fluent $column)
  337. {
  338. return 'integer';
  339. }
  340. /**
  341. * Create the column definition for a float type.
  342. *
  343. * @param \Illuminate\Support\Fluent $column
  344. * @return string
  345. */
  346. protected function typeFloat(Fluent $column)
  347. {
  348. return 'float';
  349. }
  350. /**
  351. * Create the column definition for a double type.
  352. *
  353. * @param \Illuminate\Support\Fluent $column
  354. * @return string
  355. */
  356. protected function typeDouble(Fluent $column)
  357. {
  358. return 'float';
  359. }
  360. /**
  361. * Create the column definition for a decimal type.
  362. *
  363. * @param \Illuminate\Support\Fluent $column
  364. * @return string
  365. */
  366. protected function typeDecimal(Fluent $column)
  367. {
  368. return 'numeric';
  369. }
  370. /**
  371. * Create the column definition for a boolean type.
  372. *
  373. * @param \Illuminate\Support\Fluent $column
  374. * @return string
  375. */
  376. protected function typeBoolean(Fluent $column)
  377. {
  378. return 'tinyint(1)';
  379. }
  380. /**
  381. * Create the column definition for an enum type.
  382. *
  383. * @param \Illuminate\Support\Fluent $column
  384. * @return string
  385. */
  386. protected function typeEnum(Fluent $column)
  387. {
  388. return 'varchar';
  389. }
  390. /**
  391. * Create the column definition for a json type.
  392. *
  393. * @param \Illuminate\Support\Fluent $column
  394. * @return string
  395. */
  396. protected function typeJson(Fluent $column)
  397. {
  398. return 'text';
  399. }
  400. /**
  401. * Create the column definition for a jsonb type.
  402. *
  403. * @param \Illuminate\Support\Fluent $column
  404. * @return string
  405. */
  406. protected function typeJsonb(Fluent $column)
  407. {
  408. return 'text';
  409. }
  410. /**
  411. * Create the column definition for a date type.
  412. *
  413. * @param \Illuminate\Support\Fluent $column
  414. * @return string
  415. */
  416. protected function typeDate(Fluent $column)
  417. {
  418. return 'date';
  419. }
  420. /**
  421. * Create the column definition for a date-time type.
  422. *
  423. * @param \Illuminate\Support\Fluent $column
  424. * @return string
  425. */
  426. protected function typeDateTime(Fluent $column)
  427. {
  428. return 'datetime';
  429. }
  430. /**
  431. * Create the column definition for a date-time type.
  432. *
  433. * Note: "SQLite does not have a storage class set aside for storing dates and/or times."
  434. * @link https://www.sqlite.org/datatype3.html
  435. *
  436. * @param \Illuminate\Support\Fluent $column
  437. * @return string
  438. */
  439. protected function typeDateTimeTz(Fluent $column)
  440. {
  441. return 'datetime';
  442. }
  443. /**
  444. * Create the column definition for a time type.
  445. *
  446. * @param \Illuminate\Support\Fluent $column
  447. * @return string
  448. */
  449. protected function typeTime(Fluent $column)
  450. {
  451. return 'time';
  452. }
  453. /**
  454. * Create the column definition for a time type.
  455. *
  456. * @param \Illuminate\Support\Fluent $column
  457. * @return string
  458. */
  459. protected function typeTimeTz(Fluent $column)
  460. {
  461. return 'time';
  462. }
  463. /**
  464. * Create the column definition for a timestamp type.
  465. *
  466. * @param \Illuminate\Support\Fluent $column
  467. * @return string
  468. */
  469. protected function typeTimestamp(Fluent $column)
  470. {
  471. if ($column->useCurrent) {
  472. return 'datetime default CURRENT_TIMESTAMP';
  473. }
  474. return 'datetime';
  475. }
  476. /**
  477. * Create the column definition for a timestamp type.
  478. *
  479. * @param \Illuminate\Support\Fluent $column
  480. * @return string
  481. */
  482. protected function typeTimestampTz(Fluent $column)
  483. {
  484. if ($column->useCurrent) {
  485. return 'datetime default CURRENT_TIMESTAMP';
  486. }
  487. return 'datetime';
  488. }
  489. /**
  490. * Create the column definition for a binary type.
  491. *
  492. * @param \Illuminate\Support\Fluent $column
  493. * @return string
  494. */
  495. protected function typeBinary(Fluent $column)
  496. {
  497. return 'blob';
  498. }
  499. /**
  500. * Create the column definition for a uuid type.
  501. *
  502. * @param \Illuminate\Support\Fluent $column
  503. * @return string
  504. */
  505. protected function typeUuid(Fluent $column)
  506. {
  507. return 'varchar';
  508. }
  509. /**
  510. * Get the SQL for a nullable column modifier.
  511. *
  512. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  513. * @param \Illuminate\Support\Fluent $column
  514. * @return string|null
  515. */
  516. protected function modifyNullable(Blueprint $blueprint, Fluent $column)
  517. {
  518. return $column->nullable ? ' null' : ' not null';
  519. }
  520. /**
  521. * Get the SQL for a default column modifier.
  522. *
  523. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  524. * @param \Illuminate\Support\Fluent $column
  525. * @return string|null
  526. */
  527. protected function modifyDefault(Blueprint $blueprint, Fluent $column)
  528. {
  529. if (! is_null($column->default)) {
  530. return ' default '.$this->getDefaultValue($column->default);
  531. }
  532. }
  533. /**
  534. * Get the SQL for an auto-increment column modifier.
  535. *
  536. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  537. * @param \Illuminate\Support\Fluent $column
  538. * @return string|null
  539. */
  540. protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
  541. {
  542. if (in_array($column->type, $this->serials) && $column->autoIncrement) {
  543. return ' primary key autoincrement';
  544. }
  545. }
  546. }