{"id":19479127,"url":"https://github.com/tam/pgsl","last_synced_at":"2025-07-20T12:02:21.914Z","repository":{"id":88046171,"uuid":"366192121","full_name":"Tam/pgsl","owner":"Tam","description":"A superscript language of PostgreSQL","archived":false,"fork":false,"pushed_at":"2025-03-25T21:55:36.000Z","size":77,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-25T22:33:13.399Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-10T22:34:42.000Z","updated_at":"2025-03-25T21:55:40.000Z","dependencies_parsed_at":"2023-03-14T02:00:16.480Z","dependency_job_id":"0d9cd414-beca-42dd-9e9a-4ffb269b6c79","html_url":"https://github.com/Tam/pgsl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Tam/pgsl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tam%2Fpgsl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tam%2Fpgsl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tam%2Fpgsl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tam%2Fpgsl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tam","download_url":"https://codeload.github.com/Tam/pgsl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tam%2Fpgsl/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259456326,"owners_count":22860536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T19:52:51.843Z","updated_at":"2025-07-20T12:02:21.896Z","avatar_url":"https://github.com/Tam.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pgsl\n**P**ost**g**res **S**chema **L**anguage: a superscript language of PostgreSQL\n\nRemoves a lot of the guff in postgres files, making schemas easier to write and \nunderstand at a glance.\n\nWill come with its own migrator so all you have to do is write the schema. The \nmigrator will check the structure of the database and only migrate any changes.\nIt will also warn about destructive actions (like dropping columns or enums).\n\n### Testing\n\n```shell\ncargo run -- sample.pgl --debug\n```\n\n### Sample\n\n```text\n# interfaces/archive.pgl\n\ninterface table archive:\n  columns:\n    is_archived boolean default false\n      Whether or not this item is archived (soft-deleted)\n      @omit create\n    archived_at timestamptz\n      When this item was archived\n      @omit create,update\n    restored_at timestamptz\n      When this item was restored\n      @omit create,update\n\ntrigger before insert or update on archive:\n  begin:\n    if old.is_archived = false and new.is_archived = true then\n      new.archived_at = now();\n    elsif old.is_archived = true and new.is_archived = false then\n      new.restored_at = now();\n    end if;\n\n    return new;\n  end plpgsql volatile\n\n# character.pgl\n\nrequire:\n  interfaces/archive\n  interfaces/timestamp\n  core\n  assets\n  game\n\nschema character:\n  grant usage to anonymous, member\n\ntable public.character:\n  extends:\n    archive\n    timestamp\n  columns:\n    id          uuid primary key default public.uuid_generate_v1mc()\n    owner_id    uuid references public.user(id) on delete cascade\n                @omit\n                @description Hello world!\n    game_type   text references game.type not null\n    name        varchar(256) not null\n    token_id    uuid references public.asset(id) on delete set null\n\nfunction character.example_func:\n  accept:\n    id uuid\n    some_value text\n  declare:\n    another_value boolean\n  begin:\n    select * from test;\n  end sql stable\n```\n\n### Notes-to-self on migrations\n- There should be a clear order of operations:\n  1. Creating\n     1. Types\n     2. Tables\n     3. Columns\n     4. Indexes / Foreign Keys\n     5. Views\n     6. Functions\n     7. RLS\n     8. Triggers\n  2. Updating\n     1. Column definitions\n     2. Views\n     3. Functions\n     4. RLS\n     5. Triggers\n  3. Deleting\n     - The same items as creating, but in reverse order\n- Some operations above can happen out of order if they are needed for others \n  to complete. For example, we might need to add a new column before creating a\n  table if that table references that new column (although this could probably \n  be handled in the foreign keys step?)\n\n### Notes-to-self on Custom Language Features\nThere are some features in this language that differ from Postgres' standard.\nThe main one being interfaces. Interfaces are similar to built-in postgres \ninheritance, but instead of the inherited data being stored in a separate table,\nwe add the columns, triggers, etc. to the table being extended.\n\n### TODO\n- We need a way of running additional custom migration logic for, example, \n  moving data from an old column to a new column. Perhaps something like:\n  ```diff\n  interface table archive:\n    columns:\n  -    is_archived boolean default false\n  -      Whether or not this item is archived (soft-deleted)\n  -      @omit create\n  +    is_public boolean default true\n  +      comment:\n  +        Whether this item is public\n  +        @behaviour -insert -update\n  +      migrate:\n  +        begin\n  +          update [table] set is_public = not is_archived;\n  +        exception when undefined_column then end\n      archived_at timestamptz\n        When this item was archived\n        @omit create,update\n      restored_at timestamptz\n        When this item was restored\n        @omit create,updat\n  ```\n  In the example above we're changing an interface, so we use the `[table]`\n  placeholder that should be automatically replaced with the actual table name.\n  `migrate:` should support anything available in the standard `do $$` including\n  declaring variables. Here we're wrapping the update in a catch so we don't \n  have to worry about the `is_archived` column no longer existing in future \n  updates. We should also support multiple `migrate:` blocks, run in order of \n  definition, siloed out from each other.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftam%2Fpgsl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftam%2Fpgsl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftam%2Fpgsl/lists"}