Skip to content
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

[10.x] Get foreign keys of a table #49264

Merged
merged 6 commits into from
Dec 11, 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
23 changes: 23 additions & 0 deletions src/Illuminate/Database/Query/Processors/MySqlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,27 @@ public function processIndexes($results)
];
}, $results);
}

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

return [
'name' => $result->name,
'columns' => explode(',', $result->columns),
'foreign_schema' => $result->foreign_schema,
'foreign_table' => $result->foreign_table,
'foreign_columns' => explode(',', $result->foreign_columns),
'on_update' => strtolower($result->on_update),
'on_delete' => strtolower($result->on_delete),
];
}, $results);
}
}
37 changes: 37 additions & 0 deletions src/Illuminate/Database/Query/Processors/PostgresProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,41 @@ public function processIndexes($results)
];
}, $results);
}

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

return [
'name' => $result->name,
'columns' => explode(',', $result->columns),
'foreign_schema' => $result->foreign_schema,
'foreign_table' => $result->foreign_table,
'foreign_columns' => explode(',', $result->foreign_columns),
'on_update' => match (strtolower($result->on_update)) {
'a' => 'no action',
'r' => 'restrict',
'c' => 'cascade',
'n' => 'set null',
'd' => 'set default',
default => null,
},
'on_delete' => match (strtolower($result->on_delete)) {
'a' => 'no action',
'r' => 'restrict',
'c' => 'cascade',
'n' => 'set null',
'd' => 'set default',
default => null,
},
];
}, $results);
}
}
11 changes: 11 additions & 0 deletions src/Illuminate/Database/Query/Processors/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ public function processIndexes($results)
return $results;
}

/**
* Process the results of a foreign keys query.
*
* @param array $results
* @return array
*/
public function processForeignKeys($results)
{
return $results;
}

/**
* Process the results of a column listing query.
*
Expand Down
23 changes: 23 additions & 0 deletions src/Illuminate/Database/Query/Processors/SQLiteProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,27 @@ public function processIndexes($results)

return $indexes;
}

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

return [
'name' => null,
'columns' => explode(',', $result->columns),
'foreign_schema' => null,
'foreign_table' => $result->foreign_table,
'foreign_columns' => explode(',', $result->foreign_columns),
'on_update' => strtolower($result->on_update),
'on_delete' => strtolower($result->on_delete),
];
}, $results);
}
}
23 changes: 23 additions & 0 deletions src/Illuminate/Database/Query/Processors/SqlServerProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,27 @@ public function processIndexes($results)
];
}, $results);
}

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

return [
'name' => $result->name,
'columns' => explode(',', $result->columns),
'foreign_schema' => $result->foreign_schema,
'foreign_table' => $result->foreign_table,
'foreign_columns' => explode(',', $result->foreign_columns),
'on_update' => strtolower(str_replace('_', ' ', $result->on_update)),
'on_delete' => strtolower(str_replace('_', ' ', $result->on_delete)),
];
}, $results);
}
}
15 changes: 15 additions & 0 deletions src/Illuminate/Database/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,21 @@ public function getIndexes($table)
);
}

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

return $this->connection->getPostProcessor()->processForeignKeys(
$this->connection->selectFromWriteConnection($this->grammar->compileForeignKeys($table))
);
}

/**
* Modify a table on the schema.
*
Expand Down
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,32 @@ public function compileIndexes($database, $table)
);
}

/**
* Compile the query to determine the foreign keys.
*
* @param string $database
* @param string $table
* @return string
*/
public function compileForeignKeys($database, $table)
{
return sprintf(
'select kc.constraint_name as `name`, '
.'group_concat(kc.column_name order by kc.ordinal_position) as `columns`, '
.'kc.referenced_table_schema as `foreign_schema`, '
.'kc.referenced_table_name as `foreign_table`, '
.'group_concat(kc.referenced_column_name order by kc.ordinal_position) as `foreign_columns`, '
.'rc.update_rule as `on_update`, '
.'rc.delete_rule as `on_delete` '
.'from information_schema.key_column_usage kc join information_schema.referential_constraints rc '
.'on kc.constraint_schema = rc.constraint_schema and kc.constraint_name = rc.constraint_name '
.'where kc.table_schema = %s and kc.table_name = %s and kc.referenced_table_name is not null '
.'group by kc.constraint_name, kc.referenced_table_schema, kc.referenced_table_name, rc.update_rule, rc.delete_rule',
$this->quoteString($database),
$this->quoteString($table)
);
}

/**
* Compile a create table command.
*
Expand Down
30 changes: 30 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,36 @@ public function compileIndexes($schema, $table)
);
}

/**
* Compile the query to determine the foreign keys.
*
* @param string $schema
* @param string $table
* @return string
*/
public function compileForeignKeys($schema, $table)
{
return sprintf(
'select c.conname as name, '
."string_agg(la.attname, ',' order by conseq.ord) as columns, "
.'fn.nspname as foreign_schema, fc.relname as foreign_table, '
."string_agg(fa.attname, ',' order by conseq.ord) as foreign_columns, "
.'c.confupdtype as on_update, c.confdeltype as on_delete '
.'from pg_constraint c '
.'join pg_class tc on c.conrelid = tc.oid '
.'join pg_namespace tn on tn.oid = tc.relnamespace '
.'join pg_class fc on c.confrelid = fc.oid '
.'join pg_namespace fn on fn.oid = fc.relnamespace '
.'join lateral unnest(c.conkey) with ordinality as conseq(num, ord) on true '
.'join pg_attribute la on la.attrelid = c.conrelid and la.attnum = conseq.num '
.'join pg_attribute fa on fa.attrelid = c.confrelid and fa.attnum = c.confkey[conseq.ord] '
."where c.contype = 'f' and tc.relname = %s and tn.nspname = %s "
.'group by c.conname, fn.nspname, fc.relname, c.confupdtype, c.confdeltype',
$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 @@ -146,6 +146,23 @@ public function compileIndexes($table)
);
}

/**
* Compile the query to determine the foreign keys.
*
* @param string $table
* @return string
*/
public function compileForeignKeys($table)
{
return sprintf(
'select group_concat("from") as columns, "table" as foreign_table, '
.'group_concat("to") as foreign_columns, on_update, on_delete '
.'from (select * from pragma_foreign_key_list(%s) order by id desc, seq) '
.'group by id, "table", on_update, on_delete',
$this->wrap(str_replace('.', '__', $table))
);
}

/**
* Compile a create table command.
*
Expand Down
29 changes: 29 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,35 @@ public function compileIndexes($table)
);
}

/**
* Compile the query to determine the foreign keys.
*
* @param string $table
* @return string
*/
public function compileForeignKeys($table)
{
return sprintf(
'select fk.name as name, '
."string_agg(lc.name, ',') within group (order by fkc.constraint_column_id) as columns, "
.'fs.name as foreign_schema, ft.name as foreign_table, '
."string_agg(fc.name, ',') within group (order by fkc.constraint_column_id) as foreign_columns, "
.'fk.update_referential_action_desc as on_update, '
.'fk.delete_referential_action_desc as on_delete '
.'from sys.foreign_keys as fk '
.'join sys.foreign_key_columns as fkc on fkc.constraint_object_id = fk.object_id '
.'join sys.tables as lt on lt.object_id = fk.parent_object_id '
.'join sys.schemas as ls on lt.schema_id = ls.schema_id '
.'join sys.columns as lc on fkc.parent_object_id = lc.object_id and fkc.parent_column_id = lc.column_id '
.'join sys.tables as ft on ft.object_id = fk.referenced_object_id '
.'join sys.schemas as fs on ft.schema_id = fs.schema_id '
.'join sys.columns as fc on fkc.referenced_object_id = fc.object_id and fkc.referenced_column_id = fc.column_id '
.'where lt.name = %s and ls.name = SCHEMA_NAME() '
.'group by fk.name, fs.name, ft.name, fk.update_referential_action_desc, fk.delete_referential_action_desc',
$this->quoteString($table)
);
}

/**
* Compile a create table command.
*
Expand Down
17 changes: 17 additions & 0 deletions src/Illuminate/Database/Schema/MySqlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,23 @@ public function getIndexes($table)
);
}

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

return $this->connection->getPostProcessor()->processForeignKeys(
$this->connection->selectFromWriteConnection(
$this->grammar->compileForeignKeys($this->connection->getDatabaseName(), $table)
)
);
}

/**
* Drop all tables from the database.
*
Expand Down
17 changes: 17 additions & 0 deletions src/Illuminate/Database/Schema/PostgresBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,23 @@ public function getIndexes($table)
);
}

/**
* Get the foreign keys for a given table.
*
* @param string $table
* @return array
*/
public function getForeignKeys($table)
{
[, $schema, $table] = $this->parseSchemaAndTable($table);

$table = $this->connection->getTablePrefix().$table;

return $this->connection->getPostProcessor()->processForeignKeys(
$this->connection->selectFromWriteConnection($this->grammar->compileForeignKeys($schema, $table))
);
}

/**
* Get the schemas for the connection.
*
Expand Down
1 change: 1 addition & 0 deletions src/Illuminate/Support/Facades/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* @method static array getColumnListing(string $table)
* @method static array getColumns(string $table)
* @method static array getIndexes(string $table)
* @method static array getForeignKeys(string $table)
* @method static void table(string $table, \Closure $callback)
* @method static void create(string $table, \Closure $callback)
* @method static void drop(string $table)
Expand Down
Loading