Skip to content

[10.x] Get columns of a table #48357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Query/Processors/MySqlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class MySqlProcessor extends Processor
/**
* Process the results of a column listing query.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param array $results
* @return array
*/
Expand All @@ -16,4 +18,28 @@ public function processColumnListing($results)
return ((object) $result)->column_name;
}, $results);
}

/**
* Process the results of a columns query.
*
* @param array $results
* @return array
*/
public function processColumns($results)
{
return array_map(function ($result) {
$result = (object) $result;

return [
'name' => $result->name,
'type_name' => $result->type_name,
'type' => $result->type,
'collation' => $result->collation,
'nullable' => $result->nullable === 'YES',
'default' => $result->default,
'auto_increment' => $result->extra === 'auto_increment',
'comment' => $result->comment,
];
}, $results);
}
}
28 changes: 28 additions & 0 deletions src/Illuminate/Database/Query/Processors/PostgresProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu
/**
* Process the results of a column listing query.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param array $results
* @return array
*/
Expand All @@ -42,4 +44,30 @@ public function processColumnListing($results)
return ((object) $result)->column_name;
}, $results);
}

/**
* Process the results of a columns query.
*
* @param array $results
* @return array
*/
public function processColumns($results)
{
return array_map(function ($result) {
$result = (object) $result;

$autoincrement = $result->default !== null && str_starts_with($result->default, 'nextval(');

return [
'name' => $result->name,
'type_name' => $result->type_name,
'type' => $result->type,
'collation' => $result->collation,
'nullable' => (bool) $result->nullable,
'default' => $autoincrement ? null : $result->default,
'auto_increment' => $autoincrement,
'comment' => $result->comment,
];
}, $results);
}
}
13 changes: 13 additions & 0 deletions src/Illuminate/Database/Query/Processors/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,24 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu
/**
* Process the results of a column listing query.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param array $results
* @return array
*/
public function processColumnListing($results)
{
return $results;
}

/**
* Process the results of a columns query.
*
* @param array $results
* @return array
*/
public function processColumns($results)
{
return $results;
}
}
30 changes: 30 additions & 0 deletions src/Illuminate/Database/Query/Processors/SQLiteProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class SQLiteProcessor extends Processor
/**
* Process the results of a column listing query.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param array $results
* @return array
*/
Expand All @@ -16,4 +18,32 @@ public function processColumnListing($results)
return ((object) $result)->name;
}, $results);
}

/**
* Process the results of a columns query.
*
* @param array $results
* @return array
*/
public function processColumns($results)
{
$hasPrimaryKey = array_sum(array_column($results, 'primary')) === 1;

return array_map(function ($result) use ($hasPrimaryKey) {
$result = (object) $result;

$type = strtolower($result->type);

return [
'name' => $result->name,
'type_name' => strtok($type, '('),
'type' => $type,
'collation' => null,
'nullable' => (bool) $result->nullable,
'default' => $result->default,
'auto_increment' => $hasPrimaryKey && $result->primary && $type === 'integer',
'comment' => null,
];
}, $results);
}
}
33 changes: 33 additions & 0 deletions src/Illuminate/Database/Query/Processors/SqlServerProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ protected function processInsertGetIdForOdbc(Connection $connection)
/**
* Process the results of a column listing query.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param array $results
* @return array
*/
Expand All @@ -67,4 +69,35 @@ public function processColumnListing($results)
return ((object) $result)->name;
}, $results);
}

/**
* Process the results of a columns query.
*
* @param array $results
* @return array
*/
public function processColumns($results)
{
return array_map(function ($result) {
$result = (object) $result;

$type = match ($typeName = $result->type_name) {
'binary', 'varbinary', 'char', 'varchar', 'nchar', 'nvarchar' => $result->length == -1 ? $typeName.'(max)' : $typeName."($result->length)",
'decimal', 'numeric' => $typeName."($result->precision,$result->places)",
'float', 'datetime2', 'datetimeoffset', 'time' => $typeName."($result->precision)",
default => $typeName,
};

return [
'name' => $result->name,
'type_name' => $result->type_name,
'type' => $type,
'collation' => $result->collation,
'nullable' => (bool) $result->nullable,
'default' => $result->default,
'auto_increment' => (bool) $result->autoincrement,
'comment' => $result->comment,
];
}, $results);
}
}
36 changes: 30 additions & 6 deletions src/Illuminate/Database/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,26 @@ public function whenTableDoesntHaveColumn(string $table, string $column, Closure
*
* @param string $table
* @param string $column
* @param bool $fullDefinition
* @return string
*/
public function getColumnType($table, $column)
public function getColumnType($table, $column, $fullDefinition = false)
{
$table = $this->connection->getTablePrefix().$table;

return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
if (! $this->connection->usingNativeSchemaOperations()) {
return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
}

$columns = $this->getColumns($table);

foreach ($columns as $value) {
if (strtolower($value['name']) === $column) {
return $fullDefinition ? $value['type'] : $value['type_name'];
}
}

throw new InvalidArgumentException("There is no column with name '$column' on table '$table'.");
}

/**
Expand All @@ -250,11 +263,22 @@ public function getColumnType($table, $column)
*/
public function getColumnListing($table)
{
$results = $this->connection->selectFromWriteConnection($this->grammar->compileColumnListing(
$this->connection->getTablePrefix().$table
));
return array_column($this->getColumns($table), 'name');
}

/**
* Get the columns for a given table.
*
* @param string $table
* @return array
*/
public function getColumns($table)
{
$table = $this->connection->getTablePrefix().$table;

return $this->connection->getPostProcessor()->processColumnListing($results);
return $this->connection->getPostProcessor()->processColumns(
$this->connection->selectFromWriteConnection($this->grammar->compileColumns($table))
);
}

/**
Expand Down
22 changes: 22 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,35 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @return string
*/
public function compileColumnListing()
{
return 'select column_name as `column_name` from information_schema.columns where table_schema = ? and table_name = ?';
}

/**
* Compile the query to determine the columns.
*
* @param string $database
* @param string $table
* @return string
*/
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` '
.'from information_schema.columns where table_schema = %s and table_name = %s '
.'order by ordinal_position asc',
$this->quoteString($database),
$this->quoteString($table)
);
}

/**
* Compile a create table command.
*
Expand Down
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,39 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @return string
*/
public function compileColumnListing()
{
return 'select column_name from information_schema.columns where table_catalog = ? and table_schema = ? and table_name = ?';
}

/**
* Compile the query to determine the columns.
*
* @param string $database
* @param string $schema
* @param string $table
* @return string
*/
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 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 '
.'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',
$this->quoteString($table),
$this->quoteString($schema)
);
}

/**
* Compile a create table command.
*
Expand Down
17 changes: 17 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param string $table
* @return string
*/
Expand All @@ -47,6 +49,21 @@ public function compileColumnListing($table)
return 'pragma table_info('.$this->wrap(str_replace('.', '__', $table)).')';
}

/**
* Compile the query to determine the columns.
*
* @param string $table
* @return string
*/
public function compileColumns($table)
{
return sprintf(
"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))
);
}

/**
* Compile a create table command.
*
Expand Down
27 changes: 27 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param string $table
* @return string
*/
Expand All @@ -87,6 +89,31 @@ public function compileColumnListing($table)
return "select name from sys.columns where object_id = object_id('$table')";
}

/**
* Compile the query to determine the columns.
*
* @param string $table
* @return string
*/
public function compileColumns($table)
{
return sprintf(
'select col.name, type.name as type_name, '
.'col.max_length as length, col.precision as precision, col.scale as places, '
.'col.is_nullable as nullable, def.definition as [default], '
.'col.is_identity as autoincrement, col.collation_name as collation, '
.'cast(prop.value as nvarchar(max)) as comment '
.'from sys.columns as col '
.'join sys.types as type on col.user_type_id = type.user_type_id '
.'join sys.objects as obj on col.object_id = obj.object_id '
.'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()",
$this->quoteString($table),
);
}

/**
* Compile a create table command.
*
Expand Down
Loading