From 6d65c936c744e8c823e4d7807976ae2b12297d57 Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Mon, 12 Sep 2022 21:27:19 +0430 Subject: [PATCH 1/3] enhance column modifying --- .../Database/DBAL/TimestampType.php | 6 --- .../Database/Schema/Grammars/ChangeColumn.php | 11 ++++- ...DatabaseSchemaBlueprintIntegrationTest.php | 23 ++++++++++ .../Database/DBAL/TimestampTypeTest.php | 21 +++++++++ .../Database/SchemaBuilderTest.php | 46 +++++++++++++++++++ 5 files changed, 99 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Database/DBAL/TimestampType.php b/src/Illuminate/Database/DBAL/TimestampType.php index 4fa985153594..50116f9c0ff4 100644 --- a/src/Illuminate/Database/DBAL/TimestampType.php +++ b/src/Illuminate/Database/DBAL/TimestampType.php @@ -41,12 +41,6 @@ protected function getMySqlPlatformSQLDeclaration(array $fieldDeclaration) $columnType = 'TIMESTAMP('.$fieldDeclaration['precision'].')'; } - $notNull = $fieldDeclaration['notnull'] ?? false; - - if (! $notNull) { - return $columnType.' NULL'; - } - return $columnType; } diff --git a/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php b/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php index 70ec66652eb9..95474ec3a182 100644 --- a/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php +++ b/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php @@ -121,10 +121,14 @@ protected static function getDoctrineColumnChangeOptions(Fluent $fluent) { $options = ['type' => static::getDoctrineColumnType($fluent['type'])]; - if (in_array($fluent['type'], ['text', 'mediumText', 'longText'])) { + if (in_array($fluent['type'], ['tinyText', 'text', 'mediumText', 'longText'])) { $options['length'] = static::calculateDoctrineTextLength($fluent['type']); } + if ($fluent['type'] === 'binary') { + $options['length'] = 65535; + } + if ($fluent['type'] === 'char') { $options['fixed'] = true; } @@ -152,10 +156,11 @@ protected static function getDoctrineColumnType($type) return Type::getType(match ($type) { 'biginteger' => 'bigint', 'smallinteger' => 'smallint', - 'mediumtext', 'longtext' => 'text', + 'tinytext', 'mediumtext', 'longtext' => 'text', 'binary' => 'blob', 'uuid' => 'guid', 'char' => 'string', + 'double' => 'float', default => $type, }); } @@ -169,6 +174,7 @@ protected static function getDoctrineColumnType($type) protected static function calculateDoctrineTextLength($type) { return match ($type) { + 'tinyText' => 1, 'mediumText' => 65535 + 1, 'longText' => 16777215 + 1, default => 255 + 1, @@ -197,6 +203,7 @@ protected static function doesntNeedCharacterOptions($type) 'mediumInteger', 'smallInteger', 'time', + 'timestamp', 'tinyInteger', ]); } diff --git a/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php b/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php index 0e990ecd848f..247b6c1d1516 100644 --- a/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php +++ b/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php @@ -149,6 +149,29 @@ public function testChangingCharColumnsWork() $this->assertEquals($expected, $queries); } + public function testChangingDoubleColumnsWork() + { + $this->db->connection()->getSchemaBuilder()->create('products', function ($table) { + $table->integer('price'); + }); + + $blueprint = new Blueprint('products', function ($table) { + $table->double('price')->change(); + }); + + $queries = $blueprint->toSql($this->db->connection(), new SQLiteGrammar); + + $expected = [ + 'CREATE TEMPORARY TABLE __temp__products AS SELECT price FROM products', + 'DROP TABLE products', + 'CREATE TABLE products (price DOUBLE PRECISION NOT NULL)', + 'INSERT INTO products (price) SELECT price FROM __temp__products', + 'DROP TABLE __temp__products', + ]; + + $this->assertEquals($expected, $queries); + } + public function testRenameIndexWorks() { $this->db->connection()->getSchemaBuilder()->create('users', function ($table) { diff --git a/tests/Integration/Database/DBAL/TimestampTypeTest.php b/tests/Integration/Database/DBAL/TimestampTypeTest.php index b3c9fc3e2875..14dc7e9c7f62 100644 --- a/tests/Integration/Database/DBAL/TimestampTypeTest.php +++ b/tests/Integration/Database/DBAL/TimestampTypeTest.php @@ -59,4 +59,25 @@ public function testChangeTimestampColumnToDatetimeColumn() ? $this->assertSame('timestamp', Schema::getColumnType('test', 'timestamp_to_datetime')) : $this->assertSame('datetime', Schema::getColumnType('test', 'timestamp_to_datetime')); } + + public function testChangeStringColumnToTimestampColumn() + { + if ($this->driver !== 'mysql') { + $this->markTestSkipped('Test requires a MySQL connection.'); + } + + Schema::create('test', function (Blueprint $table) { + $table->string('string_to_timestamp'); + }); + + $blueprint = new Blueprint('test', function ($table) { + $table->timestamp('string_to_timestamp')->nullable(true)->change(); + }); + + $queries = $blueprint->toSql($this->getConnection(), $this->getConnection()->getSchemaGrammar()); + + $expected = ['ALTER TABLE test CHANGE string_to_timestamp string_to_timestamp TIMESTAMP DEFAULT NULL']; + + $this->assertEquals($expected, $queries); + } } diff --git a/tests/Integration/Database/SchemaBuilderTest.php b/tests/Integration/Database/SchemaBuilderTest.php index 1b5a5401c2e2..cd03051336e5 100644 --- a/tests/Integration/Database/SchemaBuilderTest.php +++ b/tests/Integration/Database/SchemaBuilderTest.php @@ -87,4 +87,50 @@ public function testRegisterCustomDoctrineTypeASecondTime() $this->assertArrayHasKey(TinyInteger::NAME, Type::getTypesMap()); $this->assertSame('tinyinteger', Schema::getColumnType('test', 'test_column')); } + + public function testChangeToBinaryColumn() + { + if ($this->driver !== 'mysql') { + $this->markTestSkipped('Test requires a MySQL connection.'); + } + + Schema::create('test', function (Blueprint $table) { + $table->integer('test_column'); + }); + + $blueprint = new Blueprint('test', function ($table) { + $table->binary('test_column')->change(); + }); + + $queries = $blueprint->toSql($this->getConnection(), $this->getConnection()->getSchemaGrammar()); + + $expected = ['ALTER TABLE test CHANGE test_column test_column BLOB NOT NULL']; + + $this->assertEquals($expected, $queries); + } + + public function testChangeToTextColumn() + { + if ($this->driver !== 'mysql') { + $this->markTestSkipped('Test requires a MySQL connection.'); + } + + Schema::create('test', function (Blueprint $table) { + $table->integer('test_column'); + }); + + foreach (['tinyText', 'text', 'mediumText', 'longText'] as $type) { + $blueprint = new Blueprint('test', function ($table) use ($type) { + $table->$type('test_column')->change(); + }); + + $queries = $blueprint->toSql($this->getConnection(), $this->getConnection()->getSchemaGrammar()); + + $uppercase = strtoupper($type); + + $expected = ["ALTER TABLE test CHANGE test_column test_column $uppercase NOT NULL"]; + + $this->assertEquals($expected, $queries); + } + } } From bb5424de40a23c00419c6cee55f5e8852388de44 Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Mon, 12 Sep 2022 22:01:18 +0430 Subject: [PATCH 2/3] revert changes on TimestampType --- src/Illuminate/Database/DBAL/TimestampType.php | 6 ++++++ tests/Integration/Database/DBAL/TimestampTypeTest.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/DBAL/TimestampType.php b/src/Illuminate/Database/DBAL/TimestampType.php index 50116f9c0ff4..4fa985153594 100644 --- a/src/Illuminate/Database/DBAL/TimestampType.php +++ b/src/Illuminate/Database/DBAL/TimestampType.php @@ -41,6 +41,12 @@ protected function getMySqlPlatformSQLDeclaration(array $fieldDeclaration) $columnType = 'TIMESTAMP('.$fieldDeclaration['precision'].')'; } + $notNull = $fieldDeclaration['notnull'] ?? false; + + if (! $notNull) { + return $columnType.' NULL'; + } + return $columnType; } diff --git a/tests/Integration/Database/DBAL/TimestampTypeTest.php b/tests/Integration/Database/DBAL/TimestampTypeTest.php index 14dc7e9c7f62..d7cec38c53b0 100644 --- a/tests/Integration/Database/DBAL/TimestampTypeTest.php +++ b/tests/Integration/Database/DBAL/TimestampTypeTest.php @@ -76,7 +76,7 @@ public function testChangeStringColumnToTimestampColumn() $queries = $blueprint->toSql($this->getConnection(), $this->getConnection()->getSchemaGrammar()); - $expected = ['ALTER TABLE test CHANGE string_to_timestamp string_to_timestamp TIMESTAMP DEFAULT NULL']; + $expected = ['ALTER TABLE test CHANGE string_to_timestamp string_to_timestamp TIMESTAMP NULL DEFAULT NULL']; $this->assertEquals($expected, $queries); } From 8fcbca3bfaa28028732104f97f718135ba724aa5 Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Tue, 13 Sep 2022 18:27:42 +0430 Subject: [PATCH 3/3] revert changes of binary type --- .../Database/Schema/Grammars/ChangeColumn.php | 4 ---- .../Database/SchemaBuilderTest.php | 21 ------------------- 2 files changed, 25 deletions(-) diff --git a/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php b/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php index 95474ec3a182..9579222991b7 100644 --- a/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php +++ b/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php @@ -125,10 +125,6 @@ protected static function getDoctrineColumnChangeOptions(Fluent $fluent) $options['length'] = static::calculateDoctrineTextLength($fluent['type']); } - if ($fluent['type'] === 'binary') { - $options['length'] = 65535; - } - if ($fluent['type'] === 'char') { $options['fixed'] = true; } diff --git a/tests/Integration/Database/SchemaBuilderTest.php b/tests/Integration/Database/SchemaBuilderTest.php index cd03051336e5..a39f2166a85c 100644 --- a/tests/Integration/Database/SchemaBuilderTest.php +++ b/tests/Integration/Database/SchemaBuilderTest.php @@ -88,27 +88,6 @@ public function testRegisterCustomDoctrineTypeASecondTime() $this->assertSame('tinyinteger', Schema::getColumnType('test', 'test_column')); } - public function testChangeToBinaryColumn() - { - if ($this->driver !== 'mysql') { - $this->markTestSkipped('Test requires a MySQL connection.'); - } - - Schema::create('test', function (Blueprint $table) { - $table->integer('test_column'); - }); - - $blueprint = new Blueprint('test', function ($table) { - $table->binary('test_column')->change(); - }); - - $queries = $blueprint->toSql($this->getConnection(), $this->getConnection()->getSchemaGrammar()); - - $expected = ['ALTER TABLE test CHANGE test_column test_column BLOB NOT NULL']; - - $this->assertEquals($expected, $queries); - } - public function testChangeToTextColumn() { if ($this->driver !== 'mysql') {