Illuminate: ready. (critical)
- DB에서 illuminate를 가져올 수 있도록 설정 - 업그레이듵 불가, RootDB, DB를 직접 수정해야함
This commit is contained in:
+1687
@@ -0,0 +1,1687 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Closure;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Schema\Grammars\Grammar;
|
||||
use Illuminate\Database\SQLiteConnection;
|
||||
use Illuminate\Support\Fluent;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
|
||||
class Blueprint
|
||||
{
|
||||
use Macroable;
|
||||
|
||||
/**
|
||||
* The table the blueprint describes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* The prefix of the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* The columns that should be added to the table.
|
||||
*
|
||||
* @var \Illuminate\Database\Schema\ColumnDefinition[]
|
||||
*/
|
||||
protected $columns = [];
|
||||
|
||||
/**
|
||||
* The commands that should be run for the table.
|
||||
*
|
||||
* @var \Illuminate\Support\Fluent[]
|
||||
*/
|
||||
protected $commands = [];
|
||||
|
||||
/**
|
||||
* The storage engine that should be used for the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $engine;
|
||||
|
||||
/**
|
||||
* The default character set that should be used for the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $charset;
|
||||
|
||||
/**
|
||||
* The collation that should be used for the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $collation;
|
||||
|
||||
/**
|
||||
* Whether to make the table temporary.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $temporary = false;
|
||||
|
||||
/**
|
||||
* The column to add new columns after.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $after;
|
||||
|
||||
/**
|
||||
* Create a new schema blueprint.
|
||||
*
|
||||
* @param string $table
|
||||
* @param \Closure|null $callback
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($table, Closure $callback = null, $prefix = '')
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->prefix = $prefix;
|
||||
|
||||
if (! is_null($callback)) {
|
||||
$callback($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the blueprint against the database.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @return void
|
||||
*/
|
||||
public function build(Connection $connection, Grammar $grammar)
|
||||
{
|
||||
foreach ($this->toSql($connection, $grammar) as $statement) {
|
||||
$connection->statement($statement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw SQL statements for the blueprint.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @return array
|
||||
*/
|
||||
public function toSql(Connection $connection, Grammar $grammar)
|
||||
{
|
||||
$this->addImpliedCommands($grammar);
|
||||
|
||||
$statements = [];
|
||||
|
||||
// Each type of command has a corresponding compiler function on the schema
|
||||
// grammar which is used to build the necessary SQL statements to build
|
||||
// the blueprint element, so we'll just call that compilers function.
|
||||
$this->ensureCommandsAreValid($connection);
|
||||
|
||||
foreach ($this->commands as $command) {
|
||||
$method = 'compile'.ucfirst($command->name);
|
||||
|
||||
if (method_exists($grammar, $method) || $grammar::hasMacro($method)) {
|
||||
if (! is_null($sql = $grammar->$method($this, $command, $connection))) {
|
||||
$statements = array_merge($statements, (array) $sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the commands on the blueprint are valid for the connection type.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return void
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
protected function ensureCommandsAreValid(Connection $connection)
|
||||
{
|
||||
if ($connection instanceof SQLiteConnection) {
|
||||
if ($this->commandsNamed(['dropColumn', 'renameColumn'])->count() > 1) {
|
||||
throw new BadMethodCallException(
|
||||
"SQLite doesn't support multiple calls to dropColumn / renameColumn in a single modification."
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->commandsNamed(['dropForeign'])->count() > 0) {
|
||||
throw new BadMethodCallException(
|
||||
"SQLite doesn't support dropping foreign keys (you would need to re-create the table)."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the commands matching the given names.
|
||||
*
|
||||
* @param array $names
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
protected function commandsNamed(array $names)
|
||||
{
|
||||
return collect($this->commands)->filter(function ($command) use ($names) {
|
||||
return in_array($command->name, $names);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the commands that are implied by the blueprint's state.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @return void
|
||||
*/
|
||||
protected function addImpliedCommands(Grammar $grammar)
|
||||
{
|
||||
if (count($this->getAddedColumns()) > 0 && ! $this->creating()) {
|
||||
array_unshift($this->commands, $this->createCommand('add'));
|
||||
}
|
||||
|
||||
if (count($this->getChangedColumns()) > 0 && ! $this->creating()) {
|
||||
array_unshift($this->commands, $this->createCommand('change'));
|
||||
}
|
||||
|
||||
$this->addFluentIndexes();
|
||||
|
||||
$this->addFluentCommands($grammar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the index commands fluently specified on columns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addFluentIndexes()
|
||||
{
|
||||
foreach ($this->columns as $column) {
|
||||
foreach (['primary', 'unique', 'index', 'spatialIndex'] as $index) {
|
||||
// If the index has been specified on the given column, but is simply equal
|
||||
// to "true" (boolean), no name has been specified for this index so the
|
||||
// index method can be called without a name and it will generate one.
|
||||
if ($column->{$index} === true) {
|
||||
$this->{$index}($column->name);
|
||||
$column->{$index} = false;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
||||
// If the index has been specified on the given column, and it has a string
|
||||
// value, we'll go ahead and call the index method and pass the name for
|
||||
// the index since the developer specified the explicit name for this.
|
||||
elseif (isset($column->{$index})) {
|
||||
$this->{$index}($column->name, $column->{$index});
|
||||
$column->{$index} = false;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the fluent commands specified on any columns.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @return void
|
||||
*/
|
||||
public function addFluentCommands(Grammar $grammar)
|
||||
{
|
||||
foreach ($this->columns as $column) {
|
||||
foreach ($grammar->getFluentCommands() as $commandName) {
|
||||
$attributeName = lcfirst($commandName);
|
||||
|
||||
if (! isset($column->{$attributeName})) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $column->{$attributeName};
|
||||
|
||||
$this->addCommand(
|
||||
$commandName, compact('value', 'column')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the blueprint has a create command.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function creating()
|
||||
{
|
||||
return collect($this->commands)->contains(function ($command) {
|
||||
return $command->name === 'create';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the table needs to be created.
|
||||
*
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return $this->addCommand('create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the table needs to be temporary.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function temporary()
|
||||
{
|
||||
$this->temporary = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the table should be dropped.
|
||||
*
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function drop()
|
||||
{
|
||||
return $this->addCommand('drop');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the table should be dropped if it exists.
|
||||
*
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropIfExists()
|
||||
{
|
||||
return $this->addCommand('dropIfExists');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given columns should be dropped.
|
||||
*
|
||||
* @param array|mixed $columns
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropColumn($columns)
|
||||
{
|
||||
$columns = is_array($columns) ? $columns : func_get_args();
|
||||
|
||||
return $this->addCommand('dropColumn', compact('columns'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given columns should be renamed.
|
||||
*
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function renameColumn($from, $to)
|
||||
{
|
||||
return $this->addCommand('renameColumn', compact('from', 'to'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given primary key should be dropped.
|
||||
*
|
||||
* @param string|array|null $index
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropPrimary($index = null)
|
||||
{
|
||||
return $this->dropIndexCommand('dropPrimary', 'primary', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given unique key should be dropped.
|
||||
*
|
||||
* @param string|array $index
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropUnique($index)
|
||||
{
|
||||
return $this->dropIndexCommand('dropUnique', 'unique', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given index should be dropped.
|
||||
*
|
||||
* @param string|array $index
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropIndex($index)
|
||||
{
|
||||
return $this->dropIndexCommand('dropIndex', 'index', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given spatial index should be dropped.
|
||||
*
|
||||
* @param string|array $index
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropSpatialIndex($index)
|
||||
{
|
||||
return $this->dropIndexCommand('dropSpatialIndex', 'spatialIndex', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given foreign key should be dropped.
|
||||
*
|
||||
* @param string|array $index
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropForeign($index)
|
||||
{
|
||||
return $this->dropIndexCommand('dropForeign', 'foreign', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given column and foreign key should be dropped.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function dropConstrainedForeignId($column)
|
||||
{
|
||||
$this->dropForeign([$column]);
|
||||
|
||||
return $this->dropColumn($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the given indexes should be renamed.
|
||||
*
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function renameIndex($from, $to)
|
||||
{
|
||||
return $this->addCommand('renameIndex', compact('from', 'to'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the timestamp columns should be dropped.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropTimestamps()
|
||||
{
|
||||
$this->dropColumn('created_at', 'updated_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the timestamp columns should be dropped.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropTimestampsTz()
|
||||
{
|
||||
$this->dropTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the soft delete column should be dropped.
|
||||
*
|
||||
* @param string $column
|
||||
* @return void
|
||||
*/
|
||||
public function dropSoftDeletes($column = 'deleted_at')
|
||||
{
|
||||
$this->dropColumn($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the soft delete column should be dropped.
|
||||
*
|
||||
* @param string $column
|
||||
* @return void
|
||||
*/
|
||||
public function dropSoftDeletesTz($column = 'deleted_at')
|
||||
{
|
||||
$this->dropSoftDeletes($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the remember token column should be dropped.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropRememberToken()
|
||||
{
|
||||
$this->dropColumn('remember_token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the polymorphic columns should be dropped.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function dropMorphs($name, $indexName = null)
|
||||
{
|
||||
$this->dropIndex($indexName ?: $this->createIndexName('index', ["{$name}_type", "{$name}_id"]));
|
||||
|
||||
$this->dropColumn("{$name}_type", "{$name}_id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the table to a given name.
|
||||
*
|
||||
* @param string $to
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function rename($to)
|
||||
{
|
||||
return $this->addCommand('rename', compact('to'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the primary key(s) for the table.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @param string|null $name
|
||||
* @param string|null $algorithm
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function primary($columns, $name = null, $algorithm = null)
|
||||
{
|
||||
return $this->indexCommand('primary', $columns, $name, $algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a unique index for the table.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @param string|null $name
|
||||
* @param string|null $algorithm
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function unique($columns, $name = null, $algorithm = null)
|
||||
{
|
||||
return $this->indexCommand('unique', $columns, $name, $algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify an index for the table.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @param string|null $name
|
||||
* @param string|null $algorithm
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function index($columns, $name = null, $algorithm = null)
|
||||
{
|
||||
return $this->indexCommand('index', $columns, $name, $algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a spatial index for the table.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @param string|null $name
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function spatialIndex($columns, $name = null)
|
||||
{
|
||||
return $this->indexCommand('spatialIndex', $columns, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a raw index for the table.
|
||||
*
|
||||
* @param string $expression
|
||||
* @param string $name
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
public function rawIndex($expression, $name)
|
||||
{
|
||||
return $this->index([new Expression($expression)], $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a foreign key for the table.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @param string|null $name
|
||||
* @return \Illuminate\Database\Schema\ForeignKeyDefinition
|
||||
*/
|
||||
public function foreign($columns, $name = null)
|
||||
{
|
||||
$command = new ForeignKeyDefinition(
|
||||
$this->indexCommand('foreign', $columns, $name)->getAttributes()
|
||||
);
|
||||
|
||||
$this->commands[count($this->commands) - 1] = $command;
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing big integer (8-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function id($column = 'id')
|
||||
{
|
||||
return $this->bigIncrements($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing integer (4-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function increments($column)
|
||||
{
|
||||
return $this->unsignedInteger($column, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing integer (4-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function integerIncrements($column)
|
||||
{
|
||||
return $this->unsignedInteger($column, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing tiny integer (1-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function tinyIncrements($column)
|
||||
{
|
||||
return $this->unsignedTinyInteger($column, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing small integer (2-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function smallIncrements($column)
|
||||
{
|
||||
return $this->unsignedSmallInteger($column, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing medium integer (3-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function mediumIncrements($column)
|
||||
{
|
||||
return $this->unsignedMediumInteger($column, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new auto-incrementing big integer (8-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function bigIncrements($column)
|
||||
{
|
||||
return $this->unsignedBigInteger($column, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new char column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int|null $length
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function char($column, $length = null)
|
||||
{
|
||||
$length = $length ?: Builder::$defaultStringLength;
|
||||
|
||||
return $this->addColumn('char', $column, compact('length'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new string column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int|null $length
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function string($column, $length = null)
|
||||
{
|
||||
$length = $length ?: Builder::$defaultStringLength;
|
||||
|
||||
return $this->addColumn('string', $column, compact('length'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new tiny text column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function tinyText($column)
|
||||
{
|
||||
return $this->addColumn('tinyText', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new text column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function text($column)
|
||||
{
|
||||
return $this->addColumn('text', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new medium text column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function mediumText($column)
|
||||
{
|
||||
return $this->addColumn('mediumText', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new long text column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function longText($column)
|
||||
{
|
||||
return $this->addColumn('longText', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new integer (4-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function integer($column, $autoIncrement = false, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new tiny integer (1-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function tinyInteger($column, $autoIncrement = false, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('tinyInteger', $column, compact('autoIncrement', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new small integer (2-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function smallInteger($column, $autoIncrement = false, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('smallInteger', $column, compact('autoIncrement', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new medium integer (3-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function mediumInteger($column, $autoIncrement = false, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('mediumInteger', $column, compact('autoIncrement', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new big integer (8-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function bigInteger($column, $autoIncrement = false, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('bigInteger', $column, compact('autoIncrement', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned integer (4-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedInteger($column, $autoIncrement = false)
|
||||
{
|
||||
return $this->integer($column, $autoIncrement, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned tiny integer (1-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedTinyInteger($column, $autoIncrement = false)
|
||||
{
|
||||
return $this->tinyInteger($column, $autoIncrement, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned small integer (2-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedSmallInteger($column, $autoIncrement = false)
|
||||
{
|
||||
return $this->smallInteger($column, $autoIncrement, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned medium integer (3-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedMediumInteger($column, $autoIncrement = false)
|
||||
{
|
||||
return $this->mediumInteger($column, $autoIncrement, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned big integer (8-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param bool $autoIncrement
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedBigInteger($column, $autoIncrement = false)
|
||||
{
|
||||
return $this->bigInteger($column, $autoIncrement, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned big integer (8-byte) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
|
||||
*/
|
||||
public function foreignId($column)
|
||||
{
|
||||
return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
|
||||
'type' => 'bigInteger',
|
||||
'name' => $column,
|
||||
'autoIncrement' => false,
|
||||
'unsigned' => true,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a foreign ID column for the given model.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model|string $model
|
||||
* @param string|null $column
|
||||
* @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
|
||||
*/
|
||||
public function foreignIdFor($model, $column = null)
|
||||
{
|
||||
if (is_string($model)) {
|
||||
$model = new $model;
|
||||
}
|
||||
|
||||
return $model->getKeyType() === 'int' && $model->getIncrementing()
|
||||
? $this->foreignId($column ?: $model->getForeignKey())
|
||||
: $this->foreignUuid($column ?: $model->getForeignKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new float column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $total
|
||||
* @param int $places
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function float($column, $total = 8, $places = 2, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('float', $column, compact('total', 'places', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new double column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int|null $total
|
||||
* @param int|null $places
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function double($column, $total = null, $places = null, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('double', $column, compact('total', 'places', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new decimal column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $total
|
||||
* @param int $places
|
||||
* @param bool $unsigned
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function decimal($column, $total = 8, $places = 2, $unsigned = false)
|
||||
{
|
||||
return $this->addColumn('decimal', $column, compact('total', 'places', 'unsigned'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned float column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $total
|
||||
* @param int $places
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedFloat($column, $total = 8, $places = 2)
|
||||
{
|
||||
return $this->float($column, $total, $places, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned double column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $total
|
||||
* @param int $places
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedDouble($column, $total = null, $places = null)
|
||||
{
|
||||
return $this->double($column, $total, $places, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new unsigned decimal column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $total
|
||||
* @param int $places
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function unsignedDecimal($column, $total = 8, $places = 2)
|
||||
{
|
||||
return $this->decimal($column, $total, $places, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new boolean column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function boolean($column)
|
||||
{
|
||||
return $this->addColumn('boolean', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new enum column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $allowed
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function enum($column, array $allowed)
|
||||
{
|
||||
return $this->addColumn('enum', $column, compact('allowed'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new set column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $allowed
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function set($column, array $allowed)
|
||||
{
|
||||
return $this->addColumn('set', $column, compact('allowed'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new json column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function json($column)
|
||||
{
|
||||
return $this->addColumn('json', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new jsonb column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function jsonb($column)
|
||||
{
|
||||
return $this->addColumn('jsonb', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new date column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function date($column)
|
||||
{
|
||||
return $this->addColumn('date', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new date-time column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function dateTime($column, $precision = 0)
|
||||
{
|
||||
return $this->addColumn('dateTime', $column, compact('precision'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new date-time column (with time zone) on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function dateTimeTz($column, $precision = 0)
|
||||
{
|
||||
return $this->addColumn('dateTimeTz', $column, compact('precision'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new time column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function time($column, $precision = 0)
|
||||
{
|
||||
return $this->addColumn('time', $column, compact('precision'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new time column (with time zone) on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function timeTz($column, $precision = 0)
|
||||
{
|
||||
return $this->addColumn('timeTz', $column, compact('precision'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new timestamp column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function timestamp($column, $precision = 0)
|
||||
{
|
||||
return $this->addColumn('timestamp', $column, compact('precision'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new timestamp (with time zone) column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function timestampTz($column, $precision = 0)
|
||||
{
|
||||
return $this->addColumn('timestampTz', $column, compact('precision'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add nullable creation and update timestamps to the table.
|
||||
*
|
||||
* @param int $precision
|
||||
* @return void
|
||||
*/
|
||||
public function timestamps($precision = 0)
|
||||
{
|
||||
$this->timestamp('created_at', $precision)->nullable();
|
||||
|
||||
$this->timestamp('updated_at', $precision)->nullable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add nullable creation and update timestamps to the table.
|
||||
*
|
||||
* Alias for self::timestamps().
|
||||
*
|
||||
* @param int $precision
|
||||
* @return void
|
||||
*/
|
||||
public function nullableTimestamps($precision = 0)
|
||||
{
|
||||
$this->timestamps($precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add creation and update timestampTz columns to the table.
|
||||
*
|
||||
* @param int $precision
|
||||
* @return void
|
||||
*/
|
||||
public function timestampsTz($precision = 0)
|
||||
{
|
||||
$this->timestampTz('created_at', $precision)->nullable();
|
||||
|
||||
$this->timestampTz('updated_at', $precision)->nullable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a "deleted at" timestamp for the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function softDeletes($column = 'deleted_at', $precision = 0)
|
||||
{
|
||||
return $this->timestamp($column, $precision)->nullable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a "deleted at" timestampTz for the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int $precision
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function softDeletesTz($column = 'deleted_at', $precision = 0)
|
||||
{
|
||||
return $this->timestampTz($column, $precision)->nullable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new year column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function year($column)
|
||||
{
|
||||
return $this->addColumn('year', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new binary column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function binary($column)
|
||||
{
|
||||
return $this->addColumn('binary', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new uuid column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function uuid($column)
|
||||
{
|
||||
return $this->addColumn('uuid', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new UUID column on the table with a foreign key constraint.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
|
||||
*/
|
||||
public function foreignUuid($column)
|
||||
{
|
||||
return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
|
||||
'type' => 'uuid',
|
||||
'name' => $column,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IP address column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function ipAddress($column)
|
||||
{
|
||||
return $this->addColumn('ipAddress', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MAC address column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function macAddress($column)
|
||||
{
|
||||
return $this->addColumn('macAddress', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new geometry column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function geometry($column)
|
||||
{
|
||||
return $this->addColumn('geometry', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new point column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param int|null $srid
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function point($column, $srid = null)
|
||||
{
|
||||
return $this->addColumn('point', $column, compact('srid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new linestring column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function lineString($column)
|
||||
{
|
||||
return $this->addColumn('linestring', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new polygon column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function polygon($column)
|
||||
{
|
||||
return $this->addColumn('polygon', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new geometrycollection column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function geometryCollection($column)
|
||||
{
|
||||
return $this->addColumn('geometrycollection', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new multipoint column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function multiPoint($column)
|
||||
{
|
||||
return $this->addColumn('multipoint', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new multilinestring column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function multiLineString($column)
|
||||
{
|
||||
return $this->addColumn('multilinestring', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new multipolygon column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function multiPolygon($column)
|
||||
{
|
||||
return $this->addColumn('multipolygon', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new multipolygon column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function multiPolygonZ($column)
|
||||
{
|
||||
return $this->addColumn('multipolygonz', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new generated, computed column on the table.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $expression
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function computed($column, $expression)
|
||||
{
|
||||
return $this->addColumn('computed', $column, compact('expression'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the proper columns for a polymorphic table.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function morphs($name, $indexName = null)
|
||||
{
|
||||
if (Builder::$defaultMorphKeyType === 'uuid') {
|
||||
$this->uuidMorphs($name, $indexName);
|
||||
} else {
|
||||
$this->numericMorphs($name, $indexName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add nullable columns for a polymorphic table.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function nullableMorphs($name, $indexName = null)
|
||||
{
|
||||
if (Builder::$defaultMorphKeyType === 'uuid') {
|
||||
$this->nullableUuidMorphs($name, $indexName);
|
||||
} else {
|
||||
$this->nullableNumericMorphs($name, $indexName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the proper columns for a polymorphic table using numeric IDs (incremental).
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function numericMorphs($name, $indexName = null)
|
||||
{
|
||||
$this->string("{$name}_type");
|
||||
|
||||
$this->unsignedBigInteger("{$name}_id");
|
||||
|
||||
$this->index(["{$name}_type", "{$name}_id"], $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add nullable columns for a polymorphic table using numeric IDs (incremental).
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function nullableNumericMorphs($name, $indexName = null)
|
||||
{
|
||||
$this->string("{$name}_type")->nullable();
|
||||
|
||||
$this->unsignedBigInteger("{$name}_id")->nullable();
|
||||
|
||||
$this->index(["{$name}_type", "{$name}_id"], $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the proper columns for a polymorphic table using UUIDs.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function uuidMorphs($name, $indexName = null)
|
||||
{
|
||||
$this->string("{$name}_type");
|
||||
|
||||
$this->uuid("{$name}_id");
|
||||
|
||||
$this->index(["{$name}_type", "{$name}_id"], $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add nullable columns for a polymorphic table using UUIDs.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function nullableUuidMorphs($name, $indexName = null)
|
||||
{
|
||||
$this->string("{$name}_type")->nullable();
|
||||
|
||||
$this->uuid("{$name}_id")->nullable();
|
||||
|
||||
$this->index(["{$name}_type", "{$name}_id"], $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the `remember_token` column to the table.
|
||||
*
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function rememberToken()
|
||||
{
|
||||
return $this->string('remember_token', 100)->nullable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new index command to the blueprint.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string|array $columns
|
||||
* @param string $index
|
||||
* @param string|null $algorithm
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
protected function indexCommand($type, $columns, $index, $algorithm = null)
|
||||
{
|
||||
$columns = (array) $columns;
|
||||
|
||||
// If no name was specified for this index, we will create one using a basic
|
||||
// convention of the table name, followed by the columns, followed by an
|
||||
// index type, such as primary or index, which makes the index unique.
|
||||
$index = $index ?: $this->createIndexName($type, $columns);
|
||||
|
||||
return $this->addCommand(
|
||||
$type, compact('index', 'columns', 'algorithm')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new drop index command on the blueprint.
|
||||
*
|
||||
* @param string $command
|
||||
* @param string $type
|
||||
* @param string|array $index
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
protected function dropIndexCommand($command, $type, $index)
|
||||
{
|
||||
$columns = [];
|
||||
|
||||
// If the given "index" is actually an array of columns, the developer means
|
||||
// to drop an index merely by specifying the columns involved without the
|
||||
// conventional name, so we will build the index name from the columns.
|
||||
if (is_array($index)) {
|
||||
$index = $this->createIndexName($type, $columns = $index);
|
||||
}
|
||||
|
||||
return $this->indexCommand($command, $columns, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default index name for the table.
|
||||
*
|
||||
* @param string $type
|
||||
* @param array $columns
|
||||
* @return string
|
||||
*/
|
||||
protected function createIndexName($type, array $columns)
|
||||
{
|
||||
$index = strtolower($this->prefix.$this->table.'_'.implode('_', $columns).'_'.$type);
|
||||
|
||||
return str_replace(['-', '.'], '_', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new column to the blueprint.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
public function addColumn($type, $name, array $parameters = [])
|
||||
{
|
||||
return $this->addColumnDefinition(new ColumnDefinition(
|
||||
array_merge(compact('type', 'name'), $parameters)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new column definition to the blueprint.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\ColumnDefinition $definition
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition
|
||||
*/
|
||||
protected function addColumnDefinition($definition)
|
||||
{
|
||||
$this->columns[] = $definition;
|
||||
|
||||
if ($this->after) {
|
||||
$definition->after($this->after);
|
||||
|
||||
$this->after = $definition->name;
|
||||
}
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the columns from the callback after the given column.
|
||||
*
|
||||
* @param string $column
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public function after($column, Closure $callback)
|
||||
{
|
||||
$this->after = $column;
|
||||
|
||||
$callback($this);
|
||||
|
||||
$this->after = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a column from the schema blueprint.
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function removeColumn($name)
|
||||
{
|
||||
$this->columns = array_values(array_filter($this->columns, function ($c) use ($name) {
|
||||
return $c['name'] != $name;
|
||||
}));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new command to the blueprint.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
protected function addCommand($name, array $parameters = [])
|
||||
{
|
||||
$this->commands[] = $command = $this->createCommand($name, $parameters);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Fluent command.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\Support\Fluent
|
||||
*/
|
||||
protected function createCommand($name, array $parameters = [])
|
||||
{
|
||||
return new Fluent(array_merge(compact('name'), $parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table the blueprint describes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the columns on the blueprint.
|
||||
*
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the commands on the blueprint.
|
||||
*
|
||||
* @return \Illuminate\Support\Fluent[]
|
||||
*/
|
||||
public function getCommands()
|
||||
{
|
||||
return $this->commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the columns on the blueprint that should be added.
|
||||
*
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition[]
|
||||
*/
|
||||
public function getAddedColumns()
|
||||
{
|
||||
return array_filter($this->columns, function ($column) {
|
||||
return ! $column->change;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the columns on the blueprint that should be changed.
|
||||
*
|
||||
* @return \Illuminate\Database\Schema\ColumnDefinition[]
|
||||
*/
|
||||
public function getChangedColumns()
|
||||
{
|
||||
return array_filter($this->columns, function ($column) {
|
||||
return (bool) $column->change;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the blueprint has auto-increment columns.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAutoIncrementColumn()
|
||||
{
|
||||
return ! is_null(collect($this->getAddedColumns())->first(function ($column) {
|
||||
return $column->autoIncrement === true;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the auto-increment column starting values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function autoIncrementingStartingValues()
|
||||
{
|
||||
if (! $this->hasAutoIncrementColumn()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect($this->getAddedColumns())->mapWithKeys(function ($column) {
|
||||
return $column->autoIncrement === true
|
||||
? [$column->name => $column->get('startingValue', $column->get('from'))]
|
||||
: [$column->name => null];
|
||||
})->filter()->all();
|
||||
}
|
||||
}
|
||||
+450
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Closure;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Illuminate\Database\Connection;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use RuntimeException;
|
||||
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* The database connection instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The schema grammar instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Schema\Grammars\Grammar
|
||||
*/
|
||||
protected $grammar;
|
||||
|
||||
/**
|
||||
* The Blueprint resolver callback.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $resolver;
|
||||
|
||||
/**
|
||||
* The default string length for migrations.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $defaultStringLength = 255;
|
||||
|
||||
/**
|
||||
* The default relationship morph key type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $defaultMorphKeyType = 'int';
|
||||
|
||||
/**
|
||||
* Create a new database Schema manager.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->grammar = $connection->getSchemaGrammar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default string length for migrations.
|
||||
*
|
||||
* @param int $length
|
||||
* @return void
|
||||
*/
|
||||
public static function defaultStringLength($length)
|
||||
{
|
||||
static::$defaultStringLength = $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default morph key type for migrations.
|
||||
*
|
||||
* @param string $type
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function defaultMorphKeyType(string $type)
|
||||
{
|
||||
if (! in_array($type, ['int', 'uuid'])) {
|
||||
throw new InvalidArgumentException("Morph key type must be 'int' or 'uuid'.");
|
||||
}
|
||||
|
||||
static::$defaultMorphKeyType = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default morph key type for migrations to UUIDs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function morphUsingUuids()
|
||||
{
|
||||
return static::defaultMorphKeyType('uuid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a database in the schema.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
throw new LogicException('This database driver does not support creating databases.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a database from the schema if the database exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function dropDatabaseIfExists($name)
|
||||
{
|
||||
throw new LogicException('This database driver does not support dropping databases.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given table exists.
|
||||
*
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTable($table)
|
||||
{
|
||||
$table = $this->connection->getTablePrefix().$table;
|
||||
|
||||
return count($this->connection->selectFromWriteConnection(
|
||||
$this->grammar->compileTableExists(), [$table]
|
||||
)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given table has a given column.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumn($table, $column)
|
||||
{
|
||||
return in_array(
|
||||
strtolower($column), array_map('strtolower', $this->getColumnListing($table))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given table has given columns.
|
||||
*
|
||||
* @param string $table
|
||||
* @param array $columns
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumns($table, array $columns)
|
||||
{
|
||||
$tableColumns = array_map('strtolower', $this->getColumnListing($table));
|
||||
|
||||
foreach ($columns as $column) {
|
||||
if (! in_array(strtolower($column), $tableColumns)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data type for the given column name.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function getColumnType($table, $column)
|
||||
{
|
||||
$table = $this->connection->getTablePrefix().$table;
|
||||
|
||||
return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column listing for a given table.
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnListing($table)
|
||||
{
|
||||
$results = $this->connection->selectFromWriteConnection($this->grammar->compileColumnListing(
|
||||
$this->connection->getTablePrefix().$table
|
||||
));
|
||||
|
||||
return $this->connection->getPostProcessor()->processColumnListing($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a table on the schema.
|
||||
*
|
||||
* @param string $table
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public function table($table, Closure $callback)
|
||||
{
|
||||
$this->build($this->createBlueprint($table, $callback));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new table on the schema.
|
||||
*
|
||||
* @param string $table
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public function create($table, Closure $callback)
|
||||
{
|
||||
$this->build(tap($this->createBlueprint($table), function ($blueprint) use ($callback) {
|
||||
$blueprint->create();
|
||||
|
||||
$callback($blueprint);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a table from the schema.
|
||||
*
|
||||
* @param string $table
|
||||
* @return void
|
||||
*/
|
||||
public function drop($table)
|
||||
{
|
||||
$this->build(tap($this->createBlueprint($table), function ($blueprint) {
|
||||
$blueprint->drop();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a table from the schema if it exists.
|
||||
*
|
||||
* @param string $table
|
||||
* @return void
|
||||
*/
|
||||
public function dropIfExists($table)
|
||||
{
|
||||
$this->build(tap($this->createBlueprint($table), function ($blueprint) {
|
||||
$blueprint->dropIfExists();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop columns from a table schema.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string|array $columns
|
||||
* @return void
|
||||
*/
|
||||
public function dropColumns($table, $columns)
|
||||
{
|
||||
$this->table($table, function (Blueprint $blueprint) use ($columns) {
|
||||
$blueprint->dropColumn($columns);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all tables from the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function dropAllTables()
|
||||
{
|
||||
throw new LogicException('This database driver does not support dropping all tables.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all views from the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function dropAllViews()
|
||||
{
|
||||
throw new LogicException('This database driver does not support dropping all views.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all types from the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function dropAllTypes()
|
||||
{
|
||||
throw new LogicException('This database driver does not support dropping all types.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the table names for the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function getAllTables()
|
||||
{
|
||||
throw new LogicException('This database driver does not support getting all tables.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a table on the schema.
|
||||
*
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @return void
|
||||
*/
|
||||
public function rename($from, $to)
|
||||
{
|
||||
$this->build(tap($this->createBlueprint($from), function ($blueprint) use ($to) {
|
||||
$blueprint->rename($to);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable foreign key constraints.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enableForeignKeyConstraints()
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileEnableForeignKeyConstraints()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable foreign key constraints.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function disableForeignKeyConstraints()
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileDisableForeignKeyConstraints()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the blueprint to build / modify the table.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return void
|
||||
*/
|
||||
protected function build(Blueprint $blueprint)
|
||||
{
|
||||
$blueprint->build($this->connection, $this->grammar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new command set with a Closure.
|
||||
*
|
||||
* @param string $table
|
||||
* @param \Closure|null $callback
|
||||
* @return \Illuminate\Database\Schema\Blueprint
|
||||
*/
|
||||
protected function createBlueprint($table, Closure $callback = null)
|
||||
{
|
||||
$prefix = $this->connection->getConfig('prefix_indexes')
|
||||
? $this->connection->getConfig('prefix')
|
||||
: '';
|
||||
|
||||
if (isset($this->resolver)) {
|
||||
return call_user_func($this->resolver, $table, $callback, $prefix);
|
||||
}
|
||||
|
||||
return new Blueprint($table, $callback, $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom Doctrine mapping type.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @return void
|
||||
*
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function registerCustomDoctrineType($class, $name, $type)
|
||||
{
|
||||
if (! $this->connection->isDoctrineAvailable()) {
|
||||
throw new RuntimeException(
|
||||
'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).'
|
||||
);
|
||||
}
|
||||
|
||||
if (! Type::hasType($name)) {
|
||||
Type::addType($name, $class);
|
||||
|
||||
$this->connection
|
||||
->getDoctrineSchemaManager()
|
||||
->getDatabasePlatform()
|
||||
->registerDoctrineTypeMapping($type, $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database connection instance.
|
||||
*
|
||||
* @return \Illuminate\Database\Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the database connection instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return $this
|
||||
*/
|
||||
public function setConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Schema Blueprint resolver callback.
|
||||
*
|
||||
* @param \Closure $resolver
|
||||
* @return void
|
||||
*/
|
||||
public function blueprintResolver(Closure $resolver)
|
||||
{
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
/**
|
||||
* @method $this after(string $column) Place the column "after" another column (MySQL)
|
||||
* @method $this always() Used as a modifier for generatedAs() (PostgreSQL)
|
||||
* @method $this autoIncrement() Set INTEGER columns as auto-increment (primary key)
|
||||
* @method $this change() Change the column
|
||||
* @method $this charset(string $charset) Specify a character set for the column (MySQL)
|
||||
* @method $this collation(string $collation) Specify a collation for the column (MySQL/PostgreSQL/SQL Server)
|
||||
* @method $this comment(string $comment) Add a comment to the column (MySQL/PostgreSQL)
|
||||
* @method $this default(mixed $value) Specify a "default" value for the column
|
||||
* @method $this first() Place the column "first" in the table (MySQL)
|
||||
* @method $this generatedAs(string|Expression $expression = null) Create a SQL compliant identity column (PostgreSQL)
|
||||
* @method $this index(string $indexName = null) Add an index
|
||||
* @method $this nullable(bool $value = true) Allow NULL values to be inserted into the column
|
||||
* @method $this persisted() Mark the computed generated column as persistent (SQL Server)
|
||||
* @method $this primary() Add a primary index
|
||||
* @method $this spatialIndex() Add a spatial index
|
||||
* @method $this startingValue(int $startingValue) Set the starting value of an auto-incrementing field (MySQL/PostgreSQL)
|
||||
* @method $this storedAs(string $expression) Create a stored generated column (MySQL/PostgreSQL/SQLite)
|
||||
* @method $this type(string $type) Specify a type for the column
|
||||
* @method $this unique(string $indexName = null) Add a unique index
|
||||
* @method $this unsigned() Set the INTEGER column as UNSIGNED (MySQL)
|
||||
* @method $this useCurrent() Set the TIMESTAMP column to use CURRENT_TIMESTAMP as default value
|
||||
* @method $this useCurrentOnUpdate() Set the TIMESTAMP column to use CURRENT_TIMESTAMP when updating (MySQL)
|
||||
* @method $this virtualAs(string $expression) Create a virtual generated column (MySQL/PostgreSQL/SQLite)
|
||||
*/
|
||||
class ColumnDefinition extends Fluent
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ForeignIdColumnDefinition extends ColumnDefinition
|
||||
{
|
||||
/**
|
||||
* The schema builder blueprint instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Schema\Blueprint
|
||||
*/
|
||||
protected $blueprint;
|
||||
|
||||
/**
|
||||
* Create a new foreign ID column definition.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Blueprint $blueprint, $attributes = [])
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
|
||||
$this->blueprint = $blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a foreign key constraint on this column referencing the "id" column of the conventionally related table.
|
||||
*
|
||||
* @param string|null $table
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ForeignKeyDefinition
|
||||
*/
|
||||
public function constrained($table = null, $column = 'id')
|
||||
{
|
||||
return $this->references($column)->on($table ?? Str::plural(Str::beforeLast($this->name, '_'.$column)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify which column this foreign ID references on another table.
|
||||
*
|
||||
* @param string $column
|
||||
* @return \Illuminate\Database\Schema\ForeignKeyDefinition
|
||||
*/
|
||||
public function references($column)
|
||||
{
|
||||
return $this->blueprint->foreign($this->name)->references($column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
/**
|
||||
* @method ForeignKeyDefinition deferrable(bool $value = true) Set the foreign key as deferrable (PostgreSQL)
|
||||
* @method ForeignKeyDefinition initiallyImmediate(bool $value = true) Set the default time to check the constraint (PostgreSQL)
|
||||
* @method ForeignKeyDefinition on(string $table) Specify the referenced table
|
||||
* @method ForeignKeyDefinition onDelete(string $action) Add an ON DELETE action
|
||||
* @method ForeignKeyDefinition onUpdate(string $action) Add an ON UPDATE action
|
||||
* @method ForeignKeyDefinition references(string|array $columns) Specify the referenced column(s)
|
||||
*/
|
||||
class ForeignKeyDefinition extends Fluent
|
||||
{
|
||||
/**
|
||||
* Indicate that updates should cascade.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cascadeOnUpdate()
|
||||
{
|
||||
return $this->onUpdate('cascade');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that deletes should cascade.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cascadeOnDelete()
|
||||
{
|
||||
return $this->onDelete('cascade');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that deletes should be restricted.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function restrictOnDelete()
|
||||
{
|
||||
return $this->onDelete('restrict');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that deletes should set the foreign key value to null.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function nullOnDelete()
|
||||
{
|
||||
return $this->onDelete('set null');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager as SchemaManager;
|
||||
use Doctrine\DBAL\Schema\Comparator;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Fluent;
|
||||
use RuntimeException;
|
||||
|
||||
class ChangeColumn
|
||||
{
|
||||
/**
|
||||
* Compile a change column command into a series of SQL statements.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public static function compile($grammar, Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
if (! $connection->isDoctrineAvailable()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Changing columns for table "%s" requires Doctrine DBAL. Please install the doctrine/dbal package.',
|
||||
$blueprint->getTable()
|
||||
));
|
||||
}
|
||||
|
||||
$schema = $connection->getDoctrineSchemaManager();
|
||||
$databasePlatform = $schema->getDatabasePlatform();
|
||||
$databasePlatform->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
$tableDiff = static::getChangedDiff(
|
||||
$grammar, $blueprint, $schema
|
||||
);
|
||||
|
||||
if ($tableDiff !== false) {
|
||||
return (array) $databasePlatform->getAlterTableSQL($tableDiff);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Doctrine table difference for the given changes.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
|
||||
* @return \Doctrine\DBAL\Schema\TableDiff|bool
|
||||
*/
|
||||
protected static function getChangedDiff($grammar, Blueprint $blueprint, SchemaManager $schema)
|
||||
{
|
||||
$current = $schema->listTableDetails($grammar->getTablePrefix().$blueprint->getTable());
|
||||
|
||||
return (new Comparator)->diffTable(
|
||||
$current, static::getTableWithColumnChanges($blueprint, $current)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a copy of the given Doctrine table after making the column changes.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Doctrine\DBAL\Schema\Table $table
|
||||
* @return \Doctrine\DBAL\Schema\Table
|
||||
*/
|
||||
protected static function getTableWithColumnChanges(Blueprint $blueprint, Table $table)
|
||||
{
|
||||
$table = clone $table;
|
||||
|
||||
foreach ($blueprint->getChangedColumns() as $fluent) {
|
||||
$column = static::getDoctrineColumn($table, $fluent);
|
||||
|
||||
// Here we will spin through each fluent column definition and map it to the proper
|
||||
// Doctrine column definitions - which is necessary because Laravel and Doctrine
|
||||
// use some different terminology for various column attributes on the tables.
|
||||
foreach ($fluent->getAttributes() as $key => $value) {
|
||||
if (! is_null($option = static::mapFluentOptionToDoctrine($key))) {
|
||||
if (method_exists($column, $method = 'set'.ucfirst($option))) {
|
||||
$column->{$method}(static::mapFluentValueToDoctrine($option, $value));
|
||||
continue;
|
||||
}
|
||||
|
||||
$column->setCustomSchemaOption($option, static::mapFluentValueToDoctrine($option, $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Doctrine column instance for a column change.
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Table $table
|
||||
* @param \Illuminate\Support\Fluent $fluent
|
||||
* @return \Doctrine\DBAL\Schema\Column
|
||||
*/
|
||||
protected static function getDoctrineColumn(Table $table, Fluent $fluent)
|
||||
{
|
||||
return $table->changeColumn(
|
||||
$fluent['name'], static::getDoctrineColumnChangeOptions($fluent)
|
||||
)->getColumn($fluent['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Doctrine column change options.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $fluent
|
||||
* @return array
|
||||
*/
|
||||
protected static function getDoctrineColumnChangeOptions(Fluent $fluent)
|
||||
{
|
||||
$options = ['type' => static::getDoctrineColumnType($fluent['type'])];
|
||||
|
||||
if (in_array($fluent['type'], ['text', 'mediumText', 'longText'])) {
|
||||
$options['length'] = static::calculateDoctrineTextLength($fluent['type']);
|
||||
}
|
||||
|
||||
if (static::doesntNeedCharacterOptions($fluent['type'])) {
|
||||
$options['customSchemaOptions'] = [
|
||||
'collation' => '',
|
||||
'charset' => '',
|
||||
];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the doctrine column type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return \Doctrine\DBAL\Types\Type
|
||||
*/
|
||||
protected static function getDoctrineColumnType($type)
|
||||
{
|
||||
$type = strtolower($type);
|
||||
|
||||
switch ($type) {
|
||||
case 'biginteger':
|
||||
$type = 'bigint';
|
||||
break;
|
||||
case 'smallinteger':
|
||||
$type = 'smallint';
|
||||
break;
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'binary':
|
||||
$type = 'blob';
|
||||
break;
|
||||
case 'uuid':
|
||||
$type = 'guid';
|
||||
break;
|
||||
}
|
||||
|
||||
return Type::getType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the proper column length to force the Doctrine text type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return int
|
||||
*/
|
||||
protected static function calculateDoctrineTextLength($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'mediumText':
|
||||
return 65535 + 1;
|
||||
case 'longText':
|
||||
return 16777215 + 1;
|
||||
default:
|
||||
return 255 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given type does not need character / collation options.
|
||||
*
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
protected static function doesntNeedCharacterOptions($type)
|
||||
{
|
||||
return in_array($type, [
|
||||
'bigInteger',
|
||||
'binary',
|
||||
'boolean',
|
||||
'date',
|
||||
'decimal',
|
||||
'double',
|
||||
'float',
|
||||
'integer',
|
||||
'json',
|
||||
'mediumInteger',
|
||||
'smallInteger',
|
||||
'time',
|
||||
'tinyInteger',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matching Doctrine option for a given Fluent attribute name.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function mapFluentOptionToDoctrine($attribute)
|
||||
{
|
||||
switch ($attribute) {
|
||||
case 'type':
|
||||
case 'name':
|
||||
return;
|
||||
case 'nullable':
|
||||
return 'notnull';
|
||||
case 'total':
|
||||
return 'precision';
|
||||
case 'places':
|
||||
return 'scale';
|
||||
default:
|
||||
return $attribute;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matching Doctrine value for a given Fluent attribute.
|
||||
*
|
||||
* @param string $option
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function mapFluentValueToDoctrine($option, $value)
|
||||
{
|
||||
return $option === 'notnull' ? ! $value : $value;
|
||||
}
|
||||
}
|
||||
+314
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager as SchemaManager;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\Grammar as BaseGrammar;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Fluent;
|
||||
use LogicException;
|
||||
use RuntimeException;
|
||||
|
||||
abstract class Grammar extends BaseGrammar
|
||||
{
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
return RenameColumn::compile($this, $blueprint, $command, $connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
return ChangeColumn::compile($this, $blueprint, $command, $connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 the blueprint's 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 have 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 primary key command 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;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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\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 $value;
|
||||
}
|
||||
|
||||
return is_bool($value)
|
||||
? "'".(int) $value."'"
|
||||
: "'".(string) $value."'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty Doctrine DBAL TableDiff from the Blueprint.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
|
||||
* @return \Doctrine\DBAL\Schema\TableDiff
|
||||
*/
|
||||
public function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema)
|
||||
{
|
||||
$table = $this->getTablePrefix().$blueprint->getTable();
|
||||
|
||||
return tap(new TableDiff($table), function ($tableDiff) use ($schema, $table) {
|
||||
$tableDiff->fromTable = $schema->listTableDetails($table);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
+1115
@@ -0,0 +1,1115 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Fluent;
|
||||
use RuntimeException;
|
||||
|
||||
class MySqlGrammar extends Grammar
|
||||
{
|
||||
/**
|
||||
* The possible column modifiers.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $modifiers = [
|
||||
'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable',
|
||||
'Srid', 'Default', 'Increment', 'Comment', 'After', 'First',
|
||||
];
|
||||
|
||||
/**
|
||||
* The possible column serials.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
|
||||
|
||||
/**
|
||||
* Compile a create database command.
|
||||
*
|
||||
* @param string $name
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return string
|
||||
*/
|
||||
public function compileCreateDatabase($name, $connection)
|
||||
{
|
||||
return sprintf(
|
||||
'create database %s default character set %s default collate %s',
|
||||
$this->wrapValue($name),
|
||||
$this->wrapValue($connection->getConfig('charset')),
|
||||
$this->wrapValue($connection->getConfig('collation')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop database if exists command.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropDatabaseIfExists($name)
|
||||
{
|
||||
return sprintf(
|
||||
'drop database if exists %s',
|
||||
$this->wrapValue($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine the list of tables.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileTableExists()
|
||||
{
|
||||
return "select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine the list of columns.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileColumnListing()
|
||||
{
|
||||
return 'select column_name as `column_name` from information_schema.columns where table_schema = ? and table_name = ?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a create table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return array
|
||||
*/
|
||||
public function compileCreate(Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
$sql = $this->compileCreateTable(
|
||||
$blueprint, $command, $connection
|
||||
);
|
||||
|
||||
// Once we have the primary SQL, we can add the encoding option to the SQL for
|
||||
// the table. Then, we can check if a storage engine has been supplied for
|
||||
// the table. If so, we will add the engine declaration to the SQL query.
|
||||
$sql = $this->compileCreateEncoding(
|
||||
$sql, $connection, $blueprint
|
||||
);
|
||||
|
||||
// Finally, we will append the engine configuration onto this SQL statement as
|
||||
// the final thing we do before returning this finished SQL. Once this gets
|
||||
// added the query will be ready to execute against the real connections.
|
||||
return array_values(array_filter(array_merge([$this->compileCreateEngine(
|
||||
$sql, $connection, $blueprint
|
||||
)], $this->compileAutoIncrementStartingValues($blueprint))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the main create table clause.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return array
|
||||
*/
|
||||
protected function compileCreateTable($blueprint, $command, $connection)
|
||||
{
|
||||
return trim(sprintf('%s table %s (%s)',
|
||||
$blueprint->temporary ? 'create temporary' : 'create',
|
||||
$this->wrapTable($blueprint),
|
||||
implode(', ', $this->getColumns($blueprint))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the character set specifications to a command.
|
||||
*
|
||||
* @param string $sql
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return string
|
||||
*/
|
||||
protected function compileCreateEncoding($sql, Connection $connection, Blueprint $blueprint)
|
||||
{
|
||||
// First we will set the character set if one has been set on either the create
|
||||
// blueprint itself or on the root configuration for the connection that the
|
||||
// table is being created on. We will add these to the create table query.
|
||||
if (isset($blueprint->charset)) {
|
||||
$sql .= ' default character set '.$blueprint->charset;
|
||||
} elseif (! is_null($charset = $connection->getConfig('charset'))) {
|
||||
$sql .= ' default character set '.$charset;
|
||||
}
|
||||
|
||||
// Next we will add the collation to the create table statement if one has been
|
||||
// added to either this create table blueprint or the configuration for this
|
||||
// connection that the query is targeting. We'll add it to this SQL query.
|
||||
if (isset($blueprint->collation)) {
|
||||
$sql .= " collate '{$blueprint->collation}'";
|
||||
} elseif (! is_null($collation = $connection->getConfig('collation'))) {
|
||||
$sql .= " collate '{$collation}'";
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the engine specifications to a command.
|
||||
*
|
||||
* @param string $sql
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return string
|
||||
*/
|
||||
protected function compileCreateEngine($sql, Connection $connection, Blueprint $blueprint)
|
||||
{
|
||||
if (isset($blueprint->engine)) {
|
||||
return $sql.' engine = '.$blueprint->engine;
|
||||
} elseif (! is_null($engine = $connection->getConfig('engine'))) {
|
||||
return $sql.' engine = '.$engine;
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile an add column command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return array
|
||||
*/
|
||||
public function compileAdd(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = $this->prefixArray('add', $this->getColumns($blueprint));
|
||||
|
||||
return array_values(array_merge(
|
||||
['alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns)],
|
||||
$this->compileAutoIncrementStartingValues($blueprint)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the auto-incrementing column starting values.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return array
|
||||
*/
|
||||
public function compileAutoIncrementStartingValues(Blueprint $blueprint)
|
||||
{
|
||||
return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) {
|
||||
return 'alter table '.$this->wrapTable($blueprint->getTable()).' auto_increment = '.$value;
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a primary key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compilePrimary(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$command->name(null);
|
||||
|
||||
return $this->compileKey($blueprint, $command, 'primary key');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return $this->compileKey($blueprint, $command, 'unique');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a plain index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return $this->compileKey($blueprint, $command, 'index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a spatial index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return $this->compileKey($blueprint, $command, 'spatial index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile an index creation command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
protected function compileKey(Blueprint $blueprint, Fluent $command, $type)
|
||||
{
|
||||
return sprintf('alter table %s add %s %s%s(%s)',
|
||||
$this->wrapTable($blueprint),
|
||||
$type,
|
||||
$this->wrap($command->index),
|
||||
$command->algorithm ? ' using '.$command->algorithm : '',
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDrop(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table (if exists) command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table if exists '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop column command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropColumn(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = $this->prefixArray('drop', $this->wrapArray($command->columns));
|
||||
|
||||
return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop primary key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'alter table '.$this->wrapTable($blueprint).' drop primary key';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop index {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop index {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop spatial index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return $this->compileDropIndex($blueprint, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop foreign key {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRename(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$from = $this->wrapTable($blueprint);
|
||||
|
||||
return "rename table {$from} to ".$this->wrapTable($command->to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('alter table %s rename index %s to %s',
|
||||
$this->wrapTable($blueprint),
|
||||
$this->wrap($command->from),
|
||||
$this->wrap($command->to)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all tables.
|
||||
*
|
||||
* @param array $tables
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllTables($tables)
|
||||
{
|
||||
return 'drop table '.implode(',', $this->wrapArray($tables));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all views.
|
||||
*
|
||||
* @param array $views
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllViews($views)
|
||||
{
|
||||
return 'drop view '.implode(',', $this->wrapArray($views));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to retrieve all table names.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileGetAllTables()
|
||||
{
|
||||
return 'SHOW FULL TABLES WHERE table_type = \'BASE TABLE\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to retrieve all view names.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileGetAllViews()
|
||||
{
|
||||
return 'SHOW FULL TABLES WHERE table_type = \'VIEW\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to enable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEnableForeignKeyConstraints()
|
||||
{
|
||||
return 'SET FOREIGN_KEY_CHECKS=1;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to disable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDisableForeignKeyConstraints()
|
||||
{
|
||||
return 'SET FOREIGN_KEY_CHECKS=0;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a char type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeChar(Fluent $column)
|
||||
{
|
||||
return "char({$column->length})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a string type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeString(Fluent $column)
|
||||
{
|
||||
return "varchar({$column->length})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyText(Fluent $column)
|
||||
{
|
||||
return 'tinytext';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumText(Fluent $column)
|
||||
{
|
||||
return 'mediumtext';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a long text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeLongText(Fluent $column)
|
||||
{
|
||||
return 'longtext';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a big integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBigInteger(Fluent $column)
|
||||
{
|
||||
return 'bigint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeInteger(Fluent $column)
|
||||
{
|
||||
return 'int';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumInteger(Fluent $column)
|
||||
{
|
||||
return 'mediumint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyInteger(Fluent $column)
|
||||
{
|
||||
return 'tinyint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a small integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeSmallInteger(Fluent $column)
|
||||
{
|
||||
return 'smallint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a float type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeFloat(Fluent $column)
|
||||
{
|
||||
return $this->typeDouble($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a double type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDouble(Fluent $column)
|
||||
{
|
||||
if ($column->total && $column->places) {
|
||||
return "double({$column->total}, {$column->places})";
|
||||
}
|
||||
|
||||
return 'double';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a decimal type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDecimal(Fluent $column)
|
||||
{
|
||||
return "decimal({$column->total}, {$column->places})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a boolean type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBoolean(Fluent $column)
|
||||
{
|
||||
return 'tinyint(1)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an enumeration type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeEnum(Fluent $column)
|
||||
{
|
||||
return sprintf('enum(%s)', $this->quoteString($column->allowed));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a set enumeration type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeSet(Fluent $column)
|
||||
{
|
||||
return sprintf('set(%s)', $this->quoteString($column->allowed));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a json type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJson(Fluent $column)
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a jsonb type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJsonb(Fluent $column)
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDate(Fluent $column)
|
||||
{
|
||||
return 'date';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTime(Fluent $column)
|
||||
{
|
||||
$columnType = $column->precision ? "datetime($column->precision)" : 'datetime';
|
||||
|
||||
$current = $column->precision ? "CURRENT_TIMESTAMP($column->precision)" : 'CURRENT_TIMESTAMP';
|
||||
|
||||
$columnType = $column->useCurrent ? "$columnType default $current" : $columnType;
|
||||
|
||||
return $column->useCurrentOnUpdate ? "$columnType on update $current" : $columnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeDateTime($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTime(Fluent $column)
|
||||
{
|
||||
return $column->precision ? "time($column->precision)" : 'time';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTime($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestamp(Fluent $column)
|
||||
{
|
||||
$columnType = $column->precision ? "timestamp($column->precision)" : 'timestamp';
|
||||
|
||||
$current = $column->precision ? "CURRENT_TIMESTAMP($column->precision)" : 'CURRENT_TIMESTAMP';
|
||||
|
||||
$columnType = $column->useCurrent ? "$columnType default $current" : $columnType;
|
||||
|
||||
return $column->useCurrentOnUpdate ? "$columnType on update $current" : $columnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestampTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestamp($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a year type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeYear(Fluent $column)
|
||||
{
|
||||
return 'year';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a binary type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBinary(Fluent $column)
|
||||
{
|
||||
return 'blob';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a uuid type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeUuid(Fluent $column)
|
||||
{
|
||||
return 'char(36)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an IP address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeIpAddress(Fluent $column)
|
||||
{
|
||||
return 'varchar(45)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a MAC address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMacAddress(Fluent $column)
|
||||
{
|
||||
return 'varchar(17)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Geometry type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeGeometry(Fluent $column)
|
||||
{
|
||||
return 'geometry';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Point type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typePoint(Fluent $column)
|
||||
{
|
||||
return 'point';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial LineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeLineString(Fluent $column)
|
||||
{
|
||||
return 'linestring';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Polygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typePolygon(Fluent $column)
|
||||
{
|
||||
return 'polygon';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial GeometryCollection type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeGeometryCollection(Fluent $column)
|
||||
{
|
||||
return 'geometrycollection';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPoint type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiPoint(Fluent $column)
|
||||
{
|
||||
return 'multipoint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiLineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiLineString(Fluent $column)
|
||||
{
|
||||
return 'multilinestring';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPolygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiPolygon(Fluent $column)
|
||||
{
|
||||
return 'multipolygon';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 requires a type, see the virtualAs / storedAs modifiers.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated virtual column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->virtualAs)) {
|
||||
return " as ({$column->virtualAs})";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated stored column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->storedAs)) {
|
||||
return " as ({$column->storedAs}) stored";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for an unsigned column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyUnsigned(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if ($column->unsigned) {
|
||||
return ' unsigned';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a character set column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyCharset(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->charset)) {
|
||||
return ' character set '.$column->charset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a collation column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyCollate(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->collation)) {
|
||||
return " collate '{$column->collation}'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a nullable column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyNullable(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (is_null($column->virtualAs) && is_null($column->storedAs)) {
|
||||
return $column->nullable ? ' null' : ' not null';
|
||||
}
|
||||
|
||||
if ($column->nullable === false) {
|
||||
return ' not null';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a default column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyDefault(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->default)) {
|
||||
return ' default '.$this->getDefaultValue($column->default);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for an auto-increment column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
|
||||
return ' auto_increment primary key';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a "first" column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyFirst(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->first)) {
|
||||
return ' first';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for an "after" column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyAfter(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->after)) {
|
||||
return ' after '.$this->wrap($column->after);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a "comment" column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyComment(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->comment)) {
|
||||
return " comment '".addslashes($column->comment)."'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a SRID column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifySrid(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->srid) && is_int($column->srid) && $column->srid > 0) {
|
||||
return ' srid '.$column->srid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a single string in keyword identifiers.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function wrapValue($value)
|
||||
{
|
||||
if ($value !== '*') {
|
||||
return '`'.str_replace('`', '``', $value).'`';
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
+1037
@@ -0,0 +1,1037 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
class PostgresGrammar extends Grammar
|
||||
{
|
||||
/**
|
||||
* If this Grammar supports schema changes wrapped in a transaction.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $transactions = true;
|
||||
|
||||
/**
|
||||
* The possible column modifiers.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $modifiers = ['Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs'];
|
||||
|
||||
/**
|
||||
* The columns available as serials.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
|
||||
|
||||
/**
|
||||
* The commands to be executed outside of create or alter command.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fluentCommands = ['Comment'];
|
||||
|
||||
/**
|
||||
* Compile a create database command.
|
||||
*
|
||||
* @param string $name
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return string
|
||||
*/
|
||||
public function compileCreateDatabase($name, $connection)
|
||||
{
|
||||
return sprintf(
|
||||
'create database %s encoding %s',
|
||||
$this->wrapValue($name),
|
||||
$this->wrapValue($connection->getConfig('charset')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop database if exists command.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropDatabaseIfExists($name)
|
||||
{
|
||||
return sprintf(
|
||||
'drop database if exists %s',
|
||||
$this->wrapValue($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine if a table exists.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileTableExists()
|
||||
{
|
||||
return "select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine the list of columns.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileColumnListing()
|
||||
{
|
||||
return 'select column_name from information_schema.columns where table_schema = ? and table_name = ?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a create table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return array
|
||||
*/
|
||||
public function compileCreate(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return array_values(array_filter(array_merge([sprintf('%s table %s (%s)',
|
||||
$blueprint->temporary ? 'create temporary' : 'create',
|
||||
$this->wrapTable($blueprint),
|
||||
implode(', ', $this->getColumns($blueprint))
|
||||
)], $this->compileAutoIncrementStartingValues($blueprint))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a column addition command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileAdd(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return array_values(array_filter(array_merge([sprintf('alter table %s %s',
|
||||
$this->wrapTable($blueprint),
|
||||
implode(', ', $this->prefixArray('add column', $this->getColumns($blueprint)))
|
||||
)], $this->compileAutoIncrementStartingValues($blueprint))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the auto-incrementing column starting values.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return array
|
||||
*/
|
||||
public function compileAutoIncrementStartingValues(Blueprint $blueprint)
|
||||
{
|
||||
return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) {
|
||||
return 'alter sequence '.$blueprint->getTable().'_'.$column.'_seq restart with '.$value;
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a primary key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compilePrimary(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = $this->columnize($command->columns);
|
||||
|
||||
return 'alter table '.$this->wrapTable($blueprint)." add primary key ({$columns})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('alter table %s add constraint %s unique (%s)',
|
||||
$this->wrapTable($blueprint),
|
||||
$this->wrap($command->index),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a plain index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('create index %s on %s%s (%s)',
|
||||
$this->wrap($command->index),
|
||||
$this->wrapTable($blueprint),
|
||||
$command->algorithm ? ' using '.$command->algorithm : '',
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a spatial index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$command->algorithm = 'gist';
|
||||
|
||||
return $this->compileIndex($blueprint, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$sql = parent::compileForeign($blueprint, $command);
|
||||
|
||||
if (! is_null($command->deferrable)) {
|
||||
$sql .= $command->deferrable ? ' deferrable' : ' not deferrable';
|
||||
}
|
||||
|
||||
if ($command->deferrable && ! is_null($command->initiallyImmediate)) {
|
||||
$sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';
|
||||
}
|
||||
|
||||
if (! is_null($command->notValid)) {
|
||||
$sql .= ' not valid';
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDrop(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table (if exists) command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table if exists '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all tables.
|
||||
*
|
||||
* @param array $tables
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllTables($tables)
|
||||
{
|
||||
return 'drop table "'.implode('","', $tables).'" cascade';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all views.
|
||||
*
|
||||
* @param array $views
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllViews($views)
|
||||
{
|
||||
return 'drop view "'.implode('","', $views).'" cascade';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all types.
|
||||
*
|
||||
* @param array $types
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllTypes($types)
|
||||
{
|
||||
return 'drop type "'.implode('","', $types).'" cascade';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to retrieve all table names.
|
||||
*
|
||||
* @param string|array $schema
|
||||
* @return string
|
||||
*/
|
||||
public function compileGetAllTables($schema)
|
||||
{
|
||||
return "select tablename from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $schema)."')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to retrieve all view names.
|
||||
*
|
||||
* @param string|array $schema
|
||||
* @return string
|
||||
*/
|
||||
public function compileGetAllViews($schema)
|
||||
{
|
||||
return "select viewname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $schema)."')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to retrieve all type names.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileGetAllTypes()
|
||||
{
|
||||
return 'select distinct pg_type.typname from pg_type inner join pg_enum on pg_enum.enumtypid = pg_type.oid';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop column command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropColumn(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));
|
||||
|
||||
return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop primary key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap("{$blueprint->getTable()}_pkey");
|
||||
|
||||
return 'alter table '.$this->wrapTable($blueprint)." drop constraint {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return "drop index {$this->wrap($command->index)}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop spatial index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return $this->compileDropIndex($blueprint, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRename(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$from = $this->wrapTable($blueprint);
|
||||
|
||||
return "alter table {$from} rename to ".$this->wrapTable($command->to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('alter index %s rename to %s',
|
||||
$this->wrap($command->from),
|
||||
$this->wrap($command->to)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to enable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEnableForeignKeyConstraints()
|
||||
{
|
||||
return 'SET CONSTRAINTS ALL IMMEDIATE;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to disable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDisableForeignKeyConstraints()
|
||||
{
|
||||
return 'SET CONSTRAINTS ALL DEFERRED;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a comment command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileComment(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('comment on column %s.%s is %s',
|
||||
$this->wrapTable($blueprint),
|
||||
$this->wrap($command->column->name),
|
||||
"'".str_replace("'", "''", $command->value)."'"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a char type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeChar(Fluent $column)
|
||||
{
|
||||
return "char({$column->length})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a string type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeString(Fluent $column)
|
||||
{
|
||||
return "varchar({$column->length})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyText(Fluent $column)
|
||||
{
|
||||
return 'varchar(255)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a long text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeLongText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeInteger(Fluent $column)
|
||||
{
|
||||
return $this->generatableColumn('integer', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a big integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBigInteger(Fluent $column)
|
||||
{
|
||||
return $this->generatableColumn('bigint', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumInteger(Fluent $column)
|
||||
{
|
||||
return $this->generatableColumn('integer', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyInteger(Fluent $column)
|
||||
{
|
||||
return $this->generatableColumn('smallint', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a small integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeSmallInteger(Fluent $column)
|
||||
{
|
||||
return $this->generatableColumn('smallint', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a generatable column.
|
||||
*
|
||||
* @param string $type
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function generatableColumn($type, Fluent $column)
|
||||
{
|
||||
if (! $column->autoIncrement && is_null($column->generatedAs)) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
if ($column->autoIncrement && is_null($column->generatedAs)) {
|
||||
return with([
|
||||
'integer' => 'serial',
|
||||
'bigint' => 'bigserial',
|
||||
'smallint' => 'smallserial',
|
||||
])[$type];
|
||||
}
|
||||
|
||||
$options = '';
|
||||
|
||||
if (! is_bool($column->generatedAs) && ! empty($column->generatedAs)) {
|
||||
$options = sprintf(' (%s)', $column->generatedAs);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s generated %s as identity%s',
|
||||
$type,
|
||||
$column->always ? 'always' : 'by default',
|
||||
$options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a float type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeFloat(Fluent $column)
|
||||
{
|
||||
return $this->typeDouble($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a double type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDouble(Fluent $column)
|
||||
{
|
||||
return 'double precision';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a real type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeReal(Fluent $column)
|
||||
{
|
||||
return 'real';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a decimal type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDecimal(Fluent $column)
|
||||
{
|
||||
return "decimal({$column->total}, {$column->places})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a boolean type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBoolean(Fluent $column)
|
||||
{
|
||||
return 'boolean';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an enumeration type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeEnum(Fluent $column)
|
||||
{
|
||||
return sprintf(
|
||||
'varchar(255) check ("%s" in (%s))',
|
||||
$column->name,
|
||||
$this->quoteString($column->allowed)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a json type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJson(Fluent $column)
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a jsonb type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJsonb(Fluent $column)
|
||||
{
|
||||
return 'jsonb';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDate(Fluent $column)
|
||||
{
|
||||
return 'date';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTime(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestamp($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestampTz($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTime(Fluent $column)
|
||||
{
|
||||
return 'time'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimeTz(Fluent $column)
|
||||
{
|
||||
return 'time'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestamp(Fluent $column)
|
||||
{
|
||||
$columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone';
|
||||
|
||||
return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestampTz(Fluent $column)
|
||||
{
|
||||
$columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone';
|
||||
|
||||
return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a year type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeYear(Fluent $column)
|
||||
{
|
||||
return $this->typeInteger($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a binary type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBinary(Fluent $column)
|
||||
{
|
||||
return 'bytea';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a uuid type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeUuid(Fluent $column)
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an IP address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeIpAddress(Fluent $column)
|
||||
{
|
||||
return 'inet';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a MAC address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMacAddress(Fluent $column)
|
||||
{
|
||||
return 'macaddr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Geometry type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeGeometry(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('geometry', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Point type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typePoint(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('point', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial LineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeLineString(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('linestring', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Polygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typePolygon(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('polygon', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial GeometryCollection type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeGeometryCollection(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('geometrycollection', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPoint type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMultiPoint(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('multipoint', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiLineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiLineString(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('multilinestring', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPolygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMultiPolygon(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('multipolygon', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPolygonZ type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMultiPolygonZ(Fluent $column)
|
||||
{
|
||||
return $this->formatPostGisType('multipolygonz', $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the column definition for a PostGIS spatial type.
|
||||
*
|
||||
* @param string $type
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
private function formatPostGisType($type, Fluent $column)
|
||||
{
|
||||
if ($column->isGeometry === null) {
|
||||
return sprintf('geography(%s, %s)', $type, $column->projection ?? '4326');
|
||||
}
|
||||
|
||||
if ($column->projection !== null) {
|
||||
return sprintf('geometry(%s, %s)', $type, $column->projection);
|
||||
}
|
||||
|
||||
return "geometry({$type})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a collation column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyCollate(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->collation)) {
|
||||
return ' collate '.$this->wrapValue($column->collation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a nullable column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyNullable(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
return $column->nullable ? ' null' : ' not null';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a default column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyDefault(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->default)) {
|
||||
return ' default '.$this->getDefaultValue($column->default);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for an auto-increment column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if ((in_array($column->type, $this->serials) || ($column->generatedAs !== null)) && $column->autoIncrement) {
|
||||
return ' primary key';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated virtual column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if ($column->virtualAs !== null) {
|
||||
return " generated always as ({$column->virtualAs})";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated stored column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if ($column->storedAs !== null) {
|
||||
return " generated always as ({$column->storedAs}) stored";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager as SchemaManager;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
class RenameColumn
|
||||
{
|
||||
/**
|
||||
* Compile a rename column command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return array
|
||||
*/
|
||||
public static function compile(Grammar $grammar, Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
$schema = $connection->getDoctrineSchemaManager();
|
||||
$databasePlatform = $schema->getDatabasePlatform();
|
||||
$databasePlatform->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
$column = $connection->getDoctrineColumn(
|
||||
$grammar->getTablePrefix().$blueprint->getTable(), $command->from
|
||||
);
|
||||
|
||||
return (array) $databasePlatform->getAlterTableSQL(static::getRenamedDiff(
|
||||
$grammar, $blueprint, $command, $column, $schema
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new column instance with the new column name.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Doctrine\DBAL\Schema\Column $column
|
||||
* @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema
|
||||
* @return \Doctrine\DBAL\Schema\TableDiff
|
||||
*/
|
||||
protected static function getRenamedDiff(Grammar $grammar, Blueprint $blueprint, Fluent $command, Column $column, SchemaManager $schema)
|
||||
{
|
||||
return static::setRenamedColumns(
|
||||
$grammar->getDoctrineTableDiff($blueprint, $schema), $command, $column
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the renamed columns on the table diff.
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Doctrine\DBAL\Schema\Column $column
|
||||
* @return \Doctrine\DBAL\Schema\TableDiff
|
||||
*/
|
||||
protected static function setRenamedColumns(TableDiff $tableDiff, Fluent $command, Column $column)
|
||||
{
|
||||
$tableDiff->renamedColumns = [
|
||||
$command->from => new Column($command->to, $column->getType(), self::getWritableColumnOptions($column)),
|
||||
];
|
||||
|
||||
return $tableDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the writable column options.
|
||||
*
|
||||
* @param \Doctrine\DBAL\Schema\Column $column
|
||||
* @return array
|
||||
*/
|
||||
private static function getWritableColumnOptions(Column $column)
|
||||
{
|
||||
return array_filter($column->toArray(), function (string $name) use ($column) {
|
||||
return method_exists($column, 'set'.$name);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
}
|
||||
}
|
||||
+925
@@ -0,0 +1,925 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Fluent;
|
||||
use RuntimeException;
|
||||
|
||||
class SQLiteGrammar extends Grammar
|
||||
{
|
||||
/**
|
||||
* The possible column modifiers.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $modifiers = ['VirtualAs', 'StoredAs', 'Nullable', 'Default', 'Increment'];
|
||||
|
||||
/**
|
||||
* The columns available as serials.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
|
||||
|
||||
/**
|
||||
* Compile the query to determine if a table exists.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileTableExists()
|
||||
{
|
||||
return "select * from sqlite_master where type = 'table' and name = ?";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine the list of columns.
|
||||
*
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
public function compileColumnListing($table)
|
||||
{
|
||||
return 'pragma table_info('.$this->wrap(str_replace('.', '__', $table)).')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a create table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileCreate(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('%s table %s (%s%s%s)',
|
||||
$blueprint->temporary ? 'create temporary' : 'create',
|
||||
$this->wrapTable($blueprint),
|
||||
implode(', ', $this->getColumns($blueprint)),
|
||||
(string) $this->addForeignKeys($blueprint),
|
||||
(string) $this->addPrimaryKeys($blueprint)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key syntax for a table creation statement.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return string|null
|
||||
*/
|
||||
protected function addForeignKeys(Blueprint $blueprint)
|
||||
{
|
||||
$foreigns = $this->getCommandsByName($blueprint, 'foreign');
|
||||
|
||||
return collect($foreigns)->reduce(function ($sql, $foreign) {
|
||||
// Once we have all the foreign key commands for the table creation statement
|
||||
// we'll loop through each of them and add them to the create table SQL we
|
||||
// are building, since SQLite needs foreign keys on the tables creation.
|
||||
$sql .= $this->getForeignKey($foreign);
|
||||
|
||||
if (! is_null($foreign->onDelete)) {
|
||||
$sql .= " on delete {$foreign->onDelete}";
|
||||
}
|
||||
|
||||
// If this foreign key specifies the action to be taken on update we will add
|
||||
// that to the statement here. We'll append it to this SQL and then return
|
||||
// the SQL so we can keep adding any other foreign constraints onto this.
|
||||
if (! is_null($foreign->onUpdate)) {
|
||||
$sql .= " on update {$foreign->onUpdate}";
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for the foreign key.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $foreign
|
||||
* @return string
|
||||
*/
|
||||
protected function getForeignKey($foreign)
|
||||
{
|
||||
// We need to columnize the columns that the foreign key is being defined for
|
||||
// so that it is a properly formatted list. Once we have done this, we can
|
||||
// return the foreign key SQL declaration to the calling method for use.
|
||||
return sprintf(', foreign key(%s) references %s(%s)',
|
||||
$this->columnize($foreign->columns),
|
||||
$this->wrapTable($foreign->on),
|
||||
$this->columnize((array) $foreign->references)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary key syntax for a table creation statement.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @return string|null
|
||||
*/
|
||||
protected function addPrimaryKeys(Blueprint $blueprint)
|
||||
{
|
||||
if (! is_null($primary = $this->getCommandByName($blueprint, 'primary'))) {
|
||||
return ", primary key ({$this->columnize($primary->columns)})";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile alter table commands for adding columns.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return array
|
||||
*/
|
||||
public function compileAdd(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = $this->prefixArray('add column', $this->getColumns($blueprint));
|
||||
|
||||
return collect($columns)->reject(function ($column) {
|
||||
return preg_match('/as \(.*\) stored/', $column) > 0;
|
||||
})->map(function ($column) use ($blueprint) {
|
||||
return 'alter table '.$this->wrapTable($blueprint).' '.$column;
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('create unique index %s on %s (%s)',
|
||||
$this->wrap($command->index),
|
||||
$this->wrapTable($blueprint),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a plain index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('create index %s on %s (%s)',
|
||||
$this->wrap($command->index),
|
||||
$this->wrapTable($blueprint),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a spatial index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
throw new RuntimeException('The database driver in use does not support spatial indexes.');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// Handled on table creation...
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDrop(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table (if exists) command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table if exists '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all tables.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllTables()
|
||||
{
|
||||
return "delete from sqlite_master where type in ('table', 'index', 'trigger')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all views.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllViews()
|
||||
{
|
||||
return "delete from sqlite_master where type in ('view')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to rebuild the database.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileRebuild()
|
||||
{
|
||||
return 'vacuum';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop column command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return array
|
||||
*/
|
||||
public function compileDropColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
$tableDiff = $this->getDoctrineTableDiff(
|
||||
$blueprint, $schema = $connection->getDoctrineSchemaManager()
|
||||
);
|
||||
|
||||
foreach ($command->columns as $name) {
|
||||
$tableDiff->removedColumns[$name] = $connection->getDoctrineColumn(
|
||||
$this->getTablePrefix().$blueprint->getTable(), $name
|
||||
);
|
||||
}
|
||||
|
||||
return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "drop index {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "drop index {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop spatial index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
throw new RuntimeException('The database driver in use does not support spatial indexes.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRename(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$from = $this->wrapTable($blueprint);
|
||||
|
||||
return "alter table {$from} rename to ".$this->wrapTable($command->to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function compileRenameIndex(Blueprint $blueprint, Fluent $command, Connection $connection)
|
||||
{
|
||||
$schemaManager = $connection->getDoctrineSchemaManager();
|
||||
|
||||
$indexes = $schemaManager->listTableIndexes($this->getTablePrefix().$blueprint->getTable());
|
||||
|
||||
$index = Arr::get($indexes, $command->from);
|
||||
|
||||
if (! $index) {
|
||||
throw new RuntimeException("Index [{$command->from}] does not exist.");
|
||||
}
|
||||
|
||||
$newIndex = new Index(
|
||||
$command->to, $index->getColumns(), $index->isUnique(),
|
||||
$index->isPrimary(), $index->getFlags(), $index->getOptions()
|
||||
);
|
||||
|
||||
$platform = $schemaManager->getDatabasePlatform();
|
||||
|
||||
return [
|
||||
$platform->getDropIndexSQL($command->from, $this->getTablePrefix().$blueprint->getTable()),
|
||||
$platform->getCreateIndexSQL($newIndex, $this->getTablePrefix().$blueprint->getTable()),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to enable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEnableForeignKeyConstraints()
|
||||
{
|
||||
return 'PRAGMA foreign_keys = ON;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to disable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDisableForeignKeyConstraints()
|
||||
{
|
||||
return 'PRAGMA foreign_keys = OFF;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to enable a writable schema.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEnableWriteableSchema()
|
||||
{
|
||||
return 'PRAGMA writable_schema = 1;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to disable a writable schema.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDisableWriteableSchema()
|
||||
{
|
||||
return 'PRAGMA writable_schema = 0;';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a char type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeChar(Fluent $column)
|
||||
{
|
||||
return 'varchar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a string type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeString(Fluent $column)
|
||||
{
|
||||
return 'varchar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a long text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeLongText(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeInteger(Fluent $column)
|
||||
{
|
||||
return 'integer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a big integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBigInteger(Fluent $column)
|
||||
{
|
||||
return 'integer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumInteger(Fluent $column)
|
||||
{
|
||||
return 'integer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyInteger(Fluent $column)
|
||||
{
|
||||
return 'integer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a small integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeSmallInteger(Fluent $column)
|
||||
{
|
||||
return 'integer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a float type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeFloat(Fluent $column)
|
||||
{
|
||||
return 'float';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a double type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDouble(Fluent $column)
|
||||
{
|
||||
return 'float';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a decimal type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDecimal(Fluent $column)
|
||||
{
|
||||
return 'numeric';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a boolean type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBoolean(Fluent $column)
|
||||
{
|
||||
return 'tinyint(1)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an enumeration type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeEnum(Fluent $column)
|
||||
{
|
||||
return sprintf(
|
||||
'varchar check ("%s" in (%s))',
|
||||
$column->name,
|
||||
$this->quoteString($column->allowed)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a json type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJson(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a jsonb type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJsonb(Fluent $column)
|
||||
{
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDate(Fluent $column)
|
||||
{
|
||||
return 'date';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTime(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestamp($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time (with time zone) type.
|
||||
*
|
||||
* Note: "SQLite does not have a storage class set aside for storing dates and/or times."
|
||||
*
|
||||
* @link https://www.sqlite.org/datatype3.html
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeDateTime($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTime(Fluent $column)
|
||||
{
|
||||
return 'time';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTime($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestamp(Fluent $column)
|
||||
{
|
||||
return $column->useCurrent ? 'datetime default CURRENT_TIMESTAMP' : 'datetime';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestampTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestamp($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a year type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeYear(Fluent $column)
|
||||
{
|
||||
return $this->typeInteger($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a binary type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBinary(Fluent $column)
|
||||
{
|
||||
return 'blob';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a uuid type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeUuid(Fluent $column)
|
||||
{
|
||||
return 'varchar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an IP address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeIpAddress(Fluent $column)
|
||||
{
|
||||
return 'varchar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a MAC address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMacAddress(Fluent $column)
|
||||
{
|
||||
return 'varchar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Geometry type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeGeometry(Fluent $column)
|
||||
{
|
||||
return 'geometry';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Point type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typePoint(Fluent $column)
|
||||
{
|
||||
return 'point';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial LineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeLineString(Fluent $column)
|
||||
{
|
||||
return 'linestring';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Polygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typePolygon(Fluent $column)
|
||||
{
|
||||
return 'polygon';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial GeometryCollection type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeGeometryCollection(Fluent $column)
|
||||
{
|
||||
return 'geometrycollection';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPoint type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiPoint(Fluent $column)
|
||||
{
|
||||
return 'multipoint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiLineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiLineString(Fluent $column)
|
||||
{
|
||||
return 'multilinestring';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPolygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiPolygon(Fluent $column)
|
||||
{
|
||||
return 'multipolygon';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 requires a type, see the virtualAs / storedAs modifiers.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated virtual column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->virtualAs)) {
|
||||
return " as ({$column->virtualAs})";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated stored column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->storedAs)) {
|
||||
return " as ({$column->storedAs}) stored";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a nullable column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyNullable(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (is_null($column->virtualAs) && is_null($column->storedAs)) {
|
||||
return $column->nullable ? '' : ' not null';
|
||||
}
|
||||
|
||||
if ($column->nullable === false) {
|
||||
return ' not null';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a default column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyDefault(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->storedAs)) {
|
||||
return ' default '.$this->getDefaultValue($column->default);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for an auto-increment column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
|
||||
return ' primary key autoincrement';
|
||||
}
|
||||
}
|
||||
}
|
||||
+934
@@ -0,0 +1,934 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema\Grammars;
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
class SqlServerGrammar extends Grammar
|
||||
{
|
||||
/**
|
||||
* If this Grammar supports schema changes wrapped in a transaction.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $transactions = true;
|
||||
|
||||
/**
|
||||
* The possible column modifiers.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $modifiers = ['Increment', 'Collate', 'Nullable', 'Default', 'Persisted'];
|
||||
|
||||
/**
|
||||
* The columns available as serials.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $serials = ['tinyInteger', 'smallInteger', 'mediumInteger', 'integer', 'bigInteger'];
|
||||
|
||||
/**
|
||||
* Compile a create database command.
|
||||
*
|
||||
* @param string $name
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @return string
|
||||
*/
|
||||
public function compileCreateDatabase($name, $connection)
|
||||
{
|
||||
return sprintf(
|
||||
'create database %s',
|
||||
$this->wrapValue($name),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop database if exists command.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropDatabaseIfExists($name)
|
||||
{
|
||||
return sprintf(
|
||||
'drop database if exists %s',
|
||||
$this->wrapValue($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine if a table exists.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileTableExists()
|
||||
{
|
||||
return "select * from sys.sysobjects where id = object_id(?) and xtype in ('U', 'V')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the query to determine the list of columns.
|
||||
*
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
public function compileColumnListing($table)
|
||||
{
|
||||
return "select name from sys.columns where object_id = object_id('$table')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a create table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileCreate(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = implode(', ', $this->getColumns($blueprint));
|
||||
|
||||
return 'create table '.$this->wrapTable($blueprint)." ($columns)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a column addition table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileAdd(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('alter table %s add %s',
|
||||
$this->wrapTable($blueprint),
|
||||
implode(', ', $this->getColumns($blueprint))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a primary key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compilePrimary(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('alter table %s add constraint %s primary key (%s)',
|
||||
$this->wrapTable($blueprint),
|
||||
$this->wrap($command->index),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('create unique index %s on %s (%s)',
|
||||
$this->wrap($command->index),
|
||||
$this->wrapTable($blueprint),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a plain index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('create index %s on %s (%s)',
|
||||
$this->wrap($command->index),
|
||||
$this->wrapTable($blueprint),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a spatial index key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('create spatial index %s on %s (%s)',
|
||||
$this->wrap($command->index),
|
||||
$this->wrapTable($blueprint),
|
||||
$this->columnize($command->columns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDrop(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return 'drop table '.$this->wrapTable($blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop table (if exists) command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf('if exists (select * from sys.sysobjects where id = object_id(%s, \'U\')) drop table %s',
|
||||
"'".str_replace("'", "''", $this->getTablePrefix().$blueprint->getTable())."'",
|
||||
$this->wrapTable($blueprint)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL needed to drop all tables.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllTables()
|
||||
{
|
||||
return "EXEC sp_msforeachtable 'DROP TABLE ?'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop column command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropColumn(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = $this->wrapArray($command->columns);
|
||||
|
||||
$dropExistingConstraintsSql = $this->compileDropDefaultConstraint($blueprint, $command).';';
|
||||
|
||||
return $dropExistingConstraintsSql.'alter table '.$this->wrapTable($blueprint).' drop column '.implode(', ', $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop default constraint command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropDefaultConstraint(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$columns = "'".implode("','", $command->columns)."'";
|
||||
|
||||
$tableName = $this->getTablePrefix().$blueprint->getTable();
|
||||
|
||||
$sql = "DECLARE @sql NVARCHAR(MAX) = '';";
|
||||
$sql .= "SELECT @sql += 'ALTER TABLE [dbo].[{$tableName}] DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' ";
|
||||
$sql .= 'FROM SYS.COLUMNS ';
|
||||
$sql .= "WHERE [object_id] = OBJECT_ID('[dbo].[{$tableName}]') AND [name] in ({$columns}) AND [default_object_id] <> 0;";
|
||||
$sql .= 'EXEC(@sql)';
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop primary key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop unique key command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropUnique(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "drop index {$index} on {$this->wrapTable($blueprint)}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "drop index {$index} on {$this->wrapTable($blueprint)}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a drop spatial index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return $this->compileDropIndex($blueprint, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$index = $this->wrap($command->index);
|
||||
|
||||
return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename table command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRename(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
$from = $this->wrapTable($blueprint);
|
||||
|
||||
return "sp_rename {$from}, ".$this->wrapTable($command->to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a rename index command.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $command
|
||||
* @return string
|
||||
*/
|
||||
public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
|
||||
{
|
||||
return sprintf("sp_rename N'%s', %s, N'INDEX'",
|
||||
$this->wrap($blueprint->getTable().'.'.$command->from),
|
||||
$this->wrap($command->to)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to enable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEnableForeignKeyConstraints()
|
||||
{
|
||||
return 'EXEC sp_msforeachtable @command1="print \'?\'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all";';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to disable foreign key constraints.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDisableForeignKeyConstraints()
|
||||
{
|
||||
return 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to drop all foreign keys.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllForeignKeys()
|
||||
{
|
||||
return "DECLARE @sql NVARCHAR(MAX) = N'';
|
||||
SELECT @sql += 'ALTER TABLE '
|
||||
+ QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' + + QUOTENAME(OBJECT_NAME(parent_object_id))
|
||||
+ ' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
|
||||
FROM sys.foreign_keys;
|
||||
|
||||
EXEC sp_executesql @sql;";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the command to drop all views.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileDropAllViews()
|
||||
{
|
||||
return "DECLARE @sql NVARCHAR(MAX) = N'';
|
||||
SELECT @sql += 'DROP VIEW ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(name) + ';'
|
||||
FROM sys.views;
|
||||
|
||||
EXEC sp_executesql @sql;";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a char type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeChar(Fluent $column)
|
||||
{
|
||||
return "nchar({$column->length})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a string type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeString(Fluent $column)
|
||||
{
|
||||
return "nvarchar({$column->length})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyText(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(255)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeText(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(max)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumText(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(max)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a long text type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeLongText(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(max)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeInteger(Fluent $column)
|
||||
{
|
||||
return 'int';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a big integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBigInteger(Fluent $column)
|
||||
{
|
||||
return 'bigint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a medium integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMediumInteger(Fluent $column)
|
||||
{
|
||||
return 'int';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a tiny integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTinyInteger(Fluent $column)
|
||||
{
|
||||
return 'tinyint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a small integer type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeSmallInteger(Fluent $column)
|
||||
{
|
||||
return 'smallint';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a float type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeFloat(Fluent $column)
|
||||
{
|
||||
return 'float';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a double type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDouble(Fluent $column)
|
||||
{
|
||||
return 'float';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a decimal type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDecimal(Fluent $column)
|
||||
{
|
||||
return "decimal({$column->total}, {$column->places})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a boolean type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBoolean(Fluent $column)
|
||||
{
|
||||
return 'bit';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an enumeration type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeEnum(Fluent $column)
|
||||
{
|
||||
return sprintf(
|
||||
'nvarchar(255) check ("%s" in (%s))',
|
||||
$column->name,
|
||||
$this->quoteString($column->allowed)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a json type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJson(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(max)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a jsonb type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeJsonb(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(max)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDate(Fluent $column)
|
||||
{
|
||||
return 'date';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTime(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestamp($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a date-time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeDateTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTimestampTz($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTime(Fluent $column)
|
||||
{
|
||||
return $column->precision ? "time($column->precision)" : 'time';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a time (with time zone) type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimeTz(Fluent $column)
|
||||
{
|
||||
return $this->typeTime($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestamp(Fluent $column)
|
||||
{
|
||||
$columnType = $column->precision ? "datetime2($column->precision)" : 'datetime';
|
||||
|
||||
return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a timestamp (with time zone) type.
|
||||
*
|
||||
* @link https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetimeoffset-transact-sql?view=sql-server-ver15
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeTimestampTz(Fluent $column)
|
||||
{
|
||||
$columnType = $column->precision ? "datetimeoffset($column->precision)" : 'datetimeoffset';
|
||||
|
||||
return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a year type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeYear(Fluent $column)
|
||||
{
|
||||
return $this->typeInteger($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a binary type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeBinary(Fluent $column)
|
||||
{
|
||||
return 'varbinary(max)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a uuid type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeUuid(Fluent $column)
|
||||
{
|
||||
return 'uniqueidentifier';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for an IP address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeIpAddress(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(45)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a MAC address type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
protected function typeMacAddress(Fluent $column)
|
||||
{
|
||||
return 'nvarchar(17)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Geometry type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeGeometry(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Point type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typePoint(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial LineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeLineString(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial Polygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typePolygon(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial GeometryCollection type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeGeometryCollection(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPoint type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiPoint(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiLineString type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiLineString(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a spatial MultiPolygon type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string
|
||||
*/
|
||||
public function typeMultiPolygon(Fluent $column)
|
||||
{
|
||||
return 'geography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the column definition for a generated, computed column type.
|
||||
*
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function typeComputed(Fluent $column)
|
||||
{
|
||||
return "as ({$column->expression})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a collation column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyCollate(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->collation)) {
|
||||
return ' collate '.$column->collation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a nullable column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyNullable(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if ($column->type !== 'computed') {
|
||||
return $column->nullable ? ' null' : ' not null';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a default column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyDefault(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (! is_null($column->default)) {
|
||||
return ' default '.$this->getDefaultValue($column->default);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for an auto-increment column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if (in_array($column->type, $this->serials) && $column->autoIncrement) {
|
||||
return ' identity primary key';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL for a generated stored column modifier.
|
||||
*
|
||||
* @param \Illuminate\Database\Schema\Blueprint $blueprint
|
||||
* @param \Illuminate\Support\Fluent $column
|
||||
* @return string|null
|
||||
*/
|
||||
protected function modifyPersisted(Blueprint $blueprint, Fluent $column)
|
||||
{
|
||||
if ($column->persisted) {
|
||||
return ' persisted';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a table in keyword identifiers.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Expression|string $table
|
||||
* @return string
|
||||
*/
|
||||
public function wrapTable($table)
|
||||
{
|
||||
if ($table instanceof Blueprint && $table->temporary) {
|
||||
$this->setTablePrefix('#');
|
||||
}
|
||||
|
||||
return parent::wrapTable($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote the given string literal.
|
||||
*
|
||||
* @param string|array $value
|
||||
* @return string
|
||||
*/
|
||||
public function quoteString($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return implode(', ', array_map([$this, __FUNCTION__], $value));
|
||||
}
|
||||
|
||||
return "N'$value'";
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
class MySqlBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* Create a database in the schema.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileCreateDatabase($name, $this->connection)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a database from the schema if the database exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function dropDatabaseIfExists($name)
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileDropDatabaseIfExists($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given table exists.
|
||||
*
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTable($table)
|
||||
{
|
||||
$table = $this->connection->getTablePrefix().$table;
|
||||
|
||||
return count($this->connection->select(
|
||||
$this->grammar->compileTableExists(), [$this->connection->getDatabaseName(), $table]
|
||||
)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column listing for a given table.
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnListing($table)
|
||||
{
|
||||
$table = $this->connection->getTablePrefix().$table;
|
||||
|
||||
$results = $this->connection->select(
|
||||
$this->grammar->compileColumnListing(), [$this->connection->getDatabaseName(), $table]
|
||||
);
|
||||
|
||||
return $this->connection->getPostProcessor()->processColumnListing($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all tables from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllTables()
|
||||
{
|
||||
$tables = [];
|
||||
|
||||
foreach ($this->getAllTables() as $row) {
|
||||
$row = (array) $row;
|
||||
|
||||
$tables[] = reset($row);
|
||||
}
|
||||
|
||||
if (empty($tables)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->disableForeignKeyConstraints();
|
||||
|
||||
$this->connection->statement(
|
||||
$this->grammar->compileDropAllTables($tables)
|
||||
);
|
||||
|
||||
$this->enableForeignKeyConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all views from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllViews()
|
||||
{
|
||||
$views = [];
|
||||
|
||||
foreach ($this->getAllViews() as $row) {
|
||||
$row = (array) $row;
|
||||
|
||||
$views[] = reset($row);
|
||||
}
|
||||
|
||||
if (empty($views)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->connection->statement(
|
||||
$this->grammar->compileDropAllViews($views)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the table names for the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllTables()
|
||||
{
|
||||
return $this->connection->select(
|
||||
$this->grammar->compileGetAllTables()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the view names for the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllViews()
|
||||
{
|
||||
return $this->connection->select(
|
||||
$this->grammar->compileGetAllViews()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class MySqlSchemaState extends SchemaState
|
||||
{
|
||||
/**
|
||||
* Dump the database's schema into a file.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function dump(Connection $connection, $path)
|
||||
{
|
||||
$this->executeDumpProcess($this->makeProcess(
|
||||
$this->baseDumpCommand().' --routines --result-file="${:LARAVEL_LOAD_PATH}" --no-data'
|
||||
), $this->output, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
|
||||
$this->removeAutoIncrementingState($path);
|
||||
|
||||
$this->appendMigrationData($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the auto-incrementing state from the given schema dump.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected function removeAutoIncrementingState(string $path)
|
||||
{
|
||||
$this->files->put($path, preg_replace(
|
||||
'/\s+AUTO_INCREMENT=[0-9]+/iu',
|
||||
'',
|
||||
$this->files->get($path)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the migration data to the schema dump.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected function appendMigrationData(string $path)
|
||||
{
|
||||
$process = $this->executeDumpProcess($this->makeProcess(
|
||||
$this->baseDumpCommand().' '.$this->migrationTable.' --no-create-info --skip-extended-insert --skip-routines --compact'
|
||||
), null, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
//
|
||||
]));
|
||||
|
||||
$this->files->append($path, $process->getOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given schema file into the database.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function load($path)
|
||||
{
|
||||
$command = 'mysql '.$this->connectionString().' --database="${:LARAVEL_LOAD_DATABASE}" < "${:LARAVEL_LOAD_PATH}"';
|
||||
|
||||
$process = $this->makeProcess($command)->setTimeout(null);
|
||||
|
||||
$process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base dump command arguments for MySQL as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function baseDumpCommand()
|
||||
{
|
||||
$command = 'mysqldump '.$this->connectionString().' --skip-add-locks --skip-comments --skip-set-charset --tz-utc';
|
||||
|
||||
if (! $this->connection->isMaria()) {
|
||||
$command .= ' --column-statistics=0 --set-gtid-purged=OFF';
|
||||
}
|
||||
|
||||
return $command.' "${:LARAVEL_LOAD_DATABASE}"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a basic connection string (--socket, --host, --port, --user, --password) for the database.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function connectionString()
|
||||
{
|
||||
$value = ' --user="${:LARAVEL_LOAD_USER}" --password="${:LARAVEL_LOAD_PASSWORD}"';
|
||||
|
||||
$value .= $this->connection->getConfig()['unix_socket'] ?? false
|
||||
? ' --socket="${:LARAVEL_LOAD_SOCKET}"'
|
||||
: ' --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}"';
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base variables for a dump / load command.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function baseVariables(array $config)
|
||||
{
|
||||
$config['host'] = $config['host'] ?? '';
|
||||
|
||||
return [
|
||||
'LARAVEL_LOAD_SOCKET' => $config['unix_socket'] ?? '',
|
||||
'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'],
|
||||
'LARAVEL_LOAD_PORT' => $config['port'] ?? '',
|
||||
'LARAVEL_LOAD_USER' => $config['username'],
|
||||
'LARAVEL_LOAD_PASSWORD' => $config['password'] ?? '',
|
||||
'LARAVEL_LOAD_DATABASE' => $config['database'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given dump process.
|
||||
*
|
||||
* @param \Symfony\Component\Process\Process $process
|
||||
* @param callable $output
|
||||
* @param array $variables
|
||||
* @return \Symfony\Component\Process\Process
|
||||
*/
|
||||
protected function executeDumpProcess(Process $process, $output, array $variables)
|
||||
{
|
||||
try {
|
||||
$process->setTimeout(null)->mustRun($output, $variables);
|
||||
} catch (Exception $e) {
|
||||
if (Str::contains($e->getMessage(), ['column-statistics', 'column_statistics'])) {
|
||||
return $this->executeDumpProcess(Process::fromShellCommandLine(
|
||||
str_replace(' --column-statistics=0', '', $process->getCommandLine())
|
||||
), $output, $variables);
|
||||
}
|
||||
|
||||
if (Str::contains($e->getMessage(), ['set-gtid-purged'])) {
|
||||
return $this->executeDumpProcess(Process::fromShellCommandLine(
|
||||
str_replace(' --set-gtid-purged=OFF', '', $process->getCommandLine())
|
||||
), $output, $variables);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $process;
|
||||
}
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
class PostgresBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* Create a database in the schema.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileCreateDatabase($name, $this->connection)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a database from the schema if the database exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function dropDatabaseIfExists($name)
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileDropDatabaseIfExists($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given table exists.
|
||||
*
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTable($table)
|
||||
{
|
||||
[$schema, $table] = $this->parseSchemaAndTable($table);
|
||||
|
||||
$table = $this->connection->getTablePrefix().$table;
|
||||
|
||||
return count($this->connection->select(
|
||||
$this->grammar->compileTableExists(), [$schema, $table]
|
||||
)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all tables from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllTables()
|
||||
{
|
||||
$tables = [];
|
||||
|
||||
$excludedTables = $this->connection->getConfig('dont_drop') ?? ['spatial_ref_sys'];
|
||||
|
||||
foreach ($this->getAllTables() as $row) {
|
||||
$row = (array) $row;
|
||||
|
||||
$table = reset($row);
|
||||
|
||||
if (! in_array($table, $excludedTables)) {
|
||||
$tables[] = $table;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($tables)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->connection->statement(
|
||||
$this->grammar->compileDropAllTables($tables)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all views from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllViews()
|
||||
{
|
||||
$views = [];
|
||||
|
||||
foreach ($this->getAllViews() as $row) {
|
||||
$row = (array) $row;
|
||||
|
||||
$views[] = reset($row);
|
||||
}
|
||||
|
||||
if (empty($views)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->connection->statement(
|
||||
$this->grammar->compileDropAllViews($views)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all types from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllTypes()
|
||||
{
|
||||
$types = [];
|
||||
|
||||
foreach ($this->getAllTypes() as $row) {
|
||||
$row = (array) $row;
|
||||
|
||||
$types[] = reset($row);
|
||||
}
|
||||
|
||||
if (empty($types)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->connection->statement(
|
||||
$this->grammar->compileDropAllTypes($types)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the table names for the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllTables()
|
||||
{
|
||||
return $this->connection->select(
|
||||
$this->grammar->compileGetAllTables((array) $this->connection->getConfig('schema'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the view names for the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllViews()
|
||||
{
|
||||
return $this->connection->select(
|
||||
$this->grammar->compileGetAllViews((array) $this->connection->getConfig('schema'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the type names for the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllTypes()
|
||||
{
|
||||
return $this->connection->select(
|
||||
$this->grammar->compileGetAllTypes()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column listing for a given table.
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnListing($table)
|
||||
{
|
||||
[$schema, $table] = $this->parseSchemaAndTable($table);
|
||||
|
||||
$table = $this->connection->getTablePrefix().$table;
|
||||
|
||||
$results = $this->connection->select(
|
||||
$this->grammar->compileColumnListing(), [$schema, $table]
|
||||
);
|
||||
|
||||
return $this->connection->getPostProcessor()->processColumnListing($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the table name and extract the schema and table.
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
protected function parseSchemaAndTable($table)
|
||||
{
|
||||
$table = explode('.', $table);
|
||||
|
||||
if (is_array($schema = $this->connection->getConfig('schema'))) {
|
||||
if (in_array($table[0], $schema)) {
|
||||
return [array_shift($table), implode('.', $table)];
|
||||
}
|
||||
|
||||
$schema = head($schema);
|
||||
}
|
||||
|
||||
return [$schema ?: 'public', implode('.', $table)];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PostgresSchemaState extends SchemaState
|
||||
{
|
||||
/**
|
||||
* Dump the database's schema into a file.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function dump(Connection $connection, $path)
|
||||
{
|
||||
$excludedTables = collect($connection->getSchemaBuilder()->getAllTables())
|
||||
->map->tablename
|
||||
->reject(function ($table) {
|
||||
return $table === $this->migrationTable;
|
||||
})->map(function ($table) {
|
||||
return '--exclude-table-data="*.'.$table.'"';
|
||||
})->implode(' ');
|
||||
|
||||
$this->makeProcess(
|
||||
$this->baseDumpCommand().' --file="${:LARAVEL_LOAD_PATH}" '.$excludedTables
|
||||
)->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given schema file into the database.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function load($path)
|
||||
{
|
||||
$command = 'pg_restore --no-owner --no-acl --clean --if-exists --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}" "${:LARAVEL_LOAD_PATH}"';
|
||||
|
||||
if (Str::endsWith($path, '.sql')) {
|
||||
$command = 'psql --file="${:LARAVEL_LOAD_PATH}" --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"';
|
||||
}
|
||||
|
||||
$process = $this->makeProcess($command);
|
||||
|
||||
$process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base dump command arguments for PostgreSQL as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function baseDumpCommand()
|
||||
{
|
||||
return 'pg_dump --no-owner --no-acl -Fc --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base variables for a dump / load command.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function baseVariables(array $config)
|
||||
{
|
||||
$config['host'] = $config['host'] ?? '';
|
||||
|
||||
return [
|
||||
'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'],
|
||||
'LARAVEL_LOAD_PORT' => $config['port'],
|
||||
'LARAVEL_LOAD_USER' => $config['username'],
|
||||
'PGPASSWORD' => $config['password'],
|
||||
'LARAVEL_LOAD_DATABASE' => $config['database'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class SQLiteBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* Create a database in the schema.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
return File::put($name, '') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a database from the schema if the database exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function dropDatabaseIfExists($name)
|
||||
{
|
||||
return File::exists($name)
|
||||
? File::delete($name)
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all tables from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllTables()
|
||||
{
|
||||
if ($this->connection->getDatabaseName() !== ':memory:') {
|
||||
return $this->refreshDatabaseFile();
|
||||
}
|
||||
|
||||
$this->connection->select($this->grammar->compileEnableWriteableSchema());
|
||||
|
||||
$this->connection->select($this->grammar->compileDropAllTables());
|
||||
|
||||
$this->connection->select($this->grammar->compileDisableWriteableSchema());
|
||||
|
||||
$this->connection->select($this->grammar->compileRebuild());
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all views from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllViews()
|
||||
{
|
||||
$this->connection->select($this->grammar->compileEnableWriteableSchema());
|
||||
|
||||
$this->connection->select($this->grammar->compileDropAllViews());
|
||||
|
||||
$this->connection->select($this->grammar->compileDisableWriteableSchema());
|
||||
|
||||
$this->connection->select($this->grammar->compileRebuild());
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the database file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function refreshDatabaseFile()
|
||||
{
|
||||
file_put_contents($this->connection->getDatabaseName(), '');
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
abstract class SchemaState
|
||||
{
|
||||
/**
|
||||
* The connection instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* The name of the application's migration table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $migrationTable = 'migrations';
|
||||
|
||||
/**
|
||||
* The process factory callback.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $processFactory;
|
||||
|
||||
/**
|
||||
* The output callable instance.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Create a new dumper instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param \Illuminate\Filesystem\Filesystem|null $files
|
||||
* @param callable|null $processFactory
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Connection $connection, Filesystem $files = null, callable $processFactory = null)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
|
||||
$this->files = $files ?: new Filesystem;
|
||||
|
||||
$this->processFactory = $processFactory ?: function (...$arguments) {
|
||||
return Process::fromShellCommandline(...$arguments);
|
||||
};
|
||||
|
||||
$this->handleOutputUsing(function () {
|
||||
//
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the database's schema into a file.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
abstract public function dump(Connection $connection, $path);
|
||||
|
||||
/**
|
||||
* Load the given schema file into the database.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
abstract public function load($path);
|
||||
|
||||
/**
|
||||
* Create a new process instance.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return \Symfony\Component\Process\Process
|
||||
*/
|
||||
public function makeProcess(...$arguments)
|
||||
{
|
||||
return call_user_func($this->processFactory, ...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the name of the application's migration table.
|
||||
*
|
||||
* @param string $table
|
||||
* @return $this
|
||||
*/
|
||||
public function withMigrationTable(string $table)
|
||||
{
|
||||
$this->migrationTable = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the callback that should be used to handle process output.
|
||||
*
|
||||
* @param callable $output
|
||||
* @return $this
|
||||
*/
|
||||
public function handleOutputUsing(callable $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
class SqlServerBuilder extends Builder
|
||||
{
|
||||
/**
|
||||
* Create a database in the schema.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function createDatabase($name)
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileCreateDatabase($name, $this->connection)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a database from the schema if the database exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function dropDatabaseIfExists($name)
|
||||
{
|
||||
return $this->connection->statement(
|
||||
$this->grammar->compileDropDatabaseIfExists($name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all tables from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllTables()
|
||||
{
|
||||
$this->connection->statement($this->grammar->compileDropAllForeignKeys());
|
||||
|
||||
$this->connection->statement($this->grammar->compileDropAllTables());
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all views from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropAllViews()
|
||||
{
|
||||
$this->connection->statement($this->grammar->compileDropAllViews());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Schema;
|
||||
|
||||
use Illuminate\Database\Connection;
|
||||
|
||||
class SqliteSchemaState extends SchemaState
|
||||
{
|
||||
/**
|
||||
* Dump the database's schema into a file.
|
||||
*
|
||||
* @param \Illuminate\Database\Connection $connection
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function dump(Connection $connection, $path)
|
||||
{
|
||||
with($process = $this->makeProcess(
|
||||
$this->baseCommand().' .schema'
|
||||
))->setTimeout(null)->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
//
|
||||
]));
|
||||
|
||||
$migrations = collect(preg_split("/\r\n|\n|\r/", $process->getOutput()))->filter(function ($line) {
|
||||
return stripos($line, 'sqlite_sequence') === false &&
|
||||
strlen($line) > 0;
|
||||
})->all();
|
||||
|
||||
$this->files->put($path, implode(PHP_EOL, $migrations).PHP_EOL);
|
||||
|
||||
$this->appendMigrationData($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the migration data to the schema dump.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected function appendMigrationData(string $path)
|
||||
{
|
||||
with($process = $this->makeProcess(
|
||||
$this->baseCommand().' ".dump \''.$this->migrationTable.'\'"'
|
||||
))->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
//
|
||||
]));
|
||||
|
||||
$migrations = collect(preg_split("/\r\n|\n|\r/", $process->getOutput()))->filter(function ($line) {
|
||||
return preg_match('/^\s*(--|INSERT\s)/iu', $line) === 1 &&
|
||||
strlen($line) > 0;
|
||||
})->all();
|
||||
|
||||
$this->files->append($path, implode(PHP_EOL, $migrations).PHP_EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given schema file into the database.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function load($path)
|
||||
{
|
||||
$process = $this->makeProcess($this->baseCommand().' < "${:LARAVEL_LOAD_PATH}"');
|
||||
|
||||
$process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
|
||||
'LARAVEL_LOAD_PATH' => $path,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base sqlite command arguments as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function baseCommand()
|
||||
{
|
||||
return 'sqlite3 "${:LARAVEL_LOAD_DATABASE}"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base variables for a dump / load command.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function baseVariables(array $config)
|
||||
{
|
||||
return [
|
||||
'LARAVEL_LOAD_DATABASE' => $config['database'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user