| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Rel8
Synopsis
- class NotNull a => DBType a where
- newtype JSONEncoded a = JSONEncoded {
- fromJSONEncoded :: a
- newtype JSONBEncoded a = JSONBEncoded {
- fromJSONBEncoded :: a
- newtype ReadShow a = ReadShow {
- fromReadShow :: a
- newtype Composite a = Composite a
- class (DBType a, HKDable a) => DBComposite a where
- compose :: DBComposite a => HKD a Expr -> Expr a
- decompose :: DBComposite a => Expr a -> HKD a Expr
- newtype Enum a = Enum a
- class DBType a => DBEnum a where
- enumValue :: a -> String
- enumTypeName :: QualifiedName
- enumerate :: [a]
- class (Generic a, GEnumable (Rep a)) => Enumable a
- data TypeInformation a = TypeInformation {}
- data TypeName = TypeName {
- name :: QualifiedName
- modifiers :: [String]
- arrayDepth :: Word
- mapTypeInformation :: (a -> b) -> (b -> a) -> TypeInformation a -> TypeInformation b
- parseTypeInformation :: (a -> Either String b) -> (b -> a) -> TypeInformation a -> TypeInformation b
- class DBType a => DBSemigroup a where
- class DBSemigroup a => DBMonoid a where
- memptyExpr :: Expr a
- class DBType a => DBNum a
- class (DBNum a, DBOrd a) => DBIntegral a
- class DBNum a => DBFractional a
- class DBFractional a => DBFloating a
- class HTable (GColumns t) => Rel8able (t :: Rel8able)
- type KRel8able = Rel8able
- type family Column (context :: Context) a where ...
- type family HADT (context :: Context) (t :: Rel8able) where ...
- type family HEither (context :: Context) = (either :: Type -> Type -> Type) | either -> context where ...
- type family HMaybe (context :: Context) = (maybe :: Type -> Type) | maybe -> context where ...
- type family HList (context :: Context) = (list :: Type -> Type) | list -> context where ...
- type family HNonEmpty (context :: Context) = (nonEmpty :: Type -> Type) | nonEmpty -> context where ...
- type family HNull (context :: Context) = (maybe :: Type -> Type) | maybe -> context where ...
- type family HThese (context :: Context) = (these :: Type -> Type -> Type) | these -> context where ...
- type family Lift (context :: Context) a where ...
- class (HTable (Columns a), context ~ Context a, a ~ Transpose context a) => Table (context :: Context) a | a -> context where
- class HTable (t :: HTable)
- class (Table from a, Table to b, Congruent a b, b ~ Transpose to a, a ~ Transpose from b) => Transposes (from :: Context) (to :: Context) a b | a -> from, b -> to, a to -> b, b from -> a
- class AltTable (f :: Type -> Type) where
- class AltTable f => AlternativeTable (f :: Type -> Type) where
- emptyTable :: Table Expr a => f a
- class Table Expr a => EqTable a where
- (==:) :: EqTable a => a -> a -> Expr Bool
- (/=:) :: EqTable a => a -> a -> Expr Bool
- class EqTable a => OrdTable a where
- (<:) :: OrdTable a => a -> a -> Expr Bool
- (<=:) :: OrdTable a => a -> a -> Expr Bool
- (>:) :: OrdTable a => a -> a -> Expr Bool
- (>=:) :: OrdTable a => a -> a -> Expr Bool
- ascTable :: OrdTable a => Order a
- descTable :: OrdTable a => Order a
- greatest :: OrdTable a => a -> a -> a
- least :: OrdTable a => a -> a -> a
- lit :: Serializable exprs a => a -> exprs
- bool :: Table Expr a => a -> a -> Expr Bool -> a
- case_ :: Table Expr a => [(Expr Bool, a)] -> a -> a
- castTable :: Table Expr a => a -> a
- data MaybeTable (context :: Context) a
- maybeTable :: Table Expr b => b -> (a -> b) -> MaybeTable Expr a -> b
- ($?) :: forall a b. Sql DBType b => (a -> Expr b) -> MaybeTable Expr a -> Expr (Nullify b)
- nothingTable :: Table Expr a => MaybeTable Expr a
- justTable :: a -> MaybeTable Expr a
- isNothingTable :: MaybeTable Expr a -> Expr Bool
- isJustTable :: MaybeTable Expr a -> Expr Bool
- fromMaybeTable :: Table Expr a => a -> MaybeTable Expr a -> a
- optional :: Query a -> Query (MaybeTable Expr a)
- catMaybeTable :: MaybeTable Expr a -> Query a
- traverseMaybeTable :: (a -> Query b) -> MaybeTable Expr a -> Query (MaybeTable Expr b)
- aggregateJustTable :: forall a i (fold :: Fold). Table Expr a => Aggregator i a -> Aggregator' fold (MaybeTable Expr i) a
- aggregateJustTable1 :: forall a (fold :: Fold) i (fold' :: Fold). Table Expr a => Aggregator' fold i a -> Aggregator' fold' (MaybeTable Expr i) (MaybeTable Expr a)
- aggregateMaybeTable :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator1 (MaybeTable Expr i) (MaybeTable Expr a)
- nameMaybeTable :: Name (Maybe MaybeTag) -> a -> MaybeTable Name a
- data EitherTable (context :: Context) a b
- eitherTable :: Table Expr c => (a -> c) -> (b -> c) -> EitherTable Expr a b -> c
- leftTable :: Table Expr b => a -> EitherTable Expr a b
- rightTable :: Table Expr a => b -> EitherTable Expr a b
- isLeftTable :: EitherTable Expr a b -> Expr Bool
- isRightTable :: EitherTable Expr a b -> Expr Bool
- keepLeftTable :: EitherTable Expr a b -> Query a
- keepRightTable :: EitherTable Expr a b -> Query b
- bitraverseEitherTable :: (a -> Query c) -> (b -> Query d) -> EitherTable Expr a b -> Query (EitherTable Expr c d)
- aggregateLeftTable :: forall c a (fold :: Fold) b. Table Expr c => Aggregator a c -> Aggregator' fold (EitherTable Expr a b) c
- aggregateLeftTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (EitherTable Expr a b) (MaybeTable Expr c)
- aggregateRightTable :: forall c b (fold :: Fold) a. Table Expr c => Aggregator b c -> Aggregator' fold (EitherTable Expr a b) c
- aggregateRightTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (EitherTable Expr a b) (MaybeTable Expr c)
- aggregateEitherTable :: forall (fold :: Fold) i a (fold' :: Fold) i' b. Aggregator' fold i a -> Aggregator' fold' i' b -> Aggregator1 (EitherTable Expr i i') (EitherTable Expr a b)
- nameEitherTable :: Name EitherTag -> a -> b -> EitherTable Name a b
- data TheseTable (context :: Context) a b
- theseTable :: Table Expr c => (a -> c) -> (b -> c) -> (a -> b -> c) -> TheseTable Expr a b -> c
- thisTable :: Table Expr b => a -> TheseTable Expr a b
- thatTable :: Table Expr a => b -> TheseTable Expr a b
- thoseTable :: a -> b -> TheseTable Expr a b
- isThisTable :: TheseTable Expr a b -> Expr Bool
- isThatTable :: TheseTable Expr a b -> Expr Bool
- isThoseTable :: TheseTable Expr a b -> Expr Bool
- hasHereTable :: TheseTable Expr a b -> Expr Bool
- hasThereTable :: TheseTable Expr a b -> Expr Bool
- justHereTable :: forall (context :: Context) a b. TheseTable context a b -> MaybeTable context a
- justThereTable :: forall (context :: Context) a b. TheseTable context a b -> MaybeTable context b
- alignMaybeTable :: MaybeTable Expr a -> MaybeTable Expr b -> MaybeTable Expr (TheseTable Expr a b)
- alignBy :: (a -> b -> Expr Bool) -> Query a -> Query b -> Query (TheseTable Expr a b)
- keepHereTable :: TheseTable Expr a b -> Query (a, MaybeTable Expr b)
- loseHereTable :: TheseTable Expr a b -> Query b
- keepThereTable :: TheseTable Expr a b -> Query (MaybeTable Expr a, b)
- loseThereTable :: TheseTable Expr a b -> Query a
- keepThisTable :: TheseTable Expr a b -> Query a
- loseThisTable :: TheseTable Expr a b -> Query (MaybeTable Expr a, b)
- keepThatTable :: TheseTable Expr a b -> Query b
- loseThatTable :: TheseTable Expr a b -> Query (a, MaybeTable Expr b)
- keepThoseTable :: TheseTable Expr a b -> Query (a, b)
- loseThoseTable :: TheseTable Expr a b -> Query (EitherTable Expr a b)
- bitraverseTheseTable :: (a -> Query c) -> (b -> Query d) -> TheseTable Expr a b -> Query (TheseTable Expr c d)
- aggregateThisTable :: forall c a (fold :: Fold) b. Table Expr c => Aggregator a c -> Aggregator' fold (TheseTable Expr a b) c
- aggregateThisTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c)
- aggregateThatTable :: forall c b (fold :: Fold) a. Table Expr c => Aggregator b c -> Aggregator' fold (TheseTable Expr a b) c
- aggregateThatTable1 :: forall c (fold :: Fold) b (fold' :: Fold) a. Table Expr c => Aggregator' fold b c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c)
- aggregateThoseTable :: forall c a b (fold :: Fold). Table Expr c => Aggregator (a, b) c -> Aggregator' fold (TheseTable Expr a b) c
- aggregateThoseTable1 :: forall c (fold :: Fold) a b (fold' :: Fold). Table Expr c => Aggregator' fold (a, b) c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c)
- aggregateHereTable :: forall c a (fold :: Fold) b. Table Expr c => Aggregator a c -> Aggregator' fold (TheseTable Expr a b) c
- aggregateHereTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c)
- aggregateThereTable :: forall c b (fold :: Fold) a. Table Expr c => Aggregator b c -> Aggregator' fold (TheseTable Expr a b) c
- aggregateThereTable1 :: forall c (fold :: Fold) b (fold' :: Fold) a. Table Expr c => Aggregator' fold b c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c)
- aggregateTheseTable :: forall (fold :: Fold) i a (fold' :: Fold) i' b. Aggregator' fold i a -> Aggregator' fold' i' b -> Aggregator1 (TheseTable Expr i i') (TheseTable Expr a b)
- nameTheseTable :: Name (Maybe MaybeTag) -> Name (Maybe MaybeTag) -> a -> b -> TheseTable Name a b
- data ListTable (context :: Context) a
- listOf :: Sql DBType a => [Expr a] -> Expr [a]
- listTable :: Table Expr a => [a] -> ListTable Expr a
- ($*) :: Projecting a (Expr b) => Projection a (Expr b) -> ListTable Expr a -> Expr [b]
- nameListTable :: Table Name a => a -> ListTable Name a
- many :: Table Expr a => Query a -> Query (ListTable Expr a)
- manyExpr :: Sql DBType a => Query (Expr a) -> Query (Expr [a])
- catListTable :: Table Expr a => ListTable Expr a -> Query a
- catList :: Sql DBType a => Expr [a] -> Query (Expr a)
- data NonEmptyTable (context :: Context) a
- nonEmptyOf :: Sql DBType a => NonEmpty (Expr a) -> Expr (NonEmpty a)
- nonEmptyTable :: Table Expr a => NonEmpty a -> NonEmptyTable Expr a
- ($+) :: Projecting a (Expr b) => Projection a (Expr b) -> NonEmptyTable Expr a -> Expr (NonEmpty b)
- nameNonEmptyTable :: Table Name a => a -> NonEmptyTable Name a
- some :: Table Expr a => Query a -> Query (NonEmptyTable Expr a)
- someExpr :: Sql DBType a => Query (Expr a) -> Query (Expr (NonEmpty a))
- catNonEmptyTable :: Table Expr a => NonEmptyTable Expr a -> Query a
- catNonEmpty :: Sql DBType a => Expr (NonEmpty a) -> Query (Expr a)
- data NullTable (context :: Context) a
- nullableTable :: (Table Expr a, Table Expr b) => b -> (a -> b) -> NullTable Expr a -> b
- nullTable :: Table Expr a => NullTable Expr a
- nullifyTable :: a -> NullTable Expr a
- isNullTable :: Table Expr a => NullTable Expr a -> Expr Bool
- isNonNullTable :: Table Expr a => NullTable Expr a -> Expr Bool
- catNullTable :: Table Expr a => NullTable Expr a -> Query a
- nameNullTable :: a -> NullTable Name a
- toNullTable :: Table Expr a => MaybeTable Expr a -> NullTable Expr a
- toMaybeTable :: Table Expr a => NullTable Expr a -> MaybeTable Expr a
- unsafeUnnullifyTable :: NullTable Expr a -> a
- type NameADT (t :: Rel8able) = GGName 'Sum (ADTRep t) (ADT t Name)
- nameADT :: forall (t :: Rel8able). ConstructableADT t => NameADT t
- data ADT (t :: Rel8able) (context :: Context)
- class (Generic (Record (t Result)), HTable (GColumnsADT t), GSerializeADT TSerialize TColumns (Eval (ADTRep t Expr)) (Eval (ADTRep t Result))) => ADTable (t :: Rel8able)
- type DeconstructADT (t :: Rel8able) r = GGDeconstruct 'Sum (ADTRep t) (ADT t Expr) r
- deconstructADT :: forall (t :: Rel8able) r. (ConstructableADT t, Table Expr r) => DeconstructADT t r
- type BuildADT (t :: Rel8able) (name :: Symbol) = GGBuild 'Sum name (ADTRep t) (ADT t Expr)
- buildADT :: forall (t :: Rel8able) (name :: Symbol). BuildableADT t name => BuildADT t name
- type ConstructADT (t :: Rel8able) = forall r. GGConstruct 'Sum (ADTRep t) r
- constructADT :: forall (t :: Rel8able). ConstructableADT t => ConstructADT t -> ADT t Expr
- data HKD a (f :: Context)
- class (Generic (Record a), HTable (GColumns (HKD a)), KnownAlgebra (GAlgebra (Rep a)), Eval (GGSerialize (GAlgebra (Rep a)) TSerialize TColumns (Eval (HKDRep a Expr)) (Eval (HKDRep a Result))), GRecord (GMap (TColumn Result) (Rep a)) ~ Rep (Record a)) => HKDable a
- type BuildHKD a (name :: Symbol) = GGBuild (GAlgebra (Rep a)) name (HKDRep a) (HKD a Expr)
- buildHKD :: forall a (name :: Symbol). BuildableHKD a name => BuildHKD a name
- type ConstructHKD a = forall r. GGConstruct (GAlgebra (Rep a)) (HKDRep a) r
- constructHKD :: ConstructableHKD a => ConstructHKD a -> HKD a Expr
- type DeconstructHKD a r = GGDeconstruct (GAlgebra (Rep a)) (HKDRep a) (HKD a Expr) r
- deconstructHKD :: (ConstructableHKD a, Table Expr r) => DeconstructHKD a r
- type NameHKD a = GGName (GAlgebra (Rep a)) (HKDRep a) (HKD a Name)
- nameHKD :: ConstructableHKD a => NameHKD a
- data TableSchema names = TableSchema {
- name :: QualifiedName
- columns :: names
- data QualifiedName = QualifiedName {}
- data Name a
- namesFromLabels :: Table Name a => a
- namesFromLabelsWith :: Table Name a => (NonEmpty String -> String) -> a
- data Expr a
- class (constraint (Unnullify a), Nullable a) => Sql (constraint :: Type -> Constraint) a
- litExpr :: Sql DBType a => a -> Expr a
- unsafeCastExpr :: Sql DBType b => Expr a -> Expr b
- unsafeCoerceExpr :: Expr a -> Expr b
- unsafeLiteral :: String -> Expr a
- unsafePrimExpr :: PrimExpr -> Expr a
- class (Nullable a, IsMaybe a ~ 'False) => NotNull a
- class Nullable' (IsMaybe a) a => Nullable a
- class IsMaybe a ~ IsMaybe b => Homonullable a b
- null :: DBType a => Expr (Maybe a)
- nullify :: NotNull a => Expr a -> Expr (Maybe a)
- nullable :: Table Expr b => b -> (Expr a -> b) -> Expr (Maybe a) -> b
- isNull :: Expr (Maybe a) -> Expr Bool
- isNonNull :: Expr (Maybe a) -> Expr Bool
- mapNull :: DBType b => (Expr a -> Expr b) -> Expr (Maybe a) -> Expr (Maybe b)
- liftOpNull :: DBType c => (Expr a -> Expr b -> Expr c) -> Expr (Maybe a) -> Expr (Maybe b) -> Expr (Maybe c)
- catNull :: Expr (Maybe a) -> Query (Expr a)
- coalesce :: Expr (Maybe Bool) -> Expr Bool
- unsafeUnnullify :: Expr (Maybe a) -> Expr a
- class DBType a => DBEq a
- true :: Expr Bool
- false :: Expr Bool
- not_ :: Expr Bool -> Expr Bool
- (&&.) :: Expr Bool -> Expr Bool -> Expr Bool
- and_ :: Foldable f => f (Expr Bool) -> Expr Bool
- (||.) :: Expr Bool -> Expr Bool -> Expr Bool
- or_ :: Foldable f => f (Expr Bool) -> Expr Bool
- (==.) :: Sql DBEq a => Expr a -> Expr a -> Expr Bool
- (/=.) :: Sql DBEq a => Expr a -> Expr a -> Expr Bool
- (==?) :: DBEq a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
- (/=?) :: DBEq a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
- in_ :: (Sql DBEq a, Foldable f) => Expr a -> f (Expr a) -> Expr Bool
- boolExpr :: Expr a -> Expr a -> Expr Bool -> Expr a
- caseExpr :: [(Expr Bool, Expr a)] -> Expr a -> Expr a
- like :: Expr Text -> Expr Text -> Expr Bool
- ilike :: Expr Text -> Expr Text -> Expr Bool
- class DBEq a => DBOrd a
- (<.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool
- (<=.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool
- (>.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool
- (>=.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool
- (<?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
- (<=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
- (>?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
- (>=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
- leastExpr :: Sql DBOrd a => Expr a -> Expr a -> Expr a
- greatestExpr :: Sql DBOrd a => Expr a -> Expr a -> Expr a
- class Arguments a
- function :: (Arguments arguments, Sql DBType a) => QualifiedName -> arguments -> Expr a
- binaryOperator :: Sql DBType c => QualifiedName -> Expr a -> Expr b -> Expr c
- queryFunction :: (Arguments input, Table Expr output) => QualifiedName -> input -> Query output
- rawFunction :: Arguments arguments => QualifiedName -> arguments -> Expr a
- rawBinaryOperator :: QualifiedName -> Expr a -> Expr b -> Expr c
- data Query a
- showQuery :: Table Expr a => Query a -> String
- type Projection a b = Transpose (Field a) a -> Transpose (Field a) b
- class Projectable (f :: Type -> Type) where
- project :: Projecting a b => Projection a b -> f a -> f b
- class Biprojectable (p :: Type -> Type -> Type) where
- biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> p a c -> p b d
- class (Transposes (Context a) (Field a) a (Transpose (Field a) a), Transposes (Context a) (Field a) b (Transpose (Field a) b)) => Projecting a b
- data Field table a
- class Transposes Name Expr names exprs => Selects names exprs
- each :: Selects names exprs => TableSchema names -> Query exprs
- values :: (Table Expr a, Foldable f) => f a -> Query a
- filter :: (a -> Expr Bool) -> a -> Query a
- where_ :: Expr Bool -> Query ()
- present :: Query a -> Query ()
- absent :: Query a -> Query ()
- distinct :: EqTable a => Query a -> Query a
- distinctOn :: EqTable b => (a -> b) -> Query a -> Query a
- distinctOnBy :: EqTable b => (a -> b) -> Order a -> Query a -> Query a
- limit :: Word -> Query a -> Query a
- offset :: Word -> Query a -> Query a
- union :: EqTable a => Query a -> Query a -> Query a
- unionAll :: Table Expr a => Query a -> Query a -> Query a
- intersect :: EqTable a => Query a -> Query a -> Query a
- intersectAll :: EqTable a => Query a -> Query a -> Query a
- except :: EqTable a => Query a -> Query a -> Query a
- exceptAll :: EqTable a => Query a -> Query a -> Query a
- exists :: Query a -> Query (Expr Bool)
- with :: (a -> Query b) -> a -> Query a
- withBy :: (a -> b -> Expr Bool) -> Query b -> a -> Query a
- without :: (a -> Query b) -> a -> Query a
- withoutBy :: (a -> b -> Expr Bool) -> Query b -> a -> Query a
- materialize :: Table Expr a => Query a -> (Query a -> Query b) -> Query b
- loop :: Table Expr a => Query a -> (a -> Query a) -> Query a
- loopDistinct :: Table Expr a => Query a -> (a -> Query a) -> Query a
- type Aggregator = Aggregator' 'Full
- type Aggregator1 = Aggregator' 'Semi
- data Aggregator' (fold :: Fold) i a
- data Fold
- toAggregator :: forall a (fold :: Fold) i (fold' :: Fold). a -> Aggregator' fold i a -> Aggregator' fold' i a
- toAggregator1 :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator1 i a
- aggregate :: (Table Expr i, Table Expr a) => Aggregator i a -> Query i -> Query a
- aggregate1 :: forall i (fold :: Fold) a. Table Expr i => Aggregator' fold i a -> Query i -> Query a
- filterWhere :: forall a i (fold :: Fold). Table Expr a => (i -> Expr Bool) -> Aggregator i a -> Aggregator' fold i a
- filterWhereOptional :: forall a i (fold :: Fold) (fold' :: Fold). Table Expr a => (i -> Expr Bool) -> Aggregator' fold i a -> Aggregator' fold' i (MaybeTable Expr a)
- distinctAggregate :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator' fold i a
- orderAggregateBy :: forall i (fold :: Fold) a. Order i -> Aggregator' fold i a -> Aggregator' fold i a
- optionalAggregate :: forall a (fold :: Fold) i (fold' :: Fold). Table Expr a => Aggregator' fold i a -> Aggregator' fold' i (MaybeTable Expr a)
- countRows :: Query a -> Query (Expr Int64)
- groupBy :: EqTable a => Aggregator1 a a
- groupByOn :: EqTable a => (i -> a) -> Aggregator1 i a
- listAgg :: forall a (fold :: Fold). Table Expr a => Aggregator' fold a (ListTable Expr a)
- listAggOn :: forall a i (fold :: Fold). Table Expr a => (i -> a) -> Aggregator' fold i (ListTable Expr a)
- listAggExpr :: forall a (fold :: Fold). Sql DBType a => Aggregator' fold (Expr a) (Expr [a])
- listAggExprOn :: forall a i (fold :: Fold). Sql DBType a => (i -> Expr a) -> Aggregator' fold i (Expr [a])
- listCat :: forall a (fold :: Fold). Table Expr a => Aggregator' fold (ListTable Expr a) (ListTable Expr a)
- listCatOn :: forall a i (fold :: Fold). Table Expr a => (i -> ListTable Expr a) -> Aggregator' fold i (ListTable Expr a)
- listCatExpr :: forall a (fold :: Fold). Sql DBType a => Aggregator' fold (Expr [a]) (Expr [a])
- listCatExprOn :: forall a i (fold :: Fold). Sql DBType a => (i -> Expr [a]) -> Aggregator' fold i (Expr [a])
- nonEmptyAgg :: Table Expr a => Aggregator1 a (NonEmptyTable Expr a)
- nonEmptyAggOn :: Table Expr a => (i -> a) -> Aggregator1 i (NonEmptyTable Expr a)
- nonEmptyAggExpr :: Sql DBType a => Aggregator1 (Expr a) (Expr (NonEmpty a))
- nonEmptyAggExprOn :: Sql DBType a => (i -> Expr a) -> Aggregator1 i (Expr (NonEmpty a))
- nonEmptyCat :: Table Expr a => Aggregator1 (NonEmptyTable Expr a) (NonEmptyTable Expr a)
- nonEmptyCatOn :: Table Expr a => (i -> NonEmptyTable Expr a) -> Aggregator1 i (NonEmptyTable Expr a)
- nonEmptyCatExpr :: Sql DBType a => Aggregator1 (Expr (NonEmpty a)) (Expr (NonEmpty a))
- nonEmptyCatExprOn :: Sql DBType a => (i -> Expr (NonEmpty a)) -> Aggregator1 i (Expr (NonEmpty a))
- class DBOrd a => DBMax a
- max :: Sql DBMax a => Aggregator1 (Expr a) (Expr a)
- maxOn :: Sql DBMax a => (i -> Expr a) -> Aggregator1 i (Expr a)
- class DBOrd a => DBMin a
- min :: Sql DBMin a => Aggregator1 (Expr a) (Expr a)
- minOn :: Sql DBMin a => (i -> Expr a) -> Aggregator1 i (Expr a)
- class DBType a => DBSum a
- sum :: forall a (fold :: Fold). (Sql DBNum a, Sql DBSum a) => Aggregator' fold (Expr a) (Expr a)
- sumOn :: forall a i (fold :: Fold). (Sql DBNum a, Sql DBSum a) => (i -> Expr a) -> Aggregator' fold i (Expr a)
- sumWhere :: forall a i (fold :: Fold). (Sql DBNum a, Sql DBSum a) => (i -> Expr Bool) -> (i -> Expr a) -> Aggregator' fold i (Expr a)
- avg :: Sql DBSum a => Aggregator1 (Expr a) (Expr a)
- avgOn :: Sql DBSum a => (i -> Expr a) -> Aggregator1 i (Expr a)
- class DBType a => DBString a
- stringAgg :: forall a (fold :: Fold). (Sql IsString a, Sql DBString a) => Expr a -> Aggregator' fold (Expr a) (Expr a)
- count :: forall (fold :: Fold) a. Aggregator' fold (Expr a) (Expr Int64)
- countOn :: forall i a (fold :: Fold). (i -> Expr a) -> Aggregator' fold i (Expr Int64)
- countStar :: forall (fold :: Fold) i. Aggregator' fold i (Expr Int64)
- countDistinct :: forall a (fold :: Fold). Sql DBEq a => Aggregator' fold (Expr a) (Expr Int64)
- countDistinctOn :: forall a i (fold :: Fold). Sql DBEq a => (i -> Expr a) -> Aggregator' fold i (Expr Int64)
- countWhere :: forall (fold :: Fold). Aggregator' fold (Expr Bool) (Expr Int64)
- countWhereOn :: forall i (fold :: Fold). (i -> Expr Bool) -> Aggregator' fold i (Expr Int64)
- and :: forall (fold :: Fold). Aggregator' fold (Expr Bool) (Expr Bool)
- andOn :: forall i (fold :: Fold). (i -> Expr Bool) -> Aggregator' fold i (Expr Bool)
- or :: forall (fold :: Fold). Aggregator' fold (Expr Bool) (Expr Bool)
- orOn :: forall i (fold :: Fold). (i -> Expr Bool) -> Aggregator' fold i (Expr Bool)
- aggregateFunction :: (Table Expr i, Sql DBType a) => QualifiedName -> Aggregator1 i (Expr a)
- rawAggregateFunction :: Table Expr i => QualifiedName -> Aggregator1 i (Expr a)
- mode :: Sql DBOrd a => Aggregator1 (Expr a) (Expr a)
- modeOn :: Sql DBOrd a => (i -> Expr a) -> Aggregator1 i (Expr a)
- percentile :: Sql DBOrd a => Expr Double -> Aggregator1 (Expr a) (Expr a)
- percentileOn :: Sql DBOrd a => Expr Double -> (i -> Expr a) -> Aggregator1 i (Expr a)
- percentileContinuous :: Sql DBFractional a => Expr Double -> Aggregator1 (Expr a) (Expr a)
- percentileContinuousOn :: Sql DBFractional a => Expr Double -> (i -> Expr a) -> Aggregator1 i (Expr a)
- hypotheticalRank :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Int64)
- hypotheticalDenseRank :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Int64)
- hypotheticalPercentRank :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Double)
- hypotheticalCumeDist :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Double)
- orderBy :: Order a -> Query a -> Query a
- data Order a
- asc :: DBOrd a => Order (Expr a)
- desc :: DBOrd a => Order (Expr a)
- nullsFirst :: Order (Expr a) -> Order (Expr (Maybe a))
- nullsLast :: Order (Expr a) -> Order (Expr (Maybe a))
- data Window a b
- window :: Window a b -> Query a -> Query b
- data Partition a
- over :: Window a b -> Partition a -> Window a b
- partitionBy :: EqTable b => (a -> b) -> Partition a
- orderPartitionBy :: Order a -> Partition a
- cumulative :: forall (fold :: Fold) i a. Aggregator' fold i a -> Window i a
- currentRow :: Window a a
- rowNumber :: Window i (Expr Int64)
- rank :: Window i (Expr Int64)
- denseRank :: Window i (Expr Int64)
- percentRank :: Window i (Expr Double)
- cumeDist :: Window i (Expr Double)
- ntile :: Expr Int32 -> Window i (Expr Int32)
- lag :: Table Expr a => Expr Int32 -> Window a (MaybeTable Expr a)
- lagOn :: Table Expr a => Expr Int32 -> (i -> a) -> Window i (MaybeTable Expr a)
- lead :: Table Expr a => Expr Int32 -> Window a (MaybeTable Expr a)
- leadOn :: Table Expr a => Expr Int32 -> (i -> a) -> Window i (MaybeTable Expr a)
- firstValue :: Table Expr a => Window a a
- firstValueOn :: Table Expr a => (i -> a) -> Window i a
- lastValue :: Table Expr a => Window a a
- lastValueOn :: Table Expr a => (i -> a) -> Window i a
- nthValue :: Table Expr a => Expr Int32 -> Window a (MaybeTable Expr a)
- nthValueOn :: Table Expr a => Expr Int32 -> (i -> a) -> Window i (MaybeTable Expr a)
- indexed :: Query a -> Query (Expr Int64, a)
- rebind :: Table Expr a => String -> a -> Query a
- class (ToExprs exprs a, a ~ FromExprs exprs) => Serializable exprs a | exprs -> a
- class Table Expr exprs => ToExprs exprs a
- type Result = Identity
- run :: Serializable exprs a => Statement (Query exprs) -> Statement () [a]
- run_ :: Statement exprs -> Statement () ()
- runN :: Statement () -> Statement () Int64
- run1 :: Serializable exprs a => Statement (Query exprs) -> Statement () a
- runMaybe :: Serializable exprs a => Statement (Query exprs) -> Statement () (Maybe a)
- runVector :: Serializable exprs a => Statement (Query exprs) -> Statement () (Vector a)
- prepared :: forall a b i o. Serializable a i => (Statement b -> Statement () o) -> (a -> Statement b) -> Statement i o
- select :: Table Expr a => Query a -> Statement (Query a)
- data Insert a where
- data OnConflict exprs
- data Conflict exprs
- = OnConstraint String
- | OnIndex (Index exprs)
- data Index exprs where
- data Upsert exprs where
- insert :: Insert a -> Statement a
- unsafeDefault :: Expr a
- showInsert :: Insert a -> String
- data Delete a where
- delete :: Delete a -> Statement a
- showDelete :: Delete a -> String
- data Update a where
- update :: Update a -> Statement a
- showUpdate :: Update a -> String
- data Returning names a where
- data Statement a
- showStatement :: Statement a -> String
- showPreparedStatement :: Table Expr i => (i -> Statement a) -> String
- createView :: Selects names exprs => TableSchema names -> Query exprs -> Statement () ()
- createOrReplaceView :: Selects names exprs => TableSchema names -> Query exprs -> Statement () ()
- nextval :: QualifiedName -> Expr Int64
- evaluate :: Table Expr a => a -> Query a
Database types
DBType
class NotNull a => DBType a where #
Haskell types that can be represented as expressions in a database. There
should be an instance of DBType for all column types in your database
schema (e.g., int, timestamptz, etc).
Rel8 comes with stock instances for most default types in PostgreSQL, so you should only need to derive instances of this class for custom database types, such as types defined in PostgreSQL extensions, or custom domain types.
Methods
Instances
Deriving-via helpers
JSONEncoded
newtype JSONEncoded a #
A deriving-via helper type for column types that store a Haskell value
using a JSON encoding described by aeson's ToJSON and FromJSON type
classes.
Constructors
| JSONEncoded | |
Fields
| |
Instances
| Eq a => Eq (JSONEncoded a) # | |
Defined in Rel8.Internal.Type.JSONEncoded Methods (==) :: JSONEncoded a -> JSONEncoded a -> Bool # (/=) :: JSONEncoded a -> JSONEncoded a -> Bool # | |
| Ord a => Ord (JSONEncoded a) # | |
Defined in Rel8.Internal.Type.JSONEncoded Methods compare :: JSONEncoded a -> JSONEncoded a -> Ordering # (<) :: JSONEncoded a -> JSONEncoded a -> Bool # (<=) :: JSONEncoded a -> JSONEncoded a -> Bool # (>) :: JSONEncoded a -> JSONEncoded a -> Bool # (>=) :: JSONEncoded a -> JSONEncoded a -> Bool # max :: JSONEncoded a -> JSONEncoded a -> JSONEncoded a # min :: JSONEncoded a -> JSONEncoded a -> JSONEncoded a # | |
| Show a => Show (JSONEncoded a) # | |
Defined in Rel8.Internal.Type.JSONEncoded Methods showsPrec :: Int -> JSONEncoded a -> ShowS # show :: JSONEncoded a -> String # showList :: [JSONEncoded a] -> ShowS # | |
| (FromJSON a, ToJSON a) => DBType (JSONEncoded a) # | |
Defined in Rel8.Internal.Type.JSONEncoded Methods | |
newtype JSONBEncoded a #
Like JSONEncoded, but works for jsonb columns.
Constructors
| JSONBEncoded | |
Fields
| |
Instances
| Eq a => Eq (JSONBEncoded a) # | |
Defined in Rel8.Internal.Type.JSONBEncoded Methods (==) :: JSONBEncoded a -> JSONBEncoded a -> Bool # (/=) :: JSONBEncoded a -> JSONBEncoded a -> Bool # | |
| Ord a => Ord (JSONBEncoded a) # | |
Defined in Rel8.Internal.Type.JSONBEncoded Methods compare :: JSONBEncoded a -> JSONBEncoded a -> Ordering # (<) :: JSONBEncoded a -> JSONBEncoded a -> Bool # (<=) :: JSONBEncoded a -> JSONBEncoded a -> Bool # (>) :: JSONBEncoded a -> JSONBEncoded a -> Bool # (>=) :: JSONBEncoded a -> JSONBEncoded a -> Bool # max :: JSONBEncoded a -> JSONBEncoded a -> JSONBEncoded a # min :: JSONBEncoded a -> JSONBEncoded a -> JSONBEncoded a # | |
| Show a => Show (JSONBEncoded a) # | |
Defined in Rel8.Internal.Type.JSONBEncoded Methods showsPrec :: Int -> JSONBEncoded a -> ShowS # show :: JSONBEncoded a -> String # showList :: [JSONBEncoded a] -> ShowS # | |
| (FromJSON a, ToJSON a) => DBType (JSONBEncoded a) # | |
Defined in Rel8.Internal.Type.JSONBEncoded Methods | |
ReadShow
A deriving-via helper type for column types that store a Haskell value
using a Haskell's Read and Show type classes.
Constructors
| ReadShow | |
Fields
| |
Instances
| (Read a, Show a, Typeable a) => DBType (ReadShow a) # | |
Defined in Rel8.Internal.Type.ReadShow Methods typeInformation :: TypeInformation (ReadShow a) # | |
Generic
A deriving-via helper type for column types that store a Haskell product type in a single Postgres column using a Postgres composite type.
Note that this must map to a specific extant type in your database's schema
(created with CREATE TYPE). Use DBComposite to specify the name of this
Postgres type and the names of the individual fields (for projecting with
decompose).
Constructors
| Composite a |
Instances
| DBComposite a => DBType (Composite a) # | |
Defined in Rel8.Internal.Type.Composite Methods typeInformation :: TypeInformation (Composite a) # | |
| (DBComposite a, EqTable (HKD a Expr)) => DBEq (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| (DBComposite a, OrdTable (HKD a Expr)) => DBMax (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| (DBComposite a, OrdTable (HKD a Expr)) => DBMin (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| (DBComposite a, OrdTable (HKD a Expr)) => DBOrd (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
class (DBType a, HKDable a) => DBComposite a where #
DBComposite is used to associate composite type metadata with a Haskell
type.
Methods
compositeFields :: HKD a Name #
The names of all fields in the composite type that a maps to.
compositeTypeName :: QualifiedName #
The name of the composite type that a maps to.
A deriving-via helper type for column types that store an "enum" type
(in Haskell terms, a sum type where all constructors are nullary) using a
Postgres enum type.
Note that this should map to a specific type in your database's schema
(explicitly created with CREATE TYPE ... AS ENUM). Use DBEnum to
specify the name of this Postgres type and the names of the individual
values. If left unspecified, the names of the values of the Postgres
enum are assumed to match exactly exactly the names of the constructors
of the Haskell type (up to and including case sensitivity).
Constructors
| Enum a |
Instances
| DBEnum a => DBType (Enum a) # | |
Defined in Rel8.Internal.Type.Enum Methods typeInformation :: TypeInformation (Enum a) # | |
| DBEnum a => DBEq (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| DBEnum a => DBMax (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| DBEnum a => DBMin (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| DBEnum a => DBOrd (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
class DBType a => DBEnum a where #
DBEnum contains the necessary metadata to describe a PostgreSQL enum type.
Minimal complete definition
Methods
Map Haskell values to the corresponding element of the enum type. The
default implementation of this method will use the exact name of the
Haskell constructors.
enumTypeName :: QualifiedName #
The name of the PostgreSQL enum type that a maps to.
List of all possible values of the enum type.
class (Generic a, GEnumable (Rep a)) => Enumable a #
Types that are sum types, where each constructor is unary (that is, has no fields).
Instances
| (Generic a, GEnumable (Rep a)) => Enumable a # | |
Defined in Rel8.Internal.Type.Enum | |
TypeInformation
data TypeInformation a #
TypeInformation describes how to encode and decode a Haskell type to and
from database queries. The typeName is the name of the type in the
database, which is used to accurately type literals.
Constructors
| TypeInformation | |
Fields
| |
A PostgreSQL type consists of a QualifiedName (name, schema), and
optional modifiers and arrayDepth. modifiers will usually be [],
but a type like numeric(6, 2) will have ["6", "2"]. arrayDepth is
always 0 for non-array types.
Constructors
| TypeName | |
Fields
| |
Instances
| IsString TypeName # | Constructs |
Defined in Rel8.Internal.Type.Name Methods fromString :: String -> TypeName # | |
mapTypeInformation :: (a -> b) -> (b -> a) -> TypeInformation a -> TypeInformation b #
Simultaneously map over how a type is both encoded and decoded, while
retaining the name of the type. This operation is useful if you want to
essentially newtype another DBType.
The mapping is required to be total. If you have a partial mapping, see
parseTypeInformation.
parseTypeInformation :: (a -> Either String b) -> (b -> a) -> TypeInformation a -> TypeInformation b #
Apply a parser to TypeInformation.
This can be used if the data stored in the database should only be subset of
a given TypeInformation. The parser is applied when deserializing rows
returned - the encoder assumes that the input data is already in the
appropriate form.
The DBType hierarchy
class DBType a => DBSemigroup a where #
The class of DBTypes that form a semigroup. This class is purely a
Rel8 concept, and exists to mirror the Semigroup class.
Instances
| DBSemigroup ByteString # | |
Defined in Rel8.Internal.Type.Semigroup Methods (<>.) :: Expr ByteString -> Expr ByteString -> Expr ByteString # | |
| DBSemigroup ByteString # | |
Defined in Rel8.Internal.Type.Semigroup Methods (<>.) :: Expr ByteString -> Expr ByteString -> Expr ByteString # | |
| DBSemigroup EitherTag # | |
| DBSemigroup MaybeTag # | |
| DBSemigroup Text # | |
| DBSemigroup Text # | |
| DBSemigroup CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Semigroup Methods (<>.) :: Expr CalendarDiffTime -> Expr CalendarDiffTime -> Expr CalendarDiffTime # | |
| DBSemigroup (CI Text) # | |
| DBSemigroup (CI Text) # | |
| Sql DBType a => DBSemigroup (NonEmpty a) # | |
| DBRange a => DBSemigroup (Multirange a) # | |
Defined in Rel8.Internal.Type.Semigroup Methods (<>.) :: Expr (Multirange a) -> Expr (Multirange a) -> Expr (Multirange a) # | |
| Sql DBType a => DBSemigroup [a] # | |
class DBSemigroup a => DBMonoid a where #
The class of DBTypes that form a semigroup. This class is purely a
Rel8 concept, and exists to mirror the Monoid class.
Methods
memptyExpr :: Expr a #
Instances
| DBMonoid ByteString # | |
Defined in Rel8.Internal.Type.Monoid Methods | |
| DBMonoid ByteString # | |
Defined in Rel8.Internal.Type.Monoid Methods | |
| DBMonoid EitherTag # | |
Defined in Rel8.Internal.Type.Tag Methods memptyExpr :: Expr EitherTag # | |
| DBMonoid MaybeTag # | |
Defined in Rel8.Internal.Type.Tag Methods memptyExpr :: Expr MaybeTag # | |
| DBMonoid Text # | |
Defined in Rel8.Internal.Type.Monoid Methods memptyExpr :: Expr Text # | |
| DBMonoid Text # | |
Defined in Rel8.Internal.Type.Monoid Methods memptyExpr :: Expr Text # | |
| DBMonoid CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Monoid Methods | |
| DBMonoid (CI Text) # | |
Defined in Rel8.Internal.Type.Monoid Methods memptyExpr :: Expr (CI Text) # | |
| DBMonoid (CI Text) # | |
Defined in Rel8.Internal.Type.Monoid Methods memptyExpr :: Expr (CI Text) # | |
| DBRange a => DBMonoid (Multirange a) # | |
Defined in Rel8.Internal.Type.Monoid Methods memptyExpr :: Expr (Multirange a) # | |
| Sql DBType a => DBMonoid [a] # | |
Defined in Rel8.Internal.Type.Monoid Methods memptyExpr :: Expr [a] # | |
The class of database types that support the +, *, - operators, and
the abs, negate, sign functions.
Instances
| DBNum Int16 # | |
Defined in Rel8.Internal.Type.Num | |
| DBNum Int32 # | |
Defined in Rel8.Internal.Type.Num | |
| DBNum Int64 # | |
Defined in Rel8.Internal.Type.Num | |
| DBNum Scientific # | |
Defined in Rel8.Internal.Type.Num | |
| DBNum Double # | |
Defined in Rel8.Internal.Type.Num | |
| DBNum Float # | |
Defined in Rel8.Internal.Type.Num | |
| PowerOf10 n => DBNum (Fixed n) # | |
Defined in Rel8.Internal.Type.Num | |
class (DBNum a, DBOrd a) => DBIntegral a #
The class of database types that can be coerced to from integral
expressions. This is a Rel8 concept, and allows us to provide
fromIntegral.
Instances
| DBIntegral Int16 # | |
Defined in Rel8.Internal.Type.Num | |
| DBIntegral Int32 # | |
Defined in Rel8.Internal.Type.Num | |
| DBIntegral Int64 # | |
Defined in Rel8.Internal.Type.Num | |
class DBNum a => DBFractional a #
The class of database types that support the / operator.
Instances
| DBFractional Scientific # | |
Defined in Rel8.Internal.Type.Num | |
| DBFractional Double # | |
Defined in Rel8.Internal.Type.Num | |
| DBFractional Float # | |
Defined in Rel8.Internal.Type.Num | |
| PowerOf10 n => DBFractional (Fixed n) # | |
Defined in Rel8.Internal.Type.Num | |
class DBFractional a => DBFloating a #
The class of database types that support the / operator.
Instances
| DBFloating Double # | |
Defined in Rel8.Internal.Type.Num | |
| DBFloating Float # | |
Defined in Rel8.Internal.Type.Num | |
Tables and higher-kinded tables
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 # | |||||||||
| 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 # | |||||||||
type family Column (context :: Context) a where ... #
This type family is used to specify columns in Rel8ables. In Column f
a, f is the context of the column (which should be left polymorphic in
Rel8able definitions), and a is the type of the column.
type family HEither (context :: Context) = (either :: Type -> Type -> Type) | either -> context where ... #
Nest an Either value within a Rel8able. HEither f a b will produce a
EitherTable a b in the Expr context, and a Either a b in the
Result context.
Equations
| HEither Result = Either | |
| HEither context = EitherTable context |
type family HMaybe (context :: Context) = (maybe :: Type -> Type) | maybe -> context where ... #
Nest a Maybe value within a Rel8able. HMaybe f a will produce a
MaybeTable a in the Expr context, and a Maybe a in the Result
context.
Equations
| HMaybe Result = Maybe | |
| HMaybe context = MaybeTable context |
type family HList (context :: Context) = (list :: Type -> Type) | list -> context where ... #
type family HNonEmpty (context :: Context) = (nonEmpty :: Type -> Type) | nonEmpty -> context where ... #
Nest a NonEmpty list within a Rel8able. HNonEmpty f a will produce a
NonEmptyTable a in the Expr context, and a NonEmpty a in the
Result context.
Equations
| HNonEmpty Result = NonEmpty | |
| HNonEmpty context = NonEmptyTable context |
type family HNull (context :: Context) = (maybe :: Type -> Type) | maybe -> context where ... #
type family HThese (context :: Context) = (these :: Type -> Type -> Type) | these -> context where ... #
Nest an These value within a Rel8able. HThese f a b will produce a
TheseTable a b in the Expr context, and a These a b in the
Result context.
Equations
| HThese Result = These | |
| HThese context = TheseTable context |
class (HTable (Columns a), context ~ Context a, a ~ Transpose context a) => Table (context :: Context) a | a -> context where #
Tables are one of the foundational elements of Rel8, and describe data
types that have a finite number of columns. Each of these columns contains
data under a shared context, and contexts describe how to interpret the
metadata about a column to a particular Haskell type. In Rel8, we have
contexts for expressions (the Expr context), aggregations (the
Aggregate context), insert values (the Insert context), among
others.
In typical usage of Rel8 you don't need to derive instances of Table
yourself, as anything that's an instance of Rel8able is always a
Table.
Minimal complete definition
Nothing
Associated Types
The HTable functor that describes the schema of this table.
The common context that all columns use as an interpretation.
The FromExprs type family maps a type in the Expr context to the
corresponding Haskell type.
type FromExprs a = Map TFromExprs a
type Transpose (context' :: Context) a #
type Transpose (context' :: Context) a = Map (TTranspose context') a
Methods
toColumns :: a -> Columns a context #
default toColumns :: (Generic (Record a), GTable (TTable context) TColumns (Rep (Record a)), Columns a ~ GColumns TColumns (Rep (Record a))) => a -> Columns a context #
fromColumns :: Columns a context -> a #
default fromColumns :: (Generic (Record a), GTable (TTable context) TColumns (Rep (Record a)), Columns a ~ GColumns TColumns (Rep (Record a))) => Columns a context -> a #
fromResult :: Columns a Result -> FromExprs a #
Instances
| Sql DBType a => Table Expr (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr Associated Types
| |||||||||||||
| Sql DBType a => Table Name (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name Associated Types
| |||||||||||||
| Sql DBType a => Table Result (Identity a) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
| |||||||||||||
| (Rel8able t, Reifiable context, context ~ context') => Table context' (t context) # | |||||||||||||
Defined in Rel8.Internal.Table.Rel8able Associated Types
| |||||||||||||
| (Table context a, Table context b) => Table context (a, b) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
| |||||||||||||
| (HTable columns, context ~ context') => Table context' (Cols context columns) # | |||||||||||||
Defined in Rel8.Internal.Table.Cols Associated Types
Methods toColumns :: Cols context columns -> Columns (Cols context columns) context' # fromColumns :: Columns (Cols context columns) context' -> Cols context columns # fromResult :: Columns (Cols context columns) Result -> FromExprs (Cols context columns) # toResult :: FromExprs (Cols context columns) -> Columns (Cols context columns) Result # | |||||||||||||
| (Table context a, context ~ context') => Table context' (ListTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.List Associated Types
Methods toColumns :: ListTable context a -> Columns (ListTable context a) context' # fromColumns :: Columns (ListTable context a) context' -> ListTable context a # fromResult :: Columns (ListTable context a) Result -> FromExprs (ListTable context a) # toResult :: FromExprs (ListTable context a) -> Columns (ListTable context a) Result # | |||||||||||||
| (Table context a, Reifiable context, context ~ context') => Table context' (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Associated Types
Methods toColumns :: MaybeTable context a -> Columns (MaybeTable context a) context' # fromColumns :: Columns (MaybeTable context a) context' -> MaybeTable context a # fromResult :: Columns (MaybeTable context a) Result -> FromExprs (MaybeTable context a) # toResult :: FromExprs (MaybeTable context a) -> Columns (MaybeTable context a) Result # | |||||||||||||
| (Table context a, context ~ context') => Table context' (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty Associated Types
Methods toColumns :: NonEmptyTable context a -> Columns (NonEmptyTable context a) context' # fromColumns :: Columns (NonEmptyTable context a) context' -> NonEmptyTable context a # fromResult :: Columns (NonEmptyTable context a) Result -> FromExprs (NonEmptyTable context a) # toResult :: FromExprs (NonEmptyTable context a) -> Columns (NonEmptyTable context a) Result # | |||||||||||||
| (Table context a, Reifiable context, context ~ context') => Table context' (NullTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null Associated Types
Methods toColumns :: NullTable context a -> Columns (NullTable context a) context' # fromColumns :: Columns (NullTable context a) context' -> NullTable context a # fromResult :: Columns (NullTable context a) Result -> FromExprs (NullTable context a) # toResult :: FromExprs (NullTable context a) -> Columns (NullTable context a) Result # | |||||||||||||
| (Table context a, Reifiable context, context ~ context') => Table context' (Nullify context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Nullify Associated Types
Methods toColumns :: Nullify context a -> Columns (Nullify context a) context' # fromColumns :: Columns (Nullify context a) context' -> Nullify context a # fromResult :: Columns (Nullify context a) Result -> FromExprs (Nullify context a) # toResult :: FromExprs (Nullify context a) -> Columns (Nullify context a) Result # | |||||||||||||
| (Table context a, Table context b, Table context c) => Table context (a, b, c) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
| |||||||||||||
| (Table context a, Table context b, Reifiable context, context ~ context') => Table context' (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Associated Types
Methods toColumns :: EitherTable context a b -> Columns (EitherTable context a b) context' # fromColumns :: Columns (EitherTable context a b) context' -> EitherTable context a b # fromResult :: Columns (EitherTable context a b) Result -> FromExprs (EitherTable context a b) # toResult :: FromExprs (EitherTable context a b) -> Columns (EitherTable context a b) Result # | |||||||||||||
| (Table context a, Table context b, Reifiable context, context ~ context') => Table context' (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These Associated Types
Methods toColumns :: TheseTable context a b -> Columns (TheseTable context a b) context' # fromColumns :: Columns (TheseTable context a b) context' -> TheseTable context a b # fromResult :: Columns (TheseTable context a b) Result -> FromExprs (TheseTable context a b) # toResult :: FromExprs (TheseTable context a b) -> Columns (TheseTable context a b) Result # | |||||||||||||
| (Table context a, Table context b, Table context c, Table context d) => Table context (a, b, c, d) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
| |||||||||||||
| (Table context a, Table context b, Table context c, Table context d, Table context e) => Table context (a, b, c, d, e) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
| |||||||||||||
| (Table context a, Table context b, Table context c, Table context d, Table context e, Table context f) => Table context (a, b, c, d, e, f) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
Methods toColumns :: (a, b, c, d, e, f) -> Columns (a, b, c, d, e, f) context # fromColumns :: Columns (a, b, c, d, e, f) context -> (a, b, c, d, e, f) # fromResult :: Columns (a, b, c, d, e, f) Result -> FromExprs (a, b, c, d, e, f) # toResult :: FromExprs (a, b, c, d, e, f) -> Columns (a, b, c, d, e, f) Result # | |||||||||||||
| (Table context a, Table context b, Table context c, Table context d, Table context e, Table context f, Table context g) => Table context (a, b, c, d, e, f, g) # | |||||||||||||
Defined in Rel8.Internal.Table Associated Types
Methods toColumns :: (a, b, c, d, e, f, g) -> Columns (a, b, c, d, e, f, g) context # fromColumns :: Columns (a, b, c, d, e, f, g) context -> (a, b, c, d, e, f, g) # fromResult :: Columns (a, b, c, d, e, f, g) Result -> FromExprs (a, b, c, d, e, f, g) # toResult :: FromExprs (a, b, c, d, e, f, g) -> Columns (a, b, c, d, e, f, g) Result # | |||||||||||||
| Sql DBType a => Table (Field table) (Field table a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Field Associated Types
| |||||||||||||
A HTable is a functor-indexed/higher-kinded data type that is
representable (htabulate/hfield), constrainable (hdicts), and
specified (hspecs).
This is an internal concept for Rel8, and you should not need to define instances yourself or specify this constraint.
Instances
| Sql DBType a => HTable (HIdentity a) # | |||||
Defined in Rel8.Internal.Schema.HTable.Identity Associated Types
Methods hfield :: HIdentity a context -> HField (HIdentity a) a0 -> context a0 # htabulate :: (forall a0. HField (HIdentity a) a0 -> context a0) -> HIdentity a context # htraverse :: Apply m => (forall a0. f a0 -> m (g a0)) -> HIdentity a f -> m (HIdentity a g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HIdentity a) c => HIdentity a (Dict c) # | |||||
| HTable table => HTable (HMaybeTable table) # | |||||
Defined in Rel8.Internal.Schema.HTable.Maybe Associated Types
Methods hfield :: HMaybeTable table context -> HField (HMaybeTable table) a -> context a # htabulate :: (forall a. HField (HMaybeTable table) a -> context a) -> HMaybeTable table context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HMaybeTable table f -> m (HMaybeTable table g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HMaybeTable table) c => HMaybeTable table (Dict c) # hspecs :: HMaybeTable table Spec # | |||||
| HTable table => HTable (HNullify table) # | |||||
Defined in Rel8.Internal.Schema.HTable.Nullify Associated Types
Methods hfield :: HNullify table context -> HField (HNullify table) a -> context a # htabulate :: (forall a. HField (HNullify table) a -> context a) -> HNullify table context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HNullify table f -> m (HNullify table g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HNullify table) c => HNullify table (Dict c) # | |||||
| (HTable left, HTable right) => HTable (HEitherTable left right) # | |||||
Defined in Rel8.Internal.Schema.HTable.Either Associated Types
Methods hfield :: HEitherTable left right context -> HField (HEitherTable left right) a -> context a # htabulate :: (forall a. HField (HEitherTable left right) a -> context a) -> HEitherTable left right context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HEitherTable left right f -> m (HEitherTable left right g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HEitherTable left right) c => HEitherTable left right (Dict c) # hspecs :: HEitherTable left right Spec # | |||||
| (HTable table, KnownSymbol label) => HTable (HLabel label table) # | |||||
Defined in Rel8.Internal.Schema.HTable.Label Associated Types
Methods hfield :: HLabel label table context -> HField (HLabel label table) a -> context a # htabulate :: (forall a. HField (HLabel label table) a -> context a) -> HLabel label table context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HLabel label table f -> m (HLabel label table g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HLabel label table) c => HLabel label table (Dict c) # | |||||
| (HTable t, MapSpec f) => HTable (HMapTable f t) # | |||||
Defined in Rel8.Internal.Schema.HTable.MapTable Associated Types
Methods hfield :: HMapTable f t context -> HField (HMapTable f t) a -> context a # htabulate :: (forall a. HField (HMapTable f t) a -> context a) -> HMapTable f t context # htraverse :: Apply m => (forall a. f0 a -> m (g a)) -> HMapTable f t f0 -> m (HMapTable f t g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HMapTable f t) c => HMapTable f t (Dict c) # | |||||
| (HTable x, HTable y) => HTable (HProduct x y) # | |||||
Defined in Rel8.Internal.Schema.HTable Associated Types
Methods hfield :: HProduct x y context -> HField (HProduct x y) a -> context a # htabulate :: (forall a. HField (HProduct x y) a -> context a) -> HProduct x y context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HProduct x y f -> m (HProduct x y g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HProduct x y) c => HProduct x y (Dict c) # | |||||
| (HTable here, HTable there) => HTable (HTheseTable here there) # | |||||
Defined in Rel8.Internal.Schema.HTable.These Associated Types
Methods hfield :: HTheseTable here there context -> HField (HTheseTable here there) a -> context a # htabulate :: (forall a. HField (HTheseTable here there) a -> context a) -> HTheseTable here there context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HTheseTable here there f -> m (HTheseTable here there g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HTheseTable here there) c => HTheseTable here there (Dict c) # hspecs :: HTheseTable here there Spec # | |||||
| (HTable table, Vector list) => HTable (HVectorize list table) # | |||||
Defined in Rel8.Internal.Schema.HTable.Vectorize Associated Types
Methods hfield :: HVectorize list table context -> HField (HVectorize list table) a -> context a # htabulate :: (forall a. HField (HVectorize list table) a -> context a) -> HVectorize list table context # htraverse :: Apply m => (forall a. f a -> m (g a)) -> HVectorize list table f -> m (HVectorize list table g) # hdicts :: forall (c :: Type -> Constraint). HConstrainTable (HVectorize list table) c => HVectorize list table (Dict c) # hspecs :: HVectorize list table Spec # | |||||
class (Table from a, Table to b, Congruent a b, b ~ Transpose to a, a ~ Transpose from b) => Transposes (from :: Context) (to :: Context) a b | a -> from, b -> to, a to -> b, b from -> a #
means that Transposes from to a ba and b are Tables, in the
from and to contexts respectively, which share the same underlying
structure. In other words, b is a version of a transposed from the
from context to the to context (and vice versa).
Instances
| (Table from a, Table to b, Congruent a b, b ~ Transpose to a, a ~ Transpose from b) => Transposes from to a b # | |
Defined in Rel8.Internal.Table.Transpose | |
class AltTable (f :: Type -> Type) where #
Like Alt in Haskell. This class is purely a Rel8 concept, and allows you
to take a choice between two tables. See also AlternativeTable.
For example, using <|>: on MaybeTable allows you to combine two
tables and to return the first one that is a "just" MaybeTable.
Methods
(<|>:) :: Table Expr a => f a -> f a -> f a infixl 3 #
An associative binary operation on Tables.
Instances
| AltTable Query # | |
| EqTable k => AltTable (Tabulation k) Source # | If |
Defined in Rel8.Tabulate Methods (<|>:) :: Table Expr a => Tabulation k a -> Tabulation k a -> Tabulation k a # | |
| context ~ Expr => AltTable (ListTable context) # | |
| context ~ Expr => AltTable (MaybeTable context) # | |
Defined in Rel8.Internal.Table.Maybe Methods (<|>:) :: Table Expr a => MaybeTable context a -> MaybeTable context a -> MaybeTable context a # | |
| context ~ Expr => AltTable (NonEmptyTable context) # | |
Defined in Rel8.Internal.Table.NonEmpty Methods (<|>:) :: Table Expr a => NonEmptyTable context a -> NonEmptyTable context a -> NonEmptyTable context a # | |
| context ~ Expr => AltTable (NullTable context) # | |
class AltTable f => AlternativeTable (f :: Type -> Type) where #
Like Alternative in Haskell, some Tables form a monoid on applicative
functors.
Instances
| AlternativeTable Query # |
|
Defined in Rel8.Internal.Query Methods emptyTable :: Table Expr a => Query a # | |
| EqTable k => AlternativeTable (Tabulation k) Source # | |
Defined in Rel8.Tabulate Methods emptyTable :: Table Expr a => Tabulation k a # | |
| context ~ Expr => AlternativeTable (ListTable context) # | |
Defined in Rel8.Internal.Table.List Methods emptyTable :: Table Expr a => ListTable context a # | |
| context ~ Expr => AlternativeTable (MaybeTable context) # | |
Defined in Rel8.Internal.Table.Maybe Methods emptyTable :: Table Expr a => MaybeTable context a # | |
| context ~ Expr => AlternativeTable (NullTable context) # | |
Defined in Rel8.Internal.Table.Null Methods emptyTable :: Table Expr a => NullTable context a # | |
class Table Expr a => EqTable a where #
The class of Tables that can be compared for equality. Equality on
tables is defined by equality of all columns all columns, so this class
means "all columns in a Table have an instance of DBEq".
Minimal complete definition
Nothing
Methods
Instances
(==:) :: EqTable a => a -> a -> Expr Bool infix 4 #
Compare two Tables for equality. This corresponds to comparing all
columns inside each table for equality, and combining all comparisons with
AND.
(/=:) :: EqTable a => a -> a -> Expr Bool infix 4 #
Test if two Tables are different. This corresponds to comparing all
columns inside each table for inequality, and combining all comparisons with
OR.
class EqTable a => OrdTable a where #
The class of Tables that can be ordered. Ordering on tables is defined
by their lexicographic ordering of all columns, so this class means "all
columns in a Table have an instance of DBOrd".
Minimal complete definition
Nothing
Methods
Instances
(<:) :: OrdTable a => a -> a -> Expr Bool infix 4 #
Test if one Table sorts before another. Corresponds to comparing all
columns with <.
(<=:) :: OrdTable a => a -> a -> Expr Bool infix 4 #
Test if one Table sorts before, or is equal to, another. Corresponds to
comparing all columns with <=.
(>:) :: OrdTable a => a -> a -> Expr Bool infix 4 #
Test if one Table sorts after another. Corresponds to comparing all
columns with >.
(>=:) :: OrdTable a => a -> a -> Expr Bool infix 4 #
Test if one Table sorts after another. Corresponds to comparing all
columns with >=.
ascTable :: OrdTable a => Order a #
Construct an Order for a Table by sorting all columns into ascending
orders (any nullable columns will be sorted with NULLS FIRST).
descTable :: OrdTable a => Order a #
Construct an Order for a Table by sorting all columns into descending
orders (any nullable columns will be sorted with NULLS LAST).
greatest :: OrdTable a => a -> a -> a #
Given two Tables, return the table that sorts after the other.
lit :: Serializable exprs a => a -> exprs #
Use lit to turn literal Haskell values into expressions. lit is
capable of lifting single Exprs to full tables.
bool :: Table Expr a => a -> a -> Expr Bool -> a #
Case analysis for an Expr Bool. Corresponds to bool.
bool x y p returns x if p is False, and returns y if p is
True.
case_ :: Table Expr a => [(Expr Bool, a)] -> a -> a #
Produce a table expression from a list of alternatives. Returns the first
table where the Expr Bool expression is True. If no alternatives are
true, the given default is returned.
castTable :: Table Expr a => a -> a #
Transform a table by adding CAST to all columns. This is most useful for
finalising a SELECT or RETURNING statement, guaranteed that the output
matches what is encoded in each columns TypeInformation.
MaybeTable
data MaybeTable (context :: Context) a #
MaybeTable t is the table t, but as the result of an outer join. If
the outer join fails to match any rows, this is essentialy Nothing, and if
the outer join does match rows, this is like Just. Unfortunately, SQL
makes it impossible to distinguish whether or not an outer join matched any
rows based generally on the row contents - if you were to join a row
entirely of nulls, you can't distinguish if you matched an all null row, or
if the match failed. For this reason MaybeTable contains an extra field -
a "nullTag" - to track whether or not the outer join produced any rows.
Instances
| (Table context a, Reifiable context, context ~ context') => Table context' (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Associated Types
Methods toColumns :: MaybeTable context a -> Columns (MaybeTable context a) context' # fromColumns :: Columns (MaybeTable context a) context' -> MaybeTable context a # fromResult :: Columns (MaybeTable context a) Result -> FromExprs (MaybeTable context a) # toResult :: FromExprs (MaybeTable context a) -> Columns (MaybeTable context a) Result # | |||||||||||||
| context ~ Expr => Applicative (MaybeTable context) # | Has the same behavior as the | ||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods pure :: a -> MaybeTable context a # (<*>) :: MaybeTable context (a -> b) -> MaybeTable context a -> MaybeTable context b # liftA2 :: (a -> b -> c) -> MaybeTable context a -> MaybeTable context b -> MaybeTable context c # (*>) :: MaybeTable context a -> MaybeTable context b -> MaybeTable context b # (<*) :: MaybeTable context a -> MaybeTable context b -> MaybeTable context a # | |||||||||||||
| Nullifiable context => Functor (MaybeTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods fmap :: (a -> b) -> MaybeTable context a -> MaybeTable context b # (<$) :: a -> MaybeTable context b -> MaybeTable context a # | |||||||||||||
| context ~ Expr => Monad (MaybeTable context) # | Has the same behavior as the | ||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods (>>=) :: MaybeTable context a -> (a -> MaybeTable context b) -> MaybeTable context b # (>>) :: MaybeTable context a -> MaybeTable context b -> MaybeTable context b # return :: a -> MaybeTable context a # | |||||||||||||
| context ~ Expr => AltTable (MaybeTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods (<|>:) :: Table Expr a => MaybeTable context a -> MaybeTable context a -> MaybeTable context a # | |||||||||||||
| context ~ Expr => AlternativeTable (MaybeTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods emptyTable :: Table Expr a => MaybeTable context a # | |||||||||||||
| Projectable (MaybeTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods project :: Projecting a b => Projection a b -> MaybeTable context a -> MaybeTable context b # | |||||||||||||
| context ~ Expr => Apply (MaybeTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods (<.>) :: MaybeTable context (a -> b) -> MaybeTable context a -> MaybeTable context b (.>) :: MaybeTable context a -> MaybeTable context b -> MaybeTable context b (<.) :: MaybeTable context a -> MaybeTable context b -> MaybeTable context a liftF2 :: (a -> b -> c) -> MaybeTable context a -> MaybeTable context b -> MaybeTable context c | |||||||||||||
| context ~ Expr => Bind (MaybeTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods (>>-) :: MaybeTable context a -> (a -> MaybeTable context b) -> MaybeTable context b join :: MaybeTable context (MaybeTable context a) -> MaybeTable context a | |||||||||||||
| (context ~ Expr, Table Expr a, Semigroup a) => Monoid (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods mempty :: MaybeTable context a # mappend :: MaybeTable context a -> MaybeTable context a -> MaybeTable context a # mconcat :: [MaybeTable context a] -> MaybeTable context a # | |||||||||||||
| (context ~ Expr, Table Expr a, Semigroup a) => Semigroup (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe Methods (<>) :: MaybeTable context a -> MaybeTable context a -> MaybeTable context a # sconcat :: NonEmpty (MaybeTable context a) -> MaybeTable context a # stimes :: Integral b => b -> MaybeTable context a -> MaybeTable context a # | |||||||||||||
| (EqTable a, context ~ Expr) => EqTable (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
| (OrdTable a, context ~ Expr) => OrdTable (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
| (ToExprs exprs a, context ~ Expr) => ToExprs (MaybeTable context exprs) (Maybe a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
| type Transpose to (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
| type Columns (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
| type Context (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
| type FromExprs (MaybeTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Maybe | |||||||||||||
maybeTable :: Table Expr b => b -> (a -> b) -> MaybeTable Expr a -> b #
Perform case analysis on a MaybeTable. Like maybe.
($?) :: forall a b. Sql DBType b => (a -> Expr b) -> MaybeTable Expr a -> Expr (Nullify b) infixl 4 #
Project a single expression out of a MaybeTable. You can think of this
operator like the $ operator, but it also has the ability to return
null.
nothingTable :: Table Expr a => MaybeTable Expr a #
The null table. Like Nothing.
justTable :: a -> MaybeTable Expr a #
Lift any table into MaybeTable. Like Just. Note you can also use
pure.
isNothingTable :: MaybeTable Expr a -> Expr Bool #
Check if a MaybeTable is absent of any row. Like isNothing.
isJustTable :: MaybeTable Expr a -> Expr Bool #
Check if a MaybeTable contains a row. Like isJust.
fromMaybeTable :: Table Expr a => a -> MaybeTable Expr a -> a #
fromMaybe for MaybeTables.
optional :: Query a -> Query (MaybeTable Expr a) #
Convert a query that might return zero rows to a query that always returns at least one row.
To speak in more concrete terms, optional is most useful to write LEFT
JOINs.
catMaybeTable :: MaybeTable Expr a -> Query a #
Filter out MaybeTables, returning only the tables that are not-null.
This operation can be used to "undo" the effect of optional, which
operationally is like turning a LEFT JOIN back into a full JOIN. You
can think of this as analogous to catMaybes.
traverseMaybeTable :: (a -> Query b) -> MaybeTable Expr a -> Query (MaybeTable Expr b) #
Extend an optional query with another query. This is useful if you want
to step through multiple LEFT JOINs.
Note that traverseMaybeTable takes a a -> Query b function, which means
you also have the ability to "expand" one row into multiple rows. If the
a -> Query b function returns no rows, then the resulting query will also
have no rows. However, regardless of the given a -> Query b function, if
the input is nothingTable, you will always get exactly one nothingTable
back.
aggregateJustTable :: forall a i (fold :: Fold). Table Expr a => Aggregator i a -> Aggregator' fold (MaybeTable Expr i) a #
Lift an Aggregator to operate on a MaybeTable. If the input query has
s, they are folded into a single justTable ia by the given aggregator
— in the case where the input query is all nothingTables, the
Aggregator's fallback a is returned.
aggregateJustTable1 :: forall a (fold :: Fold) i (fold' :: Fold). Table Expr a => Aggregator' fold i a -> Aggregator' fold' (MaybeTable Expr i) (MaybeTable Expr a) #
Lift an Aggregator1 to operate on a MaybeTable. If the input query
has s, they are folded into a single justTable i by the
given aggregator — in the case where the input query is all
justTable anothingTables, a single nothingTable row is returned.
aggregateMaybeTable :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator1 (MaybeTable Expr i) (MaybeTable Expr a) #
Lift an aggregator to operate on a MaybeTable. nothingTables and
justTables are grouped separately.
Arguments
| :: Name (Maybe MaybeTag) | The name of the column to track whether a row is a |
| -> a | Names of the columns in |
| -> MaybeTable Name a |
Construct a MaybeTable in the Name context. This can be useful if you
have a MaybeTable that you are storing in a table and need to construct a
TableSchema.
EitherTable
data EitherTable (context :: Context) a b #
An EitherTable a b is a Rel8 table that contains either the table a or
the table b. You can construct an EitherTable using leftTable and
rightTable, and eliminate/pattern match using eitherTable.
An EitherTable is operationally the same as Haskell's Either type, but
adapted to work with Rel8.
Instances
| (Table context a, Table context b, Reifiable context, context ~ context') => Table context' (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Associated Types
Methods toColumns :: EitherTable context a b -> Columns (EitherTable context a b) context' # fromColumns :: Columns (EitherTable context a b) context' -> EitherTable context a b # fromResult :: Columns (EitherTable context a b) Result -> FromExprs (EitherTable context a b) # toResult :: FromExprs (EitherTable context a b) -> Columns (EitherTable context a b) Result # | |||||||||||||
| Nullifiable context => Bifunctor (EitherTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods bimap :: (a -> b) -> (c -> d) -> EitherTable context a c -> EitherTable context b d # first :: (a -> b) -> EitherTable context a c -> EitherTable context b c # second :: (b -> c) -> EitherTable context a b -> EitherTable context a c # | |||||||||||||
| Biprojectable (EitherTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> EitherTable context a c -> EitherTable context b d # | |||||||||||||
| (context ~ Expr, Table Expr a) => Applicative (EitherTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods pure :: a0 -> EitherTable context a a0 # (<*>) :: EitherTable context a (a0 -> b) -> EitherTable context a a0 -> EitherTable context a b # liftA2 :: (a0 -> b -> c) -> EitherTable context a a0 -> EitherTable context a b -> EitherTable context a c # (*>) :: EitherTable context a a0 -> EitherTable context a b -> EitherTable context a b # (<*) :: EitherTable context a a0 -> EitherTable context a b -> EitherTable context a a0 # | |||||||||||||
| Nullifiable context => Functor (EitherTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods fmap :: (a0 -> b) -> EitherTable context a a0 -> EitherTable context a b # (<$) :: a0 -> EitherTable context a b -> EitherTable context a a0 # | |||||||||||||
| (context ~ Expr, Table Expr a) => Monad (EitherTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods (>>=) :: EitherTable context a a0 -> (a0 -> EitherTable context a b) -> EitherTable context a b # (>>) :: EitherTable context a a0 -> EitherTable context a b -> EitherTable context a b # return :: a0 -> EitherTable context a a0 # | |||||||||||||
| Projectable (EitherTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods project :: Projecting a0 b => Projection a0 b -> EitherTable context a a0 -> EitherTable context a b # | |||||||||||||
| (context ~ Expr, Table Expr a) => Apply (EitherTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods (<.>) :: EitherTable context a (a0 -> b) -> EitherTable context a a0 -> EitherTable context a b (.>) :: EitherTable context a a0 -> EitherTable context a b -> EitherTable context a b (<.) :: EitherTable context a a0 -> EitherTable context a b -> EitherTable context a a0 liftF2 :: (a0 -> b -> c) -> EitherTable context a a0 -> EitherTable context a b -> EitherTable context a c | |||||||||||||
| (context ~ Expr, Table Expr a) => Bind (EitherTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods (>>-) :: EitherTable context a a0 -> (a0 -> EitherTable context a b) -> EitherTable context a b join :: EitherTable context a (EitherTable context a a0) -> EitherTable context a a0 | |||||||||||||
| (context ~ Expr, Table Expr a, Table Expr b) => Semigroup (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either Methods (<>) :: EitherTable context a b -> EitherTable context a b -> EitherTable context a b # sconcat :: NonEmpty (EitherTable context a b) -> EitherTable context a b # stimes :: Integral b0 => b0 -> EitherTable context a b -> EitherTable context a b # | |||||||||||||
| (EqTable a, EqTable b, context ~ Expr) => EqTable (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either | |||||||||||||
| (OrdTable a, OrdTable b, context ~ Expr) => OrdTable (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either | |||||||||||||
| type Transpose to (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either | |||||||||||||
| type Columns (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either | |||||||||||||
| type Context (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either | |||||||||||||
| type FromExprs (EitherTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.Either | |||||||||||||
eitherTable :: Table Expr c => (a -> c) -> (b -> c) -> EitherTable Expr a b -> c #
Pattern match/eliminate an EitherTable, by providing mappings from a
leftTable and rightTable.
leftTable :: Table Expr b => a -> EitherTable Expr a b #
Construct a left EitherTable. Like Left.
rightTable :: Table Expr a => b -> EitherTable Expr a b #
Construct a right EitherTable. Like Right.
isLeftTable :: EitherTable Expr a b -> Expr Bool #
Test if an EitherTable is a leftTable.
isRightTable :: EitherTable Expr a b -> Expr Bool #
Test if an EitherTable is a rightTable.
keepLeftTable :: EitherTable Expr a b -> Query a #
Filter EitherTables, keeping only leftTables.
keepRightTable :: EitherTable Expr a b -> Query b #
Filter EitherTables, keeping only rightTables.
bitraverseEitherTable :: (a -> Query c) -> (b -> Query d) -> EitherTable Expr a b -> Query (EitherTable Expr c d) #
bitraverseEitherTable f g x will pass all leftTables through f and
all rightTables through g. The results are then lifted back into
leftTable and rightTable, respectively. This is similar to bitraverse
for Either.
For example,
>>>:{select do x <- values (map lit [ Left True, Right (42 :: Int32) ]) bitraverseEitherTable (\y -> values [y, not_ y]) (\y -> pure (y * 100)) x :} [ Left True , Left False , Right 4200 ]
aggregateLeftTable :: forall c a (fold :: Fold) b. Table Expr c => Aggregator a c -> Aggregator' fold (EitherTable Expr a b) c #
Lift an Aggregator to operate on an EitherTable. If the input query has
s, they are folded into a single leftTable ac by the given aggregator
— in the case where the input query is all rightTables, the
Aggregator's fallback c is returned.
aggregateLeftTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (EitherTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on an EitherTable. If the input query
has s, they are folded into a single leftTable a
by the given aggregator — in the case where the input query is all
justTable crightTables, a single nothingTable row is returned.
aggregateRightTable :: forall c b (fold :: Fold) a. Table Expr c => Aggregator b c -> Aggregator' fold (EitherTable Expr a b) c #
Lift an Aggregator to operate on an EitherTable. If the input query has
s, they are folded into a single rightTable bc by the given aggregator
— in the case where the input query is all rightTables, the
Aggregator's fallback c is returned.
aggregateRightTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (EitherTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on an EitherTable. If the input query
has s, they are folded into a single rightTable b
by the given aggregator — in the case where the input query is all
justTable cleftTables, a single nothingTable row is returned.
aggregateEitherTable :: forall (fold :: Fold) i a (fold' :: Fold) i' b. Aggregator' fold i a -> Aggregator' fold' i' b -> Aggregator1 (EitherTable Expr i i') (EitherTable Expr a b) #
Lift a pair aggregators to operate on an EitherTable. leftTables and
rightTables are grouped separately.
Arguments
| :: Name EitherTag | The name of the column to track whether a row is a |
| -> a | Names of the columns in the |
| -> b | Names of the columns in the |
| -> EitherTable Name a b |
Construct a EitherTable in the Name context. This can be useful if you
have a EitherTable that you are storing in a table and need to construct a
TableSchema.
TheseTable
data TheseTable (context :: Context) a b #
TheseTable a b is a Rel8 table that contains either the table a, the
table b, or both tables a and b. You can construct TheseTables using
thisTable, thatTable and thoseTable. TheseTables can be
eliminated/pattern matched using theseTable.
TheseTable is operationally the same as Haskell's These type, but
adapted to work with Rel8.
Instances
| (Table context a, Table context b, Reifiable context, context ~ context') => Table context' (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These Associated Types
Methods toColumns :: TheseTable context a b -> Columns (TheseTable context a b) context' # fromColumns :: Columns (TheseTable context a b) context' -> TheseTable context a b # fromResult :: Columns (TheseTable context a b) Result -> FromExprs (TheseTable context a b) # toResult :: FromExprs (TheseTable context a b) -> Columns (TheseTable context a b) Result # | |||||||||||||
| Nullifiable context => Bifunctor (TheseTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods bimap :: (a -> b) -> (c -> d) -> TheseTable context a c -> TheseTable context b d # first :: (a -> b) -> TheseTable context a c -> TheseTable context b c # second :: (b -> c) -> TheseTable context a b -> TheseTable context a c # | |||||||||||||
| Biprojectable (TheseTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> TheseTable context a c -> TheseTable context b d # | |||||||||||||
| (context ~ Expr, Table Expr a, Semigroup a) => Applicative (TheseTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods pure :: a0 -> TheseTable context a a0 # (<*>) :: TheseTable context a (a0 -> b) -> TheseTable context a a0 -> TheseTable context a b # liftA2 :: (a0 -> b -> c) -> TheseTable context a a0 -> TheseTable context a b -> TheseTable context a c # (*>) :: TheseTable context a a0 -> TheseTable context a b -> TheseTable context a b # (<*) :: TheseTable context a a0 -> TheseTable context a b -> TheseTable context a a0 # | |||||||||||||
| Nullifiable context => Functor (TheseTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods fmap :: (a0 -> b) -> TheseTable context a a0 -> TheseTable context a b # (<$) :: a0 -> TheseTable context a b -> TheseTable context a a0 # | |||||||||||||
| (context ~ Expr, Table Expr a, Semigroup a) => Monad (TheseTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods (>>=) :: TheseTable context a a0 -> (a0 -> TheseTable context a b) -> TheseTable context a b # (>>) :: TheseTable context a a0 -> TheseTable context a b -> TheseTable context a b # return :: a0 -> TheseTable context a a0 # | |||||||||||||
| Projectable (TheseTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods project :: Projecting a0 b => Projection a0 b -> TheseTable context a a0 -> TheseTable context a b # | |||||||||||||
| (context ~ Expr, Table Expr a, Semigroup a) => Apply (TheseTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods (<.>) :: TheseTable context a (a0 -> b) -> TheseTable context a a0 -> TheseTable context a b (.>) :: TheseTable context a a0 -> TheseTable context a b -> TheseTable context a b (<.) :: TheseTable context a a0 -> TheseTable context a b -> TheseTable context a a0 liftF2 :: (a0 -> b -> c) -> TheseTable context a a0 -> TheseTable context a b -> TheseTable context a c | |||||||||||||
| (context ~ Expr, Table Expr a, Semigroup a) => Bind (TheseTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods (>>-) :: TheseTable context a a0 -> (a0 -> TheseTable context a b) -> TheseTable context a b join :: TheseTable context a (TheseTable context a a0) -> TheseTable context a a0 | |||||||||||||
| (context ~ Expr, Table Expr a, Table Expr b, Semigroup a, Semigroup b) => Semigroup (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These Methods (<>) :: TheseTable context a b -> TheseTable context a b -> TheseTable context a b # sconcat :: NonEmpty (TheseTable context a b) -> TheseTable context a b # stimes :: Integral b0 => b0 -> TheseTable context a b -> TheseTable context a b # | |||||||||||||
| (EqTable a, EqTable b, context ~ Expr) => EqTable (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These | |||||||||||||
| (OrdTable a, OrdTable b, context ~ Expr) => OrdTable (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These | |||||||||||||
| type Transpose to (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These | |||||||||||||
| type Columns (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These | |||||||||||||
| type Context (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These | |||||||||||||
| type FromExprs (TheseTable context a b) # | |||||||||||||
Defined in Rel8.Internal.Table.These | |||||||||||||
theseTable :: Table Expr c => (a -> c) -> (b -> c) -> (a -> b -> c) -> TheseTable Expr a b -> c #
Pattern match on a TheseTable. Corresponds to these.
thoseTable :: a -> b -> TheseTable Expr a b #
Construct a TheseTable. Corresponds to These.
isThisTable :: TheseTable Expr a b -> Expr Bool #
Test if a TheseTable was constructed with thisTable.
Corresponds to isThis.
isThatTable :: TheseTable Expr a b -> Expr Bool #
Test if a TheseTable was constructed with thatTable.
Corresponds to isThat.
isThoseTable :: TheseTable Expr a b -> Expr Bool #
Test if a TheseTable was constructed with thoseTable.
Corresponds to isThese.
hasHereTable :: TheseTable Expr a b -> Expr Bool #
Test if the a side of TheseTable a b is present.
Corresponds to hasHere.
hasThereTable :: TheseTable Expr a b -> Expr Bool #
Test if the b table of TheseTable a b is present.
Corresponds to hasThere.
justHereTable :: forall (context :: Context) a b. TheseTable context a b -> MaybeTable context a #
Attempt to project out the a table of a TheseTable a b.
Corresponds to justHere.
justThereTable :: forall (context :: Context) a b. TheseTable context a b -> MaybeTable context b #
Attempt to project out the b table of a TheseTable a b.
Corresponds to justThere.
alignMaybeTable :: MaybeTable Expr a -> MaybeTable Expr b -> MaybeTable Expr (TheseTable Expr a b) #
Construct a TheseTable from two MaybeTables.
alignBy :: (a -> b -> Expr Bool) -> Query a -> Query b -> Query (TheseTable Expr a b) #
Corresponds to a FULL OUTER JOIN between two queries.
keepHereTable :: TheseTable Expr a b -> Query (a, MaybeTable Expr b) #
loseHereTable :: TheseTable Expr a b -> Query b #
keepThereTable :: TheseTable Expr a b -> Query (MaybeTable Expr a, b) #
loseThereTable :: TheseTable Expr a b -> Query a #
keepThisTable :: TheseTable Expr a b -> Query a #
loseThisTable :: TheseTable Expr a b -> Query (MaybeTable Expr a, b) #
keepThatTable :: TheseTable Expr a b -> Query b #
loseThatTable :: TheseTable Expr a b -> Query (a, MaybeTable Expr b) #
keepThoseTable :: TheseTable Expr a b -> Query (a, b) #
loseThoseTable :: TheseTable Expr a b -> Query (EitherTable Expr a b) #
bitraverseTheseTable :: (a -> Query c) -> (b -> Query d) -> TheseTable Expr a b -> Query (TheseTable Expr c d) #
aggregateThisTable :: forall c a (fold :: Fold) b. Table Expr c => Aggregator a c -> Aggregator' fold (TheseTable Expr a b) c #
Lift an Aggregator to operate on a TheseTable. If the input query has
s, they are folded into a single thisTable ac by the given aggregator
— in the case where the input query is all thatTables or thoseTables,
the Aggregator's fallback c is returned.
aggregateThisTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on a TheseTable. If the input query
has s, they are folded into a single thisTable a
by the given aggregator — in the case where the input query is all
justTable cthatTables or thoseTables, a single nothingTable row is returned.
aggregateThatTable :: forall c b (fold :: Fold) a. Table Expr c => Aggregator b c -> Aggregator' fold (TheseTable Expr a b) c #
Lift an Aggregator to operate on a TheseTable. If the input query has
s, they are folded into a single thatTable bc by the given aggregator
— in the case where the input query is all thisTables or thoseTables,
the Aggregator's fallback c is returned.
aggregateThatTable1 :: forall c (fold :: Fold) b (fold' :: Fold) a. Table Expr c => Aggregator' fold b c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on a TheseTable. If the input query
has s, they are folded into a single thatTable b
by the given aggregator — in the case where the input query is all
justTable cthisTables or thoseTables, a single nothingTable row is returned.
aggregateThoseTable :: forall c a b (fold :: Fold). Table Expr c => Aggregator (a, b) c -> Aggregator' fold (TheseTable Expr a b) c #
Lift an Aggregator to operate on a ThoseTable. If the input query has
s, they are folded into a single thoseTable a bc by the given
aggregator — in the case where the input query is all thisTables or
thatTables, the Aggregator's fallback c is returned.
aggregateThoseTable1 :: forall c (fold :: Fold) a b (fold' :: Fold). Table Expr c => Aggregator' fold (a, b) c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on a TheseTable. If the input query
has s, they are folded into a single thoseTable a b
by the given aggregator — in the case where the input query is all
justTable cthisTables or thatTables, a single nothingTable row is returned.
aggregateHereTable :: forall c a (fold :: Fold) b. Table Expr c => Aggregator a c -> Aggregator' fold (TheseTable Expr a b) c #
Lift an Aggregator to operate on a TheseTable. If the input query has
s or thisTable as, the thoseTable a _as are folded into a single
c by the given aggregator — in the case where the input query is all
thatTables, the Aggregator's fallback c is returned.
aggregateHereTable1 :: forall c (fold :: Fold) a (fold' :: Fold) b. Table Expr c => Aggregator' fold a c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on an TheseTable. If the input query
has s or thisTable as, the thoseTable a _as are folded into a
single by the given aggregator — in the case where
the input query is all justTable cthatTables, a single nothingTable row is
returned.
aggregateThereTable :: forall c b (fold :: Fold) a. Table Expr c => Aggregator b c -> Aggregator' fold (TheseTable Expr a b) c #
Lift an Aggregator to operate on a TheseTable. If the input query has
s or thatTable bs, the thoseTable _ bbs are folded into a single
c by the given aggregator — in the case where the input query is all
thisTables, the Aggregator's fallback c is returned.
aggregateThereTable1 :: forall c (fold :: Fold) b (fold' :: Fold) a. Table Expr c => Aggregator' fold b c -> Aggregator' fold' (TheseTable Expr a b) (MaybeTable Expr c) #
Lift an Aggregator1 to operate on an TheseTable. If the input query
has s or thatTable bs, the thoseTable _ bbs are folded into a
single by the given aggregator — in the case where
the input query is all justTable cthisTables, a single nothingTable row is
returned.
aggregateTheseTable :: forall (fold :: Fold) i a (fold' :: Fold) i' b. Aggregator' fold i a -> Aggregator' fold' i' b -> Aggregator1 (TheseTable Expr i i') (TheseTable Expr a b) #
Lift a pair aggregators to operate on a TheseTable. thisTables,
thatTables are thoseTables are grouped separately.
Arguments
| :: Name (Maybe MaybeTag) | The name of the column to track the presence of the |
| -> Name (Maybe MaybeTag) | The name of the column to track the presence of the |
| -> a | Names of the columns in the |
| -> b | Names of the columns in the |
| -> TheseTable Name a b |
Construct a TheseTable in the Name context. This can be useful if you
have a TheseTable that you are storing in a table and need to construct a
TableSchema.
ListTable
data ListTable (context :: Context) a #
A ListTable value contains zero or more instances of a. You construct
ListTables with many or listAgg.
Instances
listTable :: Table Expr a => [a] -> ListTable Expr a #
Construct a ListTable from a list of expressions.
($*) :: Projecting a (Expr b) => Projection a (Expr b) -> ListTable Expr a -> Expr [b] infixl 4 #
Project a single expression out of a ListTable.
many :: Table Expr a => Query a -> Query (ListTable Expr a) #
Aggregate a Query into a ListTable. If the supplied query returns 0
rows, this function will produce a Query that returns one row containing
the empty ListTable. If the supplied Query does return rows, many will
return exactly one row, with a ListTable collecting all returned rows.
many is analogous to many from
Control.Applicative.
manyExpr :: Sql DBType a => Query (Expr a) -> Query (Expr [a]) #
A version of many specialised to single expressions.
NonEmptyTable
data NonEmptyTable (context :: Context) a #
A NonEmptyTable value contains one or more instances of a. You
construct NonEmptyTables with some or nonEmptyAgg.
Instances
| (Table context a, context ~ context') => Table context' (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty Associated Types
Methods toColumns :: NonEmptyTable context a -> Columns (NonEmptyTable context a) context' # fromColumns :: Columns (NonEmptyTable context a) context' -> NonEmptyTable context a # fromResult :: Columns (NonEmptyTable context a) Result -> FromExprs (NonEmptyTable context a) # toResult :: FromExprs (NonEmptyTable context a) -> Columns (NonEmptyTable context a) Result # | |||||||||||||
| context ~ Expr => AltTable (NonEmptyTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty Methods (<|>:) :: Table Expr a => NonEmptyTable context a -> NonEmptyTable context a -> NonEmptyTable context a # | |||||||||||||
| Projectable (NonEmptyTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty Methods project :: Projecting a b => Projection a b -> NonEmptyTable context a -> NonEmptyTable context b # | |||||||||||||
| (Table Expr a, context ~ Expr) => Semigroup (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty Methods (<>) :: NonEmptyTable context a -> NonEmptyTable context a -> NonEmptyTable context a # sconcat :: NonEmpty (NonEmptyTable context a) -> NonEmptyTable context a # stimes :: Integral b => b -> NonEmptyTable context a -> NonEmptyTable context a # | |||||||||||||
| (EqTable a, context ~ Expr) => EqTable (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
| (OrdTable a, context ~ Expr) => OrdTable (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
| (ToExprs exprs a, context ~ Expr) => ToExprs (NonEmptyTable context exprs) (NonEmpty a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
| type Transpose to (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
| type Columns (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
| type Context (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
| type FromExprs (NonEmptyTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.NonEmpty | |||||||||||||
nonEmptyTable :: Table Expr a => NonEmpty a -> NonEmptyTable Expr a #
Construct a NonEmptyTable from a non-empty list of expressions.
($+) :: Projecting a (Expr b) => Projection a (Expr b) -> NonEmptyTable Expr a -> Expr (NonEmpty b) infixl 4 #
Project a single expression out of a NonEmptyTable.
Arguments
| :: Table Name a | |
| => a | The names of the columns of elements of the list. |
| -> NonEmptyTable Name a |
Construct a NonEmptyTable in the Name context. This can be useful if
you have a NonEmptyTable that you are storing in a table and need to
construct a TableSchema.
some :: Table Expr a => Query a -> Query (NonEmptyTable Expr a) #
Aggregate a Query into a NonEmptyTable. If the supplied query returns
0 rows, this function will produce a Query that is empty - that is, will
produce zero NonEmptyTables. If the supplied Query does return rows,
some will return exactly one row, with a NonEmptyTable collecting all
returned rows.
some is analogous to some from
Control.Applicative.
someExpr :: Sql DBType a => Query (Expr a) -> Query (Expr (NonEmpty a)) #
A version of some specialised to single expressions.
catNonEmptyTable :: Table Expr a => NonEmptyTable Expr a -> Query a #
Expand a NonEmptyTable into a Query, where each row in the query is an
element of the given NonEmptyTable.
catNonEmptyTable is an inverse to some.
NullTable
data NullTable (context :: Context) a #
NullTable t is the table t, but where all the columns in t have the
possibility of being null. This is very similar to
MaybeTable, except that it does not use an extra tag field, so it
cannot distinguish between Nothing and Just Nothing if nested. In other
words, if all of the columns of the t passed to NullTable are already
nullable, then NullTable has no effect.
Instances
| (Table context a, Reifiable context, context ~ context') => Table context' (NullTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null Associated Types
Methods toColumns :: NullTable context a -> Columns (NullTable context a) context' # fromColumns :: Columns (NullTable context a) context' -> NullTable context a # fromResult :: Columns (NullTable context a) Result -> FromExprs (NullTable context a) # toResult :: FromExprs (NullTable context a) -> Columns (NullTable context a) Result # | |||||||||||||
| context ~ Expr => AltTable (NullTable context) # | |||||||||||||
| context ~ Expr => AlternativeTable (NullTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Null Methods emptyTable :: Table Expr a => NullTable context a # | |||||||||||||
| Projectable (NullTable context) # | |||||||||||||
Defined in Rel8.Internal.Table.Null Methods project :: Projecting a b => Projection a b -> NullTable context a -> NullTable context b # | |||||||||||||
| (EqTable a, context ~ Expr) => EqTable (NullTable context a) # | |||||||||||||
| (OrdTable a, context ~ Expr) => OrdTable (NullTable context a) # | |||||||||||||
| (ToExprs exprs a, context ~ Expr) => ToExprs (NullTable context exprs) (Maybe a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null | |||||||||||||
| type Transpose to (NullTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null | |||||||||||||
| type Columns (NullTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null | |||||||||||||
| type Context (NullTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null | |||||||||||||
| type FromExprs (NullTable context a) # | |||||||||||||
Defined in Rel8.Internal.Table.Null | |||||||||||||
nullableTable :: (Table Expr a, Table Expr b) => b -> (a -> b) -> NullTable Expr a -> b #
Like nullable.
isNonNullTable :: Table Expr a => NullTable Expr a -> Expr Bool #
The inverse of isNullTable.
nameNullTable :: a -> NullTable Name a #
toNullTable :: Table Expr a => MaybeTable Expr a -> NullTable Expr a #
Convert a MaybeTable to a NullTable. Note that if the underlying a
has no non-nullable fields, this is a lossy conversion.
toMaybeTable :: Table Expr a => NullTable Expr a -> MaybeTable Expr a #
Convert a NullTable to a MaybeTable.
unsafeUnnullifyTable :: NullTable Expr a -> a #
Assume that a NullTable is non-null. Like unsafeUnnullify.
Algebraic data types / sum types
Algebraic data types can be modelled between Haskell and SQL.
- Your SQL table needs a certain text field that tags which Haskell constructor is in use.
- You have to use a few combinators to specify the sum type's individual constructors.
- If you want to do case analysis at the
Expr(SQL) level, you can usemaybe/either-like eliminators.
The documentation in this section will assume a set of database types like this:
data Thing f = ThingEmployer (Employer f) | ThingPotato (Potato f) | Nullary
deriving stock Generic
data Employer f = Employer { employerId :: Column f Int32, employerName :: Column f Text}
deriving stock Generic
deriving anyclass Rel8able
data Potato f = Potato { size :: Column f Int32, grower :: Column f Text }
deriving stock Generic
deriving anyclass Rel8able
Naming of ADTs
First, in your TableSchema, name your type like this:
thingSchema :: TableSchema (ADT Thing Name)
thingSchema =
TableSchema
{ name = "thing",
columns =
nameADT @Thing
"tag"
Employer
{ employerName = "name",
employerId = "id"
}
Potato {size = "size", grower = "Mary"}
}
Note that nameADT @Thing "tag" is variadic: it accepts one
argument per constructor, except the nullary ones (Nullary) because
there's nothing to do for them.
nameADT :: forall (t :: Rel8able). ConstructableADT t => NameADT t #
data ADT (t :: Rel8able) (context :: Context) #
Instances
| 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 # | |||||||||
| type GColumns (ADT t) # | |||||||||
Defined in Rel8.Internal.Table.ADT | |||||||||
| type GFromExprs (ADT t) # | |||||||||
Defined in Rel8.Internal.Table.ADT | |||||||||
class (Generic (Record (t Result)), HTable (GColumnsADT t), GSerializeADT TSerialize TColumns (Eval (ADTRep t Expr)) (Eval (ADTRep t Result))) => ADTable (t :: Rel8able) #
Deconstruction of ADTs
To deconstruct sum types at the SQL level, use deconstructADT,
which is also variadic, and has one argument for each
constructor. Similar to maybe.
query :: Query (ADT Thing Expr)
query = do
thingExpr <- each thingSchema
where_ $
deconstructADT @Thing
(\employer -> employerName employer ==. lit "Mary")
(\potato -> grower potato ==. lit "Mary")
(lit False) -- Nullary case
thingExpr
pure thingExpr
SQL output:
SELECT
CAST("tag0_1" AS text) as "tag",
CAST("id1_1" AS int4) as "ThingEmployer_1employerId",
CAST("name2_1" AS text) as "ThingEmployer_1employerName",
CAST("size3_1" AS int4) as "ThingPotato_1size",
CAST(Mary4_1 AS text) as "ThingPotato_1grower"
FROM (SELECT
*
FROM (SELECT
"tag" as "tag0_1",
"id" as "id1_1",
"name" as "name2_1",
"size" as "size3_1",
Mary as Mary4_1
FROM "thing" as T1) as T1
WHERE (CASE WHEN ("tag0_1") = (CAST(EThingPotato AS text)) THEN (Mary4_1) = (CAST(EMary AS text))
WHEN ("tag0_1") = (CAST(ENullary AS text)) THEN CAST(FALSE AS bool) ELSE ("name2_1") = (CAST(EMary AS text)) END)) as T1
type DeconstructADT (t :: Rel8able) r = GGDeconstruct 'Sum (ADTRep t) (ADT t Expr) r #
deconstructADT :: forall (t :: Rel8able) r. (ConstructableADT t, Table Expr r) => DeconstructADT t r #
Construction of ADTs
To construct an ADT, you can use buildADT or constructADT. Consider the following type:
data Task f = Pending | Complete (CompletedTask f)
buildADT is for constructing values of Task in the Expr
context. buildADT needs two type-level arguments before its type
makes any sense. The first argument is the type of the ADT, which
in our case is Task. The second is the name of the constructor we
want to use. So that means we have the following possible
instantiations of buildADT for Task:
> :t buildADT @Task @"Pending" buildADT @Task @"Pending" :: ADT Task Expr > :t buildADT @Task @"Complete" buildADT @Task @"Complete" :: CompletedTask Expr -> ADT Task Expr
Note that as the Pending constructor has no fields, buildADT
@Task @Pending is equivalent to lit Pending. But buildADT
@Task @Complete is not the same as lit . Complete:
> :t lit . Complete lit . Complete :: CompletedTask Result -> ADT Task Expr
Note that the former takes a CompletedTask Expr while the latter
takes a CompletedTask Result. The former is more powerful because
you can construct Tasks using dynamic values coming a database
query.
To show what this can look like in SQL, consider:
> :{
showQuery $ values
[ buildADT @Task @"Pending"
, buildADT @Task @"Complete" CompletedTask {date = Rel8.Expr.Time.now}
]
:}
This produces the following SQL:
SELECT
CAST("values0_1" AS text) as "tag",
CAST("values1_1" AS timestamptz) as "Complete_1date"
FROM (SELECT
*
FROM (SELECT "column1" as "values0_1",
"column2" as "values1_1"
FROM
(VALUES
(CAST(EPending AS text),CAST(NULL AS timestamptz)),
(CAST(EComplete AS text),CAST(now() AS timestamptz))) as "V") as "T1") as "T1"
This is what you get if you run it in psql:
tag | Complete_1date ----------+------------------------------- Pending | Complete | 2022-05-19 21:28:23.969065+00 (2 rows)
"constructADT" is less convenient but more general alternative to "buildADT". It requires only one type-level argument for its type to make sense:
> :t constructADT Task
constructADT Task
:: (forall r. r -> (CompletedTask Expr -> r) -> r) -> ADT Task Expr
This might still seem a bit opaque, but basically it gives you a Church-encoded constructor for arbitrary algebraic data types. You might use it as follows:
let
pending :: ADT Task Expr
pending = constructADT @Task $ \pending _complete -> pending
complete :: ADT Task Expr
complete = constructADT @Task $ \_pending complete -> complete CompletedTask {date = Rel8.Expr.Time.now}
These values are otherwise identical to the ones we saw above with
buildADT, it's just a different style of constructing them.
type ConstructADT (t :: Rel8able) = forall r. GGConstruct 'Sum (ADTRep t) r #
constructADT :: forall (t :: Rel8able). ConstructableADT t => ConstructADT t -> ADT t Expr #
Miscellaneous notes
- Note that the order of the arguments for all of these functions
is determined by the order of the constructors in the data
definition. If it were
data Task = Complete (CompletedTask f) | Pendingthen the order of all the invocations ofconstructADTanddeconstructADTwould need to change. - Maybe this is obvious, but just to spell it out: once you're in
the
Resultcontext, you can of course constructTaskvalues normally and use standard Haskell pattern-matching.constructADTanddeconstructADTare specifically only needed in theExprcontext, and they allow you to do the equivalent of pattern matching in PostgreSQL.
HKD
Instances
| 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 # | |||||||||
| (GTable (TTable f) TColumns (GRecord (GMap (TColumn f) (Rep a))), GColumns TColumns (GRecord (GMap (TColumn f) (Rep a))) ~ GColumnsHKD a, GContext TContext (GRecord (GMap (TColumn f) (Rep a))) ~ f, GRecordable (GMap (TColumn f) (Rep a))) => Generic (HKD a f) # | |||||||||
| type GColumns (HKD a) # | |||||||||
Defined in Rel8.Internal.Table.HKD | |||||||||
| type GFromExprs (HKD a) # | |||||||||
Defined in Rel8.Internal.Table.HKD | |||||||||
| type Rep (HKD a f) # | |||||||||
class (Generic (Record a), HTable (GColumns (HKD a)), KnownAlgebra (GAlgebra (Rep a)), Eval (GGSerialize (GAlgebra (Rep a)) TSerialize TColumns (Eval (HKDRep a Expr)) (Eval (HKDRep a Result))), GRecord (GMap (TColumn Result) (Rep a)) ~ Rep (Record a)) => HKDable a #
Instances
buildHKD :: forall a (name :: Symbol). BuildableHKD a name => BuildHKD a name #
type ConstructHKD a = forall r. GGConstruct (GAlgebra (Rep a)) (HKDRep a) r #
constructHKD :: ConstructableHKD a => ConstructHKD a -> HKD a Expr #
type DeconstructHKD a r = GGDeconstruct (GAlgebra (Rep a)) (HKDRep a) (HKD a Expr) r #
deconstructHKD :: (ConstructableHKD a, Table Expr r) => DeconstructHKD a r #
nameHKD :: ConstructableHKD a => NameHKD a #
Table schemas
data TableSchema names #
The schema for a table. This is used to specify the name and schema that a
table belongs to (the FROM part of a SQL query), along with the schema of
the columns within this table.
For each selectable table in your database, you should provide a
TableSchema in order to interact with the table via Rel8.
Constructors
| TableSchema | |
Fields
| |
Instances
| Functor TableSchema # | |
Defined in Rel8.Internal.Schema.Table Methods fmap :: (a -> b) -> TableSchema a -> TableSchema b # (<$) :: a -> TableSchema b -> TableSchema a # | |
data QualifiedName #
A name of an object (such as a table, view, function or sequence)
qualified by an optional schema. In the absence of an explicit schema,
the connection's search_path will be used implicitly.
Constructors
| QualifiedName | |
Instances
| Eq QualifiedName # | |
Defined in Rel8.Internal.Schema.QualifiedName Methods (==) :: QualifiedName -> QualifiedName -> Bool # (/=) :: QualifiedName -> QualifiedName -> Bool # | |
| Ord QualifiedName # | |
Defined in Rel8.Internal.Schema.QualifiedName Methods compare :: QualifiedName -> QualifiedName -> Ordering # (<) :: QualifiedName -> QualifiedName -> Bool # (<=) :: QualifiedName -> QualifiedName -> Bool # (>) :: QualifiedName -> QualifiedName -> Bool # (>=) :: QualifiedName -> QualifiedName -> Bool # max :: QualifiedName -> QualifiedName -> QualifiedName # min :: QualifiedName -> QualifiedName -> QualifiedName # | |
| IsString QualifiedName # | Constructs |
Defined in Rel8.Internal.Schema.QualifiedName Methods fromString :: String -> QualifiedName # | |
| Show QualifiedName # | |
Defined in Rel8.Internal.Schema.QualifiedName Methods showsPrec :: Int -> QualifiedName -> ShowS # show :: QualifiedName -> String # showList :: [QualifiedName] -> ShowS # | |
A Name is the name of a column, as it would be defined in a table's
schema definition. You can construct names by using the OverloadedStrings
extension and writing string literals. This is typically done when providing
a TableSchema value.
Instances
| Reifiable Name # | |||||||||||||
Defined in Rel8.Internal.Kind.Context Methods contextSing :: SContext Name # | |||||||||||||
| Nullifiable Name # | |||||||||||||
Defined in Rel8.Internal.Schema.Context.Nullify Methods | |||||||||||||
| Sql DBType a => Table Name (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name Associated Types
| |||||||||||||
| IsString (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name Methods fromString :: String -> Name a # | |||||||||||||
| Show (Name a) # | |||||||||||||
| type Transpose to (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name | |||||||||||||
| type Columns (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name | |||||||||||||
| type Context (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name | |||||||||||||
| type FromExprs (Name a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Name | |||||||||||||
namesFromLabels :: Table Name a => a #
Construct a table in the Name context containing the names of all
columns. Nested column names will be combined with /, the resulting
name will be truncated and a unique tag appended to the end of the name
so that the resulting name has 63 or less characters (Postgres' default
maximum column name length).
See also: namesFromLabelsTagged, namesFromLabelsWith.
namesFromLabelsWith :: Table Name a => (NonEmpty String -> String) -> a #
Construct a table in the Name context containing the names of all
columns. The supplied function can be used to transform column names.
This function can be used to generically derive the columns for a
TableSchema. For example,
myTableSchema :: TableSchema (MyTable Name)
myTableSchema = TableSchema
{ columns = namesFromLabelsWith last
}
will construct a TableSchema where each columns names exactly corresponds
to the name of the Haskell field.
Expressions
Typed SQL expressions.
Instances
| Reifiable Expr # | |||||||||||||
Defined in Rel8.Internal.Kind.Context Methods contextSing :: SContext Expr # | |||||||||||||
| Nullifiable Expr # | |||||||||||||
Defined in Rel8.Internal.Schema.Context.Nullify Methods | |||||||||||||
| Sql DBType a => Table Expr (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr Associated Types
| |||||||||||||
| Sql DBMonoid a => Monoid (Expr a) # | |||||||||||||
| Sql DBSemigroup a => Semigroup (Expr a) # | |||||||||||||
| (Sql IsString a, Sql DBType a) => IsString (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr Methods fromString :: String -> Expr a # | |||||||||||||
| Sql DBFloating a => Floating (Expr a) # | |||||||||||||
| Sql DBNum a => Num (Expr a) # | |||||||||||||
| Sql DBFractional a => Fractional (Expr a) # | |||||||||||||
| Show (Expr a) # | |||||||||||||
| Sql DBEq a => EqTable (Expr a) # | |||||||||||||
| Sql DBOrd a => OrdTable (Expr a) # | |||||||||||||
| Sql DBType a => Serializable (Expr a) a # | |||||||||||||
Defined in Rel8.Internal.Table.Serialize | |||||||||||||
| (Sql DBType a, NotNull a, x ~ NonEmpty a) => ToExprs (Expr x) (NonEmpty a) # | |||||||||||||
Defined in Rel8.Internal.Table.Serialize | |||||||||||||
| (Sql DBType a, NotNull a, x ~ Maybe a) => ToExprs (Expr x) (Maybe a) # | |||||||||||||
Defined in Rel8.Internal.Table.Serialize | |||||||||||||
| (Sql DBType a, x ~ [a]) => ToExprs (Expr x) [a] # | |||||||||||||
Defined in Rel8.Internal.Table.Serialize | |||||||||||||
| type Transpose to (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr | |||||||||||||
| type Columns (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr | |||||||||||||
| type Context (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr | |||||||||||||
| type FromExprs (Expr a) # | |||||||||||||
Defined in Rel8.Internal.Expr | |||||||||||||
class (constraint (Unnullify a), Nullable a) => Sql (constraint :: Type -> Constraint) a #
The Sql type class describes both null and not null database values,
constrained by a specific class.
For example, if you see Sql DBEq a, this means any database type that
supports equality, and a can either be exactly an a, or it could also be
Maybe a.
Instances
| (constraint (Unnullify a), Nullable a) => Sql constraint a # | |
Defined in Rel8.Internal.Schema.Null | |
litExpr :: Sql DBType a => a -> Expr a #
Produce an expression from a literal.
Note that you can usually use lit, but litExpr can solve problems
of inference in polymorphic code.
unsafeCastExpr :: Sql DBType b => Expr a -> Expr b #
Cast an expression to a different type. Corresponds to a CAST() function
call.
unsafeCoerceExpr :: Expr a -> Expr b #
Change the type of an Expr, without a cast. Even more unsafe than
unsafeCastExpr. Only use this if you are certain that the typeNames of
a and b refer to exactly the same PostgreSQL type.
unsafeLiteral :: String -> Expr a #
Unsafely construct an expression from literal SQL.
This is an escape hatch, and can be used if Rel8 cannot adequately express the expression you need. If you find yourself using this function, please let us know, as it may indicate that something is missing from Rel8!
unsafePrimExpr :: PrimExpr -> Expr a #
Import a raw PrimExpr from opaleye, without a cast.
This is an escape hatch, and can be used if Rel8 cannot adequately express the expression you need. If you find yourself using this function, please let us know, as it may indicate that something is missing from Rel8!
null
class Nullable' (IsMaybe a) a => Nullable a #
Nullable a means that rel8 is able to check if the type a is a
type that can take null values or not.
Instances
| Nullable' (IsMaybe a) a => Nullable a # | |
Defined in Rel8.Internal.Schema.Null | |
class IsMaybe a ~ IsMaybe b => Homonullable a b #
Homonullable a b means that both a and b can be null, or neither
a or b can be null.
Instances
| IsMaybe a ~ IsMaybe b => Homonullable a b # | |
Defined in Rel8.Internal.Schema.Null | |
nullify :: NotNull a => Expr a -> Expr (Maybe a) #
Lift an expression that can't be null to a type that might be null.
This is an identity operation in terms of any generated query, and just
modifies the query's type.
nullable :: Table Expr b => b -> (Expr a -> b) -> Expr (Maybe a) -> b #
Like maybe, but to eliminate null.
liftOpNull :: DBType c => (Expr a -> Expr b -> Expr c) -> Expr (Maybe a) -> Expr (Maybe b) -> Expr (Maybe c) #
coalesce :: Expr (Maybe Bool) -> Expr Bool #
Convert a Expr (Maybe Bool) to a Expr Bool by treating Nothing as
False. This can be useful when combined with where_, which expects
a Bool, and produces expressions that optimize better than general case
analysis.
unsafeUnnullify :: Expr (Maybe a) -> Expr a #
Assume that a nullable column's value is non-null. If the column is
actually null, this will lead to runtime errors when you try to decode
the value into Haskell, so you should prefer to use nullable
unless you know what you're doing.
Boolean operations
Database types that can be compared for equality in queries. If a type is
an instance of DBEq, it means we can compare expressions for equality
using the SQL = operator.
Instances
| DBEq Value # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq ByteString # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq ByteString # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Int16 # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Int32 # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Int64 # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Oid # | |
Defined in Rel8.Internal.Table.Verify | |
| DBEq Relkind # | |
Defined in Rel8.Internal.Table.Verify | |
| DBEq EitherTag # | |
Defined in Rel8.Internal.Type.Tag | |
| DBEq MaybeTag # | |
Defined in Rel8.Internal.Type.Tag | |
| DBEq Tag # | |
Defined in Rel8.Internal.Type.Tag | |
| DBEq Scientific # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Text # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Text # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Day # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq UTCTime # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq LocalTime # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq TimeOfDay # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq UUID # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Bool # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Char # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Double # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq Float # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq (CI Text) # | |
Defined in Rel8.Internal.Type.Eq | |
| DBEq (CI Text) # | |
Defined in Rel8.Internal.Type.Eq | |
| Sql DBEq a => DBEq (NonEmpty a) # | |
Defined in Rel8.Internal.Type.Eq | |
| DBRange a => DBEq (Range a) # | |
Defined in Rel8.Internal.Data.Range | |
| DBRange a => DBEq (Multirange a) # | |
Defined in Rel8.Internal.Data.Range | |
| (DBComposite a, EqTable (HKD a Expr)) => DBEq (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| DBEnum a => DBEq (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| Sql DBEq a => DBEq [a] # | |
Defined in Rel8.Internal.Type.Eq | |
| PowerOf10 n => DBEq (Fixed n) # | |
Defined in Rel8.Internal.Type.Eq | |
(/=.) :: Sql DBEq a => Expr a -> Expr a -> Expr Bool infix 4 #
Test if two expressions are different (not equal).
This corresponds to the SQL IS DISTINCT FROM operator, and will return
false when comparing two null values. This differs from ordinary <>
which would return null. This operator is closer to Haskell's /=
operator. For an operator identical to SQL <>, see /=?.
(/=?) :: DBEq a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool infix 4 #
Test if two expressions are different.
This corresponds to the SQL <> operator, though it will always return a
Bool.
boolExpr :: Expr a -> Expr a -> Expr Bool -> Expr a #
Eliminate a boolean-valued expression.
Corresponds to bool.
caseExpr :: [(Expr Bool, Expr a)] -> Expr a -> Expr a #
A multi-way ifthenelse statement. The first argument to caseExpr is a
list of alternatives. The first alternative that is of the form (true, x)
will be returned. If no such alternative is found, a fallback expression is
returned.
Corresponds to a CASE expression in SQL.
like :: Expr Text -> Expr Text -> Expr Bool #
like x y corresponds to the expression y LIKE x.
Note that the arguments to like are swapped. This is to aid currying, so
you can write expressions like
filter (like "Rel%" . packageName) =<< each haskellPackages
ilike :: Expr Text -> Expr Text -> Expr Bool #
ilike x y corresponds to the expression y ILIKE x.
Note that the arguments to ilike are swapped. This is to aid currying, so
you can write expressions like
filter (ilike "Rel%" . packageName) =<< each haskellPackages
Ordering
The class of database types that support the <, <=, > and >=
operators.
Instances
| DBOrd ByteString # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd ByteString # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Int16 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Int32 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Int64 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd EitherTag # | |
Defined in Rel8.Internal.Type.Tag | |
| DBOrd MaybeTag # | |
Defined in Rel8.Internal.Type.Tag | |
| DBOrd Tag # | |
Defined in Rel8.Internal.Type.Tag | |
| DBOrd Scientific # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Text # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Text # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Day # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd UTCTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd LocalTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd TimeOfDay # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd UUID # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Bool # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Char # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Double # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd Float # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd (CI Text) # | |
Defined in Rel8.Internal.Type.Ord | |
| DBOrd (CI Text) # | |
Defined in Rel8.Internal.Type.Ord | |
| Sql DBOrd a => DBOrd (NonEmpty a) # | |
Defined in Rel8.Internal.Type.Ord | |
| DBRange a => DBOrd (Range a) # | |
Defined in Rel8.Internal.Data.Range | |
| DBRange a => DBOrd (Multirange a) # | |
Defined in Rel8.Internal.Data.Range | |
| (DBComposite a, OrdTable (HKD a Expr)) => DBOrd (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| DBEnum a => DBOrd (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| Sql DBOrd a => DBOrd [a] # | |
Defined in Rel8.Internal.Type.Ord | |
| PowerOf10 n => DBOrd (Fixed n) # | |
Defined in Rel8.Internal.Type.Ord | |
(<.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool infix 4 #
Corresponds to the SQL < operator. Note that this differs from SQL <
as null will sort below any other value. For a version of < that exactly
matches SQL, see (<?).
(<=.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool infix 4 #
Corresponds to the SQL <= operator. Note that this differs from SQL <=
as null will sort below any other value. For a version of <= that exactly
matches SQL, see (<=?).
(>.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool infix 4 #
Corresponds to the SQL > operator. Note that this differs from SQL >
as null will sort below any other value. For a version of > that exactly
matches SQL, see (>?).
(>=.) :: Sql DBOrd a => Expr a -> Expr a -> Expr Bool infix 4 #
Corresponds to the SQL >= operator. Note that this differs from SQL >
as null will sort below any other value. For a version of >= that
exactly matches SQL, see (>=?).
(<?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool infix 4 #
Corresponds to the SQL < operator. Returns null if either arguments
are null.
(<=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool infix 4 #
Corresponds to the SQL <= operator. Returns null if either arguments
are null.
(>?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool infix 4 #
Corresponds to the SQL > operator. Returns null if either arguments
are null.
(>=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool infix 4 #
Corresponds to the SQL >= operator. Returns null if either arguments
are null.
leastExpr :: Sql DBOrd a => Expr a -> Expr a -> Expr a #
Given two expressions, return the expression that sorts less than the other.
Corresponds to the SQL least() function.
greatestExpr :: Sql DBOrd a => Expr a -> Expr a -> Expr a #
Given two expressions, return the expression that sorts greater than the other.
Corresponds to the SQL greatest() function.
Functions
This type class is basically , where each column of the
Table ExprTable is an argument to the function, but it also has an additional
instance for () for calling functions with no arguments.
Minimal complete definition
arguments
Instances
| Arguments () # | |
Defined in Rel8.Internal.Expr.Function Methods arguments :: () -> [PrimExpr] | |
| Table Expr a => Arguments a # | |
Defined in Rel8.Internal.Expr.Function Methods arguments :: a -> [PrimExpr] | |
binaryOperator :: Sql DBType c => QualifiedName -> Expr a -> Expr b -> Expr c #
Construct an expression by applying an infix binary operator to two operands.
queryFunction :: (Arguments input, Table Expr output) => QualifiedName -> input -> Query output #
Select each row from a function that returns a relation. This is
equivalent to FROM function(input).
rawFunction :: Arguments arguments => QualifiedName -> arguments -> Expr a #
A less safe version of function that does not wrap the return value in
a cast.
rawBinaryOperator :: QualifiedName -> Expr a -> Expr b -> Expr c #
A less safe version of binaryOperator that does not wrap the return
value in a cast.
Queries
The Query monad allows you to compose a SELECT query. This monad has
semantics similar to the list ([]) monad.
Instances
| Applicative Query # | |
| Functor Query # | |
| Monad Query # | |
| AltTable Query # | |
| AlternativeTable Query # |
|
Defined in Rel8.Internal.Query Methods emptyTable :: Table Expr a => Query a # | |
| Projectable Query # | |
Defined in Rel8.Internal.Query Methods project :: Projecting a b => Projection a b -> Query a -> Query b # | |
| Apply Query # | |
| Bind Query # | |
| Table Expr a => Monoid (Query a) # | |
| Table Expr a => Semigroup (Query a) # | |
Projection
type Projection a b = Transpose (Field a) a -> Transpose (Field a) b #
A s is a special type of function Projection a ba -> b whereby the
resulting b is guaranteed to be composed only from columns contained in
a.
class Projectable (f :: Type -> Type) where #
means that Projectable ff is a kind of functor on Tables
that allows the mapping of a Projection over its underlying columns.
Instances
| Projectable Query # | |
Defined in Rel8.Internal.Query Methods project :: Projecting a b => Projection a b -> Query a -> Query b # | |
| Projectable (Tabulation k) Source # | |
Defined in Rel8.Tabulate Methods project :: Projecting a b => Projection a b -> Tabulation k a -> Tabulation k b # | |
| Projectable (ListTable context) # | |
Defined in Rel8.Internal.Table.List Methods project :: Projecting a b => Projection a b -> ListTable context a -> ListTable context b # | |
| Projectable (MaybeTable context) # | |
Defined in Rel8.Internal.Table.Maybe Methods project :: Projecting a b => Projection a b -> MaybeTable context a -> MaybeTable context b # | |
| Projectable (NonEmptyTable context) # | |
Defined in Rel8.Internal.Table.NonEmpty Methods project :: Projecting a b => Projection a b -> NonEmptyTable context a -> NonEmptyTable context b # | |
| Projectable (NullTable context) # | |
Defined in Rel8.Internal.Table.Null Methods project :: Projecting a b => Projection a b -> NullTable context a -> NullTable context b # | |
| Projectable (Nullify context) # | |
Defined in Rel8.Internal.Table.Nullify Methods project :: Projecting a b => Projection a b -> Nullify context a -> Nullify context b # | |
| Projectable (EitherTable context a) # | |
Defined in Rel8.Internal.Table.Either Methods project :: Projecting a0 b => Projection a0 b -> EitherTable context a a0 -> EitherTable context a b # | |
| Projectable (TheseTable context a) # | |
Defined in Rel8.Internal.Table.These Methods project :: Projecting a0 b => Projection a0 b -> TheseTable context a a0 -> TheseTable context a b # | |
class Biprojectable (p :: Type -> Type -> Type) where #
means that Biprojectable pp is a kind of bifunctor on
Tables that allows the mapping of a pair of Projections over its
underlying columns.
Methods
biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> p a c -> p b d #
Map a pair of Projections over p.
Instances
| Biprojectable Tabulation Source # | |
Defined in Rel8.Tabulate Methods biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> Tabulation a c -> Tabulation b d # | |
| Biprojectable (EitherTable context) # | |
Defined in Rel8.Internal.Table.Either Methods biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> EitherTable context a c -> EitherTable context b d # | |
| Biprojectable (TheseTable context) # | |
Defined in Rel8.Internal.Table.These Methods biproject :: (Projecting a b, Projecting c d) => Projection a b -> Projection c d -> TheseTable context a c -> TheseTable context b d # | |
class (Transposes (Context a) (Field a) a (Transpose (Field a) a), Transposes (Context a) (Field a) b (Transpose (Field a) b)) => Projecting a b #
The constraint ensures that Projecting a b is a
usable Projection a bProjection.
Instances
| (Transposes (Context a) (Field a) a (Transpose (Field a) a), Transposes (Context a) (Field a) b (Transpose (Field a) b)) => Projecting a b # | |
Defined in Rel8.Internal.Table.Projection | |
A special context used in the construction of Projections.
Instances
| Reifiable (Field table) # | |||||||||||||
Defined in Rel8.Internal.Kind.Context Methods contextSing :: SContext (Field table) # | |||||||||||||
| Sql DBType a => Table (Field table) (Field table a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Field Associated Types
| |||||||||||||
| type Transpose to (Field table a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Field | |||||||||||||
| type Columns (Field table a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Field | |||||||||||||
| type Context (Field table a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Field | |||||||||||||
| type FromExprs (Field table a) # | |||||||||||||
Defined in Rel8.Internal.Schema.Field | |||||||||||||
Selecting rows
class Transposes Name Expr names exprs => Selects names exprs #
Instances
| Transposes Name Expr names exprs => Selects names exprs # | |
Defined in Rel8.Internal.Schema.Name | |
each :: Selects names exprs => TableSchema names -> Query exprs #
Select each row from a table definition. This is equivalent to FROM
table.
Filtering
where_ :: Expr Bool -> Query () #
Drop any rows that don't match a predicate. where_ expr is equivalent
to the SQL WHERE expr.
present :: Query a -> Query () #
Produce the empty query if the given query returns no rows. present
is equivalent to WHERE EXISTS in SQL.
absent :: Query a -> Query () #
Produce the empty query if the given query returns rows. absent
is equivalent to WHERE NOT EXISTS in SQL.
distinct :: EqTable a => Query a -> Query a #
Select all distinct rows from a query, removing duplicates. distinct q
is equivalent to the SQL statement SELECT DISTINCT q.
distinctOn :: EqTable b => (a -> b) -> Query a -> Query a #
Select all distinct rows from a query, where rows are equivalent according
to a projection. If multiple rows have the same projection, it is
unspecified which row will be returned. If this matters, use distinctOnBy.
distinctOnBy :: EqTable b => (a -> b) -> Order a -> Query a -> Query a #
Select all distinct rows from a query, where rows are equivalent according
to a projection. If there are multiple rows with the same projection, the
first row according to the specified Order will be returned.
LIMIT/OFFSET
limit :: Word -> Query a -> Query a #
limit n select at most n rows from a query. limit n is equivalent
to the SQL LIMIT n.
offset :: Word -> Query a -> Query a #
offset n drops the first n rows from a query. offset n is equivalent
to the SQL OFFSET n.
UNION
union :: EqTable a => Query a -> Query a -> Query a #
Combine the results of two queries of the same type, collapsing
duplicates. union a b is the same as the SQL statement a UNION b.
unionAll :: Table Expr a => Query a -> Query a -> Query a #
Combine the results of two queries of the same type, retaining duplicates.
unionAll a b is the same as the SQL statement a UNION ALL b.
INTERSECT
intersect :: EqTable a => Query a -> Query a -> Query a #
Find the intersection of two queries, collapsing duplicates. intersect a
b is the same as the SQL statement a INTERSECT b.
intersectAll :: EqTable a => Query a -> Query a -> Query a #
Find the intersection of two queries, retaining duplicates. intersectAll
a b is the same as the SQL statement a INTERSECT ALL b.
EXCEPT
except :: EqTable a => Query a -> Query a -> Query a #
Find the difference of two queries, collapsing duplicates except a b is
the same as the SQL statement a EXCEPT b.
exceptAll :: EqTable a => Query a -> Query a -> Query a #
Find the difference of two queries, retaining duplicates. exceptAll a b
is the same as the SQL statement a EXCEPT ALL b.
EXISTS
withBy :: (a -> b -> Expr Bool) -> Query b -> a -> Query a #
Like with, but with a custom membership test.
withoutBy :: (a -> b -> Expr Bool) -> Query b -> a -> Query a #
Like without, but with a custom membership test.
WITH
materialize :: Table Expr a => Query a -> (Query a -> Query b) -> Query b #
materialize takes a Query and fully evaluates it and caches the
results thereof, and passes to a continuation a new Query that simply
looks up these cached results. It's usually best not to use this and to let
the Postgres optimizer decide for itself what's best, but if you know what
you're doing this can sometimes help to nudge it in a particular direction.
materialize is currently implemented in terms of Postgres'
@WITH syntax,
specifically the WITH _ AS MATERIALIZED (_) form introduced in PostgreSQL
12. This means that materialize can only be used with PostgreSQL 12 or
newer.
WITH RECURSIVE
loop :: Table Expr a => Query a -> (a -> Query a) -> Query a #
loop allows the construction of recursive queries, using Postgres'
WITH RECURSIVE
under the hood. The first argument to loop is what the Postgres
documentation refers to as the "non-recursive term" and the second
argument is the "recursive term", which is defined in terms of the result
of the "non-recursive term". loop uses UNION ALL to combine the
recursive and non-recursive terms.
Denotionally, is the smallest set of rows loop s fr such
that
r == s `unionAll` (r >>= f)
Operationally, takes each row in an initial set loop s fs and
supplies it to f, resulting in a new generation of rows which are added
to the result set. Each row from this new generation is then fed back to
f, and this process is repeated until a generation comes along for which
f returns an empty set for each row therein.
loopDistinct :: Table Expr a => Query a -> (a -> Query a) -> Query a #
loopDistinct is like loop but uses UNION instead of UNION ALL to
combine the recursive and non-recursive terms.
Denotationally, is the smallest set of rows
loopDistinct s fr such that
r == s `union` (r >>= f)
Operationally, takes each distinct row in an
initial set loopDistinct s fs and supplies it to f, resulting in a new generation of
rows. Any rows returned by f that already exist in the result set are not
considered part of this new generation by loopDistinct (in contrast to
loop). This new generation is then added to the result set, and each row
therein is then fed back to f, and this process is repeated until a
generation comes along for which f returns no rows that don't already
exist in the result set.
Aggregation
type Aggregator = Aggregator' 'Full #
An Aggregator takes a Query producing a collection of rows of
type a and transforms it into a Query producing a single row of
type b. If the given Query produces an empty collection of rows,
then the single row in the resulting Query contains the identity
values of the aggregation functions comprising the Aggregator (i.e.,
0 for sum, false for or, etc.).
Aggregator is a special form of Aggregator' parameterised by Full.
type Aggregator1 = Aggregator' 'Semi #
An Aggregator1 takes a collection of rows of type a, groups them, and
transforms each group into a single row of type b. This corresponds to
aggregators using GROUP BY in SQL. If given an empty collection of rows,
Aggregator1 will have no groups and will therefore also return an empty
collection of rows.
Aggregator1 is a special form of Aggregator' parameterised by Semi.
data Aggregator' (fold :: Fold) i a #
Aggregator' is the most general form of "aggregator", of which
Aggregator and Aggregator1 are special cases. Aggregator's are
comprised of aggregation functions and/or GROUP BY clauses.
Aggregation functions operating on individual Exprs such as
sum can be combined into Aggregators operating on larger types
using the Applicative, Profunctor and ProductProfunctor interfaces.
Working with Profunctors can sometimes be awkward so for every sum
we also provide a sumOn which bundles an lmap. For
complex aggregations, we recommend using these functions along with
ApplicativeDo, BlockArguments, OverloadedRecordDot and
RecordWildCards:
data Input f = Input
{ orderId :: Column f OrderId
, customerId :: Column f CustomerId
, productId :: Column f ProductId
, quantity :: Column f Int64
, price :: Column f Scientific
}
deriving (Generic, Rel8able)
totalPrice :: Input Expr -> Expr Scientific
totalPrice input = fromIntegral input.quantity * input.price
data Result f = Result
{ customerId :: Column f CustomerId
, totalOrders :: Column f Int64
, productsOrdered :: Column f Int64
, totalPrice :: Column f Scientific
}
deriving (Generic, Rel8able)
allResults :: Query (Result Expr)
allResults =
aggregate
do
customerId <- groupByOn (.customerId)
totalOrders <- countDistinctOn (.orderId)
productsOrdered <- countDistinctOn (.productId)
totalPrice <- sumOn totalPrice
pure Result {..}
do
order <- each orderSchema
orderLine <- each orderLineSchema
where_ $ order.id ==. orderLine.orderId
pure
Input
{ orderId = order.id
, customerId = order.customerId
, productId = orderLine.productId
, quantity = orderLine.quantity
, price = orderLine.price
}
Instances
| ProductProfunctor (Aggregator' fold) # | |
Defined in Rel8.Internal.Aggregate Methods purePP :: b -> Aggregator' fold a b (****) :: Aggregator' fold a (b -> c) -> Aggregator' fold a b -> Aggregator' fold a c empty :: Aggregator' fold () () (***!) :: Aggregator' fold a b -> Aggregator' fold a' b' -> Aggregator' fold (a, a') (b, b') | |
| SumProfunctor (Aggregator' fold) # | |
Defined in Rel8.Internal.Aggregate Methods (+++!) :: Aggregator' fold a b -> Aggregator' fold a' b' -> Aggregator' fold (Either a a') (Either b b') | |
| Profunctor (Aggregator' fold) # | |
Defined in Rel8.Internal.Aggregate Methods dimap :: (a -> b) -> (c -> d) -> Aggregator' fold b c -> Aggregator' fold a d lmap :: (a -> b) -> Aggregator' fold b c -> Aggregator' fold a c rmap :: (b -> c) -> Aggregator' fold a b -> Aggregator' fold a c (#.) :: forall a b c q. Coercible c b => q b c -> Aggregator' fold a b -> Aggregator' fold a c (.#) :: forall a b c q. Coercible b a => Aggregator' fold b c -> q a b -> Aggregator' fold a c | |
| Applicative (Aggregator' fold i) # | |
Defined in Rel8.Internal.Aggregate Methods pure :: a -> Aggregator' fold i a # (<*>) :: Aggregator' fold i (a -> b) -> Aggregator' fold i a -> Aggregator' fold i b # liftA2 :: (a -> b -> c) -> Aggregator' fold i a -> Aggregator' fold i b -> Aggregator' fold i c # (*>) :: Aggregator' fold i a -> Aggregator' fold i b -> Aggregator' fold i b # (<*) :: Aggregator' fold i a -> Aggregator' fold i b -> Aggregator' fold i a # | |
| Functor (Aggregator' fold i) # | |
Defined in Rel8.Internal.Aggregate Methods fmap :: (a -> b) -> Aggregator' fold i a -> Aggregator' fold i b # (<$) :: a -> Aggregator' fold i b -> Aggregator' fold i a # | |
| Apply (Aggregator' fold i) # | |
Defined in Rel8.Internal.Aggregate Methods (<.>) :: Aggregator' fold i (a -> b) -> Aggregator' fold i a -> Aggregator' fold i b (.>) :: Aggregator' fold i a -> Aggregator' fold i b -> Aggregator' fold i b (<.) :: Aggregator' fold i a -> Aggregator' fold i b -> Aggregator' fold i a liftF2 :: (a -> b -> c) -> Aggregator' fold i a -> Aggregator' fold i b -> Aggregator' fold i c | |
Fold is a kind that parameterises aggregations. Aggregations
parameterised by Semi are analogous to foldMap1
(i.e, they can only produce results on a non-empty Query) whereas
aggregations parameterised by Full are analagous to foldMap (given a
non-empty) query, they return the identity values of the aggregation
functions.
toAggregator :: forall a (fold :: Fold) i (fold' :: Fold). a -> Aggregator' fold i a -> Aggregator' fold' i a #
Given a value to fall back on if given an empty collection of rows,
toAggregator turns an Aggregator1 into an Aggregator.
toAggregator1 :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator1 i a #
toAggregator1 turns an Aggregator into an Aggregator1.
aggregate :: (Table Expr i, Table Expr a) => Aggregator i a -> Query i -> Query a #
Apply an Aggregator to all rows returned by a Query. If the Query
is empty, then a single "fallback" row is returned, composed of the
identity elements of the constituent aggregation functions.
aggregate1 :: forall i (fold :: Fold) a. Table Expr i => Aggregator' fold i a -> Query i -> Query a #
Apply an Aggregator1 to all rows returned by a Query. If
the Query is empty, then zero rows are returned.
filterWhere :: forall a i (fold :: Fold). Table Expr a => (i -> Expr Bool) -> Aggregator i a -> Aggregator' fold i a #
filterWhere allows an Aggregator to filter out rows from the input
query before considering them for aggregation. Note that because the
predicate supplied to filterWhere could return false for every
row, filterWhere needs an Aggregator as opposed to an Aggregator1, so
that it can return a default value in such a case. For a variant of
filterWhere that can work with Aggregator1s, see
filterWhereOptional.
filterWhereOptional :: forall a i (fold :: Fold) (fold' :: Fold). Table Expr a => (i -> Expr Bool) -> Aggregator' fold i a -> Aggregator' fold' i (MaybeTable Expr a) #
A variant of filterWhere that can be used with an Aggregator1
(upgrading it to an Aggregator in the process). It returns
nothingTable in the case where the predicate matches zero rows.
distinctAggregate :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator' fold i a #
distinctAggregate modifies an Aggregator to consider only distinct
values of each particular column. Note that this "distinction" only happens
within each column individually, not across all columns simultaneously.
orderAggregateBy :: forall i (fold :: Fold) a. Order i -> Aggregator' fold i a -> Aggregator' fold i a #
Order the values within each aggregation in an Aggregator using the
given ordering. This is only relevant for aggregations that depend on the
order they get their elements, like listAgg and stringAgg.
optionalAggregate :: forall a (fold :: Fold) i (fold' :: Fold). Table Expr a => Aggregator' fold i a -> Aggregator' fold' i (MaybeTable Expr a) #
optionalAggregate upgrades an Aggregator1 into an Aggregator by
having it return nothingTable when aggregating over an empty collection
of rows.
countRows :: Query a -> Query (Expr Int64) #
Count the number of rows returned by a query. Note that this is different
from countStar, as even if the given query yields no rows, countRows
will return 0.
groupBy :: EqTable a => Aggregator1 a a #
Group equal tables together. This works by aggregating each column in the
given table with groupByExpr.
For example, if we have a table of items, we could group the items by the order they belong to:
itemsByOrder :: Query (OrderId Expr, ListTable Expr (Item Expr))
itemsByOrder =
aggregate
do
orderId <- groupByOn (.orderId)
items <- listAgg
pure (orderId, items)
do
each itemSchema
groupByOn :: EqTable a => (i -> a) -> Aggregator1 i a #
Applies groupBy to the columns selected by the given function.
listAgg :: forall a (fold :: Fold). Table Expr a => Aggregator' fold a (ListTable Expr a) #
Aggregate rows into a single row containing an array of all aggregated rows. This can be used to associate multiple rows with a single row, without changing the over cardinality of the query. This allows you to essentially return a tree-like structure from queries.
For example, if we have a table of orders and each orders contains multiple items, we could aggregate the table of orders, pairing each order with its items:
ordersWithItems :: Query (Order Expr, ListTable Expr (Item Expr)) ordersWithItems = do order <- each orderSchema items <- aggregate listAgg (itemsFromOrder order) return (order, items)
listAggOn :: forall a i (fold :: Fold). Table Expr a => (i -> a) -> Aggregator' fold i (ListTable Expr a) #
Applies listAgg to the columns selected by the given function.
listAggExpr :: forall a (fold :: Fold). Sql DBType a => Aggregator' fold (Expr a) (Expr [a]) #
Collect expressions values as a list.
listAggExprOn :: forall a i (fold :: Fold). Sql DBType a => (i -> Expr a) -> Aggregator' fold i (Expr [a]) #
Applies listAggExpr to the column selected by the given function.
listCat :: forall a (fold :: Fold). Table Expr a => Aggregator' fold (ListTable Expr a) (ListTable Expr a) #
Concatenate lists into a single list.
listCatOn :: forall a i (fold :: Fold). Table Expr a => (i -> ListTable Expr a) -> Aggregator' fold i (ListTable Expr a) #
Applies listCat to the list selected by the given function.
listCatExpr :: forall a (fold :: Fold). Sql DBType a => Aggregator' fold (Expr [a]) (Expr [a]) #
Concatenate lists into a single list.
listCatExprOn :: forall a i (fold :: Fold). Sql DBType a => (i -> Expr [a]) -> Aggregator' fold i (Expr [a]) #
Applies listCatExpr to the column selected by the given function.
nonEmptyAgg :: Table Expr a => Aggregator1 a (NonEmptyTable Expr a) #
Like listAgg, but the result is guaranteed to be a non-empty list.
nonEmptyAggOn :: Table Expr a => (i -> a) -> Aggregator1 i (NonEmptyTable Expr a) #
Applies nonEmptyAgg to the columns selected by the given function.
nonEmptyAggExpr :: Sql DBType a => Aggregator1 (Expr a) (Expr (NonEmpty a)) #
Collect expressions values as a non-empty list.
nonEmptyAggExprOn :: Sql DBType a => (i -> Expr a) -> Aggregator1 i (Expr (NonEmpty a)) #
Applies nonEmptyAggExpr to the column selected by the given function.
nonEmptyCat :: Table Expr a => Aggregator1 (NonEmptyTable Expr a) (NonEmptyTable Expr a) #
Concatenate non-empty lists into a single non-empty list.
nonEmptyCatOn :: Table Expr a => (i -> NonEmptyTable Expr a) -> Aggregator1 i (NonEmptyTable Expr a) #
Applies nonEmptyCat to the non-empty list selected by the given
function.
nonEmptyCatExpr :: Sql DBType a => Aggregator1 (Expr (NonEmpty a)) (Expr (NonEmpty a)) #
Concatenate non-empty lists into a single non-empty list.
nonEmptyCatExprOn :: Sql DBType a => (i -> Expr (NonEmpty a)) -> Aggregator1 i (Expr (NonEmpty a)) #
Applies nonEmptyCatExpr to the column selected by the given function.
The class of database types that support the max aggregation function.
Instances
| DBMax ByteString # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax ByteString # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Int16 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Int32 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Int64 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Scientific # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Text # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Text # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Day # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax UTCTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax LocalTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax TimeOfDay # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Char # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Double # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax Float # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax (CI Text) # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMax (CI Text) # | |
Defined in Rel8.Internal.Type.Ord | |
| Sql DBMax a => DBMax (NonEmpty a) # | |
Defined in Rel8.Internal.Type.Ord | |
| (DBComposite a, OrdTable (HKD a Expr)) => DBMax (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| DBEnum a => DBMax (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| Sql DBMax a => DBMax [a] # | |
Defined in Rel8.Internal.Type.Ord | |
| PowerOf10 n => DBMax (Fixed n) # | |
Defined in Rel8.Internal.Type.Ord | |
max :: Sql DBMax a => Aggregator1 (Expr a) (Expr a) #
Produce an aggregation for Expr a using the max function.
maxOn :: Sql DBMax a => (i -> Expr a) -> Aggregator1 i (Expr a) #
Applies max to the column selected by the given function.
The class of database types that support the min aggregation function.
Instances
| DBMin ByteString # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin ByteString # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Int16 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Int32 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Int64 # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Scientific # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Text # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Text # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Day # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin UTCTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin LocalTime # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin TimeOfDay # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Char # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Double # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin Float # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin (CI Text) # | |
Defined in Rel8.Internal.Type.Ord | |
| DBMin (CI Text) # | |
Defined in Rel8.Internal.Type.Ord | |
| Sql DBMin a => DBMin (NonEmpty a) # | |
Defined in Rel8.Internal.Type.Ord | |
| (DBComposite a, OrdTable (HKD a Expr)) => DBMin (Composite a) # | |
Defined in Rel8.Internal.Type.Composite | |
| DBEnum a => DBMin (Enum a) # | |
Defined in Rel8.Internal.Type.Enum | |
| Sql DBMin a => DBMin [a] # | |
Defined in Rel8.Internal.Type.Ord | |
| PowerOf10 n => DBMin (Fixed n) # | |
Defined in Rel8.Internal.Type.Ord | |
min :: Sql DBMin a => Aggregator1 (Expr a) (Expr a) #
Produce an aggregation for Expr a using the min function.
minOn :: Sql DBMin a => (i -> Expr a) -> Aggregator1 i (Expr a) #
Applies min to the column selected by the given function.
The class of database types that support the sum() aggregation function.
Instances
| DBSum Int16 # | |
Defined in Rel8.Internal.Type.Sum | |
| DBSum Int32 # | |
Defined in Rel8.Internal.Type.Sum | |
| DBSum Int64 # | |
Defined in Rel8.Internal.Type.Sum | |
| DBSum Scientific # | |
Defined in Rel8.Internal.Type.Sum | |
| DBSum CalendarDiffTime # | |
Defined in Rel8.Internal.Type.Sum | |
| DBSum Double # | |
Defined in Rel8.Internal.Type.Sum | |
| DBSum Float # | |
Defined in Rel8.Internal.Type.Sum | |
| PowerOf10 n => DBSum (Fixed n) # | |
Defined in Rel8.Internal.Type.Sum | |
sum :: forall a (fold :: Fold). (Sql DBNum a, Sql DBSum a) => Aggregator' fold (Expr a) (Expr a) #
Corresponds to sum. Note that in SQL, sum is type changing - for
example the sum of integer returns a bigint. Rel8 doesn't support
this, and will add explicit casts back to the original input type. This can
lead to overflows, and if you anticipate very large sums, you should upcast
your input.
sumOn :: forall a i (fold :: Fold). (Sql DBNum a, Sql DBSum a) => (i -> Expr a) -> Aggregator' fold i (Expr a) #
Applies sum to the column selected by the given fucntion.
sumWhere :: forall a i (fold :: Fold). (Sql DBNum a, Sql DBSum a) => (i -> Expr Bool) -> (i -> Expr a) -> Aggregator' fold i (Expr a) #
sumWhere is a combination of filterWhere and sumOn.
avg :: Sql DBSum a => Aggregator1 (Expr a) (Expr a) #
Corresponds to avg. Note that in SQL, avg is type changing - for
example, the avg of integer returns a numeric. Rel8 doesn't support
this, and will add explicit casts back to the original input type. If you
need a fractional result on an integral column, you should cast your input
to Double or Scientific before calling avg.
avgOn :: Sql DBSum a => (i -> Expr a) -> Aggregator1 i (Expr a) #
Applies avg to the column selected by the given fucntion.
class DBType a => DBString a #
The class of data types that support the string_agg() aggregation
function.
Instances
| DBString ByteString # | |
Defined in Rel8.Internal.Type.String | |
| DBString ByteString # | |
Defined in Rel8.Internal.Type.String | |
| DBString Text # | |
Defined in Rel8.Internal.Type.String | |
| DBString Text # | |
Defined in Rel8.Internal.Type.String | |
| DBString (CI Text) # | |
Defined in Rel8.Internal.Type.String | |
| DBString (CI Text) # | |
Defined in Rel8.Internal.Type.String | |
stringAgg :: forall a (fold :: Fold). (Sql IsString a, Sql DBString a) => Expr a -> Aggregator' fold (Expr a) (Expr a) #
Corresponds to string_agg().
count :: forall (fold :: Fold) a. Aggregator' fold (Expr a) (Expr Int64) #
Count the occurances of a single column. Corresponds to COUNT(a)
countOn :: forall i a (fold :: Fold). (i -> Expr a) -> Aggregator' fold i (Expr Int64) #
Applies count to the column selected by the given function.
countDistinct :: forall a (fold :: Fold). Sql DBEq a => Aggregator' fold (Expr a) (Expr Int64) #
Count the number of distinct occurrences of a single column. Corresponds to
COUNT(DISTINCT a)
countDistinctOn :: forall a i (fold :: Fold). Sql DBEq a => (i -> Expr a) -> Aggregator' fold i (Expr Int64) #
Applies countDistinct to the column selected by the given function.
countWhere :: forall (fold :: Fold). Aggregator' fold (Expr Bool) (Expr Int64) #
A count of the number of times a given expression is true.
countWhereOn :: forall i (fold :: Fold). (i -> Expr Bool) -> Aggregator' fold i (Expr Int64) #
Applies countWhere to the column selected by the given function.
andOn :: forall i (fold :: Fold). (i -> Expr Bool) -> Aggregator' fold i (Expr Bool) #
Applies and to the column selected by the given function.
orOn :: forall i (fold :: Fold). (i -> Expr Bool) -> Aggregator' fold i (Expr Bool) #
Applies or to the column selected by the given function.
aggregateFunction :: (Table Expr i, Sql DBType a) => QualifiedName -> Aggregator1 i (Expr a) #
aggregateFunction allows the use use of custom aggregation functions
or PostgreSQL aggregation functions which are not otherwise supported by
Rel8.
rawAggregateFunction :: Table Expr i => QualifiedName -> Aggregator1 i (Expr a) #
mode :: Sql DBOrd a => Aggregator1 (Expr a) (Expr a) #
Corresponds to mode() WITHIN GROUP (ORDER BY _).
modeOn :: Sql DBOrd a => (i -> Expr a) -> Aggregator1 i (Expr a) #
Applies mode to the column selected by the given function.
percentile :: Sql DBOrd a => Expr Double -> Aggregator1 (Expr a) (Expr a) #
Corresponds to percentile_disc(_) WITHIN GROUP (ORDER BY _).
percentileOn :: Sql DBOrd a => Expr Double -> (i -> Expr a) -> Aggregator1 i (Expr a) #
Applies percentile to the column selected by the given function.
percentileContinuous :: Sql DBFractional a => Expr Double -> Aggregator1 (Expr a) (Expr a) #
Corresponds to percentile_cont(_) WITHIN GROUP (ORDER BY _).
percentileContinuousOn :: Sql DBFractional a => Expr Double -> (i -> Expr a) -> Aggregator1 i (Expr a) #
Applies percentileContinuous to the column selected by the given
function.
hypotheticalRank :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Int64) #
Corresponds to rank(_) WITHIN GROUP (ORDER BY _).
hypotheticalDenseRank :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Int64) #
Corresponds to dense_rank(_) WITHIN GROUP (ORDER BY _).
hypotheticalPercentRank :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Double) #
Corresponds to percent_rank(_) WITHIN GROUP (ORDER BY _).
hypotheticalCumeDist :: forall a (fold :: Fold). Order a -> a -> Aggregator' fold a (Expr Double) #
Corresponds to cume_dist(_) WITHIN GROUP (ORDER BY _).
Ordering
An ordering expression for a. Primitive orderings are defined with
asc and desc, and you can combine Order via its various
instances.
A common pattern is to use <> to combine multiple orderings in sequence,
and >$< to select individual columns.
nullsFirst :: Order (Expr a) -> Order (Expr (Maybe a)) #
Transform an ordering so that null values appear first. This corresponds
to NULLS FIRST in SQL.
nullsLast :: Order (Expr a) -> Order (Expr (Maybe a)) #
Transform an ordering so that null values appear last. This corresponds
to NULLS LAST in SQL.
Window functions
Window is an applicative functor that represents expressions that
contain
window functions.
window can be used to
evaluate these expressions over a particular query.
Instances
| ProductProfunctor Window # | |
| Profunctor Window # | |
Defined in Rel8.Internal.Window Methods dimap :: (a -> b) -> (c -> d) -> Window b c -> Window a d lmap :: (a -> b) -> Window b c -> Window a c rmap :: (b -> c) -> Window a b -> Window a c (#.) :: forall a b c q. Coercible c b => q b c -> Window a b -> Window a c (.#) :: forall a b c q. Coercible b a => Window b c -> q a b -> Window a c | |
| Applicative (Window a) # | |
| Functor (Window a) # | |
| Apply (Window a) # | |
window :: Window a b -> Query a -> Query b #
window runs a query composed of expressions containing
window functions.
window is similar to aggregate, with the main difference being
that in a window query, each input row corresponds to one output row,
whereas aggregation queries fold the entire input query down into a single
row. To put this into a Haskell context, aggregate is to foldl as
window is to scanl.
In PostgreSQL, window functions must specify the "window" or
"partition" over which they operate. The syntax for this looks like:
SUM(salary) OVER (PARTITION BY department). The Rel8 type Partition
represents everything that comes after OVER.
Partition is a Monoid, so Windows created with partitionBy and
orderWindowBy can be combined using <>.
over :: Window a b -> Partition a -> Window a b infixl 1 #
over adds a Partition to a Window expression.
cumulative(sum. salary)overpartitionBydepartment <>orderPartitionBy(salary >$<desc)
partitionBy :: EqTable b => (a -> b) -> Partition a #
Restricts a window function to operate only the group of rows that share the same value(s) for the given expression(s).
orderPartitionBy :: Order a -> Partition a #
Controls the order in which rows are processed by window functions. This does not need to match the ordering of the overall query.
cumulative :: forall (fold :: Fold) i a. Aggregator' fold i a -> Window i a #
cumulative allows the use of aggregation functions in Window
expressions. In particular,
(when combined with cumulative sumorderPartitionBy) gives a running total,
also known as a "cumulative sum", hence the name cumulative.
currentRow :: Window a a #
Return every column of the current row of a window query.
percentRank :: Window i (Expr Double) #
lag :: Table Expr a => Expr Int32 -> Window a (MaybeTable Expr a) #
returns the row lag nn rows before the current row in a given
window. Returns nothingTable if n is out of bounds.
lagOn :: Table Expr a => Expr Int32 -> (i -> a) -> Window i (MaybeTable Expr a) #
Applies lag to the columns selected by the given function.
lead :: Table Expr a => Expr Int32 -> Window a (MaybeTable Expr a) #
returns the row lead nn rows after the current row in a given
window. Returns nothingTable if n is out of bounds.
leadOn :: Table Expr a => Expr Int32 -> (i -> a) -> Window i (MaybeTable Expr a) #
Applies lead to the columns selected by the given function.
firstValue :: Table Expr a => Window a a #
firstValue returns the first row of the window of the current row.
firstValueOn :: Table Expr a => (i -> a) -> Window i a #
Applies firstValue to the columns selected by the given function.
lastValue :: Table Expr a => Window a a #
lastValue returns the first row of the window of the current row.
lastValueOn :: Table Expr a => (i -> a) -> Window i a #
Applies lastValue to the columns selected by the given function.
nthValue :: Table Expr a => Expr Int32 -> Window a (MaybeTable Expr a) #
returns the nthValue nnth row of the window of the current row.
Returns nothingTable if n is out of bounds.
nthValueOn :: Table Expr a => Expr Int32 -> (i -> a) -> Window i (MaybeTable Expr a) #
Applies nthValue to the columns selected by the given function.
indexed :: Query a -> Query (Expr Int64, a) #
Pair each row of a query with its index within the query.
Bindings
rebind :: Table Expr a => String -> a -> Query a #
rebind takes a variable name, some expressions, and binds each of them
to a new variable in the SQL. The a returned consists only of these
variables. It's essentially a let binding for Postgres expressions.
IO
class (ToExprs exprs a, a ~ FromExprs exprs) => Serializable exprs a | exprs -> a #
Serializable witnesses the one-to-one correspondence between the type
sql, which contains SQL expressions, and the type haskell, which
contains the Haskell decoding of rows containing sql SQL expressions.
Instances
| (ToExprs exprs a, a ~ FromExprs exprs) => Serializable exprs a # | |
Defined in Rel8.Internal.Table.Serialize | |
| Sql DBType a => Serializable (Expr a) a # | |
Defined in Rel8.Internal.Table.Serialize | |
class Table Expr exprs => ToExprs exprs a #
ToExprs exprs a is evidence that the types exprs and a describe
essentially the same type, but exprs is in the Expr context, and a is
a normal Haskell type.
Instances
| (Sql DBType a, x ~ Expr a) => ToExprs x a # | |
Defined in Rel8.Internal.Table.Serialize | |
| (Rel8able t', t' ~ Choose (Algebra t) t, x ~ t' Expr, result ~ Result) => ToExprs x (t result) # | |
Defined in Rel8.Internal.Table.Rel8able | |
| (ToExprs exprs1 a, ToExprs exprs2 b, x ~ EitherTable Expr exprs1 exprs2) => ToExprs x (Either a b) # | |
Defined in Rel8.Internal.Table.Either | |
| (ToExprs exprs1 a, ToExprs exprs2 b, x ~ TheseTable Expr exprs1 exprs2) => ToExprs x (These a b) # | |
Defined in Rel8.Internal.Table.These | |
| (ToExprs exprs1 a, ToExprs exprs2 b, x ~ (exprs1, exprs2)) => ToExprs x (a, b) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (ToExprs exprs1 a, ToExprs exprs2 b, ToExprs exprs3 c, x ~ (exprs1, exprs2, exprs3)) => ToExprs x (a, b, c) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (ToExprs exprs1 a, ToExprs exprs2 b, ToExprs exprs3 c, ToExprs exprs4 d, x ~ (exprs1, exprs2, exprs3, exprs4)) => ToExprs x (a, b, c, d) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (ToExprs exprs1 a, ToExprs exprs2 b, ToExprs exprs3 c, ToExprs exprs4 d, ToExprs exprs5 e, x ~ (exprs1, exprs2, exprs3, exprs4, exprs5)) => ToExprs x (a, b, c, d, e) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (ToExprs exprs1 a, ToExprs exprs2 b, ToExprs exprs3 c, ToExprs exprs4 d, ToExprs exprs5 e, ToExprs exprs6 f, x ~ (exprs1, exprs2, exprs3, exprs4, exprs5, exprs6)) => ToExprs x (a, b, c, d, e, f) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (ToExprs exprs1 a, ToExprs exprs2 b, ToExprs exprs3 c, ToExprs exprs4 d, ToExprs exprs5 e, ToExprs exprs6 f, ToExprs exprs7 g, x ~ (exprs1, exprs2, exprs3, exprs4, exprs5, exprs6, exprs7)) => ToExprs x (a, b, c, d, e, f, g) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (Sql DBType a, NotNull a, x ~ NonEmpty a) => ToExprs (Expr x) (NonEmpty a) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (Sql DBType a, NotNull a, x ~ Maybe a) => ToExprs (Expr x) (Maybe a) # | |
Defined in Rel8.Internal.Table.Serialize | |
| (Sql DBType a, x ~ [a]) => ToExprs (Expr x) [a] # | |
Defined in Rel8.Internal.Table.Serialize | |
| (ToExprs exprs a, context ~ Expr) => ToExprs (ListTable context exprs) [a] # | |
Defined in Rel8.Internal.Table.List | |
| (ToExprs exprs a, context ~ Expr) => ToExprs (MaybeTable context exprs) (Maybe a) # | |
Defined in Rel8.Internal.Table.Maybe | |
| (ToExprs exprs a, context ~ Expr) => ToExprs (NonEmptyTable context exprs) (NonEmpty a) # | |
Defined in Rel8.Internal.Table.NonEmpty | |
| (ToExprs exprs a, context ~ Expr) => ToExprs (NullTable context exprs) (Maybe a) # | |
Defined in Rel8.Internal.Table.Null | |
The Result context is the context used for decoded query results.
When a query is executed against a PostgreSQL database, Rel8 parses the
returned rows, decoding each row into the Result context.
Running statements
To run queries and otherwise interact with a PostgreSQL database, Rel8
provides the run functions. These produce a Statements
which can be passed to statement to execute the statement
against a PostgreSQL Connection.
run takes a Statement, which can be constructed using either select,
insert, update or delete. It decodes the rows returned by the
statement as a list of Haskell of values. See run_, runN, run1,
runMaybe and runVector for other variations.
Note that constructing an Insert, Update or Delete will require the
DisambiguateRecordFields language extension to be enabled.
prepared :: forall a b i o. Serializable a i => (Statement b -> Statement () o) -> (a -> Statement b) -> Statement i o #
Given a run function that converts a Statement to a
Statement, return a run-like function which instead takes a
parameterized Statement and converts it to a preparable
Statement.
The parameters i are sent to the database directly via PostgreSQL's binary
format. For large amounts of data this can be significantly more efficient
than embedding the values in the statement with lit.
SELECT
INSERT
The constituent parts of a SQL INSERT statement.
Constructors
| Insert | |
Fields
| |
data OnConflict exprs #
OnConflict represents the ON CONFLICT clause of an INSERT
statement. This specifies what ought to happen when one or more of the
rows proposed for insertion conflict with an existing row in the table.
Constructors
| Abort | Abort the transaction if there are conflicting rows (Postgres' default) |
| DoNothing (Maybe (Conflict exprs)) |
|
| DoUpdate (Upsert exprs) | ON CONFLICT (...) DO UPDATE ... |
Represents what PostgreSQL calls a
conflict_target
in an ON CONFLICT clause of an INSERT statement.
Constructors
| OnConstraint String | Use a specific named constraint for the conflict target. This
corresponds the the syntax |
| OnIndex (Index exprs) | Have PostgreSQL perform what it calls _unique index inference_ by giving it a description of the target index. |
A description of the target unique index — its columns (and/or expressions) and, in the case of partial indexes, a predicate.
The ON CONFLICT (...) DO UPDATE clause of an INSERT statement, also
known as "upsert".
When an existing row conflicts with a row proposed for insertion,
ON CONFLICT DO UPDATE allows you to instead update this existing row. The
conflicting row proposed for insertion is then "excluded", but its values
can still be referenced from the SET and WHERE clauses of the UPDATE
statement.
Upsert in Postgres a "conflict target" to be specified — this is the
UNIQUE index from conflicts with which we would like to recover. Indexes
are specified by listing the columns that comprise them along with an
optional predicate in the case of partial indexes.
Constructors
| Upsert | |
unsafeDefault :: Expr a #
Corresponds to the SQL DEFAULT expression.
This Expr is unsafe for numerous reasons, and should be used with care:
- This
Expronly makes sense in anINSERTorUPDATEstatement. - Rel8 is not able to verify that a particular column actually has a
DEFAULTvalue. Trying to useunsafeDefaultwhere there is no default will cause a runtime crash DEFAULTvalues cannot be transformed. For example, the innocuous Rel8 codeunsafeDefault + 1will crash, despite type checking.
Also note, PostgreSQL's syntax rules mean that DEFAULT can only appear in
INSERT expressions whose rows are specified using VALUES. This means
that if the rows field of your Insert record doesn't look like
values [..], then unsafeDefault won't work.
Given all these caveats, we suggest avoiding the use of default values where
possible, instead being explicit. A common scenario where default values are
used is with auto-incrementing identifier columns. In this case, we suggest
using nextval instead.
DELETE
The constituent parts of a DELETE statement.
Constructors
| Delete | |
Fields
| |
UPDATE
The constituent parts of an UPDATE statement.
Constructors
| Update | |
Fields
| |
.. RETURNING
data Returning names a where #
Constructors
| NoReturning :: forall names. Returning names () | No |
| Returning :: forall names exprs a1. (Selects names exprs, Table Expr a1) => (exprs -> a1) -> Returning names (Query a1) |
|
WITH
Statement represents a single PostgreSQL statement. Most commonly,
this is constructed using select, insert, update
or delete.
However, in addition to SELECT, INSERT, UPDATE and DELETE,
PostgreSQL also supports compositions thereof via its statement-level
WITH syntax (with some caveats). Each such "sub-statement" can
reference the results of previous sub-statements. Statement provides a
Monad instance that captures this "binding" pattern.
The caveat with this is that the side-effects of these sub-statements
are not visible to other sub-statements;
only the explicit results of previous sub-statements (from SELECTs or
RETURNING clauses) are visible. So, for example, an INSERT into a table
followed immediately by a SELECT therefrom will not return the inserted
rows. However, it is possible to return the inserted rows using
RETURNING, unionAlling this with the result of a SELECT
from the same table will produce the desired result.
An example of where this can be useful is if you want to delete rows from a table and simultaneously log their deletion in a log table.
deleteFoo :: (Foo Expr -> Expr Bool) -> Statement ()
deleteFoo predicate = do
foos <-
delete Delete
{ from = fooSchema
, using = pure ()
, deleteWhere = \_ -> predicate
, returning = Returning id
}
insert Insert
{ into = deletedFooSchema
, rows = do
Foo {..} <- foos
let
deletedAt = now
pure DeletedFoo {..}
, onConflict = Abort
, returning = NoReturning
}
showStatement :: Statement a -> String #
CREATE VIEW
createView :: Selects names exprs => TableSchema names -> Query exprs -> Statement () () #
Given a TableSchema and Query, createView runs a CREATE VIEW
statement that will save the given query as a view. This can be useful if
you want to share Rel8 queries with other applications.
createOrReplaceView :: Selects names exprs => TableSchema names -> Query exprs -> Statement () () #
Given a TableSchema and Query, createOrReplaceView runs a
CREATE OR REPLACE VIEW statement that will save the given query
as a view, replacing the current view definition if it exists and
adheres to the restrictions in place for replacing a view in
PostgreSQL.
Sequences
nextval :: QualifiedName -> Expr Int64 #