From 55b6c77fb957581c8fccaeb1821a1b5804dd2a23 Mon Sep 17 00:00:00 2001 From: Khalil Laleh Date: Thu, 17 Jun 2021 14:40:23 +0430 Subject: [PATCH 1/3] Execute creating the Primary Key in single Query Remove the primary item from the fluent indexes and add it to the modifiers --- src/Illuminate/Database/Schema/Blueprint.php | 2 +- .../Database/Schema/Grammars/MySqlGrammar.php | 16 +++++++++++++- .../Schema/Grammars/PostgresGrammar.php | 16 +++++++++++++- .../Schema/Grammars/SQLiteGrammar.php | 21 +++++++++++++++---- .../Schema/Grammars/SqlServerGrammar.php | 16 +++++++++++++- 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Database/Schema/Blueprint.php b/src/Illuminate/Database/Schema/Blueprint.php index e2b968ab6bd4..c1a0a2acc92f 100755 --- a/src/Illuminate/Database/Schema/Blueprint.php +++ b/src/Illuminate/Database/Schema/Blueprint.php @@ -208,7 +208,7 @@ protected function addImpliedCommands(Grammar $grammar) protected function addFluentIndexes() { foreach ($this->columns as $column) { - foreach (['primary', 'unique', 'index', 'spatialIndex'] as $index) { + foreach (['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. diff --git a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php index b6e4e3568d8e..6d2a62c70d4e 100755 --- a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php @@ -15,7 +15,7 @@ class MySqlGrammar extends Grammar * @var string[] */ protected $modifiers = [ - 'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable', + 'Primary', 'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable', 'Srid', 'Default', 'Increment', 'Comment', 'After', 'First', ]; @@ -1014,6 +1014,20 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) } } + /** + * Get the SQL for a primary column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + public function modifyPrimary(Blueprint $blueprint, Fluent $column) + { + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; + } + } + /** * Get the SQL for a default column modifier. * diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 133da288f19d..fb9b53136430 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -19,7 +19,7 @@ class PostgresGrammar extends Grammar * * @var string[] */ - protected $modifiers = ['Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs']; + protected $modifiers = ['Primary', 'Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs']; /** * The columns available as serials. @@ -979,6 +979,20 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) return $column->nullable ? ' null' : ' not null'; } + /** + * Get the SQL for a primary column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + public function modifyPrimary(Blueprint $blueprint, Fluent $column) + { + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; + } + } + /** * Get the SQL for a default column modifier. * diff --git a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php index b7e406f578ef..cf56f03fb2f7 100755 --- a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php @@ -16,7 +16,7 @@ class SQLiteGrammar extends Grammar * * @var string[] */ - protected $modifiers = ['VirtualAs', 'StoredAs', 'Nullable', 'Default', 'Increment']; + protected $modifiers = ['Primary', 'VirtualAs', 'StoredAs', 'Nullable', 'Default', 'Increment']; /** * The columns available as serials. @@ -55,12 +55,11 @@ public function compileColumnListing($table) */ public function compileCreate(Blueprint $blueprint, Fluent $command) { - return sprintf('%s table %s (%s%s%s)', + return sprintf('%s table %s (%s%s)', $blueprint->temporary ? 'create temporary' : 'create', $this->wrapTable($blueprint), implode(', ', $this->getColumns($blueprint)), - (string) $this->addForeignKeys($blueprint), - (string) $this->addPrimaryKeys($blueprint) + (string) $this->addForeignKeys($blueprint) ); } @@ -894,6 +893,20 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) } } + /** + * Get the SQL for a primary column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + public function modifyPrimary(Blueprint $blueprint, Fluent $column) + { + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; + } + } + /** * Get the SQL for a default column modifier. * diff --git a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php index caec020401ca..077519bc063d 100755 --- a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php @@ -19,7 +19,7 @@ class SqlServerGrammar extends Grammar * * @var string[] */ - protected $modifiers = ['Increment', 'Collate', 'Nullable', 'Default', 'Persisted']; + protected $modifiers = ['Primary', 'Increment', 'Collate', 'Nullable', 'Default', 'Persisted']; /** * The columns available as serials. @@ -860,6 +860,20 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) } } + /** + * Get the SQL for a primary column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + public function modifyPrimary(Blueprint $blueprint, Fluent $column) + { + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; + } + } + /** * Get the SQL for a default column modifier. * From 4935be452c20b4a52824d7b7cb2f57e0f99f041d Mon Sep 17 00:00:00 2001 From: Khalil Laleh Date: Thu, 17 Jun 2021 14:41:58 +0430 Subject: [PATCH 2/3] Create Tests for MySql, Postgres, SqlServer & SQLite to assert the creating primary key in single query without altering table --- .../Database/DatabaseMySqlSchemaGrammarTest.php | 17 +++++++++++++++++ .../DatabasePostgresSchemaGrammarTest.php | 11 +++++++++++ .../DatabaseSQLiteSchemaGrammarTest.php | 4 ++-- .../DatabaseSqlServerSchemaGrammarTest.php | 11 +++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/tests/Database/DatabaseMySqlSchemaGrammarTest.php b/tests/Database/DatabaseMySqlSchemaGrammarTest.php index 05e92a085435..1182c2cff147 100755 --- a/tests/Database/DatabaseMySqlSchemaGrammarTest.php +++ b/tests/Database/DatabaseMySqlSchemaGrammarTest.php @@ -47,6 +47,23 @@ public function testBasicCreateTable() $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key, add `email` varchar(255) not null', $statements[0]); } + public function testBasicCreateWithPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('foo')->primary(); + + $conn = $this->getConnection(); + $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8'); + $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci'); + $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null); + + $statements = $blueprint->toSql($conn, $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame("create table `users` (`foo` varchar(255) primary key not null) default character set utf8 collate 'utf8_unicode_ci'", $statements[0]); + } + public function testAutoIncrementStartingValue() { $blueprint = new Blueprint('users'); diff --git a/tests/Database/DatabasePostgresSchemaGrammarTest.php b/tests/Database/DatabasePostgresSchemaGrammarTest.php index 3a7f80ae3865..4d97e180d9f2 100755 --- a/tests/Database/DatabasePostgresSchemaGrammarTest.php +++ b/tests/Database/DatabasePostgresSchemaGrammarTest.php @@ -37,6 +37,17 @@ public function testBasicCreateTable() $this->assertSame('alter table "users" add column "id" serial primary key not null, add column "email" varchar(255) not null', $statements[0]); } + public function testBasicCreateWithPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('foo')->primary(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("foo" varchar(255) primary key not null)', $statements[0]); + } + public function testCreateTableWithAutoIncrementStartingValue() { $blueprint = new Blueprint('users'); diff --git a/tests/Database/DatabaseSQLiteSchemaGrammarTest.php b/tests/Database/DatabaseSQLiteSchemaGrammarTest.php index 226c58bf2b34..f7566b56f7d3 100755 --- a/tests/Database/DatabaseSQLiteSchemaGrammarTest.php +++ b/tests/Database/DatabaseSQLiteSchemaGrammarTest.php @@ -196,7 +196,7 @@ public function testAddingPrimaryKey() $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("foo" varchar not null, primary key ("foo"))', $statements[0]); + $this->assertSame('create table "users" ("foo" varchar primary key not null)', $statements[0]); } public function testAddingForeignKey() @@ -209,7 +209,7 @@ public function testAddingForeignKey() $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); $this->assertCount(1, $statements); - $this->assertSame('create table "users" ("foo" varchar not null, "order_id" varchar not null, foreign key("order_id") references "orders"("id"), primary key ("foo"))', $statements[0]); + $this->assertSame('create table "users" ("foo" varchar primary key not null, "order_id" varchar not null, foreign key("order_id") references "orders"("id"))', $statements[0]); } public function testAddingUniqueKey() diff --git a/tests/Database/DatabaseSqlServerSchemaGrammarTest.php b/tests/Database/DatabaseSqlServerSchemaGrammarTest.php index e675df85dfbb..117b1146c33e 100755 --- a/tests/Database/DatabaseSqlServerSchemaGrammarTest.php +++ b/tests/Database/DatabaseSqlServerSchemaGrammarTest.php @@ -45,6 +45,17 @@ public function testBasicCreateTable() $this->assertSame('create table "prefix_users" ("id" int identity primary key not null, "email" nvarchar(255) not null)', $statements[0]); } + public function testBasicCreateWithPrimaryKey() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->string('foo')->primary(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create table "users" ("foo" nvarchar(255) primary key not null)', $statements[0]); + } + public function testCreateTemporaryTable() { $blueprint = new Blueprint('users'); From 7ddce19affb559247a0ee8dfa399d14ec5921997 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 18 Jun 2021 08:45:01 -0500 Subject: [PATCH 3/3] formatting --- .../Database/Schema/Grammars/MySqlGrammar.php | 40 +++++++++---------- .../Schema/Grammars/SQLiteGrammar.php | 40 +++++++++---------- .../Schema/Grammars/SqlServerGrammar.php | 24 +++++------ 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php index 6d2a62c70d4e..ceb6c0f955d3 100755 --- a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php @@ -927,30 +927,30 @@ protected function typeComputed(Fluent $column) } /** - * Get the SQL for a generated virtual column modifier. + * Get the SQL for a primary column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) + public function modifyPrimary(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->virtualAs)) { - return " as ({$column->virtualAs})"; + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; } } /** - * Get the SQL for a generated stored column modifier. + * 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 modifyStoredAs(Blueprint $blueprint, Fluent $column) + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->storedAs)) { - return " as ({$column->storedAs}) stored"; + if (in_array($column->type, $this->serials) && $column->autoIncrement) { + return ' auto_increment primary key'; } } @@ -1015,44 +1015,44 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) } /** - * Get the SQL for a primary column modifier. + * Get the SQL for a default column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - public function modifyPrimary(Blueprint $blueprint, Fluent $column) + protected function modifyDefault(Blueprint $blueprint, Fluent $column) { - if (! $column->autoIncrement && ! is_null($column->primary)) { - return ' primary key'; + if (! is_null($column->default)) { + return ' default '.$this->getDefaultValue($column->default); } } /** - * Get the SQL for a default column modifier. + * 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 modifyDefault(Blueprint $blueprint, Fluent $column) + protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->default)) { - return ' default '.$this->getDefaultValue($column->default); + if (! is_null($column->virtualAs)) { + return " as ({$column->virtualAs})"; } } /** - * Get the SQL for an auto-increment column modifier. + * 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 modifyIncrement(Blueprint $blueprint, Fluent $column) + protected function modifyStoredAs(Blueprint $blueprint, Fluent $column) { - if (in_array($column->type, $this->serials) && $column->autoIncrement) { - return ' auto_increment primary key'; + if (! is_null($column->storedAs)) { + return " as ({$column->storedAs}) stored"; } } diff --git a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php index cf56f03fb2f7..bae761d944d0 100755 --- a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php @@ -848,30 +848,30 @@ protected function typeComputed(Fluent $column) } /** - * Get the SQL for a generated virtual column modifier. + * Get the SQL for a primary column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) + public function modifyPrimary(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->virtualAs)) { - return " as ({$column->virtualAs})"; + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; } } /** - * Get the SQL for a generated stored column modifier. + * 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 modifyStoredAs(Blueprint $blueprint, Fluent $column) + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->storedAs)) { - return " as ({$column->storedAs}) stored"; + if (in_array($column->type, $this->serials) && $column->autoIncrement) { + return ' primary key autoincrement'; } } @@ -894,44 +894,44 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) } /** - * Get the SQL for a primary column modifier. + * Get the SQL for a default column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - public function modifyPrimary(Blueprint $blueprint, Fluent $column) + protected function modifyDefault(Blueprint $blueprint, Fluent $column) { - if (! $column->autoIncrement && ! is_null($column->primary)) { - return ' primary key'; + if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->storedAs)) { + return ' default '.$this->getDefaultValue($column->default); } } /** - * Get the SQL for a default column modifier. + * 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 modifyDefault(Blueprint $blueprint, Fluent $column) + protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->storedAs)) { - return ' default '.$this->getDefaultValue($column->default); + if (! is_null($column->virtualAs)) { + return " as ({$column->virtualAs})"; } } /** - * Get the SQL for an auto-increment column modifier. + * 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 modifyIncrement(Blueprint $blueprint, Fluent $column) + protected function modifyStoredAs(Blueprint $blueprint, Fluent $column) { - if (in_array($column->type, $this->serials) && $column->autoIncrement) { - return ' primary key autoincrement'; + if (! is_null($column->storedAs)) { + return " as ({$column->storedAs}) stored"; } } } diff --git a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php index 077519bc063d..788a1fae1ded 100755 --- a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php @@ -833,44 +833,44 @@ protected function typeComputed(Fluent $column) } /** - * Get the SQL for a collation column modifier. + * Get the SQL for a primary column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - protected function modifyCollate(Blueprint $blueprint, Fluent $column) + public function modifyPrimary(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->collation)) { - return ' collate '.$column->collation; + if (! $column->autoIncrement && ! is_null($column->primary)) { + return ' primary key'; } } /** - * Get the SQL for a nullable column modifier. + * Get the SQL for a collation column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - protected function modifyNullable(Blueprint $blueprint, Fluent $column) + protected function modifyCollate(Blueprint $blueprint, Fluent $column) { - if ($column->type !== 'computed') { - return $column->nullable ? ' null' : ' not null'; + if (! is_null($column->collation)) { + return ' collate '.$column->collation; } } /** - * Get the SQL for a primary column modifier. + * Get the SQL for a nullable column modifier. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $column * @return string|null */ - public function modifyPrimary(Blueprint $blueprint, Fluent $column) + protected function modifyNullable(Blueprint $blueprint, Fluent $column) { - if (! $column->autoIncrement && ! is_null($column->primary)) { - return ' primary key'; + if ($column->type !== 'computed') { + return $column->nullable ? ' null' : ' not null'; } }