Safe Haskell | None |
---|---|
Language | Haskell2010 |
Rel8.Table.Verify
Synopsis
- getSchemaErrors :: [SomeTableSchema] -> Statement () (Maybe Text)
- data SomeTableSchema where
- SomeTableSchema :: forall (k :: (Type -> Type) -> Type). (ToExprs (k Expr) (GFromExprs k), Rel8able k) => TableSchema (k Name) -> SomeTableSchema
- showCreateTable :: Rel8able k => TableSchema (k Name) -> String
- checkedShowCreateTable :: Rel8able k => TableSchema (k Name) -> Either (Map String (NonEmpty [String])) String
Documentation
getSchemaErrors :: [SomeTableSchema] -> Statement () (Maybe Text) Source #
checks whether the provided schemas have the correct PostgreSQL
column names and types to allow reading and writing from their equivalent Haskell
types, returning a list of errors if that is not the case. The function does not
crash on encountering a bug, instead leaving it to the caller to decide how
to respond. A schema is valid if:getSchemaErrors
- for every existing field, the types match
- all non-nullable columns are present in the hs type
- no nonexistent columns are present in the hs type
- no two columns in the same schema share the same name
It's still possible for a valid schema to allow invalid data, for instance, if using an ADT, which can introduce restrictions on which values are allowed for the column representing the tag, and introduce restrictions on which columns are non-null depending on the value of the tag. However, if the schema is valid rel8 shouldn't be able to write invalid data to the table.
However, it is possible for migrations to cause valid data to become invalid in ways not detectable by this function, if the migration code changes the schema correctly but doesn't handle the value-level constraints correctly. So it is a good idea to both read from the tables and check the schema for errors in a transaction during the migration. The former will catch value-level bugs, while the latter will help ensure the schema is set up correctly to be able to insert new data.
This function does nothing to check that the conflict target of an Upsert
are valid for the schema, nor can it prevent invalid uses of unsafeDefault
.
However, it should be enough to catch the most likely errors.
data SomeTableSchema where Source #
is used to allow the collection of a variety of different
SomeTableSchema
TableSchema
s under a single type, like:
userTable :: TableSchema (User Name) orderTable :: TableSchema (Order Name) tables :: [SomeTableSchema] tables = [SomeTableSchema userTable, SomeTable orderTable]
This is used by
to conveniently group every table an
application relies on for typechecking the postgresql schemas
together in a single batch.schemaErrors
Constructors
SomeTableSchema :: forall (k :: (Type -> Type) -> Type). (ToExprs (k Expr) (GFromExprs k), Rel8able k) => TableSchema (k Name) -> SomeTableSchema |
showCreateTable :: Rel8able k => TableSchema (k Name) -> String Source #
shows an example CREATE TABLE statement for the table.
This does not show relationships like primary or foreign keys, but can still
be useful to see what types showCreateTable
rel8
will expect of the underlying database.
In the event that multiple columns have the same name, this will fail silently. To
handle that case, see checkedShowCreateTable
checkedShowCreateTable :: Rel8able k => TableSchema (k Name) -> Either (Map String (NonEmpty [String])) String Source #
shows an example CREATE TABLE statement for the
table. This does not show relationships like primary or foreign keys, but can
still be useful to see what types rel8 will expect of the underlying database.checkedShowCreateTable
In the event that multiple columns have the same name, this will return a map of names to the labels identifying the column.