| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- <?php
- namespace Illuminate\Database\Schema\Grammars;
- use BackedEnum;
- use Illuminate\Contracts\Database\Query\Expression;
- use Illuminate\Database\Concerns\CompilesJsonPaths;
- use Illuminate\Database\Connection;
- use Illuminate\Database\Grammar as BaseGrammar;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Support\Fluent;
- use LogicException;
- use RuntimeException;
- abstract class Grammar extends BaseGrammar
- {
- use CompilesJsonPaths;
- /**
- * The possible column modifiers.
- *
- * @var string[]
- */
- protected $modifiers = [];
- /**
- * If this Grammar supports schema changes wrapped in a transaction.
- *
- * @var bool
- */
- protected $transactions = false;
- /**
- * The commands to be executed outside of create or alter command.
- *
- * @var array
- */
- protected $fluentCommands = [];
- /**
- * Compile a create database command.
- *
- * @param string $name
- * @param \Illuminate\Database\Connection $connection
- * @return void
- *
- * @throws \LogicException
- */
- public function compileCreateDatabase($name, $connection)
- {
- throw new LogicException('This database driver does not support creating databases.');
- }
- /**
- * Compile a drop database if exists command.
- *
- * @param string $name
- * @return void
- *
- * @throws \LogicException
- */
- public function compileDropDatabaseIfExists($name)
- {
- throw new LogicException('This database driver does not support dropping databases.');
- }
- /**
- * Compile a rename column command.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $command
- * @param \Illuminate\Database\Connection $connection
- * @return array|string
- */
- public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
- {
- return sprintf('alter table %s rename column %s to %s',
- $this->wrapTable($blueprint),
- $this->wrap($command->from),
- $this->wrap($command->to)
- );
- }
- /**
- * Compile a change column command into a series of SQL statements.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $command
- * @param \Illuminate\Database\Connection $connection
- * @return array|string
- *
- * @throws \RuntimeException
- */
- public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection)
- {
- throw new LogicException('This database driver does not support modifying columns.');
- }
- /**
- * Compile a fulltext index key command.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $command
- * @return string
- *
- * @throws \RuntimeException
- */
- public function compileFulltext(Blueprint $blueprint, Fluent $command)
- {
- throw new RuntimeException('This database driver does not support fulltext index creation.');
- }
- /**
- * Compile a drop fulltext index command.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $command
- * @return string
- *
- * @throws \RuntimeException
- */
- public function compileDropFullText(Blueprint $blueprint, Fluent $command)
- {
- throw new RuntimeException('This database driver does not support fulltext index removal.');
- }
- /**
- * Compile a foreign key command.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $command
- * @return string
- */
- public function compileForeign(Blueprint $blueprint, Fluent $command)
- {
- // We need to prepare several of the elements of the foreign key definition
- // before we can create the SQL, such as wrapping the tables and convert
- // an array of columns to comma-delimited strings for the SQL queries.
- $sql = sprintf('alter table %s add constraint %s ',
- $this->wrapTable($blueprint),
- $this->wrap($command->index)
- );
- // Once we have the initial portion of the SQL statement we will add on the
- // key name, table name, and referenced columns. These will complete the
- // main portion of the SQL statement and this SQL will almost be done.
- $sql .= sprintf('foreign key (%s) references %s (%s)',
- $this->columnize($command->columns),
- $this->wrapTable($command->on),
- $this->columnize((array) $command->references)
- );
- // Once we have the basic foreign key creation statement constructed we can
- // build out the syntax for what should happen on an update or delete of
- // the affected columns, which will get something like "cascade", etc.
- if (! is_null($command->onDelete)) {
- $sql .= " on delete {$command->onDelete}";
- }
- if (! is_null($command->onUpdate)) {
- $sql .= " on update {$command->onUpdate}";
- }
- return $sql;
- }
- /**
- * Compile a drop foreign key command.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $command
- * @return string
- */
- public function compileDropForeign(Blueprint $blueprint, Fluent $command)
- {
- throw new RuntimeException('This database driver does not support dropping foreign keys.');
- }
- /**
- * Compile the blueprint's added column definitions.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @return array
- */
- protected function getColumns(Blueprint $blueprint)
- {
- $columns = [];
- foreach ($blueprint->getAddedColumns() as $column) {
- // Each of the column types has their own compiler functions, which are tasked
- // with turning the column definition into its SQL format for this platform
- // used by the connection. The column's modifiers are compiled and added.
- $sql = $this->wrap($column).' '.$this->getType($column);
- $columns[] = $this->addModifiers($sql, $blueprint, $column);
- }
- return $columns;
- }
- /**
- * Get the SQL for the column data type.
- *
- * @param \Illuminate\Support\Fluent $column
- * @return string
- */
- protected function getType(Fluent $column)
- {
- return $this->{'type'.ucfirst($column->type)}($column);
- }
- /**
- * Create the column definition for a generated, computed column type.
- *
- * @param \Illuminate\Support\Fluent $column
- * @return void
- *
- * @throws \RuntimeException
- */
- protected function typeComputed(Fluent $column)
- {
- throw new RuntimeException('This database driver does not support the computed type.');
- }
- /**
- * Add the column modifiers to the definition.
- *
- * @param string $sql
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param \Illuminate\Support\Fluent $column
- * @return string
- */
- protected function addModifiers($sql, Blueprint $blueprint, Fluent $column)
- {
- foreach ($this->modifiers as $modifier) {
- if (method_exists($this, $method = "modify{$modifier}")) {
- $sql .= $this->{$method}($blueprint, $column);
- }
- }
- return $sql;
- }
- /**
- * Get the command with a given name if it exists on the blueprint.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param string $name
- * @return \Illuminate\Support\Fluent|null
- */
- protected function getCommandByName(Blueprint $blueprint, $name)
- {
- $commands = $this->getCommandsByName($blueprint, $name);
- if (count($commands) > 0) {
- return reset($commands);
- }
- }
- /**
- * Get all of the commands with a given name.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param string $name
- * @return array
- */
- protected function getCommandsByName(Blueprint $blueprint, $name)
- {
- return array_filter($blueprint->getCommands(), function ($value) use ($name) {
- return $value->name == $name;
- });
- }
- /*
- * Determine if a command with a given name exists on the blueprint.
- *
- * @param \Illuminate\Database\Schema\Blueprint $blueprint
- * @param string $name
- * @return bool
- */
- protected function hasCommand(Blueprint $blueprint, $name)
- {
- foreach ($blueprint->getCommands() as $command) {
- if ($command->name === $name) {
- return true;
- }
- }
- return false;
- }
- /**
- * Add a prefix to an array of values.
- *
- * @param string $prefix
- * @param array $values
- * @return array
- */
- public function prefixArray($prefix, array $values)
- {
- return array_map(function ($value) use ($prefix) {
- return $prefix.' '.$value;
- }, $values);
- }
- /**
- * Wrap a table in keyword identifiers.
- *
- * @param mixed $table
- * @return string
- */
- public function wrapTable($table)
- {
- return parent::wrapTable(
- $table instanceof Blueprint ? $table->getTable() : $table
- );
- }
- /**
- * Wrap a value in keyword identifiers.
- *
- * @param \Illuminate\Support\Fluent|\Illuminate\Contracts\Database\Query\Expression|string $value
- * @param bool $prefixAlias
- * @return string
- */
- public function wrap($value, $prefixAlias = false)
- {
- return parent::wrap(
- $value instanceof Fluent ? $value->name : $value, $prefixAlias
- );
- }
- /**
- * Format a value so that it can be used in "default" clauses.
- *
- * @param mixed $value
- * @return string
- */
- protected function getDefaultValue($value)
- {
- if ($value instanceof Expression) {
- return $this->getValue($value);
- }
- if ($value instanceof BackedEnum) {
- return "'{$value->value}'";
- }
- return is_bool($value)
- ? "'".(int) $value."'"
- : "'".(string) $value."'";
- }
- /**
- * Get the fluent commands for the grammar.
- *
- * @return array
- */
- public function getFluentCommands()
- {
- return $this->fluentCommands;
- }
- /**
- * Check if this Grammar supports schema changes wrapped in a transaction.
- *
- * @return bool
- */
- public function supportsSchemaTransactions()
- {
- return $this->transactions;
- }
- }
|