Store primary keys in pgroll internal schema (#135)

Add a `primaryKey` field to each table in the internal schema store to
record the column(s) that make up a table's primary key.

This will be used when backfilling rows
(https://github.com/xataio/pgroll/issues/127)

An example schema now looks like:

```json
{
  "name": "public",
  "tables": {
    "users": {
      "oid": "16412",
      "name": "users",
      "columns": {
        "id": {
          "name": "id",
          "type": "integer",
          "comment": null,
          "default": "nextval('users_id_seq'::regclass)",
          "nullable": false
        },
        "name": {
          "name": "name",
          "type": "text",
          "comment": null,
          "default": null,
          "nullable": true
        }
      },
      "comment": null,
      "indexes": {
        "users_pkey": {
          "name": "users_pkey"
        }
      },
      "primaryKey": [
        "id"
      ]
    }
  }
}
```
Where the `primaryKey` field is the new field.
This commit is contained in:
Andrew Farries 2023-09-26 07:08:21 +01:00 committed by GitHub
parent 02a2e0edcd
commit 7f4b90ef54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 0 deletions

View File

@ -43,6 +43,9 @@ type Table struct {
// Indexes is a map of the indexes defined on the table
Indexes map[string]Index `json:"indexes"`
// The columns that make up the primary key
PrimaryKey []string `json:"primaryKey"`
}
type Column struct {
@ -112,6 +115,13 @@ func (t *Table) GetColumn(name string) *Column {
return &c
}
func (t *Table) GetPrimaryKey() (columns []*Column) {
for _, name := range t.PrimaryKey {
columns = append(columns, t.GetColumn(name))
}
return columns
}
func (t *Table) AddColumn(name string, c Column) {
if t.Columns == nil {
t.Columns = make(map[string]Column)

View File

@ -120,6 +120,15 @@ BEGIN
attr.attnum
) c
),
'primaryKey', (
SELECT json_agg(kcu.column_name) AS primary_key_columns
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.table_name = t.relname
AND tc.table_schema = schemaname
AND tc.constraint_type = 'PRIMARY KEY'
),
'indexes', (
SELECT json_object_agg(pi.indexrelid::regclass, json_build_object(
'name', pi.indexrelid::regclass