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

https://gitlab.com/jjpa2018/dashboard · PHP · 340 lines · 140 code · 35 blank · 165 comment · 6 complexity · 68e4a04daec9849d141315ed96065b52 MD5 · raw file

  1. <?php
  2. namespace Illuminate\Database\Schema\Grammars;
  3. use Doctrine\DBAL\Schema\AbstractSchemaManager as SchemaManager;
  4. use Doctrine\DBAL\Schema\TableDiff;
  5. use Illuminate\Database\Connection;
  6. use Illuminate\Database\Grammar as BaseGrammar;
  7. use Illuminate\Database\Query\Expression;
  8. use Illuminate\Database\Schema\Blueprint;
  9. use Illuminate\Support\Fluent;
  10. use LogicException;
  11. use RuntimeException;
  12. abstract class Grammar extends BaseGrammar
  13. {
  14. /**
  15. * If this Grammar supports schema changes wrapped in a transaction.
  16. *
  17. * @var bool
  18. */
  19. protected $transactions = false;
  20. /**
  21. * The commands to be executed outside of create or alter command.
  22. *
  23. * @var array
  24. */
  25. protected $fluentCommands = [];
  26. /**
  27. * Compile a create database command.
  28. *
  29. * @param string $name
  30. * @param \Illuminate\Database\Connection $connection
  31. * @return void
  32. *
  33. * @throws \LogicException
  34. */
  35. public function compileCreateDatabase($name, $connection)
  36. {
  37. throw new LogicException('This database driver does not support creating databases.');
  38. }
  39. /**
  40. * Compile a drop database if exists command.
  41. *
  42. * @param string $name
  43. * @return void
  44. *
  45. * @throws \LogicException
  46. */
  47. public function compileDropDatabaseIfExists($name)
  48. {
  49. throw new LogicException('This database driver does not support dropping databases.');
  50. }
  51. /**
  52. * Compile a rename column command.
  53. *
  54. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  55. * @param \Illuminate\Support\Fluent $command
  56. * @param \Illuminate\Database\Connection $connection
  57. * @return array
  58. */
  59. public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
  60. {
  61. return RenameColumn::compile($this, $blueprint, $command, $connection);
  62. }
  63. /**
  64. * Compile a change column command into a series of SQL statements.
  65. *
  66. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  67. * @param \Illuminate\Support\Fluent $command
  68. * @param \Illuminate\Database\Connection $connection
  69. * @return array
  70. *
  71. * @throws \RuntimeException
  72. */
  73. public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection)
  74. {
  75. return ChangeColumn::compile($this, $blueprint, $command, $connection);
  76. }
  77. /**
  78. * Compile a fulltext index key command.
  79. *
  80. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  81. * @param \Illuminate\Support\Fluent $command
  82. * @return string
  83. *
  84. * @throws \RuntimeException
  85. */
  86. public function compileFulltext(Blueprint $blueprint, Fluent $command)
  87. {
  88. throw new RuntimeException('This database driver does not support fulltext index creation.');
  89. }
  90. /**
  91. * Compile a drop fulltext index command.
  92. *
  93. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  94. * @param \Illuminate\Support\Fluent $command
  95. * @return string
  96. */
  97. public function compileDropFullText(Blueprint $blueprint, Fluent $command)
  98. {
  99. throw new RuntimeException('This database driver does not support fulltext index creation.');
  100. }
  101. /**
  102. * Compile a foreign key command.
  103. *
  104. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  105. * @param \Illuminate\Support\Fluent $command
  106. * @return string
  107. */
  108. public function compileForeign(Blueprint $blueprint, Fluent $command)
  109. {
  110. // We need to prepare several of the elements of the foreign key definition
  111. // before we can create the SQL, such as wrapping the tables and convert
  112. // an array of columns to comma-delimited strings for the SQL queries.
  113. $sql = sprintf('alter table %s add constraint %s ',
  114. $this->wrapTable($blueprint),
  115. $this->wrap($command->index)
  116. );
  117. // Once we have the initial portion of the SQL statement we will add on the
  118. // key name, table name, and referenced columns. These will complete the
  119. // main portion of the SQL statement and this SQL will almost be done.
  120. $sql .= sprintf('foreign key (%s) references %s (%s)',
  121. $this->columnize($command->columns),
  122. $this->wrapTable($command->on),
  123. $this->columnize((array) $command->references)
  124. );
  125. // Once we have the basic foreign key creation statement constructed we can
  126. // build out the syntax for what should happen on an update or delete of
  127. // the affected columns, which will get something like "cascade", etc.
  128. if (! is_null($command->onDelete)) {
  129. $sql .= " on delete {$command->onDelete}";
  130. }
  131. if (! is_null($command->onUpdate)) {
  132. $sql .= " on update {$command->onUpdate}";
  133. }
  134. return $sql;
  135. }
  136. /**
  137. * Compile the blueprint's column definitions.
  138. *
  139. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  140. * @return array
  141. */
  142. protected function getColumns(Blueprint $blueprint)
  143. {
  144. $columns = [];
  145. foreach ($blueprint->getAddedColumns() as $column) {
  146. // Each of the column types have their own compiler functions which are tasked
  147. // with turning the column definition into its SQL format for this platform
  148. // used by the connection. The column's modifiers are compiled and added.
  149. $sql = $this->wrap($column).' '.$this->getType($column);
  150. $columns[] = $this->addModifiers($sql, $blueprint, $column);
  151. }
  152. return $columns;
  153. }
  154. /**
  155. * Get the SQL for the column data type.
  156. *
  157. * @param \Illuminate\Support\Fluent $column
  158. * @return string
  159. */
  160. protected function getType(Fluent $column)
  161. {
  162. return $this->{'type'.ucfirst($column->type)}($column);
  163. }
  164. /**
  165. * Create the column definition for a generated, computed column type.
  166. *
  167. * @param \Illuminate\Support\Fluent $column
  168. * @return void
  169. *
  170. * @throws \RuntimeException
  171. */
  172. protected function typeComputed(Fluent $column)
  173. {
  174. throw new RuntimeException('This database driver does not support the computed type.');
  175. }
  176. /**
  177. * Add the column modifiers to the definition.
  178. *
  179. * @param string $sql
  180. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  181. * @param \Illuminate\Support\Fluent $column
  182. * @return string
  183. */
  184. protected function addModifiers($sql, Blueprint $blueprint, Fluent $column)
  185. {
  186. foreach ($this->modifiers as $modifier) {
  187. if (method_exists($this, $method = "modify{$modifier}")) {
  188. $sql .= $this->{$method}($blueprint, $column);
  189. }
  190. }
  191. return $sql;
  192. }
  193. /**
  194. * Get the primary key command if it exists on the blueprint.
  195. *
  196. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  197. * @param string $name
  198. * @return \Illuminate\Support\Fluent|null
  199. */
  200. protected function getCommandByName(Blueprint $blueprint, $name)
  201. {
  202. $commands = $this->getCommandsByName($blueprint, $name);
  203. if (count($commands) > 0) {
  204. return reset($commands);
  205. }
  206. }
  207. /**
  208. * Get all of the commands with a given name.
  209. *
  210. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  211. * @param string $name
  212. * @return array
  213. */
  214. protected function getCommandsByName(Blueprint $blueprint, $name)
  215. {
  216. return array_filter($blueprint->getCommands(), function ($value) use ($name) {
  217. return $value->name == $name;
  218. });
  219. }
  220. /**
  221. * Add a prefix to an array of values.
  222. *
  223. * @param string $prefix
  224. * @param array $values
  225. * @return array
  226. */
  227. public function prefixArray($prefix, array $values)
  228. {
  229. return array_map(function ($value) use ($prefix) {
  230. return $prefix.' '.$value;
  231. }, $values);
  232. }
  233. /**
  234. * Wrap a table in keyword identifiers.
  235. *
  236. * @param mixed $table
  237. * @return string
  238. */
  239. public function wrapTable($table)
  240. {
  241. return parent::wrapTable(
  242. $table instanceof Blueprint ? $table->getTable() : $table
  243. );
  244. }
  245. /**
  246. * Wrap a value in keyword identifiers.
  247. *
  248. * @param \Illuminate\Database\Query\Expression|string $value
  249. * @param bool $prefixAlias
  250. * @return string
  251. */
  252. public function wrap($value, $prefixAlias = false)
  253. {
  254. return parent::wrap(
  255. $value instanceof Fluent ? $value->name : $value, $prefixAlias
  256. );
  257. }
  258. /**
  259. * Format a value so that it can be used in "default" clauses.
  260. *
  261. * @param mixed $value
  262. * @return string
  263. */
  264. protected function getDefaultValue($value)
  265. {
  266. if ($value instanceof Expression) {
  267. return $value;
  268. }
  269. return is_bool($value)
  270. ? "'".(int) $value."'"
  271. : "'".(string) $value."'";
  272. }
  273. /**
  274. * Create an empty Doctrine DBAL TableDiff from the Blueprint.
  275. *
  276. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  277. * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
  278. * @return \Doctrine\DBAL\Schema\TableDiff
  279. */
  280. public function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema)
  281. {
  282. $table = $this->getTablePrefix().$blueprint->getTable();
  283. return tap(new TableDiff($table), function ($tableDiff) use ($schema, $table) {
  284. $tableDiff->fromTable = $schema->listTableDetails($table);
  285. });
  286. }
  287. /**
  288. * Get the fluent commands for the grammar.
  289. *
  290. * @return array
  291. */
  292. public function getFluentCommands()
  293. {
  294. return $this->fluentCommands;
  295. }
  296. /**
  297. * Check if this Grammar supports schema changes wrapped in a transaction.
  298. *
  299. * @return bool
  300. */
  301. public function supportsSchemaTransactions()
  302. {
  303. return $this->transactions;
  304. }
  305. }