Commit Graph

18 Commits

Author SHA1 Message Date
Andrew Farries
4f0a715613
Support setting table and column comments to NULL (#345)
Build on #344 to allow removing column comments by setting them to
`null`.

Make use of https://github.com/omissis/go-jsonschema/pull/220 and use
the [nullable](https://github.com/oapi-codegen/nullable) package so that
it's possible to distingush between a missing `comment` field and one
that is explicitly set to `null`.

With https://github.com/omissis/go-jsonschema/pull/220 not being part of
a release yet, use a custom build of `go-jsonschema`. It should be
possible to switch back to the official release images once
https://github.com/omissis/go-jsonschema/pull/220 is part of a release.

Without this change it becomes impossible to remove a comment from a
column using the 'set comment' 'alter column' sub-operation
(https://github.com/xataio/pgroll/pull/344).
2024-04-29 13:23:29 +01:00
Andrew Farries
4fbfdf7b7e
Add a 'set comment' sub-operation to 'alter column' (#344)
Allow 'alter column' operations to set the comment on a column:

```json
{
  "name": "02_change_comment",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "comment": "The full name of the event"
      }
    }
  ]
}
```

This is a versioned migration so the column to which the comment is
applied is duplicated and backfilled according to the `up` and `down`
SQL supplied with the 'alter column' operation. `up` and `down` default
to a simple copy of the field between new and old columns.

The intention is that this can be combined with a 'change type'
sub-operation if there is some column metadata that should be updated as
part of the type change:

```json
{
  "name": "35_alter_column_multiple",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "name": "event_name",
        "type": "text",
        "comment": "{type: some-metadata}",
        "up": "name",
        "down": "name"
      }
    }
  ]
}
```

Fixes #328
2024-04-29 10:40:10 +01:00
Andrew Farries
afad3d88cd
Add a 'set default' sub-operation to 'alter column' (#346)
Allow 'alter column' operations to set the default value on a column:

```json
{
  "name": "02_change_default",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "default": "'new default value'"
      }
    }
  ]
}
```

This is a versioned migration so the column to which the default is
applied is duplicated and backfilled according to the `up` and `down`
SQL supplied with the 'alter column' operation. `up` and `down` default
to a simple copy of the field between new and old columns.

Fixes #327
2024-04-25 11:47:44 +01:00
Andrew Farries
a4222d8f8c
Support multiple 'alter column' sub operations (#338)
Allow 'alter column' operations to include multiple sub-operations. This
means migrations like this one are now possible:

```json
{
  "name": "35_alter_column_multiple",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "name": "event_name",
        "type": "text",
        "nullable": false,
        "unique": {
          "name": "events_event_name_unique"
        },
        "check": {
          "name": "event_name_length",
          "constraint": "length(name) > 3"
        },
        "up": "(SELECT CASE WHEN name IS NULL THEN 'placeholder' ELSE name END)",
        "down": "name"
      }
    }
  ]
}
```

This 'alter column' operation:
* Renames a column
* Changes its type
* Sets it `NOT NULL`
* Adds a unique constraint
* Adds a check constraint

Previously, this would have required 5 different operations.

Builds on https://github.com/xataio/pgroll/pull/337. Fixes
https://github.com/xataio/pgroll/issues/336
2024-04-22 12:11:15 +01:00
Andrew Farries
cf66d1f5b7
Update operation types to set a default of "" for up and down SQL (#325)
Improve consistency between operation types by updating operation types
to ensure that all operations that use `up` or `down` SQL default these
fields to `""`.

There is no distinction between an empty string and `nil` for these
fields.
2024-03-26 09:52:33 +00:00
Andrew Farries
eda936f158
Add rename_constraint operation to PgRollOperation JSON schema definition (#300)
Otherwise migrations that include this operation are not valid according
to the JSON schema.

Fixup to https://github.com/xataio/pgroll/pull/293.
2024-03-01 16:02:28 +00:00
Alexis Rico
577870c325
Add rename_constraint operation (#293) 2024-03-01 11:30:09 +00:00
Andrew Farries
def08e2bcc
Allow setting the ON DELETE behaviour of foreign key constraints (#297)
Add support for setting the `ON DELETE` behaviour of a foreign key
constraint.

An example migration that uses the behaviour is:

```json
{
  "name": "21_add_foreign_key_constraint",
  "operations": [
    {
      "alter_column": {
        "table": "posts",
        "column": "user_id",
        "references": {
          "name": "fk_users_id",
          "table": "users",
          "column": "id",
          "on_delete": "CASCADE"
        },
        "up": "(SELECT CASE WHEN EXISTS (SELECT 1 FROM users WHERE users.id = user_id) THEN user_id ELSE NULL END)",
        "down": "user_id"
      }
    }
  ]
}
```

The valid options for `on_delete` are `CASCADE`, `SET NULL`, `RESTRICT`,
or `NO ACTION`. If the field is omitted, the default is `NO ACTION`,

Fixes #221
2024-03-01 09:26:50 +00:00
Alexis Rico
52fb532e63
Format schema.json on generate (#294)
Add rule to format JSON Schema with prettier

---------

Signed-off-by: Alexis Rico <sferadev@gmail.com>
2024-03-01 09:24:05 +00:00
Alexis Rico
6e4ee68310
Make name not required in PgRollMigration (#282)
Signed-off-by: Alexis Rico <sferadev@gmail.com>
2024-02-19 16:43:26 +00:00
Carlos Pérez-Aradros Herce
58fa7ae970
Add SQL onComplete flag, allow sql migration to run with others (#280)
This change updates the `sql` operation to:

* Allow for a new `onComplete` flag, that will make it run on the
Complete phase, rather than doing it during Start (default behavior).
* Allows for `sql` operations next to others in the same migration. We
added this limitation to ensure this operation doesn't affect others,
especially around schema state management.

Having `sql` next to other operations has proven convenient sometimes,
by adding `onComplete` flag, we can allow for these migrations to run
and rely on views recreation based on the final state.

---------

Co-authored-by: Andrew Farries <andyrb@gmail.com>
2024-02-12 16:37:15 +01:00
Andrew Farries
d06a0afe0a
Update JSON schema to specify that not all Column fields are required (#265)
Update the JSON schema in `schema.json` to state that only `name` and
`type` are required fields when specifying a column.

Previously `required` was set to `["name", "nullable", "pk", "type",
"unique"]` resulting in some valid `create_table` and `add_column`
migrations failing to validate.

Add two new testcases to the JSON schema tests to cover 'create_table'
and 'add_column' operations.
2024-02-02 12:44:37 +00:00
Andrew Farries
5a6a83a65c
Update schema.json to correctly describe the 'alter column' operation (#261)
Update `schema.json` to correctly describe the 'alter column' operation.

The [alter column
](https://github.com/xataio/pgroll/tree/main/docs#alter-column)
operation is used to perform different alter column operations according
to which fields are present.

The rules are:
* `table` and `column` are always required.
* Exactly one of `name`, `type`, `check`, `unique`, `references`,
`nullable` must be present.
* If `type`, `check`, `unique`, `references` or `nullable` is present,
then `up` and `down` must also be present.
* If `name` is present then neither `up` or `down` is allowed.

This PR updates `schema.json` to capture these dependencies.

This change causes churn in the test code as some fields that previously
`string` have become `*string`.

Fixes #222
2024-02-02 09:10:22 +00:00
Carlos Pérez-Aradros Herce
bb79eecc3b
Fix raw SQL migrations spec in schema.json (#264)
[User facing
](7e65cda1ed/pkg/migrations/op_common.go (L25))
these operations are called `sql`, not `raw_sql`
2024-02-02 09:59:09 +01:00
Andrew Farries
b9e781932d
Add drop NOT NULL operation to remove NOT NULL from a column (#258)
Add a new sub-operation to the 'alter column' operation to drop `NOT
NULL` constraints from columns.

Currently, it is only possible to **set** `NOT NULL` constraints on
columns but not remove them. The syntax for doing this is:

```json
{
  "name": "16_set_nullable",
  "operations": [
    {
      "alter_column": {
        "table": "reviews",
        "column": "review",
        "nullable": false,
        "up": "(SELECT CASE WHEN review IS NULL THEN product || ' is good' ELSE review END)",
        "down": "review"
      }
    }
  ]
}
```

Setting `nullable: true` in the above migration would result in a
validation error saying that removing `NOT NULL` constraints was not
supported. This PR removes this restriction and allows `nullable: true`
to remove an existing `NOT NULL` constraint.

A migration to remove a `NOT NULL` constraint looks like:

```json
{
  "name": "31_unset_not_null",
  "operations": [
    {
      "alter_column": {
        "table": "posts",
        "column": "title",
        "nullable": true,
        "up": "title",
        "down": "(SELECT CASE WHEN title IS NULL THEN 'placeholder title' ELSE title END)"
      }
    }
  ]
}
```

The differences between adding and removing a `NOT NULL` constraint are:
* `nullable: true` vs `nullable: false`
* The roles of `up` and `down` SQL are reversed; `down` now needs to
rewrite any `NULL`s to meet the `NOT NULL` constraint on the old column.
`up` defaults to a simple copy of the data from the old column to the
new.


Fixes #223
2024-02-01 07:08:02 +00:00
Andrew Farries
61cc53ab88
Add support for creating tables and columns with comments (#224)
Update the **create table** and **add column** operations so that they
support adding [Postgres
comments](https://www.postgresql.org/docs/current/sql-comment.html):

* **create table**: comments can be added to the table itself and to
each of its columns.
* **add column**: a comment can be added to the column.

A **create table** migration that includes a comment on the table itself
and on one of its columns looks like this:

```json
{
  "name": "12_create_employees_table",
  "operations": [
    {
      "create_table": {
        "name": "employees",
        "comment": "This is a comment for the employees table",
        "columns": [
          {
            "name": "id",
            "type": "serial",
            "pk": true
          },
          {
            "name": "role",
            "type": "varchar(255)",
            "comment": "This is a comment for the role column"
          }
        ]
      }
    }
  ]
}
```

and an **add column** migration that includes a comment looks like this:

```json
{
  "name": "30_add_column_simple_up",
  "operations": [
    {
      "add_column": {
        "table": "people",
        "up": "'temporary-description'",
        "column": {
          "name": "description",
          "type": "varchar(255)",
          "nullable": false,
          "comment": "This is a comment for the description column"
        }
      }
    }
  ]
}
```

This allows new tables and columns to be created with comments.

Deletion and modification of comments should still be performed with a
raw SQL migration. Until we see a use case that requires versioned
modification/removal of comments, these operations are best performed
directly on the base table with raw SQL.
2024-01-10 15:58:57 +00:00
Alexis Rico
c10dabfc3c
Fix pgroll migration definition (#216)
- Split `PgRollMigration` so that we can properly use it in the frontend
- Fix operation keys not being included in the schema
2024-01-02 19:15:14 +01:00
Alexis Rico
788bac6e4e
Add JSON schema struct generation (#210)
All structs matched well except for `PrimaryKey` which we mapped
differently, I've refactored it to `Pk` as it doesn't seem to support
different names for go and JSON

---------

Signed-off-by: Alexis Rico <sferadev@gmail.com>
Co-authored-by: Andrew Farries <andyrb@gmail.com>
2023-12-01 16:01:40 +00:00