From 393476a7e369394b99615f9288393dee539439f1 Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Mon, 18 Dec 2023 19:13:11 +0330 Subject: [PATCH] [10.x] Improve schema builder `getColumns()` method (#49416) * wip * fix tests * wip --- .../Query/Processors/PostgresProcessor.php | 2 +- .../Query/Processors/SQLiteProcessor.php | 2 +- .../Database/Schema/Grammars/MySqlGrammar.php | 2 +- .../Schema/Grammars/PostgresGrammar.php | 4 +-- .../Schema/Grammars/SQLiteGrammar.php | 2 +- .../Schema/Grammars/SqlServerGrammar.php | 3 +- .../Database/SchemaBuilderTest.php | 32 +++++++++++++++++++ 7 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Illuminate/Database/Query/Processors/PostgresProcessor.php b/src/Illuminate/Database/Query/Processors/PostgresProcessor.php index d35ee2dc2c6c..e7b062785eb0 100755 --- a/src/Illuminate/Database/Query/Processors/PostgresProcessor.php +++ b/src/Illuminate/Database/Query/Processors/PostgresProcessor.php @@ -107,7 +107,7 @@ public function processColumns($results) $autoincrement = $result->default !== null && str_starts_with($result->default, 'nextval('); return [ - 'name' => str_starts_with($result->name, '"') ? str_replace('"', '', $result->name) : $result->name, + 'name' => $result->name, 'type_name' => $result->type_name, 'type' => $result->type, 'collation' => $result->collation, diff --git a/src/Illuminate/Database/Query/Processors/SQLiteProcessor.php b/src/Illuminate/Database/Query/Processors/SQLiteProcessor.php index 8f5fb98206e0..adcb16a2038a 100644 --- a/src/Illuminate/Database/Query/Processors/SQLiteProcessor.php +++ b/src/Illuminate/Database/Query/Processors/SQLiteProcessor.php @@ -36,7 +36,7 @@ public function processColumns($results) return [ 'name' => $result->name, - 'type_name' => strtok($type, '('), + 'type_name' => strtok($type, '(') ?: '', 'type' => $type, 'collation' => null, 'nullable' => (bool) $result->nullable, diff --git a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php index 4a78039aff17..aaafa322860f 100755 --- a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php @@ -158,7 +158,7 @@ public function compileColumns($database, $table) return sprintf( 'select column_name as `name`, data_type as `type_name`, column_type as `type`, ' .'collation_name as `collation`, is_nullable as `nullable`, ' - .'column_default as `default`, column_comment AS `comment`, extra as `extra` ' + .'column_default as `default`, column_comment as `comment`, extra as `extra` ' .'from information_schema.columns where table_schema = %s and table_name = %s ' .'order by ordinal_position asc', $this->quoteString($database), diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 688d4acfac1f..acc9c5800715 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -168,11 +168,11 @@ public function compileColumnListing() public function compileColumns($database, $schema, $table) { return sprintf( - 'select quote_ident(a.attname) as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, ' + 'select a.attname as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, ' .'(select tc.collcollate from pg_catalog.pg_collation tc where tc.oid = a.attcollation) as collation, ' .'not a.attnotnull as nullable, ' .'(select pg_get_expr(adbin, adrelid) from pg_attrdef where c.oid = pg_attrdef.adrelid and pg_attrdef.adnum = a.attnum) as default, ' - .'(select pg_description.description from pg_description where pg_description.objoid = c.oid and a.attnum = pg_description.objsubid) as comment ' + .'col_description(c.oid, a.attnum) as comment ' .'from pg_attribute a, pg_class c, pg_type t, pg_namespace n ' .'where c.relname = %s and n.nspname = %s and a.attnum > 0 and a.attrelid = c.oid and a.atttypid = t.oid and n.oid = c.relnamespace ' .'order by a.attnum', diff --git a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php index e9c7d8c80490..201121cb6170 100755 --- a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php @@ -121,7 +121,7 @@ public function compileColumnListing($table) public function compileColumns($table) { return sprintf( - "select name, type, not 'notnull' as 'nullable', dflt_value as 'default', pk as 'primary' " + 'select name, type, not "notnull" as "nullable", dflt_value as "default", pk as "primary" ' .'from pragma_table_info(%s) order by cid asc', $this->wrap(str_replace('.', '__', $table)) ); diff --git a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php index 4b9091a1d6ef..5af6631be2b7 100755 --- a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php @@ -162,7 +162,8 @@ public function compileColumns($table) .'join sys.schemas as scm on obj.schema_id = scm.schema_id ' .'left join sys.default_constraints def on col.default_object_id = def.object_id and col.object_id = def.parent_object_id ' ."left join sys.extended_properties as prop on obj.object_id = prop.major_id and col.column_id = prop.minor_id and prop.name = 'MS_Description' " - ."where obj.type = 'U' and obj.name = %s and scm.name = SCHEMA_NAME()", + ."where obj.type in ('U', 'V') and obj.name = %s and scm.name = SCHEMA_NAME() " + .'order by col.column_id', $this->quoteString($table), ); } diff --git a/tests/Integration/Database/SchemaBuilderTest.php b/tests/Integration/Database/SchemaBuilderTest.php index 5d38e0e2a8a2..456e382fd964 100644 --- a/tests/Integration/Database/SchemaBuilderTest.php +++ b/tests/Integration/Database/SchemaBuilderTest.php @@ -209,6 +209,38 @@ public function testGetAndDropTypes() $this->assertEmpty($types); } + public function testGetColumns() + { + Schema::create('foo', function (Blueprint $table) { + $table->id(); + $table->string('bar')->nullable(); + $table->string('baz')->default('test'); + }); + + $columns = Schema::getColumns('foo'); + + $this->assertCount(3, $columns); + $this->assertTrue(collect($columns)->contains( + fn ($column) => $column['name'] === 'id' && $column['auto_increment'] && ! $column['nullable'] + )); + $this->assertTrue(collect($columns)->contains( + fn ($column) => $column['name'] === 'bar' && $column['nullable'] + )); + $this->assertTrue(collect($columns)->contains( + fn ($column) => $column['name'] === 'baz' && ! $column['nullable'] && str_contains($column['default'], 'test') + )); + } + + public function testGetColumnsOnView() + { + DB::statement('create view foo (bar) as select 1'); + + $columns = Schema::getColumns('foo'); + + $this->assertCount(1, $columns); + $this->assertTrue($columns[0]['name'] === 'bar'); + } + public function testGetIndexes() { Schema::create('foo', function (Blueprint $table) {