Skip to content

Instantly share code, notes, and snippets.

@ilyakooo0
Created April 4, 2025 09:07
Show Gist options
  • Save ilyakooo0/1b76cc0b63cb9d8d2e4e9e5c718c2f35 to your computer and use it in GitHub Desktop.
Save ilyakooo0/1b76cc0b63cb9d8d2e4e9e5c718c2f35 to your computer and use it in GitHub Desktop.
pgroll Dhall definitions
let Prelude = ./Prelude.dhall
let TypeName
: Type
= Text
let ColumnName
: Type
= Text
let ConstraintName
: Type
= Text
let IndexName
: Type
= Text
let TableName
: Type
= Text
let ConstraintName
: Type
= Text
let SQL
: Type
= Text
let Check
: Type
= { name : Text, constraint : SQL }
let References
: Type
= { name : Text, table : TableName, column : ColumnName, on_delete : SQL }
let Column
: Type
= { name : ColumnName
, type : TypeName
, nullable : Bool
, unique : Bool
, pk : Bool
, default : Optional SQL
, check : Optional Check
, references : Optional References
}
let IndexMethod
: Type
= < btree | hash | gist | spgist | gin | brin >
let ConstraintType
: Type
= < unique | check | foreign_key >
let Operation
: Type
= < add_column : { table : TableName, up : SQL, column : Column }
| alter_column :
{ table : TableName
, column : ColumnName
, name : Optional ColumnName
, type : Optional TypeName
, up : Optional SQL
, down : Optional SQL
, check : Optional Check
, references : Optional References
, nullable : Optional Bool
, unique : Optional { name : ConstraintName }
}
| create_index :
{ table : TableName
, name : IndexName
, columns : List ColumnName
, predicate : Optional SQL
, unique : Bool
, method : IndexMethod
}
| create_constraint :
{ table : TableName
, name : ConstraintName
, columns : List ColumnName
, type : ConstraintType
, check : Optional SQL
, references : Optional References
, up : Prelude.Map.Type ColumnName SQL
, down : Prelude.Map.Type ColumnName SQL
}
| create_table : { name : TableName, columns : List Column }
| drop_column :
{ table : TableName, column : ColumnName, down : Optional SQL }
| drop_multicolumn_constraint :
{ table : TableName
, name : ConstraintName
, up : Prelude.Map.Type ColumnName SQL
, down : Prelude.Map.Type ColumnName SQL
}
| drop_index : { name : IndexName }
| drop_table : { name : TableName }
| sql : { up : SQL, down : SQL }
| rename_table : { from : TableName, to : TableName }
| rename_constraint :
{ table : TableName, from : ConstraintName, to : ConstraintName }
>
let Migration
: Type
= { name : Text, operations : List Operation }
let operation =
\(op : Operation) ->
Prelude.JSON.keyValue Operation (showConstructor op) op
let operations =
Prelude.List.map
Operation
(List { mapKey : Text, mapValue : Operation })
(\(op : Operation) -> [ operation op ])
in { Migration
, Operation
, TableName
, ColumnName
, ConstraintName
, Column
, TypeName
, SQL
, References
, Check
, operations
, IndexMethod
, ConstraintType
}
https://prelude.dhall-lang.org/v20.1.0/package.dhall
sha256:26b0ef498663d269e4dc6a82b0ee289ec565d683ef4c00d0ebdd25333a5a3c98
let PGRoll = ./PGRoll.dhall
let Rel8 = ./Rel8.dhall
let column
: PGRoll.ColumnName -> PGRoll.TypeName -> PGRoll.Column
= \(name : PGRoll.ColumnName) ->
\(type : PGRoll.TypeName) ->
{ name
, type
, nullable = False
, unique = False
, pk = False
, default = None PGRoll.SQL
, check = None PGRoll.Check
, references = None PGRoll.References
}
let maybeColumn =
\(name : PGRoll.ColumnName) ->
\(type : PGRoll.TypeName) ->
(column name type)
with nullable = True
let createdAt = column "createdAt" Rel8.UTCTime
let updatedAt = column "updatedAt" Rel8.UTCTime
let id = (column "id" Rel8.Id) with pk = True with unique = True
let new = \(name : PGRoll.TableName) -> "_pgroll_new_" ++ name
let fkId =
\(name : Text) ->
\(table : PGRoll.TableName) ->
{ name = name ++ "_" ++ table ++ "_id"
, table
, column = "id"
, on_delete = "RESTRICT"
}
: PGRoll.References
let newFkId =
\(name : Text) ->
\(table : PGRoll.TableName) ->
{ name = name ++ "_" ++ table ++ "_id"
, table = new table
, column = "id"
, on_delete = "RESTRICT"
}
: PGRoll.References
let fk =
\(name : Text) ->
\(table : PGRoll.TableName) ->
(column table Rel8.Id)
with references = Some (fkId name table)
let newFk =
\(name : Text) ->
\(table : PGRoll.TableName) ->
(column table Rel8.Id)
with references = Some (newFkId name table)
let maybeFk =
\(name : Text) ->
\(table : PGRoll.TableName) ->
(fk name table)
with nullable = True
let index =
\(table : PGRoll.TableName) ->
\(column : PGRoll.ColumnName) ->
PGRoll.Operation.create_index
{ table
, name = table ++ "_" ++ column
, columns = [ column ]
, method = PGRoll.IndexMethod.btree
, predicate = None PGRoll.SQL
, unique = False
}
: PGRoll.Operation
let translation = \(name : PGRoll.TableName) -> column name Rel8.Id
let maybeTranslation =
\(name : PGRoll.TableName) -> (translation name) with nullable = True
let createReference =
\ ( args
: { table : PGRoll.TableName
, column : PGRoll.ColumnName
, references : PGRoll.References
}
) ->
PGRoll.Operation.alter_column
{ table = args.table
, column = args.column
, name = None PGRoll.ColumnName
, type = None PGRoll.TypeName
, up = Some "NULL"
, down = Some "NULL"
, check = None PGRoll.Check
, references = Some args.references
, nullable = None Bool
, unique = None { name : PGRoll.ConstraintName }
}
in { maybeColumn
, column
, createdAt
, updatedAt
, id
, index
, fkId
, fk
, translation
, maybeTranslation
, maybeFk
, newFk
, newFkId
, createReference
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment