| Copyright | (c) 2026 The Polytropos Authors |
|---|---|
| License | EUPL-1.2 OR Apache-2.0 |
| Maintainer | nadia.yvette.chambers@ik.me |
| Stability | experimental |
| Portability | non-portable (GHC extensions) |
| Safe Haskell | None |
| Language | GHC2021 |
Polytropos.Rel8
Description
Integration of polytropos open rows with Oliver Charles' rel8 PostgreSQL
framework.
Architectural Overview & Rationale
provides rel8's PolyRowRel8able for the product row r:
* Its column schema is a right-nested HProduct tree of HLabeled HIdentity
columns built directly from the row's type-level field list.
* The flat SmallArray payload of the underlying
is read and written slot by slot — one slot per column, in row order.
* Conversion to and from rel8's columnar representation never materialises an
intermediate tuple and is unbounded in arity, completely avoiding GHC's 62-column
tuple limit.Rep
When to Use This Module
- When defining database schemas and type-safe SQL queries with
rel8where rows are modelled as openpolytroposrecords.
Worked Example
Worked Example
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fplugin=Polytropos.Plugin #-}
import Rel8
import Polytropos
import Polytropos.Rel8
type AccountRow = '["id" ':= Int64, "balance" ':= Double]
type AccountTable = PolyRow AccountRow
-- Lift a record to a Rel8 SQL expression row:
rec :: Record AccountRow
rec = REC { id = 42 :: Int64, balance = 1000.50 :: Double }
sqlExpr :: AccountTable Expr
sqlExpr = litRecord recSynopsis
- newtype PolyRow (r :: Row) (context :: Type -> Type) = PolyRow {
- unPolyRow :: RowRep context 'ProductRowT r ()
- toRecord :: forall (r :: Row). PolyRow r Result -> Record r
- fromRecord :: forall (r :: Row). Record r -> PolyRow r Result
- class HTable (GColumns t) => Rel8able (t :: Rel8able)
- class (AllSql r, HTable (RowHTable r)) => Rel8ableRow (r :: Row) where
- type family RowHTable (r :: Row) :: Context -> Type where ...
- type family AllSql (r :: Row) where ...
- rowToColumns :: forall (r :: Row). Rel8ableRow r => Record r -> RowHTable r Identity
- columnsToRow :: forall (r :: Row). Rel8ableRow r => RowHTable r Identity -> Record r
- litPolyRow :: forall (r :: Row). Rel8ableRow r => PolyRow r Result -> PolyRow r Expr
- litRecord :: forall (r :: Row). Rel8ableRow r => Record r -> PolyRow r Expr
- hfield :: forall (name :: Symbol) (r :: Row) context a. FieldIndex name r a => Field name -> PolyRow r context -> context a
- hfieldAt :: forall (r :: Row) context. Int -> PolyRow r context -> context (Any :: Type)
- htabulate :: forall (r :: Row) context. Rel8ableRow r => (Int -> context (Any :: Type)) -> PolyRow r context
- hmap :: forall (r :: Row) f g. Rel8ableRow r => (forall a. f a -> g a) -> PolyRow r f -> PolyRow r g
- htraverse :: forall (r :: Row) f g m. (Applicative m, Rel8ableRow r) => (forall a. f a -> m (g a)) -> PolyRow r f -> m (PolyRow r g)
- hzipWith :: forall (r :: Row) f g h. Rel8ableRow r => (forall a. f a -> g a -> h a) -> PolyRow r f -> PolyRow r g -> PolyRow r h
A rel8 Table from an Open Row
newtype PolyRow (r :: Row) (context :: Type -> Type) Source #
A rel8 table row backed by an open polytropos product row r.
The newtype is polymorphic in the rel8 context functor context so that rel8
can use the same Rel8able at Result, Expr, Name, etc.
Constructors
| PolyRow | |
Fields
| |
Instances
| Rel8ableRow r => Rel8able (PolyRow r) Source # | |||||||||
Defined in Polytropos.Rel8 Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns (PolyRow r) context -> PolyRow r context # gtoColumns :: forall (context :: Context). SContext context -> PolyRow r context -> GColumns (PolyRow r) context # gfromResult :: GColumns (PolyRow r) Result -> GFromExprs (PolyRow r) # gtoResult :: GFromExprs (PolyRow r) -> GColumns (PolyRow r) Result # | |||||||||
| Eq (Record r) => Eq (PolyRow r Result) Source # | |||||||||
| Show (Record r) => Show (PolyRow r Result) Source # | |||||||||
| type GColumns (PolyRow r) Source # | |||||||||
Defined in Polytropos.Rel8 | |||||||||
| type GFromExprs (PolyRow r) Source # | |||||||||
Defined in Polytropos.Rel8 | |||||||||
Schema & Rel8able Row Class
class HTable (GColumns t) => Rel8able (t :: Rel8able) #
This type class allows you to define custom Tables using higher-kinded
data types. Higher-kinded data types are data types of the pattern:
data MyType f =
MyType { field1 :: Column f T1 OR HK1 f
, field2 :: Column f T2 OR HK2 f
, ...
, fieldN :: Column f Tn OR HKn f
}
where Tn is any Haskell type, and HKn is any higher-kinded type.
That is, higher-kinded data are records where all fields in the record are
all either of the type Column f T (for any T), or are themselves
higher-kinded data:
- Nested
data Nested f =
Nested { nested1 :: MyType f
, nested2 :: MyType f
}
The Rel8able type class is used to give us a special mapping operation
that lets us change the type parameter f.
- Supplying
Rel8ableinstances
This type class should be derived generically for all table types in your
project. To do this, enable the DeriveAnyClass and DeriveGeneric language
extensions:
{-# LANGUAGE DeriveAnyClass, DeriveGeneric #-}
data MyType f = MyType { fieldA :: Column f T }
deriving ( GHC.Generics.Generic, Rel8able )
Instances
| Rel8able Attribute # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns Attribute context -> Attribute context # gtoColumns :: forall (context :: Context). SContext context -> Attribute context -> GColumns Attribute context # gfromResult :: GColumns Attribute Result -> GFromExprs Attribute # gtoResult :: GFromExprs Attribute -> GColumns Attribute Result # | |||||||||
| Rel8able Cast # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns Cast context -> Cast context # gtoColumns :: forall (context :: Context). SContext context -> Cast context -> GColumns Cast context # gfromResult :: GColumns Cast Result -> GFromExprs Cast # gtoResult :: GFromExprs Cast -> GColumns Cast Result # | |||||||||
| Rel8able PGAttribute # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns PGAttribute context -> PGAttribute context # gtoColumns :: forall (context :: Context). SContext context -> PGAttribute context -> GColumns PGAttribute context # gfromResult :: GColumns PGAttribute Result -> GFromExprs PGAttribute # gtoResult :: GFromExprs PGAttribute -> GColumns PGAttribute Result # | |||||||||
| Rel8able PGCast # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns PGCast context -> PGCast context # gtoColumns :: forall (context :: Context). SContext context -> PGCast context -> GColumns PGCast context # gfromResult :: GColumns PGCast Result -> GFromExprs PGCast # gtoResult :: GFromExprs PGCast -> GColumns PGCast Result # | |||||||||
| Rel8able PGClass # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns PGClass context -> PGClass context # gtoColumns :: forall (context :: Context). SContext context -> PGClass context -> GColumns PGClass context # gfromResult :: GColumns PGClass Result -> GFromExprs PGClass # gtoResult :: GFromExprs PGClass -> GColumns PGClass Result # | |||||||||
| Rel8able PGNamespace # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns PGNamespace context -> PGNamespace context # gtoColumns :: forall (context :: Context). SContext context -> PGNamespace context -> GColumns PGNamespace context # gfromResult :: GColumns PGNamespace Result -> GFromExprs PGNamespace # gtoResult :: GFromExprs PGNamespace -> GColumns PGNamespace Result # | |||||||||
| Rel8able PGTable # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns PGTable context -> PGTable context # gtoColumns :: forall (context :: Context). SContext context -> PGTable context -> GColumns PGTable context # gfromResult :: GColumns PGTable Result -> GFromExprs PGTable # gtoResult :: GFromExprs PGTable -> GColumns PGTable Result # | |||||||||
| Rel8able PGType # | |||||||||
Defined in Rel8.Internal.Table.Verify Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns PGType context -> PGType context # gtoColumns :: forall (context :: Context). SContext context -> PGType context -> GColumns PGType context # gfromResult :: GColumns PGType Result -> GFromExprs PGType # gtoResult :: GFromExprs PGType -> GColumns PGType Result # | |||||||||
| Rel8ableRow r => Rel8able (PolyRow r) Source # | |||||||||
Defined in Polytropos.Rel8 Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns (PolyRow r) context -> PolyRow r context # gtoColumns :: forall (context :: Context). SContext context -> PolyRow r context -> GColumns (PolyRow r) context # gfromResult :: GColumns (PolyRow r) Result -> GFromExprs (PolyRow r) # gtoResult :: GFromExprs (PolyRow r) -> GColumns (PolyRow r) Result # | |||||||||
| ADTable t => Rel8able (ADT t) # | |||||||||
Defined in Rel8.Internal.Table.ADT Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns (ADT t) context -> ADT t context # gtoColumns :: forall (context :: Context). SContext context -> ADT t context -> GColumns (ADT t) context # gfromResult :: GColumns (ADT t) Result -> GFromExprs (ADT t) # gtoResult :: GFromExprs (ADT t) -> GColumns (ADT t) Result # | |||||||||
| HKDable a => Rel8able (HKD a) # | |||||||||
Defined in Rel8.Internal.Table.HKD Associated Types
Methods gfromColumns :: forall (context :: Context). SContext context -> GColumns (HKD a) context -> HKD a context # gtoColumns :: forall (context :: Context). SContext context -> HKD a context -> GColumns (HKD a) context # gfromResult :: GColumns (HKD a) Result -> GFromExprs (HKD a) # gtoResult :: GFromExprs (HKD a) -> GColumns (HKD a) Result # | |||||||||
class (AllSql r, HTable (RowHTable r)) => Rel8ableRow (r :: Row) where Source #
Type class providing bidirectional conversion between a flat SmallArray
of slots and the nested rel8 RowHTable column tree.
Methods
toHTable :: SmallArray (context (Any :: Type)) -> Int -> (RowHTable r context, Int) Source #
Convert a flat array into the nested HTable tree at a given starting offset.
fromHTable :: RowHTable r context -> [context (Any :: Type)] Source #
Unroll the nested HTable tree into a list of erased column context slots.
litHTable :: RowHTable r Result -> RowHTable r Expr Source #
Arity (number of columns).
Instances
| (KnownSymbol n, Sql DBType a, Rel8ableRow (r1 ': rs)) => Rel8ableRow ((n ':= a) ': (r1 ': rs)) Source # | |
Defined in Polytropos.Rel8 Methods toHTable :: SmallArray (context (Any :: Type)) -> Int -> (RowHTable ((n ':= a) ': (r1 ': rs)) context, Int) Source # fromHTable :: RowHTable ((n ':= a) ': (r1 ': rs)) context -> [context (Any :: Type)] Source # litHTable :: RowHTable ((n ':= a) ': (r1 ': rs)) Result -> RowHTable ((n ':= a) ': (r1 ': rs)) Expr Source # | |
| (KnownSymbol n, Sql DBType a) => Rel8ableRow '[n ':= a] Source # | |
Defined in Polytropos.Rel8 | |
type family RowHTable (r :: Row) :: Context -> Type where ... Source #
type family AllSql (r :: Row) where ... Source #
Constraint: every field label has a KnownSymbol instance and its type is a PostgreSQL
Sql DBType.
Entry points for Identity/Result
rowToColumns :: forall (r :: Row). Rel8ableRow r => Record r -> RowHTable r Identity Source #
columnsToRow :: forall (r :: Row). Rel8ableRow r => RowHTable r Identity -> Record r Source #
Lifting to SQL Expressions
litPolyRow :: forall (r :: Row). Rel8ableRow r => PolyRow r Result -> PolyRow r Expr Source #
Columnar Combinators
hfield :: forall (name :: Symbol) (r :: Row) context a. FieldIndex name r a => Field name -> PolyRow r context -> context a Source #
Read a field by name using FieldIndex.
hfieldAt :: forall (r :: Row) context. Int -> PolyRow r context -> context (Any :: Type) Source #
Read a field at a slot index from a PolyRow.
htabulate :: forall (r :: Row) context. Rel8ableRow r => (Int -> context (Any :: Type)) -> PolyRow r context Source #
Build a PolyRow by evaluating a generator across each column slot.
hmap :: forall (r :: Row) f g. Rel8ableRow r => (forall a. f a -> g a) -> PolyRow r f -> PolyRow r g Source #
Map a natural transformation across all columns in a PolyRow.
htraverse :: forall (r :: Row) f g m. (Applicative m, Rel8ableRow r) => (forall a. f a -> m (g a)) -> PolyRow r f -> m (PolyRow r g) Source #
Traverse all columnar fields in a PolyRow.