-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Squeal PostgreSQL Library -- -- Squeal is a type-safe embedding of PostgreSQL in Haskell @package squeal-postgresql @version 0.1.1.4 -- | Pretty print helper functions. module Squeal.PostgreSQL.Prettyprint -- | Parenthesize a ByteString. parenthesized :: ByteString -> ByteString -- | Concatenate two ByteStrings with a space between. (<+>) :: ByteString -> ByteString -> ByteString -- | Comma separate a list of ByteStrings. commaSeparated :: [ByteString] -> ByteString -- | Comma separate the renderings of a heterogeneous list. renderCommaSeparated :: SListI xs => (forall x. expression x -> ByteString) -> NP expression xs -> ByteString -- | Comma separate the Maybe renderings of a heterogeneous list, -- dropping Nothings. renderCommaSeparatedMaybe :: SListI xs => (forall x. expression x -> Maybe ByteString) -> NP expression xs -> ByteString -- | Render a promoted Nat. renderNat :: KnownNat n => proxy n -> ByteString -- | Embedding of PostgreSQL type and alias system module Squeal.PostgreSQL.Schema -- | PGType is the promoted datakind of PostgreSQL types. data PGType -- | logical Boolean (true/false) PGbool :: PGType -- | signed two-byte integer PGint2 :: PGType -- | signed four-byte integer PGint4 :: PGType -- | signed eight-byte integer PGint8 :: PGType -- | arbitrary precision numeric type PGnumeric :: PGType -- | single precision floating-point number (4 bytes) PGfloat4 :: PGType -- | double precision floating-point number (8 bytes) PGfloat8 :: PGType -- | fixed-length character string PGchar :: Nat -> PGType -- | variable-length character string PGvarchar :: Nat -> PGType -- | variable-length character string PGtext :: PGType -- | binary data ("byte array") PGbytea :: PGType -- | date and time (no time zone) PGtimestamp :: PGType -- | date and time, including time zone PGtimestamptz :: PGType -- | calendar date (year, month, day) PGdate :: PGType -- | time of day (no time zone) PGtime :: PGType -- | time of day, including time zone PGtimetz :: PGType -- | time span PGinterval :: PGType -- | universally unique identifier PGuuid :: PGType -- | IPv4 or IPv6 host address PGinet :: PGType -- | textual JSON data PGjson :: PGType -- | binary JSON data, decomposed PGjsonb :: PGType -- | an escape hatch for unsupported PostgreSQL types UnsafePGType :: Symbol -> PGType -- | NullityType encodes the potential presence or definite absence -- of a NULL allowing operations which are sensitive to such to -- be well typed. data NullityType -- | NULL may be present Null :: PGType -> NullityType -- | NULL is absent NotNull :: PGType -> NullityType -- | ColumnType encodes the allowance of DEFAULT and the -- only way to generate an Optional Expression is to use -- def, unDef or param. data ColumnType -- | DEFAULT is allowed Optional :: NullityType -> ColumnType -- | DEFAULT is not allowed Required :: NullityType -> ColumnType -- | ColumnsType is a kind synonym for a row of ColumnTypes. type ColumnsType = [(Symbol, ColumnType)] -- | TablesType is a kind synonym for a row of ColumnsTypes. -- It is used as a kind for both a schema, a disjoint union of tables, -- and a joined table FromClause, a product of tables. type TablesType = [(Symbol, ColumnsType)] -- | Grouping is an auxiliary namespace, created by GROUP -- BY clauses (group), and used for typesafe aggregation data Grouping Ungrouped :: Grouping Grouped :: [(Symbol, Symbol)] -> Grouping -- | PGNum is a constraint on PGType whose Expressions -- have a Num constraint. type PGNum ty = In ty '[ 'PGint2, 'PGint4, 'PGint8, 'PGnumeric, 'PGfloat4, 'PGfloat8] -- | PGIntegral is a constraint on PGType whose -- Expressions have div_ and mod_ functions. type PGIntegral ty = In ty '[ 'PGint2, 'PGint4, 'PGint8] -- | PGFloating is a constraint on PGType whose -- Expressions have Fractional and Floating -- constraints. type PGFloating ty = In ty '[ 'PGfloat4, 'PGfloat8, 'PGnumeric] -- | ::: is like a promoted version of As, a type level pair -- between an alias and some type, usually a column alias and a -- ColumnType or a table alias and a ColumnsType. type (:::) (alias :: Symbol) (ty :: polykind) = '(alias, ty) -- | Aliases are proxies for a type level string or Symbol -- and have an IsLabel instance so that with -- -XOverloadedLabels -- --
--   >>> :set -XOverloadedLabels
--   
--   >>> #foobar :: Alias "foobar"
--   Alias
--   
data Alias (alias :: Symbol) Alias :: Alias -- |
--   >>> renderAlias #alias
--   "alias"
--   
renderAlias :: KnownSymbol alias => Alias alias -> ByteString -- | The As operator is used to name an expression. As is -- like a demoted version of :::. -- --
--   >>> Just "hello" `As` #hi :: Aliased Maybe ("hi" ::: String)
--   As (Just "hello") Alias
--   
data Aliased expression aliased [As] :: KnownSymbol alias => expression ty -> Alias alias -> Aliased expression (alias ::: ty) -- |
--   >>> let renderMaybe = fromString . maybe "Nothing" (const "Just")
--   
--   >>> renderAliased renderMaybe (Just (3::Int) `As` #an_int)
--   "Just AS an_int"
--   
renderAliased :: (forall ty. expression ty -> ByteString) -> Aliased expression aliased -> ByteString class IsLabel (x :: Symbol) a fromLabel :: IsLabel x a => a -- | Analagous to IsLabel, the constraint IsTableColumn -- defines ! for a column alias qualified by a table alias. class IsTableColumn table column expression (!) :: IsTableColumn table column expression => Alias table -> Alias column -> expression -- | In x xs is a constraint that proves that x is in -- xs. -- | HasUnique alias xs x is a constraint that proves that -- xs is a singleton of alias ::: x. type HasUnique alias xs x = xs ~ '[alias ::: x] -- | BaseType forgets about NULL and DEFAULT -- | SameTypes is a constraint that proves two ColumnsTypes -- have the same length and the same ColumnTypes. -- | AllNotNull is a constraint that proves a ColumnsType has -- no NULLs. -- | NotAllNull is a constraint that proves a ColumnsType has -- some NOT NULL. -- | NullifyType is an idempotent that nullifies a -- ColumnType. -- | NullifyColumns is an idempotent that nullifies a -- ColumnsType. -- | NullifyTables is an idempotent that nullifies a -- TablesType used to nullify the left or right hand side of an -- outer join in a FromClause. -- | Join is simply promoted ++ and is used in JOINs -- in FromClauses. -- | Create alias x xs adds alias ::: x to the end of -- xs and is used in createTable statements and in -- ALTER TABLE addColumnDefault and addColumnNull -- statements. -- | Drop alias xs removes the type associated with alias -- in xs and is used in dropTable statements and in -- ALTER TABLE dropColumn statements. -- | Alter alias xs x replaces the type associated with an -- alias in xs with the type x and is used in -- alterTable and alterColumn. -- | Rename alias0 alias1 xs replaces the alias alias0 by -- alias1 in xs and is used in alterTableRename -- and renameColumn. -- | A SameField constraint is an equality constraint on a -- FieldInfo and the column alias in a ::: pair. class SameField (fieldInfo :: FieldInfo) (fieldty :: (Symbol, ColumnType)) -- | A SameFields constraint proves that a DatatypeInfo of a -- record type has the same field names as the column aliases of a -- ColumnsType. instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Schema.Alias alias) instance GHC.Show.Show (Squeal.PostgreSQL.Schema.Alias alias) instance GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Alias alias) instance GHC.Generics.Generic (Squeal.PostgreSQL.Schema.Alias alias) instance GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Alias alias) instance forall polykind (expression :: polykind -> *) (ty :: polykind) (alias :: GHC.Types.Symbol). GHC.Show.Show (expression ty) => GHC.Show.Show (Squeal.PostgreSQL.Schema.Aliased polykind expression ((Squeal.PostgreSQL.Schema.:::) polykind alias ty)) instance forall polykind (expression :: polykind -> *) (ty :: polykind) (alias :: GHC.Types.Symbol). GHC.Classes.Eq (expression ty) => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Aliased polykind expression ((Squeal.PostgreSQL.Schema.:::) polykind alias ty)) instance forall polykind (expression :: polykind -> *) (ty :: polykind) (alias :: GHC.Types.Symbol). GHC.Classes.Ord (expression ty) => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Aliased polykind expression ((Squeal.PostgreSQL.Schema.:::) polykind alias ty)) instance field ~ column => Squeal.PostgreSQL.Schema.SameField ('Generics.SOP.Type.Metadata.FieldInfo field) ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column ty) instance Squeal.PostgreSQL.Schema.IsTableColumn table column (Squeal.PostgreSQL.Schema.Alias table, Squeal.PostgreSQL.Schema.Alias column) instance alias1 ~ alias2 => GHC.OverloadedLabels.IsLabel alias1 (Squeal.PostgreSQL.Schema.Alias alias2) -- | Squeal expressions are the atoms used to build statements. module Squeal.PostgreSQL.Expression -- | Expressions are used in a variety of contexts, such as in the -- target list of the select command, as new column values in -- insertInto or update, or in search Conditions -- in a number of commands. -- -- The expression syntax allows the calculation of values from primitive -- expression using arithmetic, logical, and other operations. newtype Expression (tables :: TablesType) (grouping :: Grouping) (params :: [ColumnType]) (ty :: ColumnType) UnsafeExpression :: ByteString -> Expression [renderExpression] :: Expression -> ByteString -- | A HasParameter constraint is used to indicate a value that is -- supplied externally to a SQL statement. manipulateParams, -- queryParams and traversePrepared support specifying data -- values separately from the SQL command string, in which case -- params are used to refer to the out-of-line data values. class (PGTyped (BaseType ty), KnownNat n) => HasParameter (n :: Nat) params ty | n params -> ty param :: HasParameter n params ty => Expression tables grouping params ty -- | A HasColumn constraint indicates an unqualified column -- reference. getColumn can only be unambiguous when the -- TableExpression the column references is unique, in which -- case the column may be referenced using -XOverloadedLabels. -- Otherwise, combined with a HasTable constraint, the qualified -- column reference operator ! may be used. class KnownSymbol column => HasColumn column columns ty | column columns -> ty getColumn :: (HasColumn column columns ty, HasUnique table tables columns) => Alias column -> Expression tables 'Ungrouped params ty -- | A Column is a witness to a HasColumn constraint. It's -- used in unique and other TableConstraints to witness a -- subcolumns relationship. data Column (columns :: ColumnsType) (columnty :: (Symbol, ColumnType)) [Column] :: HasColumn column columns ty => Alias column -> Column columns (column ::: ty) -- | Render a Column. renderColumn :: Column columns columnty -> ByteString -- | A GroupedBy constraint indicates that a table qualified column -- is a member of the auxiliary namespace created by GROUP BY -- clauses and thus, may be called in an output Expression without -- aggregating. class (KnownSymbol table, KnownSymbol column) => GroupedBy table column bys getGroup1 :: (GroupedBy table column bys, HasUnique table tables columns, HasColumn column columns ty) => Alias column -> Expression tables ( 'Grouped bys) params ty getGroup2 :: (GroupedBy table column bys, HasTable table tables columns, HasColumn column columns ty) => Alias table -> Alias column -> Expression tables ( 'Grouped bys) params ty -- |
--   >>> renderExpression def
--   "DEFAULT"
--   
def :: Expression '[] 'Ungrouped params ( 'Optional (nullity ty)) -- |
--   >>> renderExpression $ unDef false
--   "FALSE"
--   
unDef :: Expression '[] 'Ungrouped params ( 'Required (nullity ty)) -> Expression '[] 'Ungrouped params ( 'Optional (nullity ty)) -- | analagous to Nothing -- --
--   >>> renderExpression $ null_
--   "NULL"
--   
null_ :: Expression tables grouping params (optionality ( 'Null ty)) -- | analagous to Just -- --
--   >>> renderExpression $ unNull true
--   "TRUE"
--   
unNull :: Expression tables grouping params (optionality ( 'NotNull ty)) -> Expression tables grouping params (optionality ( 'Null ty)) -- | return the leftmost value which is not NULL -- --
--   >>> renderExpression $ coalesce [null_, unNull true] false
--   "COALESCE(NULL, TRUE, FALSE)"
--   
coalesce :: [Expression tables grouping params ( 'Required ( 'Null ty))] -> Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'NotNull ty)) -- | analagous to fromMaybe using COALESCE -- --
--   >>> renderExpression $ fromNull true null_
--   "COALESCE(NULL, TRUE)"
--   
fromNull :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'Null ty)) -> Expression tables grouping params ( 'Required ( 'NotNull ty)) -- |
--   >>> renderExpression $ null_ & isNull
--   "NULL IS NULL"
--   
isNull :: Expression tables grouping params ( 'Required ( 'Null ty)) -> Condition tables grouping params -- |
--   >>> renderExpression $ null_ & isn'tNull
--   "NULL IS NOT NULL"
--   
isn'tNull :: Expression tables grouping params ( 'Required ( 'Null ty)) -> Condition tables grouping params -- | analagous to maybe using IS NULL -- --
--   >>> renderExpression $ matchNull true not_ null_
--   "CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END"
--   
matchNull :: Expression tables grouping params ( 'Required nullty) -> (Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required nullty)) -> Expression tables grouping params ( 'Required ( 'Null ty)) -> Expression tables grouping params ( 'Required nullty) -- | right inverse to fromNull, if its arguments are equal then -- nullIf gives NULL. -- --
--   >>> :set -XTypeApplications -XDataKinds
--   
--   >>> renderExpression @_ @_ @'[_] $ fromNull false (nullIf false (param @1))
--   "COALESCE(NULL IF (FALSE, ($1 :: bool)), FALSE)"
--   
nullIf :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'NotNull ty)) -> Expression tables grouping params ( 'Required ( 'Null ty)) -- |
--   >>> renderExpression $ unsafeBinaryOp "OR" true false
--   "(TRUE OR FALSE)"
--   
unsafeBinaryOp :: ByteString -> Expression tables grouping params ( 'Required ty0) -> Expression tables grouping params ( 'Required ty1) -> Expression tables grouping params ( 'Required ty2) -- |
--   >>> renderExpression $ unsafeUnaryOp "NOT" true
--   "(NOT TRUE)"
--   
unsafeUnaryOp :: ByteString -> Expression tables grouping params ( 'Required ty0) -> Expression tables grouping params ( 'Required ty1) -- |
--   >>> renderExpression $ unsafeFunction "f" true
--   "f(TRUE)"
--   
unsafeFunction :: ByteString -> Expression tables grouping params ( 'Required xty) -> Expression tables grouping params ( 'Required yty) -- |
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ atan2_ pi 2
--   "atan2(pi(), 2)"
--   
atan2_ :: PGFloating float => Expression tables grouping params ( 'Required (nullity float)) -> Expression tables grouping params ( 'Required (nullity float)) -> Expression tables grouping params ( 'Required (nullity float)) -- |
--   >>> renderExpression $ true & cast int4
--   "(TRUE :: int4)"
--   
cast :: TypeExpression ( 'Required ( 'Null ty1)) -> Expression tables grouping params ( 'Required (nullity ty0)) -> Expression tables grouping params ( 'Required (nullity ty1)) -- | integer division, truncates the result -- --
--   >>> renderExpression @_ @_ @_ @(_(_ 'PGint2)) $ 5 `quot_` 2
--   "(5 / 2)"
--   
quot_ :: PGIntegral int => Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int)) -- | remainder upon integer division -- --
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ 5 `rem_` 2
--   "(5 % 2)"
--   
rem_ :: PGIntegral int => Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int)) -> Expression tables grouping params ( 'Required (nullity int)) -- |
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ trunc pi
--   "trunc(pi())"
--   
trunc :: PGFloating frac => Expression tables grouping params ( 'Required (nullity frac)) -> Expression tables grouping params ( 'Required (nullity frac)) -- |
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ round_ pi
--   "round(pi())"
--   
round_ :: PGFloating frac => Expression tables grouping params ( 'Required (nullity frac)) -> Expression tables grouping params ( 'Required (nullity frac)) -- |
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ ceiling_ pi
--   "ceiling(pi())"
--   
ceiling_ :: PGFloating frac => Expression tables grouping params ( 'Required (nullity frac)) -> Expression tables grouping params ( 'Required (nullity frac)) -- |
--   >>> renderExpression @_ @_ @'[_] $ greatest currentTimestamp [param @1]
--   "GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))"
--   
greatest :: Expression tables grouping params ( 'Required nullty) -> [Expression tables grouping params ( 'Required nullty)] -> Expression tables grouping params ( 'Required nullty) -- |
--   >>> renderExpression $ least currentTimestamp [null_]
--   "LEAST(CURRENT_TIMESTAMP, NULL)"
--   
least :: Expression tables grouping params ( 'Required nullty) -> [Expression tables grouping params ( 'Required nullty)] -> Expression tables grouping params ( 'Required nullty) -- | A Condition is a boolean valued Expression. While SQL -- allows conditions to have NULL, squeal instead chooses to -- disallow NULL, forcing one to handle the case of -- NULL explicitly to produce a Condition. type Condition tables grouping params = Expression tables grouping params ( 'Required ( 'NotNull 'PGbool)) -- |
--   >>> renderExpression true
--   "TRUE"
--   
true :: Condition tables grouping params -- |
--   >>> renderExpression false
--   "FALSE"
--   
false :: Condition tables grouping params -- |
--   >>> renderExpression $ not_ true
--   "(NOT TRUE)"
--   
not_ :: Condition tables grouping params -> Condition tables grouping params -- |
--   >>> renderExpression $ true .&& false
--   "(TRUE AND FALSE)"
--   
(.&&) :: Condition tables grouping params -> Condition tables grouping params -> Condition tables grouping params -- |
--   >>> renderExpression $ true .|| false
--   "(TRUE OR FALSE)"
--   
(.||) :: Condition tables grouping params -> Condition tables grouping params -> Condition tables grouping params -- |
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ caseWhenThenElse [(true, 1), (false, 2)] 3
--   "CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END"
--   
caseWhenThenElse :: [(Condition tables grouping params, Expression tables grouping params ( 'Required ty))] -> Expression tables grouping params ( 'Required ty) -> Expression tables grouping params ( 'Required ty) -- |
--   >>> renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ ifThenElse true 1 0
--   "CASE WHEN TRUE THEN 1 ELSE 0 END"
--   
ifThenElse :: Condition tables grouping params -> Expression tables grouping params ( 'Required ty) -> Expression tables grouping params ( 'Required ty) -> Expression tables grouping params ( 'Required ty) -- | Comparison operations like .==, ./=, .>, -- .>=, .< and .<= will produce -- NULLs if one of their arguments is NULL. -- --
--   >>> renderExpression $ unNull true .== null_
--   "(TRUE = NULL)"
--   
(.==) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) infix 4 .== -- |
--   >>> renderExpression $ unNull true ./= null_
--   "(TRUE <> NULL)"
--   
(./=) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) infix 4 ./= -- |
--   >>> renderExpression $ unNull true .>= null_
--   "(TRUE >= NULL)"
--   
(.>=) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) infix 4 .>= -- |
--   >>> renderExpression $ unNull true .< null_
--   "(TRUE < NULL)"
--   
(.<) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) infix 4 .< -- |
--   >>> renderExpression $ unNull true .<= null_
--   "(TRUE <= NULL)"
--   
(.<=) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) infix 4 .<= -- |
--   >>> renderExpression $ unNull true .> null_
--   "(TRUE > NULL)"
--   
(.>) :: Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity ty)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) infix 4 .> -- |
--   >>> renderExpression $ currentDate
--   "CURRENT_DATE"
--   
currentDate :: Expression tables grouping params ( 'Required (nullity 'PGdate)) -- |
--   >>> renderExpression $ currentTime
--   "CURRENT_TIME"
--   
currentTime :: Expression tables grouping params ( 'Required (nullity 'PGtimetz)) -- |
--   >>> renderExpression $ currentTimestamp
--   "CURRENT_TIMESTAMP"
--   
currentTimestamp :: Expression tables grouping params ( 'Required (nullity 'PGtimestamptz)) -- |
--   >>> renderExpression $ localTime
--   "LOCALTIME"
--   
localTime :: Expression tables grouping params ( 'Required (nullity 'PGtime)) -- |
--   >>> renderExpression $ localTimestamp
--   "LOCALTIMESTAMP"
--   
localTimestamp :: Expression tables grouping params ( 'Required (nullity 'PGtimestamp)) -- |
--   >>> renderExpression $ lower "ARRRGGG"
--   "lower(E'ARRRGGG')"
--   
lower :: Expression tables grouping params ( 'Required (nullity 'PGtext)) -> Expression tables grouping params ( 'Required (nullity 'PGtext)) -- |
--   >>> renderExpression $ upper "eeee"
--   "upper(E'eeee')"
--   
upper :: Expression tables grouping params ( 'Required (nullity 'PGtext)) -> Expression tables grouping params ( 'Required (nullity 'PGtext)) -- |
--   >>> renderExpression $ charLength "four"
--   "char_length(E'four')"
--   
charLength :: Expression tables grouping params ( 'Required (nullity 'PGtext)) -> Expression tables grouping params ( 'Required (nullity 'PGint4)) -- | The like expression returns true if the string matches -- the supplied pattern. If pattern does not contain -- percent signs or underscores, then the pattern only represents the -- string itself; in that case like acts like the equals operator. -- An underscore (_) in pattern stands for (matches) any single -- character; a percent sign (%) matches any sequence of zero or more -- characters. -- --
--   >>> renderExpression $ "abc" `like` "a%"
--   "(E'abc' LIKE E'a%')"
--   
like :: Expression tables grouping params ( 'Required (nullity 'PGtext)) -> Expression tables grouping params ( 'Required (nullity 'PGtext)) -> Expression tables grouping params ( 'Required (nullity 'PGbool)) -- | escape hatch to define aggregate functions unsafeAggregate :: ByteString -> Expression tables 'Ungrouped params ( 'Required xty) -> Expression tables ( 'Grouped bys) params ( 'Required yty) -- | escape hatch to define aggregate functions over distinct values unsafeAggregateDistinct :: ByteString -> Expression tables 'Ungrouped params ( 'Required xty) -> Expression tables ( 'Grouped bys) params ( 'Required yty) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGnumeric)]] $ sum_ #col
--   "sum(col)"
--   
sum_ :: PGNum ty => Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGnumeric)]] $ sumDistinct #col
--   "sum(DISTINCT col)"
--   
sumDistinct :: PGNum ty => Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty)) -- | A constraint for PGTypes that you can take averages of and the -- resulting PGType. class PGAvg ty avg | ty -> avg avg, avgDistinct :: PGAvg ty avg => Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity avg)) avg, avgDistinct :: PGAvg ty avg => Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity avg)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitAnd #col
--   "bit_and(col)"
--   
bitAnd :: PGIntegral int => Expression tables 'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitOr #col
--   "bit_or(col)"
--   
bitOr :: PGIntegral int => Expression tables 'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolAnd #col
--   "bool_and(col)"
--   
boolAnd :: Expression tables 'Ungrouped params ( 'Required (nullity 'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity 'PGbool)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolOr #col
--   "bool_or(col)"
--   
boolOr :: Expression tables 'Ungrouped params ( 'Required (nullity 'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity 'PGbool)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitAndDistinct #col
--   "bit_and(DISTINCT col)"
--   
bitAndDistinct :: PGIntegral int => Expression tables 'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitOrDistinct #col
--   "bit_or(DISTINCT col)"
--   
bitOrDistinct :: PGIntegral int => Expression tables 'Ungrouped params ( 'Required (nullity int)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity int)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolAndDistinct #col
--   "bool_and(DISTINCT col)"
--   
boolAndDistinct :: Expression tables 'Ungrouped params ( 'Required (nullity 'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity 'PGbool)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolOrDistinct #col
--   "bool_or(DISTINCT col)"
--   
boolOrDistinct :: Expression tables 'Ungrouped params ( 'Required (nullity 'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity 'PGbool)) -- | A special aggregation that does not require an input -- --
--   >>> renderExpression countStar
--   "count(*)"
--   
countStar :: Expression tables ( 'Grouped bys) params ( 'Required ( 'NotNull 'PGint8)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Optional _]] $ count #col
--   "count(col)"
--   
count :: Expression tables 'Ungrouped params ( 'Required ty) -> Expression tables ( 'Grouped bys) params ( 'Required ( 'NotNull 'PGint8)) -- |
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required _]] $ countDistinct #col
--   "count(DISTINCT col)"
--   
countDistinct :: Expression tables 'Ungrouped params ( 'Required ty) -> Expression tables ( 'Grouped bys) params ( 'Required ( 'NotNull 'PGint8)) -- | synonym for boolAnd -- --
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ every #col
--   "every(col)"
--   
every :: Expression tables 'Ungrouped params ( 'Required (nullity 'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity 'PGbool)) -- | synonym for boolAndDistinct -- --
--   >>> renderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ everyDistinct #col
--   "every(DISTINCT col)"
--   
everyDistinct :: Expression tables 'Ungrouped params ( 'Required (nullity 'PGbool)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity 'PGbool)) -- | minimum and maximum aggregation max_ :: Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty)) -- | minimum and maximum aggregation maxDistinct :: Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty)) -- | minimum and maximum aggregation min_ :: Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty)) -- | minimum and maximum aggregation minDistinct :: Expression tables 'Ungrouped params ( 'Required (nullity ty)) -> Expression tables ( 'Grouped bys) params ( 'Required (nullity ty)) -- | A Table from a schema without its alias with an IsLabel -- instance to call a table reference by its alias. newtype Table (schema :: TablesType) (columns :: ColumnsType) UnsafeTable :: ByteString -> Table [renderTable] :: Table -> ByteString -- | A HasTable constraint indicates a table reference. class KnownSymbol table => HasTable table tables columns | table tables -> columns getTable :: HasTable table tables columns => Alias table -> Table tables columns -- | TypeExpressions are used in casts and -- createTable commands. newtype TypeExpression (ty :: ColumnType) UnsafeTypeExpression :: ByteString -> TypeExpression [renderTypeExpression] :: TypeExpression -> ByteString -- | pgtype is a demoted version of a PGType class PGTyped (ty :: PGType) pgtype :: PGTyped ty => TypeExpression ( 'Required ( 'Null ty)) -- | logical Boolean (true/false) bool :: TypeExpression ( 'Required ( 'Null 'PGbool)) -- | signed two-byte integer int2 :: TypeExpression ( 'Required ( 'Null 'PGint2)) -- | signed two-byte integer smallint :: TypeExpression ( 'Required ( 'Null 'PGint2)) -- | signed four-byte integer int4 :: TypeExpression ( 'Required ( 'Null 'PGint4)) -- | signed four-byte integer int :: TypeExpression ( 'Required ( 'Null 'PGint4)) -- | signed four-byte integer integer :: TypeExpression ( 'Required ( 'Null 'PGint4)) -- | signed eight-byte integer int8 :: TypeExpression ( 'Required ( 'Null 'PGint8)) -- | signed eight-byte integer bigint :: TypeExpression ( 'Required ( 'Null 'PGint8)) -- | arbitrary precision numeric type numeric :: TypeExpression ( 'Required ( 'Null 'PGnumeric)) -- | single precision floating-point number (4 bytes) float4 :: TypeExpression ( 'Required ( 'Null 'PGfloat4)) -- | single precision floating-point number (4 bytes) real :: TypeExpression ( 'Required ( 'Null 'PGfloat4)) -- | double precision floating-point number (8 bytes) float8 :: TypeExpression ( 'Required ( 'Null 'PGfloat8)) -- | double precision floating-point number (8 bytes) doublePrecision :: TypeExpression ( 'Required ( 'Null 'PGfloat8)) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type `PGint2 serial2 :: TypeExpression ( 'Optional ( 'NotNull 'PGint2)) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type `PGint2 smallserial :: TypeExpression ( 'Optional ( 'NotNull 'PGint2)) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type `PGint4 serial4 :: TypeExpression ( 'Optional ( 'NotNull 'PGint4)) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type `PGint4 serial :: TypeExpression ( 'Optional ( 'NotNull 'PGint4)) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type `PGint8 serial8 :: TypeExpression ( 'Optional ( 'NotNull 'PGint8)) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type `PGint8 bigserial :: TypeExpression ( 'Optional ( 'NotNull 'PGint8)) -- | variable-length character string text :: TypeExpression ( 'Required ( 'Null 'PGtext)) -- | fixed-length character string char :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGchar n))) -- | fixed-length character string character :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGchar n))) -- | variable-length character string varchar :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGvarchar n))) -- | variable-length character string characterVarying :: (KnownNat n, 1 <= n) => proxy n -> TypeExpression ( 'Required ( 'Null ( 'PGvarchar n))) -- | binary data ("byte array") bytea :: TypeExpression ( 'Required ( 'Null 'PGbytea)) -- | date and time (no time zone) timestamp :: TypeExpression ( 'Required ( 'Null 'PGtimestamp)) -- | date and time, including time zone timestampWithTimeZone :: TypeExpression ( 'Required ( 'Null 'PGtimestamptz)) -- | calendar date (year, month, day) date :: TypeExpression ( 'Required ( 'Null 'PGdate)) -- | time of day (no time zone) time :: TypeExpression ( 'Required ( 'Null 'PGtime)) -- | time of day, including time zone timeWithTimeZone :: TypeExpression ( 'Required ( 'Null 'PGtimetz)) -- | time span interval :: TypeExpression ( 'Required ( 'Null 'PGinterval)) -- | universally unique identifier uuid :: TypeExpression ( 'Required ( 'Null 'PGuuid)) -- | IPv4 or IPv6 host address inet :: TypeExpression ( 'Required ( 'Null 'PGinet)) -- | textual JSON data json :: TypeExpression ( 'Required ( 'Null 'PGjson)) -- | binary JSON data, decomposed jsonb :: TypeExpression ( 'Required ( 'Null 'PGjsonb)) -- | used in createTable commands as a column constraint to ensure -- NULL is not present notNull :: TypeExpression (optionality ( 'Null ty)) -> TypeExpression (optionality ( 'NotNull ty)) -- | used in createTable commands as a column constraint to give a -- default default_ :: Expression '[] 'Ungrouped '[] ( 'Required ty) -> TypeExpression ( 'Required ty) -> TypeExpression ( 'Optional ty) -- | & is a reverse application operator. This provides -- notational convenience. Its precedence is one higher than that of the -- forward application operator $, which allows & to be -- nested in $. (&) :: () => a -> (a -> b) -> b infixl 1 & -- | An n-ary product. -- -- The product is parameterized by a type constructor f and -- indexed by a type-level list xs. The length of the list -- determines the number of elements in the product, and if the -- i-th element of the list is of type x, then the -- i-th element of the product is of type f x. -- -- The constructor names are chosen to resemble the names of the list -- constructors. -- -- Two common instantiations of f are the identity functor -- I and the constant functor K. For I, the product -- becomes a heterogeneous list, where the type-level list describes the -- types of its components. For K a, the product becomes -- a homogeneous list, where the contents of the type-level list are -- ignored, but its length still specifies the number of elements. -- -- In the context of the SOP approach to generic programming, an n-ary -- product describes the structure of the arguments of a single data -- constructor. -- -- Examples: -- --
--   I 'x'    :* I True  :* Nil  ::  NP I       '[ Char, Bool ]
--   K 0      :* K 1     :* Nil  ::  NP (K Int) '[ Char, Bool ]
--   Just 'x' :* Nothing :* Nil  ::  NP Maybe   '[ Char, Bool ]
--   
data NP k (a :: k -> *) (b :: [k]) :: forall k. () => (k -> *) -> [k] -> * [Nil] :: NP k a [] k [:*] :: NP k a (:) k x xs instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.TypeExpression ty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.TypeExpression ty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.TypeExpression ty) instance GHC.Show.Show (Squeal.PostgreSQL.Expression.TypeExpression ty) instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.TypeExpression ty) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.Table schema columns) instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Table schema columns) instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Table schema columns) instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Table schema columns) instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.Table schema columns) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.Expression tables grouping params ty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Expression tables grouping params ty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Expression tables grouping params ty) instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Expression tables grouping params ty) instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.Expression tables grouping params ty) instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Column columns columnty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Column columns columnty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Column columns columnty) instance Squeal.PostgreSQL.Expression.PGTyped (Squeal.PostgreSQL.Schema.BaseType ty1) => Squeal.PostgreSQL.Expression.HasParameter 1 ((':) Squeal.PostgreSQL.Schema.ColumnType ty1 tys) ty1 instance (GHC.TypeNats.KnownNat n, Squeal.PostgreSQL.Expression.HasParameter (n GHC.TypeNats.- 1) params ty) => Squeal.PostgreSQL.Expression.HasParameter n ((':) Squeal.PostgreSQL.Schema.ColumnType ty' params) ty instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGbool instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGint2 instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGint4 instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGint8 instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGfloat4 instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtext instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Squeal.PostgreSQL.Expression.PGTyped ('Squeal.PostgreSQL.Schema.PGchar n) instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Squeal.PostgreSQL.Expression.PGTyped ('Squeal.PostgreSQL.Schema.PGvarchar n) instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGbytea instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtimestamp instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtimestamptz instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGdate instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtime instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGtimetz instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGinterval instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGuuid instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGjson instance Squeal.PostgreSQL.Expression.PGTyped 'Squeal.PostgreSQL.Schema.PGjsonb instance (GHC.TypeLits.KnownSymbol table, GHC.TypeLits.KnownSymbol column) => Squeal.PostgreSQL.Expression.GroupedBy table column ((':) (GHC.Types.Symbol, GHC.Types.Symbol) '(table, column) bys) instance (GHC.TypeLits.KnownSymbol table, GHC.TypeLits.KnownSymbol column, Squeal.PostgreSQL.Expression.GroupedBy table column bys) => Squeal.PostgreSQL.Expression.GroupedBy table column ((':) (GHC.Types.Symbol, GHC.Types.Symbol) tabcol bys) instance (Squeal.PostgreSQL.Schema.HasUnique Squeal.PostgreSQL.Schema.ColumnsType table tables columns, Squeal.PostgreSQL.Expression.HasColumn column columns ty, Squeal.PostgreSQL.Expression.GroupedBy table column bys) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Expression.Expression tables ('Squeal.PostgreSQL.Schema.Grouped bys) params ty) instance (Squeal.PostgreSQL.Expression.HasTable table tables columns, Squeal.PostgreSQL.Expression.HasColumn column columns ty, Squeal.PostgreSQL.Expression.GroupedBy table column bys) => Squeal.PostgreSQL.Schema.IsTableColumn table column (Squeal.PostgreSQL.Expression.Expression tables ('Squeal.PostgreSQL.Schema.Grouped bys) params ty) instance (Squeal.PostgreSQL.Expression.HasTable table tables columns, Squeal.PostgreSQL.Expression.HasColumn column columns ty) => Squeal.PostgreSQL.Schema.IsTableColumn table column (Squeal.PostgreSQL.Expression.Expression tables 'Squeal.PostgreSQL.Schema.Ungrouped params ty) instance GHC.TypeLits.KnownSymbol table => Squeal.PostgreSQL.Expression.HasTable table ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnsType) ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnsType table columns) tables) columns instance (GHC.TypeLits.KnownSymbol table, Squeal.PostgreSQL.Expression.HasTable table schema columns) => Squeal.PostgreSQL.Expression.HasTable table ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnsType) table' schema) columns instance Squeal.PostgreSQL.Expression.HasTable table schema columns => GHC.OverloadedLabels.IsLabel table (Squeal.PostgreSQL.Expression.Table schema columns) instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGint2 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGint4 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGint8 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGnumeric 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGfloat4 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGfloat8 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Expression.PGAvg Squeal.PostgreSQL.Schema.PGType 'Squeal.PostgreSQL.Schema.PGinterval 'Squeal.PostgreSQL.Schema.PGinterval instance GHC.TypeLits.KnownSymbol column => Squeal.PostgreSQL.Expression.HasColumn column ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column (optionality ty)) tys) ('Squeal.PostgreSQL.Schema.Required ty) instance (GHC.TypeLits.KnownSymbol column, Squeal.PostgreSQL.Expression.HasColumn column table ty) => Squeal.PostgreSQL.Expression.HasColumn column ((':) (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) ty' table) ty instance (Squeal.PostgreSQL.Expression.HasColumn column columns ty, Squeal.PostgreSQL.Schema.HasUnique Squeal.PostgreSQL.Schema.ColumnsType table tables columns) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Expression.Expression tables 'Squeal.PostgreSQL.Schema.Ungrouped params ty) instance Squeal.PostgreSQL.Schema.PGNum ty => GHC.Num.Num (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity ty))) instance (Squeal.PostgreSQL.Schema.PGNum ty, Squeal.PostgreSQL.Schema.PGFloating ty) => GHC.Real.Fractional (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity ty))) instance (Squeal.PostgreSQL.Schema.PGNum ty, Squeal.PostgreSQL.Schema.PGFloating ty) => GHC.Float.Floating (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity ty))) instance Data.String.IsString (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity 'Squeal.PostgreSQL.Schema.PGtext))) instance GHC.Base.Monoid (Squeal.PostgreSQL.Expression.Expression tables grouping params ('Squeal.PostgreSQL.Schema.Required (nullity 'Squeal.PostgreSQL.Schema.PGtext))) -- | Squeal queries. module Squeal.PostgreSQL.Query -- | The process of retrieving or the command to retrieve data from a -- database is called a Query. The select, -- selectStar, selectDotStar, selectDistinct, -- selectDistinctStar and selectDistinctDotStar commands -- are used to specify queries. -- -- simple query: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectStar (from (Table (#tab `As` #t)))
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t"
--   
-- -- restricted query: -- --
--   >>> :{
--   let
--     query :: Query
--       '[ "tab" :::
--          '[ "col1" ::: 'Required ('NotNull 'PGint4)
--           , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[]
--       '[ "sum" ::: 'Required ('NotNull 'PGint4)
--        , "col1" ::: 'Required ('NotNull 'PGint4) ]
--     query = 
--       select
--         ((#col1 + #col2) `As` #sum :* #col1 `As` #col1 :* Nil)
--         ( from (Table (#tab `As` #t))
--           & where_ (#col1 .> #col2)
--           & where_ (#col2 .> 0) )
--   in renderQuery query
--   :}
--   "SELECT (col1 + col2) AS sum, col1 AS col1 FROM tab AS t WHERE ((col1 > col2) AND (col2 > 0))"
--   
-- -- subquery: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query =
--       selectStar
--         (from (Subquery (selectStar (from (Table (#tab `As` #t))) `As` #sub)))
--   in renderQuery query
--   :}
--   "SELECT * FROM (SELECT * FROM tab AS t) AS sub"
--   
-- -- limits and offsets: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectStar
--       (from (Table (#tab `As` #t)) & limit 100 & offset 2 & limit 50 & offset 2)
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t LIMIT 50 OFFSET 4"
--   
-- -- parameterized query: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('NotNull 'PGfloat8)]]
--       '[ 'Required ('NotNull 'PGfloat8)]
--       '["col" ::: 'Required ('NotNull 'PGfloat8)]
--     query = selectStar
--       (from (Table (#tab `As` #t)) & where_ (#col .> param @1))
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t WHERE (col > ($1 :: float8))"
--   
-- -- aggregation query: -- --
--   >>> :{
--   let
--     query :: Query
--       '[ "tab" :::
--          '[ "col1" ::: 'Required ('NotNull 'PGint4)
--           , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[]
--       '[ "sum" ::: 'Required ('NotNull 'PGint4)
--        , "col1" ::: 'Required ('NotNull 'PGint4) ]
--     query =
--       select (sum_ #col2 `As` #sum :* #col1 `As` #col1 :* Nil)
--       ( from (Table (#tab `As` #table1))
--         & group (By #col1 :* Nil) 
--         & having (#col1 + sum_ #col2 .> 1) )
--   in renderQuery query
--   :}
--   "SELECT sum(col2) AS sum, col1 AS col1 FROM tab AS table1 GROUP BY col1 HAVING ((col1 + sum(col2)) > 1)"
--   
-- -- sorted query: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectStar
--       (from (Table (#tab `As` #t)) & orderBy [#col & AscNullsFirst])
--   in renderQuery query
--   :}
--   "SELECT * FROM tab AS t ORDER BY col ASC NULLS FIRST"
--   
-- -- joins: -- --
--   >>> :set -XFlexibleContexts
--   
--   >>> :{
--   let
--     query :: Query
--       '[ "orders" :::
--            '[ "id"    ::: 'Required ('NotNull 'PGint4)
--             , "price"   ::: 'Required ('NotNull 'PGfloat4)
--             , "customer_id" ::: 'Required ('NotNull 'PGint4)
--             , "shipper_id"  ::: 'Required ('NotNull 'PGint4)
--             ]
--        , "customers" :::
--            '[ "id" ::: 'Required ('NotNull 'PGint4)
--             , "name" ::: 'Required ('NotNull 'PGtext)
--             ]
--        , "shippers" :::
--            '[ "id" ::: 'Required ('NotNull 'PGint4)
--             , "name" ::: 'Required ('NotNull 'PGtext)
--             ]
--        ]
--       '[]
--       '[ "order_price" ::: 'Required ('NotNull 'PGfloat4)
--        , "customer_name" ::: 'Required ('NotNull 'PGtext)
--        , "shipper_name" ::: 'Required ('NotNull 'PGtext)
--        ]
--     query = select
--       ( #o ! #price `As` #order_price :*
--         #c ! #name `As` #customer_name :*
--         #s ! #name `As` #shipper_name :* Nil )
--       ( from (Table (#orders `As` #o)
--         & InnerJoin (Table (#customers `As` #c))
--           (#o ! #customer_id .== #c ! #id)
--         & InnerJoin (Table (#shippers `As` #s))
--           (#o ! #shipper_id .== #s ! #id)) )
--   in renderQuery query
--   :}
--   "SELECT o.price AS order_price, c.name AS customer_name, s.name AS shipper_name FROM orders AS o INNER JOIN customers AS c ON (o.customer_id = c.id) INNER JOIN shippers AS s ON (o.shipper_id = s.id)"
--   
-- -- self-join: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query = selectDotStar #t1
--       (from (Table (#tab `As` #t1) & CrossJoin (Table (#tab `As` #t2))))
--   in renderQuery query
--   :}
--   "SELECT t1.* FROM tab AS t1 CROSS JOIN tab AS t2"
--   
-- -- set operations: -- --
--   >>> :{
--   let
--     query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]
--       '["col" ::: 'Required ('Null 'PGint4)]
--     query =
--       selectStar (from (Table (#tab `As` #t)))
--       `unionAll`
--       selectStar (from (Table (#tab `As` #t)))
--   in renderQuery query
--   :}
--   "(SELECT * FROM tab AS t) UNION ALL (SELECT * FROM tab AS t)"
--   
newtype Query (schema :: TablesType) (params :: [ColumnType]) (columns :: ColumnsType) UnsafeQuery :: ByteString -> Query [renderQuery] :: Query -> ByteString -- | The results of two queries can be combined using the set operation -- union. Duplicate rows are eliminated. union :: Query schema params columns -> Query schema params columns -> Query schema params columns -- | The results of two queries can be combined using the set operation -- unionAll, the disjoint union. Duplicate rows are retained. unionAll :: Query schema params columns -> Query schema params columns -> Query schema params columns -- | The results of two queries can be combined using the set operation -- intersect, the intersection. Duplicate rows are eliminated. intersect :: Query schema params columns -> Query schema params columns -> Query schema params columns -- | The results of two queries can be combined using the set operation -- intersectAll, the intersection. Duplicate rows are retained. intersectAll :: Query schema params columns -> Query schema params columns -> Query schema params columns -- | The results of two queries can be combined using the set operation -- except, the set difference. Duplicate rows are eliminated. except :: Query schema params columns -> Query schema params columns -> Query schema params columns -- | The results of two queries can be combined using the set operation -- exceptAll, the set difference. Duplicate rows are retained. exceptAll :: Query schema params columns -> Query schema params columns -> Query schema params columns -- | the TableExpression in the select command constructs an -- intermediate virtual table by possibly combining tables, views, -- eliminating rows, grouping, etc. This table is finally passed on to -- processing by the select list. The select list determines which -- columns of the intermediate table are actually output. select :: SListI columns => NP (Aliased (Expression tables grouping params)) (column : columns) -> TableExpression schema params tables grouping -> Query schema params (column : columns) -- | After the select list has been processed, the result table can be -- subject to the elimination of duplicate rows using -- selectDistinct. selectDistinct :: SListI columns => NP (Aliased (Expression tables 'Ungrouped params)) (column : columns) -> TableExpression schema params tables 'Ungrouped -> Query schema params (column : columns) -- | The simplest kind of query is selectStar which emits all -- columns that the table expression produces. selectStar :: HasUnique table tables columns => TableExpression schema params tables 'Ungrouped -> Query schema params columns -- | A selectDistinctStar emits all columns that the table -- expression produces and eliminates duplicate rows. selectDistinctStar :: HasUnique table tables columns => TableExpression schema params tables 'Ungrouped -> Query schema params columns -- | When working with multiple tables, it can also be useful to ask for -- all the columns of a particular table, using selectDotStar. selectDotStar :: HasTable table tables columns => Alias table -> TableExpression schema params tables 'Ungrouped -> Query schema params columns -- | A selectDistinctDotStar asks for all the columns of a -- particular table, and eliminates duplicate rows. selectDistinctDotStar :: HasTable table tables columns => Alias table -> TableExpression schema params tables 'Ungrouped -> Query schema params columns -- | A TableExpression computes a table. The table expression -- contains a fromClause that is optionally followed by a -- whereClause, groupByClause, havingClause, -- orderByClause, limitClause and offsetClauses. -- Trivial table expressions simply refer to a table on disk, a so-called -- base table, but more complex expressions can be used to modify or -- combine base tables in various ways. data TableExpression (schema :: TablesType) (params :: [ColumnType]) (tables :: TablesType) (grouping :: Grouping) TableExpression :: FromClause schema params tables -> [Condition tables 'Ungrouped params] -> GroupByClause tables grouping -> HavingClause tables grouping params -> [SortExpression tables grouping params] -> [Word64] -> [Word64] -> TableExpression -- | A table reference that can be a table name, or a derived table such as -- a subquery, a JOIN construct, or complex combinations of -- these. [fromClause] :: TableExpression -> FromClause schema params tables -- | optional search coditions, combined with .&&. After the -- processing of the fromClause is done, each row of the derived -- virtual table is checked against the search condition. If the result -- of the condition is true, the row is kept in the output table, -- otherwise it is discarded. The search condition typically references -- at least one column of the table generated in the fromClause; -- this is not required, but otherwise the WHERE clause will be fairly -- useless. [whereClause] :: TableExpression -> [Condition tables 'Ungrouped params] -- | The groupByClause is used to group together those rows in a -- table that have the same values in all the columns listed. The order -- in which the columns are listed does not matter. The effect is to -- combine each set of rows having common values into one group row that -- represents all rows in the group. This is done to eliminate redundancy -- in the output and/or compute aggregates that apply to these groups. [groupByClause] :: TableExpression -> GroupByClause tables grouping -- | If a table has been grouped using groupBy, but only certain -- groups are of interest, the havingClause can be used, much like -- a whereClause, to eliminate groups from the result. Expressions -- in the havingClause can refer both to grouped expressions and -- to ungrouped expressions (which necessarily involve an aggregate -- function). [havingClause] :: TableExpression -> HavingClause tables grouping params -- | The orderByClause is for optional sorting. When more than one -- SortExpression is specified, the later (right) values are used -- to sort rows that are equal according to the earlier (left) values. [orderByClause] :: TableExpression -> [SortExpression tables grouping params] -- | The limitClause is combined with min to give a limit -- count if nonempty. If a limit count is given, no more than that many -- rows will be returned (but possibly fewer, if the query itself yields -- fewer rows). [limitClause] :: TableExpression -> [Word64] -- | The offsetClause is combined with + to give an offset -- count if nonempty. The offset count says to skip that many rows before -- beginning to return rows. The rows are skipped before the limit count -- is applied. [offsetClause] :: TableExpression -> [Word64] -- | Render a TableExpression renderTableExpression :: TableExpression schema params tables grouping -> ByteString -- | A from generates a TableExpression from a table -- reference that can be a table name, or a derived table such as a -- subquery, a JOIN construct, or complex combinations of these. A -- from may be transformed by where_, group, -- having, orderBy, limit and offset, using -- the & operator to match the left-to-right sequencing of -- their placement in SQL. from :: FromClause schema params tables -> TableExpression schema params tables 'Ungrouped -- | A where_ is an endomorphism of TableExpressions which -- adds a search condition to the whereClause. where_ :: Condition tables 'Ungrouped params -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping -- | A group is a transformation of TableExpressions which -- switches its Grouping from Ungrouped to Grouped. -- Use group Nil to perform a "grand total" aggregation query. group :: SListI bys => NP (By tables) bys -> TableExpression schema params tables 'Ungrouped -> TableExpression schema params tables ( 'Grouped bys) -- | A having is an endomorphism of TableExpressions which -- adds a search condition to the havingClause. having :: Condition tables ( 'Grouped bys) params -> TableExpression schema params tables ( 'Grouped bys) -> TableExpression schema params tables ( 'Grouped bys) -- | An orderBy is an endomorphism of TableExpressions which -- appends an ordering to the right of the orderByClause. orderBy :: [SortExpression tables grouping params] -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping -- | A limit is an endomorphism of TableExpressions which -- adds to the limitClause. limit :: Word64 -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping -- | An offset is an endomorphism of TableExpressions which -- adds to the offsetClause. offset :: Word64 -> TableExpression schema params tables grouping -> TableExpression schema params tables grouping -- | A FromClause can be a table name, or a derived table such as a -- subquery, a JOIN construct, or complex combinations of these. -- -- data FromClause schema params tables [Table] :: Aliased (Table schema) table -> FromClause schema params '[table] [Subquery] :: Aliased (Query schema params) table -> FromClause schema params '[table] [CrossJoin] :: FromClause schema params right -> FromClause schema params left -> FromClause schema params (Join left right) [InnerJoin] :: FromClause schema params right -> Condition (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join left right) [LeftOuterJoin] :: FromClause schema params right -> Condition (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join left (NullifyTables right)) [RightOuterJoin] :: FromClause schema params right -> Condition (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join (NullifyTables left) right) [FullOuterJoin] :: FromClause schema params right -> Condition (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join (NullifyTables left) (NullifyTables right)) -- | Renders a FromClause. renderFromClause :: FromClause schema params tables -> ByteString -- | Bys are used in group to reference a list of columns -- which are then used to group together those rows in a table that have -- the same values in all the columns listed. By #col will -- reference an unambiguous column col; otherwise By2 (#tab -- ! #col) will reference a table qualified column tab.col. data By (tables :: TablesType) (by :: (Symbol, Symbol)) [By] :: (HasUnique table tables columns, HasColumn column columns ty) => Alias column -> By tables '(table, column) [By2] :: (HasTable table tables columns, HasColumn column columns ty) => (Alias table, Alias column) -> By tables '(table, column) -- | Renders a By. renderBy :: By tables tabcolty -> ByteString -- | A GroupByClause indicates the Grouping of a -- TableExpression. A NoGroups indicates Ungrouped -- while a Group indicates Grouped. NoGroups is -- distinguised from Group Nil since no aggregation can be done -- on NoGroups while all output Expressions must be -- aggregated in Group Nil. data GroupByClause tables grouping [NoGroups] :: GroupByClause tables 'Ungrouped [Group] :: SListI bys => NP (By tables) bys -> GroupByClause tables ( 'Grouped bys) -- | Renders a GroupByClause. renderGroupByClause :: GroupByClause tables grouping -> ByteString -- | A HavingClause is used to eliminate groups that are not of -- interest. An Ungrouped TableExpression may only use -- NoHaving while a Grouped TableExpression must use -- Having whose conditions are combined with .&&. data HavingClause tables grouping params [NoHaving] :: HavingClause tables 'Ungrouped params [Having] :: [Condition tables ( 'Grouped bys) params] -> HavingClause tables ( 'Grouped bys) params -- | Render a HavingClause. renderHavingClause :: HavingClause tables grouping params -> ByteString -- | SortExpressions are used by sortBy to optionally sort -- the results of a Query. Asc or Desc set the sort -- direction of a NotNull result column to ascending or -- descending. Ascending order puts smaller values first, where "smaller" -- is defined in terms of the .< operator. Similarly, -- descending order is determined with the .> operator. -- AscNullsFirst, AscNullsLast, DescNullsFirst and -- DescNullsLast options are used to determine whether nulls -- appear before or after non-null values in the sort ordering of a -- Null result column. data SortExpression tables grouping params [Asc] :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> SortExpression tables grouping params [Desc] :: Expression tables grouping params ( 'Required ( 'NotNull ty)) -> SortExpression tables grouping params [AscNullsFirst] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params [AscNullsLast] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params [DescNullsFirst] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params [DescNullsLast] :: Expression tables grouping params ( 'Required ( 'Null ty)) -> SortExpression tables grouping params -- | Render a SortExpression. renderSortExpression :: SortExpression tables grouping params -> ByteString instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Query.Query schema params columns) instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.Query schema params columns) instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.Query schema params columns) instance GHC.Show.Show (Squeal.PostgreSQL.Query.Query schema params columns) instance GHC.Generics.Generic (Squeal.PostgreSQL.Query.Query schema params columns) instance GHC.Show.Show (Squeal.PostgreSQL.Query.By tables by) instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.By tables by) instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.By tables by) instance GHC.Show.Show (Squeal.PostgreSQL.Query.HavingClause tables grouping params) instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.HavingClause tables grouping params) instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.HavingClause tables grouping params) instance GHC.Show.Show (Squeal.PostgreSQL.Query.SortExpression tables grouping params) -- | Squeal data manipulation language. module Squeal.PostgreSQL.Manipulation -- | A Manipulation is a statement which may modify data in the -- database, but does not alter the schema. Examples are -- insertInto, update and deleteFrom. A Query -- is also considered a Manipulation even though it does not -- modify data. newtype Manipulation (schema :: TablesType) (params :: [ColumnType]) (columns :: ColumnsType) UnsafeManipulation :: ByteString -> Manipulation [renderManipulation] :: Manipulation -> ByteString -- | Convert a Query into a Manipulation. queryStatement :: Query schema params columns -> Manipulation schema params columns -- | When a table is created, it contains no data. The first thing to do -- before a database can be of much use is to insert data. Data is -- conceptually inserted one row at a time. Of course you can also insert -- more than one row, but there is no way to insert less than one row. -- Even if you know only some column values, a complete row must be -- created. -- -- simple insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[] '[]
--     manipulation =
--       insertInto #tab (Values (2 `As` #col1 :* 4 `As` #col2 :* Nil) [])
--         OnConflictDoRaise (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (2, 4);"
--   
-- -- parameterized insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[ 'Required ('NotNull 'PGint4)
--        , 'Required ('NotNull 'PGint4) ] '[]
--     manipulation =
--       insertInto #tab
--         (Values (param @1 `As` #col1 :* param @2 `As` #col2 :* Nil) [])
--         OnConflictDoRaise (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (($1 :: int4), ($2 :: int4));"
--   
-- -- returning insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]
--       '["fromOnly" ::: 'Required ('NotNull 'PGint4)]
--     manipulation =
--       insertInto #tab (Values (2 `As` #col1 :* 4 `As` #col2 :* Nil) [])
--         OnConflictDoRaise (Returning (#col1 `As` #fromOnly :* Nil))
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (2, 4) RETURNING col1 AS fromOnly;"
--   
-- -- query insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4)
--          ]
--        , "other_tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4)
--          ]
--        ] '[] '[]
--     manipulation = 
--       insertInto #tab
--         ( ValuesQuery $
--           selectStar (from (Table (#other_tab `As` #t))) )
--         OnConflictDoRaise (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab SELECT * FROM other_tab AS t;"
--   
-- -- upsert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]]
--       '[] '[ "sum" ::: 'Required ('NotNull 'PGint4)]
--     manipulation =
--       insertInto #tab
--         (Values
--           (2 `As` #col1 :* 4 `As` #col2 :* Nil)
--           [6 `As` #col1 :* 8 `As` #col2 :* Nil])
--         (OnConflictDoUpdate
--           (Set 2 `As` #col1 :* Same `As` #col2 :* Nil)
--           (Just (#col1 .== #col2)))
--         (Returning $ (#col1 + #col2) `As` #sum :* Nil)
--   in renderManipulation manipulation
--   :}
--   "INSERT INTO tab (col1, col2) VALUES (2, 4), (6, 8) ON CONFLICT DO UPDATE SET col1 = 2 WHERE (col1 = col2) RETURNING (col1 + col2) AS sum;"
--   
insertInto :: (SListI columns, SListI results, HasTable table schema columns) => Alias table -> ValuesClause schema params columns -> ConflictClause columns params -> ReturningClause columns params results -> Manipulation schema params results -- | A ValuesClause lets you insert either values, free -- Expressions, or the result of a Query. data ValuesClause (schema :: TablesType) (params :: [ColumnType]) (columns :: ColumnsType) -- | at least one row of values Values :: (NP (Aliased (Expression '[] 'Ungrouped params)) columns) -> [NP (Aliased (Expression '[] 'Ungrouped params)) columns] -> ValuesClause ValuesQuery :: (Query schema params columns) -> ValuesClause -- | Render a ValuesClause. renderValuesClause :: SListI columns => ValuesClause schema params columns -> ByteString -- | A ReturningClause computes and return value(s) based on each -- row actually inserted, updated or deleted. This is primarily useful -- for obtaining values that were supplied by defaults, such as a serial -- sequence number. However, any expression using the table's columns is -- allowed. Only rows that were successfully inserted or updated or -- deleted will be returned. For example, if a row was locked but not -- updated because an OnConflictDoUpdate condition was not -- satisfied, the row will not be returned. ReturningStar will -- return all columns in the row. Use `Returning Nil` in the common case -- where no return values are desired. data ReturningClause (columns :: ColumnsType) (params :: [ColumnType]) (results :: ColumnsType) [ReturningStar] :: ReturningClause columns params columns [Returning] :: NP (Aliased (Expression '[table ::: columns] 'Ungrouped params)) results -> ReturningClause columns params results -- | Render a ReturningClause. renderReturningClause :: SListI results => ReturningClause params columns results -> ByteString -- | A ConflictClause specifies an action to perform upon a -- constraint violation. OnConflictDoRaise will raise an error. -- OnConflictDoNothing simply avoids inserting a row. -- OnConflictDoUpdate updates the existing row that conflicts with -- the row proposed for insertion. data ConflictClause columns params [OnConflictDoRaise] :: ConflictClause columns params [OnConflictDoNothing] :: ConflictClause columns params [OnConflictDoUpdate] :: NP (Aliased (UpdateExpression columns params)) columns -> Maybe (Condition '[table ::: columns] 'Ungrouped params) -> ConflictClause columns params -- | Render a ConflictClause. renderConflictClause :: SListI columns => ConflictClause columns params -> ByteString -- | An update command changes the values of the specified columns -- in all rows that satisfy the condition. -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[] '[]
--     manipulation =
--       update #tab (Set 2 `As` #col1 :* Same `As` #col2 :* Nil)
--         (#col1 ./= #col2) (Returning Nil)
--   in renderManipulation manipulation
--   :}
--   "UPDATE tab SET col1 = 2 WHERE (col1 <> col2);"
--   
update :: (HasTable table schema columns, SListI columns, SListI results) => Alias table -> NP (Aliased (UpdateExpression columns params)) columns -> Condition '[tab ::: columns] 'Ungrouped params -> ReturningClause columns params results -> Manipulation schema params results -- | Columns to be updated are mentioned with Set; columns which are -- to remain the same are mentioned with Same. data UpdateExpression columns params ty -- | column to remain the same upon update Same :: UpdateExpression columns params ty -- | column to be updated Set :: (forall table. Expression '[table ::: columns] 'Ungrouped params ty) -> UpdateExpression columns params ty -- | Render an UpdateExpression. renderUpdateExpression :: Aliased (UpdateExpression params columns) column -> Maybe ByteString -- | Delete rows of a table. -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" :::
--         '[ "col1" ::: 'Required ('NotNull 'PGint4)
--          , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]
--       '[ "col1" ::: 'Required ('NotNull 'PGint4)
--        , "col2" ::: 'Required ('NotNull 'PGint4) ]
--     manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar
--   in renderManipulation manipulation
--   :}
--   "DELETE FROM tab WHERE (col1 = col2) RETURNING *;"
--   
deleteFrom :: (SListI results, HasTable table schema columns) => Alias table -> Condition '[table ::: columns] 'Ungrouped params -> ReturningClause columns params results -> Manipulation schema params results instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns) instance GHC.Classes.Ord (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns) instance GHC.Classes.Eq (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns) instance GHC.Show.Show (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns) instance GHC.Generics.Generic (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns) instance GHC.Show.Show (Squeal.PostgreSQL.Manipulation.UpdateExpression columns params ty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Manipulation.UpdateExpression columns params ty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Manipulation.UpdateExpression columns params ty) -- | Squeal data definition language. module Squeal.PostgreSQL.Definition -- | A Definition is a statement that changes the schema of the -- database, like a createTable, dropTable, or -- alterTable command. Definitions may be composed using -- the >>> operator. newtype Definition (schema0 :: TablesType) (schema1 :: TablesType) UnsafeDefinition :: ByteString -> Definition [renderDefinition] :: Definition -> ByteString -- | Left-to-right composition (>>>) :: Category k cat => cat a b -> cat b c -> cat a c infixr 1 >>> -- | createTable adds a table to the schema. -- --
--   >>> :set -XOverloadedLabels
--   
--   >>> :{
--   renderDefinition $
--     createTable #tab (int `As` #a :* real `As` #b :* Nil) []
--   :}
--   "CREATE TABLE tab (a int, b real);"
--   
createTable :: (KnownSymbol table, SListI columns) => Alias table -> NP (Aliased TypeExpression) (column : columns) -> [TableConstraint schema (column : columns)] -> Definition schema (Create table (column : columns) schema) -- | Data types are a way to limit the kind of data that can be stored in a -- table. For many applications, however, the constraint they provide is -- too coarse. For example, a column containing a product price should -- probably only accept positive values. But there is no standard data -- type that accepts only positive numbers. Another issue is that you -- might want to constrain column data with respect to other columns or -- rows. For example, in a table containing product information, there -- should be only one row for each product number. -- TableConstraints give you as much control over the data in your -- tables as you wish. If a user attempts to store data in a column that -- would violate a constraint, an error is raised. This applies even if -- the value came from the default value definition. newtype TableConstraint (schema :: TablesType) (columns :: ColumnsType) UnsafeTableConstraint :: ByteString -> TableConstraint [renderTableConstraint] :: TableConstraint -> ByteString -- | A check constraint is the most generic TableConstraint -- type. It allows you to specify that the value in a certain column must -- satisfy a Boolean (truth-value) expression. -- --
--   >>> :{
--   renderDefinition $
--     createTable #tab
--       ( (int & notNull) `As` #a :*
--         (int & notNull) `As` #b :* Nil )
--       [ check (#a .> #b) ]
--   :}
--   "CREATE TABLE tab (a int NOT NULL, b int NOT NULL, CHECK ((a > b)));"
--   
check :: Condition '[table ::: columns] 'Ungrouped '[] -> TableConstraint schema columns -- | A unique constraint ensure that the data contained in a column, -- or a group of columns, is unique among all the rows in the table. -- --
--   >>> :{
--   renderDefinition $
--     createTable #tab
--       ( int `As` #a :*
--         int `As` #b :* Nil )
--       [ unique (Column #a :* Column #b :* Nil) ]
--   :}
--   "CREATE TABLE tab (a int, b int, UNIQUE (a, b));"
--   
unique :: SListI subcolumns => NP (Column columns) subcolumns -> TableConstraint schema columns -- | A primaryKey constraint indicates that a column, or group of -- columns, can be used as a unique identifier for rows in the table. -- This requires that the values be both unique and not null. -- --
--   >>> :{
--   renderDefinition $
--     createTable #tab
--       ( serial `As` #id :*
--         (text & notNull) `As` #name :* Nil )
--       [ primaryKey (Column #id :* Nil) ]
--   :}
--   "CREATE TABLE tab (id serial, name text NOT NULL, PRIMARY KEY (id));"
--   
primaryKey :: (SListI subcolumns, AllNotNull subcolumns) => NP (Column columns) subcolumns -> TableConstraint schema columns -- | A foreignKey specifies that the values in a column (or a group -- of columns) must match the values appearing in some row of another -- table. We say this maintains the referential integrity between two -- related tables. -- --
--   >>> :{
--   let
--     definition :: Definition '[]
--       '[ "users" :::
--          '[ "id" ::: 'Optional ('NotNull 'PGint4)
--           , "username" ::: 'Required ('NotNull 'PGtext)
--           ]
--        , "emails" :::
--          '[ "id" ::: 'Optional ('NotNull 'PGint4)
--           , "userid" ::: 'Required ('NotNull 'PGint4)
--           , "email" ::: 'Required ('NotNull 'PGtext)
--           ]
--        ]
--     definition =
--       createTable #users
--         (serial `As` #id :* (text & notNull) `As` #username :* Nil)
--         [primaryKey (Column #id :* Nil)] >>>
--       createTable #emails
--         ( serial `As` #id :*
--           (integer & notNull) `As` #userid :*
--           (text & notNull) `As` #email :* Nil )
--         [ primaryKey (Column #id :* Nil)
--         , foreignKey (Column #userid :* Nil) #users (Column #id :* Nil)
--           OnDeleteCascade OnUpdateRestrict
--         ]
--   in renderDefinition definition
--   :}
--   "CREATE TABLE users (id serial, username text NOT NULL, PRIMARY KEY (id)); CREATE TABLE emails (id serial, userid integer NOT NULL, email text NOT NULL, PRIMARY KEY (id), FOREIGN KEY (userid) REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT);"
--   
foreignKey :: (HasTable reftable schema refcolumns, SameTypes subcolumns refsubcolumns, AllNotNull subcolumns, SListI subcolumns, SListI refsubcolumns) => NP (Column columns) subcolumns -> Alias reftable -> NP (Column refcolumns) refsubcolumns -> OnDeleteClause -> OnUpdateClause -> TableConstraint schema columns -- | OnDelete indicates what to do with rows that reference a -- deleted row. data OnDeleteClause -- | if any referencing rows still exist when the constraint is checked, an -- error is raised OnDeleteNoAction :: OnDeleteClause -- | prevents deletion of a referenced row OnDeleteRestrict :: OnDeleteClause -- | specifies that when a referenced row is deleted, row(s) referencing it -- should be automatically deleted as well OnDeleteCascade :: OnDeleteClause -- | Render OnDeleteClause. renderOnDeleteClause :: OnDeleteClause -> ByteString -- | Analagous to OnDelete there is also OnUpdate which -- is invoked when a referenced column is changed (updated). data OnUpdateClause -- | if any referencing rows has not changed when the constraint is -- checked, an error is raised OnUpdateNoAction :: OnUpdateClause -- | prevents update of a referenced row OnUpdateRestrict :: OnUpdateClause -- | the updated values of the referenced column(s) should be copied into -- the referencing row(s) OnUpdateCascade :: OnUpdateClause -- | Render OnUpdateClause. renderOnUpdateClause :: OnUpdateClause -> ByteString -- | dropTable removes a table from the schema. -- --
--   >>> renderDefinition $ dropTable #muh_table
--   "DROP TABLE muh_table;"
--   
dropTable :: KnownSymbol table => Alias table -> Definition schema (Drop table schema) -- | alterTable changes the definition of a table from the schema. alterTable :: HasTable table schema columns0 => Alias table -> AlterColumns columns0 columns1 -> Definition schema (Alter table schema columns1) -- | alterTableRename changes the name of a table from the schema. -- --
--   >>> renderDefinition $ alterTableRename #foo #bar
--   "ALTER TABLE foo RENAME TO bar;"
--   
alterTableRename :: (KnownSymbol table0, KnownSymbol table1) => Alias table0 -> Alias table1 -> Definition schema (Rename table0 table1 schema) -- | An alterTableAddConstraint adds a table constraint. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--     definition = alterTableAddConstraint #tab (check (#col .> 0))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ADD CHECK ((col > 0));"
--   
alterTableAddConstraint :: HasTable table schema columns => Alias table -> TableConstraint schema columns -> Definition schema schema -- | An AlterColumns describes the alteration to perform on the -- columns of a table. newtype AlterColumns (columns0 :: ColumnsType) (columns1 :: ColumnsType) UnsafeAlterColumns :: ByteString -> AlterColumns [renderAlterColumns] :: AlterColumns -> ByteString -- | An addColumnDefault adds a new Optional column. The new -- column is initially filled with whatever default value is given. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Optional ('Null 'PGtext) ]]
--     definition = alterTable #tab
--       (addColumnDefault #col2 (text & default_ "foo"))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ADD COLUMN col2 text DEFAULT E'foo';"
--   
addColumnDefault :: KnownSymbol column => Alias column -> TypeExpression ( 'Optional ty) -> AlterColumns columns (Create column ( 'Optional ty) columns) -- | An addColumnDefault adds a new Null column. The new -- column is initially filled with NULLs. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Required ('Null 'PGtext) ]]
--     definition = alterTable #tab (addColumnNull #col2 text)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ADD COLUMN col2 text;"
--   
addColumnNull :: KnownSymbol column => Alias column -> TypeExpression ( 'Required ( 'Null ty)) -> AlterColumns columns (Create column ( 'Required ( 'Null ty)) columns) -- | A dropColumn removes a column. Whatever data was in the column -- disappears. Table constraints involving the column are dropped, too. -- However, if the column is referenced by a foreign key constraint of -- another table, PostgreSQL will not silently drop that constraint. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Required ('Null 'PGtext) ]]
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (dropColumn #col2)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab DROP COLUMN col2;"
--   
dropColumn :: KnownSymbol column => Alias column -> AlterColumns columns (Drop column columns) -- | Like dropColumn but authorizes dropping everything that depends -- on the column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" :::
--          '[ "col1" ::: 'Required ('Null 'PGint4)
--           , "col2" ::: 'Required ('Null 'PGtext) ]]
--       '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (dropColumnCascade #col2)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab DROP COLUMN col2 CASCADE;"
--   
dropColumnCascade :: KnownSymbol column => Alias column -> AlterColumns columns (Drop column columns) -- | A renameColumn renames a column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["foo" ::: 'Required ('Null 'PGint4)]]
--       '["tab" ::: '["bar" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (renameColumn #foo #bar)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab RENAME COLUMN foo TO bar;"
--   
renameColumn :: (KnownSymbol column0, KnownSymbol column1) => Alias column0 -> Alias column1 -> AlterColumns columns (Rename column0 column1 columns) -- | An alterColumn alters a single column. alterColumn :: (KnownSymbol column, HasColumn column columns ty0) => Alias column -> AlterColumn ty0 ty1 -> AlterColumns columns (Alter column columns ty1) -- | An AlterColumn describes the alteration to perform on a single -- column. newtype AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) UnsafeAlterColumn :: ByteString -> AlterColumn [renderAlterColumn] :: AlterColumn -> ByteString -- | A setDefault sets a new default for a column. Note that this -- doesn't affect any existing rows in the table, it just changes the -- default for future insertTable and updateTable -- commands. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col (setDefault 5))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col SET DEFAULT 5;"
--   
setDefault :: Expression '[] 'Ungrouped '[] ( 'Required ty) -> AlterColumn (optionality ty) ( 'Optional ty) -- | A dropDefault removes any default value for a column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col dropDefault)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col DROP DEFAULT;"
--   
dropDefault :: AlterColumn (optionality ty) ( 'Required ty) -- | A setNotNull adds a NOT NULL constraint to a column. -- The constraint will be checked immediately, so the table data must -- satisfy the constraint before it can be added. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col setNotNull)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col SET NOT NULL;"
--   
setNotNull :: AlterColumn (optionality ( 'Null ty)) (optionality ( 'NotNull ty)) -- | A dropNotNull drops a NOT NULL constraint from a -- column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
--     definition = alterTable #tab (alterColumn #col dropNotNull)
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col DROP NOT NULL;"
--   
dropNotNull :: AlterColumn (optionality ( 'NotNull ty)) (optionality ( 'Null ty)) -- | An alterType converts a column to a different data type. This -- will succeed only if each existing entry in the column can be -- converted to the new type by an implicit cast. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
--       '["tab" ::: '["col" ::: 'Required ('NotNull 'PGnumeric)]]
--     definition =
--       alterTable #tab (alterColumn #col (alterType (numeric & notNull)))
--   in renderDefinition definition
--   :}
--   "ALTER TABLE tab ALTER COLUMN col TYPE numeric NOT NULL;"
--   
alterType :: TypeExpression ty -> AlterColumn ty0 ty instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.AlterColumn ty0 ty1) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.AlterColumns columns0 columns1) instance GHC.Classes.Ord Squeal.PostgreSQL.Definition.OnUpdateClause instance GHC.Classes.Eq Squeal.PostgreSQL.Definition.OnUpdateClause instance GHC.Show.Show Squeal.PostgreSQL.Definition.OnUpdateClause instance GHC.Generics.Generic Squeal.PostgreSQL.Definition.OnUpdateClause instance GHC.Classes.Ord Squeal.PostgreSQL.Definition.OnDeleteClause instance GHC.Classes.Eq Squeal.PostgreSQL.Definition.OnDeleteClause instance GHC.Show.Show Squeal.PostgreSQL.Definition.OnDeleteClause instance GHC.Generics.Generic Squeal.PostgreSQL.Definition.OnDeleteClause instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.TableConstraint schema columns) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.TableConstraint schema columns) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.TableConstraint schema columns) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.TableConstraint schema columns) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.TableConstraint schema columns) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.Definition schema0 schema1) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.Definition schema0 schema1) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.Definition schema0 schema1) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.Definition schema0 schema1) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.Definition schema0 schema1) instance Control.DeepSeq.NFData Squeal.PostgreSQL.Definition.OnUpdateClause instance Control.DeepSeq.NFData Squeal.PostgreSQL.Definition.OnDeleteClause instance Control.Category.Category Squeal.PostgreSQL.Schema.TablesType Squeal.PostgreSQL.Definition.Definition -- | Binary encoding and decoding between Haskell and PostgreSQL types. module Squeal.PostgreSQL.Binary -- | A ToParam constraint gives an encoding of a Haskell Type -- into into the binary format of a PostgreSQL PGType. class ToParam (x :: Type) (pg :: PGType) -- |
--   >>> :set -XTypeApplications -XDataKinds
--   
--   >>> toParam @Bool @'PGbool False
--   K "\NUL"
--   
-- --
--   >>> toParam @Int16 @'PGint2 0
--   K "\NUL\NUL"
--   
-- --
--   >>> toParam @Int32 @'PGint4 0
--   K "\NUL\NUL\NUL\NUL"
--   
-- --
--   >>> :set -XMultiParamTypeClasses
--   
--   >>> newtype Id = Id { getId :: Int16 } deriving Show
--   
--   >>> instance ToParam Id 'PGint2 where toParam = toParam . getId
--   
--   >>> toParam @Id @'PGint2 (Id 1)
--   K "\NUL\SOH"
--   
toParam :: ToParam x pg => x -> K Encoding pg -- | A ToColumnParam constraint lifts the ToParam encoding of -- a Type to a ColumnType, encoding Maybes to -- Nulls. You should not define instances of ToColumnParam, -- just use the provided instances. class ToColumnParam (x :: Type) (ty :: ColumnType) -- |
--   >>> toColumnParam @Int16 @('Required ('NotNull 'PGint2)) 0
--   K (Just "\NUL\NUL")
--   
-- --
--   >>> toColumnParam @(Maybe Int16) @('Required ('Null 'PGint2)) (Just 0)
--   K (Just "\NUL\NUL")
--   
-- --
--   >>> toColumnParam @(Maybe Int16) @('Required ('Null 'PGint2)) Nothing
--   K Nothing
--   
toColumnParam :: ToColumnParam x ty => x -> K (Maybe ByteString) ty -- | A ToParams constraint generically sequences the encodings of -- Types of the fields of a tuple or record to a row of -- ColumnTypes. You should not define instances of -- ToParams. Instead define Generic instances which in turn -- provide ToParams instances. class SListI tys => ToParams (x :: Type) (tys :: [ColumnType]) -- |
--   >>> type PGparams = '[ 'Required ('NotNull 'PGbool), 'Required ('Null 'PGint2)]
--   
--   >>> toParams @(Bool, Maybe Int16) @PGparams (False, Just 0)
--   K (Just "\NUL") :* (K (Just "\NUL\NUL") :* Nil)
--   
-- --
--   >>> :set -XDeriveGeneric
--   
--   >>> data Hparams = Hparams { col1 :: Bool, col2 :: Maybe Int16} deriving GHC.Generic
--   
--   >>> instance Generic Hparams
--   
--   >>> toParams @Hparams @PGparams (Hparams False (Just 0))
--   K (Just "\NUL") :* (K (Just "\NUL\NUL") :* Nil)
--   
toParams :: ToParams x tys => x -> NP (K (Maybe ByteString)) tys -- | A FromValue constraint gives a parser from the binary format of -- a PostgreSQL PGType into a Haskell Type. class FromValue (pg :: PGType) (y :: Type) -- |
--   >>> newtype Id = Id { getId :: Int16 } deriving Show
--   
--   >>> instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
--   
fromValue :: FromValue pg y => proxy pg -> Value y -- | A FromColumnValue constraint lifts the FromValue parser -- to a decoding of a (Symbol, ColumnType) to a Type, -- decoding Nulls to Maybes. You should not define -- instances for FromColumnValue, just use the provided instances. class FromColumnValue (colty :: (Symbol, ColumnType)) (y :: Type) -- |
--   >>> :set -XTypeOperators -XOverloadedStrings
--   
--   >>> newtype Id = Id { getId :: Int16 } deriving Show
--   
--   >>> instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
--   
--   >>> fromColumnValue @("col" ::: 'Required ('NotNull 'PGint2)) @Id (K (Just "\NUL\SOH"))
--   Id {getId = 1}
--   
-- --
--   >>> fromColumnValue @("col" ::: 'Required ('Null 'PGint2)) @(Maybe Id) (K (Just "\NUL\SOH"))
--   Just (Id {getId = 1})
--   
fromColumnValue :: FromColumnValue colty y => K (Maybe ByteString) colty -> y -- | A FromRow constraint generically sequences the parsings of the -- columns of a ColumnsType into the fields of a record -- Type provided they have the same field names. You should not -- define instances of FromRow. Instead define Generic and -- HasDatatypeInfo instances which in turn provide FromRow -- instances. class SListI results => FromRow (results :: ColumnsType) y -- |
--   >>> :set -XOverloadedStrings
--   
--   >>> import Data.Text
--   
--   >>> newtype Id = Id { getId :: Int16 } deriving Show
--   
--   >>> instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
--   
--   >>> data Hrow = Hrow { userId :: Id, userName :: Maybe Text } deriving (Show, GHC.Generic)
--   
--   >>> instance Generic Hrow
--   
--   >>> instance HasDatatypeInfo Hrow
--   
--   >>> type PGrow = '["userId" ::: 'Required ('NotNull 'PGint2), "userName" ::: 'Required ('Null 'PGtext)]
--   
--   >>> fromRow @PGrow @Hrow (K (Just "\NUL\SOH") :* K (Just "bloodninja") :* Nil)
--   Hrow {userId = Id {getId = 1}, userName = Just "bloodninja"}
--   
fromRow :: FromRow results y => NP (K (Maybe ByteString)) results -> y -- | Only is a 1-tuple type, useful for encoding a single parameter -- with toParams or decoding a single value with fromRow. -- --
--   >>> import Data.Text
--   
--   >>> toParams @(Only (Maybe Text)) @'[ 'Required ('Null 'PGtext)] (Only (Just "foo"))
--   K (Just "foo") :* Nil
--   
-- --
--   >>> type PGShortRow = '["fromOnly" ::: 'Required ('Null 'PGtext)]
--   
--   >>> fromRow @PGShortRow @(Only (Maybe Text)) (K (Just "bar") :* Nil)
--   Only {fromOnly = Just "bar"}
--   
newtype Only x Only :: x -> Only x [fromOnly] :: Only x -> x instance GHC.Generics.Generic (Squeal.PostgreSQL.Binary.Only x) instance GHC.Show.Show x => GHC.Show.Show (Squeal.PostgreSQL.Binary.Only x) instance GHC.Read.Read x => GHC.Read.Read (Squeal.PostgreSQL.Binary.Only x) instance GHC.Classes.Ord x => GHC.Classes.Ord (Squeal.PostgreSQL.Binary.Only x) instance GHC.Classes.Eq x => GHC.Classes.Eq (Squeal.PostgreSQL.Binary.Only x) instance Data.Traversable.Traversable Squeal.PostgreSQL.Binary.Only instance Data.Foldable.Foldable Squeal.PostgreSQL.Binary.Only instance GHC.Base.Functor Squeal.PostgreSQL.Binary.Only instance Generics.SOP.Universe.Generic (Squeal.PostgreSQL.Binary.Only x) instance Generics.SOP.Universe.HasDatatypeInfo (Squeal.PostgreSQL.Binary.Only x) instance (Generics.SOP.Sing.SListI (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) results, Generics.SOP.Universe.IsProductType y ys, Generics.SOP.Constraint.AllZip (GHC.Types.Symbol, Squeal.PostgreSQL.Schema.ColumnType) * Squeal.PostgreSQL.Binary.FromColumnValue results ys, Squeal.PostgreSQL.Schema.SameFields (Generics.SOP.Universe.DatatypeInfoOf y) results) => Squeal.PostgreSQL.Binary.FromRow results y instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromColumnValue ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column ('Squeal.PostgreSQL.Schema.Required ('Squeal.PostgreSQL.Schema.NotNull pg))) y instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromColumnValue ((Squeal.PostgreSQL.Schema.:::) Squeal.PostgreSQL.Schema.ColumnType column ('Squeal.PostgreSQL.Schema.Required ('Squeal.PostgreSQL.Schema.Null pg))) (GHC.Base.Maybe y) instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGbool GHC.Types.Bool instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGint2 GHC.Int.Int16 instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGint4 GHC.Int.Int32 instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGint8 GHC.Int.Int64 instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGfloat4 GHC.Types.Float instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGfloat8 GHC.Types.Double instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGnumeric Data.Scientific.Scientific instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGuuid Data.UUID.Types.Internal.UUID instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGinet (Network.IP.Addr.NetAddr Network.IP.Addr.IP) instance Squeal.PostgreSQL.Binary.FromValue ('Squeal.PostgreSQL.Schema.PGchar 1) GHC.Types.Char instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtext Data.Text.Internal.Text instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtext Data.Text.Internal.Lazy.Text instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGbytea Data.ByteString.Internal.ByteString instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGbytea Data.ByteString.Lazy.Internal.ByteString instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGdate Data.Time.Calendar.Days.Day instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtime Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtimetz (Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay, Data.Time.LocalTime.Internal.TimeZone.TimeZone) instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtimestamp Data.Time.LocalTime.Internal.LocalTime.LocalTime instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGtimestamptz Data.Time.Clock.Internal.UTCTime.UTCTime instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGinterval Data.Time.Clock.Internal.DiffTime.DiffTime instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGjson Data.Aeson.Types.Internal.Value instance Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGjsonb Data.Aeson.Types.Internal.Value instance (Generics.SOP.Sing.SListI Squeal.PostgreSQL.Schema.ColumnType tys, Generics.SOP.Universe.IsProductType x xs, Generics.SOP.Constraint.AllZip * Squeal.PostgreSQL.Schema.ColumnType Squeal.PostgreSQL.Binary.ToColumnParam xs tys) => Squeal.PostgreSQL.Binary.ToParams x tys instance Squeal.PostgreSQL.Binary.ToParam x pg => Squeal.PostgreSQL.Binary.ToColumnParam x (optionality ('Squeal.PostgreSQL.Schema.NotNull pg)) instance Squeal.PostgreSQL.Binary.ToParam x pg => Squeal.PostgreSQL.Binary.ToColumnParam (GHC.Base.Maybe x) (optionality ('Squeal.PostgreSQL.Schema.Null pg)) instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Bool 'Squeal.PostgreSQL.Schema.PGbool instance Squeal.PostgreSQL.Binary.ToParam GHC.Int.Int16 'Squeal.PostgreSQL.Schema.PGint2 instance Squeal.PostgreSQL.Binary.ToParam GHC.Word.Word16 'Squeal.PostgreSQL.Schema.PGint2 instance Squeal.PostgreSQL.Binary.ToParam GHC.Int.Int32 'Squeal.PostgreSQL.Schema.PGint4 instance Squeal.PostgreSQL.Binary.ToParam GHC.Word.Word32 'Squeal.PostgreSQL.Schema.PGint4 instance Squeal.PostgreSQL.Binary.ToParam GHC.Int.Int64 'Squeal.PostgreSQL.Schema.PGint8 instance Squeal.PostgreSQL.Binary.ToParam GHC.Word.Word64 'Squeal.PostgreSQL.Schema.PGint8 instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Float 'Squeal.PostgreSQL.Schema.PGfloat4 instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Double 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Binary.ToParam Data.Scientific.Scientific 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Binary.ToParam Data.UUID.Types.Internal.UUID 'Squeal.PostgreSQL.Schema.PGuuid instance Squeal.PostgreSQL.Binary.ToParam (Network.IP.Addr.NetAddr Network.IP.Addr.IP) 'Squeal.PostgreSQL.Schema.PGinet instance Squeal.PostgreSQL.Binary.ToParam GHC.Types.Char ('Squeal.PostgreSQL.Schema.PGchar 1) instance Squeal.PostgreSQL.Binary.ToParam Data.Text.Internal.Text 'Squeal.PostgreSQL.Schema.PGtext instance Squeal.PostgreSQL.Binary.ToParam Data.Text.Internal.Lazy.Text 'Squeal.PostgreSQL.Schema.PGtext instance Squeal.PostgreSQL.Binary.ToParam Data.ByteString.Internal.ByteString 'Squeal.PostgreSQL.Schema.PGbytea instance Squeal.PostgreSQL.Binary.ToParam Data.ByteString.Lazy.Internal.ByteString 'Squeal.PostgreSQL.Schema.PGbytea instance Squeal.PostgreSQL.Binary.ToParam Data.Time.Calendar.Days.Day 'Squeal.PostgreSQL.Schema.PGdate instance Squeal.PostgreSQL.Binary.ToParam Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay 'Squeal.PostgreSQL.Schema.PGtime instance Squeal.PostgreSQL.Binary.ToParam (Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay, Data.Time.LocalTime.Internal.TimeZone.TimeZone) 'Squeal.PostgreSQL.Schema.PGtimetz instance Squeal.PostgreSQL.Binary.ToParam Data.Time.LocalTime.Internal.LocalTime.LocalTime 'Squeal.PostgreSQL.Schema.PGtimestamp instance Squeal.PostgreSQL.Binary.ToParam Data.Time.Clock.Internal.UTCTime.UTCTime 'Squeal.PostgreSQL.Schema.PGtimestamptz instance Squeal.PostgreSQL.Binary.ToParam Data.Time.Clock.Internal.DiffTime.DiffTime 'Squeal.PostgreSQL.Schema.PGinterval instance Squeal.PostgreSQL.Binary.ToParam Data.Aeson.Types.Internal.Value 'Squeal.PostgreSQL.Schema.PGjson instance Squeal.PostgreSQL.Binary.ToParam Data.Aeson.Types.Internal.Value 'Squeal.PostgreSQL.Schema.PGjsonb -- | PQ is where Squeal statements come to actually get run by -- LibPQ. It contains a PQ indexed monad transformer to -- run Definitions and a MonadPQ constraint for running a -- Manipulation or Query. module Squeal.PostgreSQL.PQ -- | A Connection consists of a LibPQ Connection and a -- phantom TablesType newtype Connection (schema :: TablesType) Connection :: Connection -> Connection [unConnection] :: Connection -> Connection -- | Makes a new connection to the database server. -- -- This function opens a new database connection using the parameters -- taken from the string conninfo. -- -- The passed string can be empty to use all default parameters, or it -- can contain one or more parameter settings separated by whitespace. -- Each parameter setting is in the form keyword = value. Spaces around -- the equal sign are optional. To write an empty value or a value -- containing spaces, surround it with single quotes, e.g., keyword = 'a -- value'. Single quotes and backslashes within the value must be escaped -- with a backslash, i.e., ' and . -- -- To specify the schema you wish to connect with, use type application. -- --
--   >>> :set -XDataKinds
--   
--   >>> :set -XTypeOperators
--   
--   >>> type Schema = '["tab" ::: '["col" ::: 'Required ('Null 'PGint2)]]
--   
--   >>> :set -XTypeApplications
--   
--   >>> :set -XOverloadedStrings
--   
--   >>> conn <- connectdb @Schema "host=localhost port=5432 dbname=exampledb"
--   
-- -- Note that, for now, squeal doesn't offer any protection from -- connecting with the wrong schema! connectdb :: forall schema io. MonadBase IO io => ByteString -> io (Connection schema) -- | Closes the connection to the server. finish :: MonadBase IO io => Connection schema -> io () -- | Do connectdb and finish before and after a computation. withConnection :: forall schema0 schema1 io x. MonadBaseControl IO io => ByteString -> (Connection schema0 -> io (x, Connection schema1)) -> io x -- | We keep track of the schema via an Atkey indexed state monad -- transformer, PQ. newtype PQ (schema0 :: TablesType) (schema1 :: TablesType) (m :: Type -> Type) (x :: Type) PQ :: (Connection schema0 -> m (x, Connection schema1)) -> PQ [runPQ] :: PQ -> Connection schema0 -> m (x, Connection schema1) -- | Run a PQ and discard the result but keep the Connection. execPQ :: Functor m => PQ schema0 schema1 m x -> Connection schema0 -> m (Connection schema1) -- | indexed analog of <*> pqAp :: Monad m => PQ schema0 schema1 m (x -> y) -> PQ schema1 schema2 m x -> PQ schema0 schema2 m y -- | indexed analog of =<< pqBind :: Monad m => (x -> PQ schema1 schema2 m y) -> PQ schema0 schema1 m x -> PQ schema0 schema2 m y -- | indexed analog of flipped >> pqThen :: Monad m => PQ schema1 schema2 m y -> PQ schema0 schema1 m x -> PQ schema0 schema2 m y -- | Run a Definition with exec, we expect that libpq obeys -- the law -- --
--   define statement1 & thenDefine statement2 = define (statement1 >>> statement2)
--   
define :: MonadBase IO io => Definition schema0 schema1 -> PQ schema0 schema1 io (Result '[]) -- | Chain together define actions. thenDefine :: MonadBase IO io => Definition schema1 schema2 -> PQ schema0 schema1 io x -> PQ schema0 schema2 io (Result '[]) -- | MonadPQ is an mtl style constraint, similar to -- MonadState, for using LibPQ to -- -- -- -- To define an instance, you can minimally define only -- manipulateParams, traversePrepared, -- traversePrepared_ and liftPQ. Monad transformers get a -- default instance. class Monad pq => MonadPQ schema pq | pq -> schema manipulateParams :: (MonadPQ schema pq, ToParams x params) => Manipulation schema params ys -> x -> pq (Result ys) manipulateParams :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => ToParams x params => Manipulation schema params ys -> x -> pq (Result ys) manipulate :: MonadPQ schema pq => Manipulation schema '[] ys -> pq (Result ys) runQueryParams :: (MonadPQ schema pq, ToParams x params) => Query schema params ys -> x -> pq (Result ys) runQuery :: MonadPQ schema pq => Query schema '[] ys -> pq (Result ys) traversePrepared :: (MonadPQ schema pq, ToParams x params, Traversable list) => Manipulation schema params ys -> list x -> pq (list (Result ys)) traversePrepared :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (ToParams x params, Traversable list) => Manipulation schema params ys -> list x -> pq (list (Result ys)) forPrepared :: (MonadPQ schema pq, ToParams x params, Traversable list) => list x -> Manipulation schema params ys -> pq (list (Result ys)) traversePrepared_ :: (MonadPQ schema pq, ToParams x params, Foldable list) => Manipulation schema params '[] -> list x -> pq () traversePrepared_ :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (ToParams x params, Foldable list) => Manipulation schema params '[] -> list x -> pq () forPrepared_ :: (MonadPQ schema pq, ToParams x params, Foldable list) => list x -> Manipulation schema params '[] -> pq () liftPQ :: MonadPQ schema pq => (Connection -> IO a) -> pq a liftPQ :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (Connection -> IO a) -> pq a -- | A snapshot of the state of a PQ computation. type PQRun schema = forall m x. Monad m => PQ schema schema m x -> m (x, Connection schema) -- | Helper function in defining MonadBaseControl instance for -- PQ. pqliftWith :: Functor m => (PQRun schema -> m a) -> PQ schema schema m a -- | Encapsulates the result of a squeal command run by LibPQ. -- Results are parameterized by a ColumnsType describing -- the column names and their types. newtype Result (columns :: ColumnsType) Result :: Result -> Result [unResult] :: Result -> Result -- | Just newtypes around a CInt newtype RowNumber RowNumber :: Row -> RowNumber [unRowNumber] :: RowNumber -> Row -- | In addition to being newtypes around a CInt, a -- ColumnNumber is parameterized by a Natural number and -- acts as an index into a row. newtype ColumnNumber (n :: Nat) (cs :: [k]) (c :: k) UnsafeColumnNumber :: Column -> ColumnNumber [getColumnNumber] :: ColumnNumber -> Column -- |
--   >>> getColumnNumber (columnNumber @5 @'[_,_,_,_,_,_])
--   Col 5
--   
class KnownNat n => HasColumnNumber n columns column | n columns -> column columnNumber :: HasColumnNumber n columns column => ColumnNumber n columns column -- | Get a single value corresponding to a given row and column number from -- a Result. getValue :: (FromColumnValue colty y, MonadBase IO io) => RowNumber -> ColumnNumber n columns colty -> Result columns -> io y -- | Get a row corresponding to a given row number from a Result. getRow :: (FromRow columns y, MonadBase IO io) => RowNumber -> Result columns -> io y -- | Get all rows from a Result. getRows :: (FromRow columns y, MonadBase IO io) => Result columns -> io [y] -- | Returns the number of rows (tuples) in the query result. ntuples :: MonadBase IO io => Result columns -> io RowNumber -- | Intended to be used for unfolding in streaming libraries, -- nextRow takes a total number of rows (which can be found with -- ntuples) and a Result and given a row number if it's too -- large returns Nothing, otherwise returning the row along with -- the next row number. nextRow :: (FromRow columns y, MonadBase IO io) => RowNumber -> Result columns -> RowNumber -> io (Maybe (RowNumber, y)) -- | Get the first row if possible from a Result. firstRow :: (FromRow columns y, MonadBase IO io) => Result columns -> io (Maybe y) -- | Lifts actions on results from LibPQ. liftResult :: MonadBase IO io => (Result -> IO x) -> Result results -> io x instance GHC.Base.Functor m => GHC.Base.Functor (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m) instance forall k (column1 :: k) (columns :: [k]). Squeal.PostgreSQL.PQ.HasColumnNumber k 0 ((':) k column1 columns) column1 instance forall k (n :: GHC.Types.Nat) (columns :: [k]) (column :: k) (column' :: k). (GHC.TypeNats.KnownNat n, Squeal.PostgreSQL.PQ.HasColumnNumber k (n GHC.TypeNats.- 1) columns column) => Squeal.PostgreSQL.PQ.HasColumnNumber k n ((':) k column' columns) column instance Control.Monad.Base.MonadBase GHC.Types.IO io => Squeal.PostgreSQL.PQ.MonadPQ schema (Squeal.PostgreSQL.PQ.PQ schema schema io) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Identity.IdentityT * m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Reader.ReaderT * r m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.State.Strict.StateT s m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.State.Lazy.StateT s m) instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Writer.Strict.WriterT w m) instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Writer.Lazy.WriterT w m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Maybe.MaybeT m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Except.ExceptT e m) instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.RWS.Strict.RWST r w s m) instance (GHC.Base.Monoid w, Squeal.PostgreSQL.PQ.MonadPQ schema m) => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.RWS.Lazy.RWST r w s m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.Cont.ContT * r m) instance Squeal.PostgreSQL.PQ.MonadPQ schema m => Squeal.PostgreSQL.PQ.MonadPQ schema (Control.Monad.Trans.List.ListT m) instance GHC.Base.Monad m => GHC.Base.Applicative (Squeal.PostgreSQL.PQ.PQ schema schema m) instance GHC.Base.Monad m => GHC.Base.Monad (Squeal.PostgreSQL.PQ.PQ schema schema m) instance Control.Monad.Trans.Class.MonadTrans (Squeal.PostgreSQL.PQ.PQ schema schema) instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Squeal.PostgreSQL.PQ.PQ schema schema m) instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Squeal.PostgreSQL.PQ.PQ schema schema m) -- | Squeal is a deep embedding of PostgreSQL in Haskell. Let's see an -- example! -- -- First, we need some language extensions because Squeal uses modern GHC -- features. -- --
--   {-# LANGUAGE
--       DataKinds
--     , DeriveGeneric
--     , OverloadedLabels
--     , OverloadedStrings
--     , TypeApplications
--     , TypeOperators
--   #-}
--   
-- -- Here comes the Main module and imports. -- --
--   module Main (main) where
--   
--   import Control.Monad.Base (liftBase)
--   import Data.Int (Int32)
--   import Data.Text (Text)
--   
--   import Squeal.PostgreSQL
--   
-- -- We'll use generics to easily convert between Haskell and PostgreSQL -- values. -- --
--   import qualified Generics.SOP as SOP
--   import qualified GHC.Generics as GHC
--   
-- -- The first step is to define the schema of our database. This is where -- we use DataKinds and TypeOperators. The schema -- consists of a type-level list of tables, a ::: pairing of a -- type level string or Symbol and a list a columns, itself a -- ::: pairing of a Symbol and a ColumnType. The -- ColumnType describes the PostgreSQL type of the column as well -- as whether or not it may contain NULL and whether or not -- inserts and updates can use a DEFAULT. For our schema, we'll -- define two tables, a users table and an emails table. -- --
--   type Schema =
--     '[ "users"  :::
--          '[ "id"   ::: 'Optional ('NotNull 'PGint4)
--           , "name" ::: 'Required ('NotNull 'PGtext)
--           ]
--      , "emails" :::
--          '[ "id"      ::: 'Optional ('NotNull 'PGint4)
--           , "user_id" ::: 'Required ('NotNull 'PGint4)
--           , "email"   ::: 'Required ('Null 'PGtext)
--           ]
--      ]
--   
-- -- Next, we'll write Definitions to set up and tear down the -- schema. In Squeal, a Definition is a createTable, -- alterTable or dropTable command and has two type -- parameters, corresponding to the schema before being run and the -- schema after. We can compose definitions using >>>. -- Here and in the rest of our commands we make use of overloaded labels -- to refer to named tables and columns in our schema. -- --
--   setup :: Definition '[] Schema
--   setup = 
--     createTable #users
--       ( serial `As` #id :*
--         (text & notNull) `As` #name :* Nil )
--       [ primaryKey (Column #id :* Nil) ]
--     >>>
--     createTable #emails
--       ( serial `As` #id :*
--         (int & notNull) `As` #user_id :*
--         text `As` #email :* Nil )
--       [ primaryKey (Column #id :* Nil)
--       , foreignKey (Column #user_id :* Nil) #users (Column #id :* Nil)
--         OnDeleteCascade OnUpdateCascade ]
--   
-- -- Notice that setup starts with an empty schema '[] -- and produces Schema. In our createTable commands we -- included TableConstraints to define primary and foreign keys, -- making them somewhat complex. Our tear down Definition is -- simpler. -- --
--   teardown :: Definition Schema '[]
--   teardown = dropTable #emails >>> dropTable #users
--   
-- -- Next, we'll write Manipulations to insert data into our two -- tables. A Manipulation is a insertInto, update or -- deleteFrom command and has three type parameters, the schema it -- refers to, a list of parameters it can take as input, and a list of -- columns it produces as output. When we insert into the users table, we -- will need a parameter for the name field but not for the -- id field. Since it's optional, we can use a default value. -- However, since the emails table refers to the users table, we will -- need to retrieve the user id that the insert generates and insert it -- into the emails table. Take a careful look at the type and definition -- of both of our inserts. -- --
--   insertUser :: Manipulation Schema
--     '[ 'Required ('NotNull 'PGtext)]
--     '[ "fromOnly" ::: 'Required ('NotNull 'PGint4) ]
--   insertUser = insertInto #users
--     ( Values (def `As` #id :* param @1 `As` #name :* Nil) [] )
--     OnConflictDoNothing (Returning (#id `As` #fromOnly :* Nil))
--   
--   insertEmail :: Manipulation Schema
--     '[ 'Required ('NotNull 'PGint4), 'Required ('Null 'PGtext)] '[]
--   insertEmail = insertInto #emails ( Values
--     ( def `As` #id :*
--       param @1 `As` #user_id :*
--       param @2 `As` #email :* Nil) [] )
--     OnConflictDoNothing (Returning Nil)
--   
-- -- Next we write a Query to retrieve users from the database. -- We're not interested in the ids here, just the usernames and email -- addresses. We need to use an inner join to get the right result. A -- Query is like a Manipulation with the same kind of type -- parameters. -- --
--   getUsers :: Query Schema '[]
--     '[ "userName" ::: 'Required ('NotNull 'PGtext)
--      , "userEmail" ::: 'Required ('Null 'PGtext) ]
--   getUsers = select
--     (#u ! #name `As` #userName :* #e ! #email `As` #userEmail :* Nil)
--     ( from (Table (#users `As` #u)
--       & InnerJoin (Table (#emails `As` #e))
--         (#u ! #id .== #e ! #user_id)) )
--   
-- -- Now that we've defined the SQL side of things, we'll need a Haskell -- type for users. We give the type Generic and -- HasDatatypeInfo instances so that we can decode the rows we -- receive when we run getUsers. Notice that the record fields -- of the User type match the column names of getUsers. -- --
--   data User = User { userName :: Text, userEmail :: Maybe Text }
--     deriving (Show, GHC.Generic)
--   instance SOP.Generic User
--   instance SOP.HasDatatypeInfo User
--   
-- -- Let's also create some users to add to the database. -- --
--   users :: [User]
--   users = 
--     [ User "Alice" (Just "alice@gmail.com")
--     , User "Bob" Nothing
--     , User "Carole" (Just "carole@hotmail.com")
--     ]
--   
-- -- Now we can put together all the pieces into a program. The program -- connects to the database, sets up the schema, inserts the user data -- (using prepared statements as an optimization), queries the user data -- and prints it out and finally closes the connection. We can thread the -- changing schema information through by using the indexed PQ -- monad transformer and when the schema doesn't change we can use -- Monad and MonadPQ functionality. -- --
--   main :: IO ()
--   main = void $
--     withConnection "host=localhost port=5432 dbname=exampledb" . runPQ $
--       define setup
--       & pqThen session
--       & thenDefine teardown
--     where
--       session = do
--         idResults <- traversePrepared insertUser (Only . userName <$> users)
--         ids <- traverse (fmap fromOnly . getRow (RowNumber 0)) idResults
--         traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail <$> users))
--         usersResult <- runQuery getUsers
--         usersRows <- getRows usersResult
--         liftBase $ print (usersRows :: [User])
--   
module Squeal.PostgreSQL