BSD-3-Clause licensed by Dmitry Olshansky
Maintained by [email protected]
This version can be pinned in stack with:pg-schema-0.8.1.0@sha256:c07277ffd859e98eaf9536a4d1bcd07f4c7ebe664b2c7967a1925654d1d5bae1,8578

Module documentation for 0.8.1.0

pg-schema

pg-schema is a Haskell library that lifts a PostgreSQL schema description to the type level and gives you type-safe, compile-time-checked access to data.

The core idea is a type provider: from a live database (tables, primary and unique keys, foreign keys, column types—including arrays and enums) a schema representation is built that you then use with ordinary GHC types. You can have any number of such schemas; each may include any subset of tables.

To generate schemas you create a separate application that uses PgSchema.Generation.updateSchemaFile to produce .hs files describing each schema (sets of tables, relationships between them, and the types in use).

For reading and writing data, use the PgSchema.DML module. Queries are built from a typed EDSL, without hand-written SQL. You can describe data trees (nested records along relationships), including inserting an entire tree in one database round-trip (JSON is used internally), and fetching a tree with a single SELECT, with predicates, ordering, and limits at each level of the tree (WHERE, ORDER BY, LIMIT/OFFSET, and so on).

Inserts and reads use either ordinary Haskell records with a Generic instance or types of the form "fld1" := Int32 :. "fld2" := Maybe Text. Field names in Haskell records must match those in the database (with renaming supported) but you can work with any subset of the table’s fields. Navigation along relationships uses foreign-key constraint names. Types and nullability are checked against the data layout.

SELECT and INSERT/UPDATE/UPSERT are implemented for the nested structures. There are also versions of UPDATE and DELETE applied to a single table.

When reading data, an EDSL sets conditions, ordering, and grouping. All of these operations are type-safe.

For inserts and updates, additional compile-time checks derive from database constraints—for example, inserts verify that mandatory fields are present at every level.

Requirements

GHC ≥ 9.10. Theoretically, one could target older GHC version at the cost of a slightly worse API without RequiredTypeArguments.

Changes

Changelog for pg-schema

0.8.1.0

  • upsertJSON: require Maybe on child returning when upsert uses ON CONFLICT DO NOTHING with parent FK columns outside the conflict key (NeedsFkKeyOnlyMaybe in ReturningMatchesUpsert)

0.8.0.1

  • Build all with -Wall
  • Small fixes in doc

0.8.0.0

  • Fix SELECT path matching after renamer: promoted PathElem' (peName, peDbName, peKind) replaces (Text, PathKind); runtime pathStepMatches supports point paths and broadcast by shared db fk name; independent filters on aliased sibling fields (e.g. mid1RootFk vs mid1_root_fk2).
  • Internal SELECT paths: [PathElemK] in PathCtx / TabOnDPathRen; removed EffPath on renamer-only pairs; TabOnDPath2 walks peDbName.
  • Flat DML: upsertByKey / upsertByKey_ and updateByKey / updateByKey_ (upsertByKey requires all mandatory columns and a full key — always INSERT … ON CONFLICT …; updateByKey is key-only, never inserts, bare returning type r', result IO ([Maybe r'], Text)).
  • Tree DML: updateJSON / updateJSON_ (update-only); InsertMode for the JSON pipeline.
  • Tree returning: Maybe or Bare for upsertJSON.
  • New constraints: AllHasKeyTree, CheckHasKey, ReturningMatches{Insert,Upsert,Update}, FromJSON / ToJSON for Maybe rows and null in returning arrays.
  • Rename TreeSch to HasSchema

0.7.1.2

  • Fix bug with aggregates (Min/Max/Sum/Avg)

0.7.1.1

  • Add upsertJSONText, upsertJSONText_

0.7.1.0

  • Condition DSL: (=??) on nullable columns generates SQL IS NOT DISTINCT FROM (same null-safe key equality as upsertJSON)
  • Improve transaction behavior for insertJSON/upsertJSON
  • Add tests for insertJSON/upsertJSON with transactions
  • upsertJSON / upsertJSON_: optional ON CONFLICT targets include NOT NULL unique keys (primary key still first), then nullable unique keys when the table has no NOT NULL UK; UPDATE by key uses IS NOT DISTINCT FROM for key columns; IdentityCandidates (compile-time) lists every PK/UK from the schema
  • insertJSON / insertJSON_: insert-only (plain INSERT, no ON CONFLICT or UPDATE; duplicate keys fail at the database)
  • Rename AllMandatoryOrHasPKTree to AllMandatoryOrHasKeyTree

0.7.0.1

  • Bug fixing (upsertJSON_ without change fields: on conflict do nothing)

0.7.0.0

  • Bug fixing (updateText_ signature)
  • Change signature for deleteByCond
  • Add CondAnn & QueryParamsAnn

0.6.1.0

  • Bug fixing (ins/upsertJSON for json db-fields)

0.6.0.0

  • Using Renamer for QueryParams and Cond
  • Improve error messaging
  • Support for ‘UnsafeCol’
  • Check possibility of type conversions for select-list/insert/update (it was broken in 0.5.0)
  • Check optional/mandatory for parent references is SELECT
  • Added qPathFromHere/qPathToHere. Self-reference require explicit direction in qPathXXX

0.5.2.0

  • Bug fixing (Problem with Self-references)

0.5.1.1

  • Improve error messaging

0.5.1.0

  • Bug fixing (TF stucks in some cases)

0.5.0.0

  • First release on Hackage