-- 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.4.0.0 -- | Rendering helper functions. module Squeal.PostgreSQL.Render -- | Parenthesize a ByteString. parenthesized :: ByteString -> ByteString -- | Concatenate two ByteStrings with a space between. (<+>) :: ByteString -> ByteString -> ByteString infixr 7 <+> -- | Comma separate a list of ByteStrings. commaSeparated :: [ByteString] -> ByteString -- | Add double quotes around a ByteString. doubleQuoted :: ByteString -> ByteString -- | Add single quotes around a Text and escape single quotes within -- it. singleQuotedText :: Text -> ByteString -- | Add single quotes around a ByteString and escape single quotes -- within it. singleQuotedUtf8 :: 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 :: forall n. KnownNat n => ByteString -- | Render a promoted Symbol. renderSymbol :: forall s. KnownSymbol s => ByteString -- | A class for rendering SQL class RenderSQL sql renderSQL :: RenderSQL sql => sql -> ByteString -- | Print SQL. printSQL :: (RenderSQL sql, MonadBase IO io) => sql -> io () -- | This module provides a type-level DSL for kinds of Postgres types, -- tables, schema, constraints, aliases, enumerated labels, and -- groupings. It also defines useful type families to operate on these. -- Finally, it defines an embedding of Haskell types into Postgres types. module Squeal.PostgreSQL.Schema -- | PGType is the promoted datakind of PostgreSQL types. -- --
--   >>> import Squeal.PostgreSQL.Schema
--   
--   >>> :kind 'PGbool
--   'PGbool :: PGType
--   
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 -- | variable length array PGvararray :: NullityType -> PGType -- | fixed length array PGfixarray :: Nat -> NullityType -> PGType -- | enumerated (enum) types are data types that comprise a static, ordered -- set of values. PGenum :: [Symbol] -> PGType -- | a composite type represents the structure of a row or record; it is -- essentially just a list of field names and their data types. PGcomposite :: RowType -> 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. -- --
--   >>> :kind 'Null 'PGint4
--   'Null 'PGint4 :: NullityType
--   
--   >>> :kind 'NotNull ('PGvarchar 50)
--   'NotNull ('PGvarchar 50) :: NullityType
--   
data NullityType -- | NULL may be present Null :: PGType -> NullityType -- | NULL is absent NotNull :: PGType -> NullityType -- | A RowType is a row of NullityType. They correspond to -- Haskell record types by means of RowPG and are used in many -- places. -- --
--   >>> :{
--   type family PersonRow :: RowType where
--     PersonRow =
--       '[ "name"        ::: 'NotNull 'PGtext
--        , "age"         ::: 'NotNull 'PGint4
--        , "dateOfBirth" :::    'Null 'PGdate
--        ]
--   :}
--   
type RowType = [(Symbol, NullityType)] -- | FromType is a row of RowTypes. It can be thought of as a -- product, or horizontal gluing and is used in FromClauses and -- TableExpressions. type FromType = [(Symbol, RowType)] -- | The PG type family embeds a subset of Haskell types as Postgres -- types. As an open type family, PG is extensible. -- --
--   >>> :kind! PG LocalTime
--   PG LocalTime :: PGType
--   = 'PGtimestamp
--   
-- --
--   >>> newtype MyDouble = My Double
--   
--   >>> type instance PG MyDouble = 'PGfloat8
--   
-- | NullPG turns a Haskell type into a NullityType. -- --
--   >>> :kind! NullPG Double
--   NullPG Double :: NullityType
--   = 'NotNull 'PGfloat8
--   
--   >>> :kind! NullPG (Maybe Double)
--   NullPG (Maybe Double) :: NullityType
--   = 'Null 'PGfloat8
--   
-- | TuplePG turns a Haskell tuple type (including record types) -- into the corresponding list of NullityTypes. -- --
--   >>> :kind! TuplePG (Double, Maybe Char)
--   TuplePG (Double, Maybe Char) :: [NullityType]
--   = '['NotNull 'PGfloat8, 'Null ('PGchar 1)]
--   
-- | RowPG turns a Haskell record type into a RowType. -- --
--   >>> data Person = Person { name :: Text, age :: Int32 } deriving GHC.Generic
--   
--   >>> instance Generic Person
--   
--   >>> instance HasDatatypeInfo Person
--   
--   >>> :kind! RowPG Person
--   RowPG Person :: [(Symbol, NullityType)]
--   = '["name" ::: 'NotNull 'PGtext, "age" ::: 'NotNull 'PGint4]
--   
-- | The Json newtype is an indication that the Haskell type it's -- applied to should be stored as PGjson. newtype Json hask Json :: hask -> Json hask [getJson] :: Json hask -> hask -- | The Jsonb newtype is an indication that the Haskell type it's -- applied to should be stored as PGjsonb. newtype Jsonb hask Jsonb :: hask -> Jsonb hask [getJsonb] :: Jsonb hask -> hask -- | The Composite newtype is an indication that the Haskell type -- it's applied to should be stored as a PGcomposite. newtype Composite record Composite :: record -> Composite record [getComposite] :: Composite record -> record -- | The Enumerated newtype is an indication that the Haskell type -- it's applied to should be stored as PGenum. newtype Enumerated enum Enumerated :: enum -> Enumerated enum [getEnumerated] :: Enumerated enum -> enum -- | ColumnType encodes the allowance of DEFAULT and -- NULL and the base PGType for a column. -- --
--   >>> :set -XTypeFamilies -XTypeInType
--   
--   >>> import GHC.TypeLits
--   
--   >>> type family IdColumn :: ColumnType where IdColumn = 'Def :=> 'NotNull 'PGint4
--   
--   >>> type family EmailColumn :: ColumnType where EmailColumn = 'NoDef :=> 'Null 'PGtext
--   
type ColumnType = (ColumnConstraint, NullityType) -- | ColumnsType is a row of ColumnTypes. -- --
--   >>> :{
--   type family UsersColumns :: ColumnsType where
--     UsersColumns =
--       '[ "name" ::: 'NoDef :=> 'NotNull 'PGtext
--        , "id"   :::   'Def :=> 'NotNull 'PGint4
--        ]
--   :}
--   
type ColumnsType = [(Symbol, ColumnType)] -- | TableType encodes a row of constraints on a table as well as -- the types of its columns. -- --
--   >>> :{
--   type family UsersTable :: TableType where
--     UsersTable =
--       '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
--       '[ "id"       :::   'Def :=> 'NotNull 'PGint4
--        , "name"     ::: 'NoDef :=> 'NotNull 'PGtext
--        ]
--   :}
--   
type TableType = (TableConstraints, ColumnsType) -- | A SchemumType is a user-defined type, either a Table, -- View or Typedef. data SchemumType Table :: TableType -> SchemumType View :: RowType -> SchemumType Typedef :: PGType -> SchemumType -- | The schema of a database consists of a list of aliased, user-defined -- SchemumTypes. -- --
--   >>> :{
--   type family Schema :: SchemaType where
--     Schema =
--       '[ "users" ::: 'Table (
--           '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
--           '[ "id"   :::   'Def :=> 'NotNull 'PGint4
--           , "name" ::: 'NoDef :=> 'NotNull 'PGtext
--           ])
--       , "emails" ::: 'Table (
--           '[ "pk_emails"  ::: 'PrimaryKey '["id"]
--           , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"]
--           ] :=>
--           '[ "id"      :::   'Def :=> 'NotNull 'PGint4
--           , "user_id" ::: 'NoDef :=> 'NotNull 'PGint4
--           , "email"   ::: 'NoDef :=>    'Null 'PGtext
--           ])
--       ]
--   :}
--   
type SchemaType = [(Symbol, SchemumType)] -- | The constraint operator, :=> is a type level pair between a -- "constraint" and some type, for use in pairing a -- ColumnConstraint with a NullityType to produce a -- ColumnType or a TableConstraints and a -- ColumnsType to produce a TableType. type (:=>) constraint ty = '(constraint, ty) -- | ColumnConstraint encodes the availability of DEFAULT -- for inserts and updates. A column can be assigned a default value. A -- data Manipulation command can also request explicitly that a -- column be set to its default value, without having to know what that -- value is. data ColumnConstraint -- | DEFAULT is available for inserts and updates Def :: ColumnConstraint -- | DEFAULT is unavailable for inserts and updates NoDef :: ColumnConstraint -- | TableConstraint encodes various forms of data constraints of -- columns in a table. 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. data TableConstraint Check :: [Symbol] -> TableConstraint Unique :: [Symbol] -> TableConstraint PrimaryKey :: [Symbol] -> TableConstraint ForeignKey :: [Symbol] -> Symbol -> [Symbol] -> TableConstraint -- | A TableConstraints is a row of TableConstraints. type TableConstraints = [(Symbol, TableConstraint)] -- | A ForeignKey must reference columns that either are a -- PrimaryKey or form a Unique constraint. -- | The alias operator ::: is like a promoted version of As, -- a type level pair between an alias and some type. type (:::) (alias :: Symbol) ty = '(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 #jimbob
--   "\"jimbob\""
--   
renderAlias :: KnownSymbol alias => Alias alias -> ByteString -- |
--   >>> import Generics.SOP (NP(..))
--   
--   >>> renderAliases (#jimbob :* #kandi)
--   ["\"jimbob\"","\"kandi\""]
--   
renderAliases :: All KnownSymbol aliases => NP Alias aliases -> [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) -- | The Aliasable class provides a way to scrap your Nils in -- an NP list of Aliased expressions. class KnownSymbol alias => Aliasable alias expression aliased | aliased -> expression, aliased -> alias as :: Aliasable alias expression aliased => expression -> Alias alias -> aliased -- |
--   >>> let renderMaybe = fromString . maybe "Nothing" (const "Just")
--   
--   >>> renderAliasedAs renderMaybe (Just (3::Int) `As` #an_int)
--   "Just AS \"an_int\""
--   
renderAliasedAs :: (forall ty. expression ty -> ByteString) -> Aliased expression aliased -> ByteString -- | Has alias fields field is a constraint that proves that -- fields has a field of alias ::: field, inferring -- field from alias and fields. class KnownSymbol alias => Has (alias :: Symbol) (fields :: [(Symbol, kind)]) (field :: kind) | alias fields -> field -- | HasUnique alias fields field is a constraint that proves that -- fields is a singleton of alias ::: field. type HasUnique alias fields field = fields ~ '[alias ::: field] -- | HasAll extends Has to take lists of aliases and -- fields and infer a list of subfields. class (All KnownSymbol aliases) => HasAll (aliases :: [Symbol]) (fields :: [(Symbol, kind)]) (subfields :: [(Symbol, kind)]) | aliases fields -> subfields class IsLabel (x :: Symbol) a fromLabel :: IsLabel x a => a -- | Analagous to IsLabel, the constraint IsQualified defines -- ! for a column alias qualified by a table alias. class IsQualified table column expression (!) :: IsQualified table column expression => Alias table -> Alias column -> expression -- |
--   >>> renderAliasString #ohmahgerd
--   "'ohmahgerd'"
--   
renderAliasString :: KnownSymbol alias => Alias alias -> ByteString -- | IsPGlabel looks very much like the IsLabel class. -- Whereas the overloaded label, fromLabel is used for column -- references, labels are used for enum terms. A label is -- called with type application like `label @"beef"`. class IsPGlabel (label :: Symbol) expr label :: IsPGlabel label expr => expr -- | A PGlabel unit type with an IsPGlabel instance data PGlabel (label :: Symbol) PGlabel :: PGlabel -- | Renders a label renderLabel :: KnownSymbol label => proxy label -> ByteString -- | Renders a list of labels renderLabels :: All KnownSymbol labels => NP PGlabel labels -> [ByteString] -- | The LabelsPG type family calculates the constructors of a -- Haskell enum type. -- --
--   >>> data Schwarma = Beef | Lamb | Chicken deriving GHC.Generic
--   
--   >>> instance Generic Schwarma
--   
--   >>> instance HasDatatypeInfo Schwarma
--   
--   >>> :kind! LabelsPG Schwarma
--   LabelsPG Schwarma :: [Type.ConstructorName]
--   = '["Beef", "Lamb", "Chicken"]
--   
-- | Grouping is an auxiliary namespace, created by GROUP -- BY clauses (group), and used for typesafe aggregation data Grouping -- | no aggregation permitted Ungrouped :: Grouping -- | aggregation required for any column which is not grouped Grouped :: [(Symbol, Symbol)] -> Grouping -- | 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 -- | An AlignedList is a type-aligned list or free category. data AlignedList p x0 x1 [Done] :: AlignedList p x x [:>>] :: p x0 x1 -> AlignedList p x1 x2 -> AlignedList p x0 x2 -- | A single step. single :: p x0 x1 -> AlignedList p x0 x1 -- | Create alias x xs adds alias ::: x to the end of -- xs and is used in createTable statements and in -- ALTER TABLE addColumn. -- | 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 x xs 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. -- | Drop all TableConstraints that involve a column -- | Join is simply promoted ++ and is used in JOINs -- in FromClauses. -- | Elem is a promoted elem. -- | In x xs is a constraint that proves that x is in -- xs. -- | Calculate the Length of a type level list -- --
--   >>> :kind! Length '[Char,String,Bool,Double]
--   Length '[Char,String,Bool,Double] :: Nat
--   = 4
--   
-- | The object identifier of a PGType. -- --
--   >>> :set -XTypeApplications
--   
--   >>> oid @'PGbool
--   16
--   
class HasOid (ty :: PGType) oid :: HasOid ty => Word32 -- | Numeric Postgres types. type PGNum = '[ 'PGint2, 'PGint4, 'PGint8, 'PGnumeric, 'PGfloat4, 'PGfloat8] -- | Integral Postgres types. type PGIntegral = '[ 'PGint2, 'PGint4, 'PGint8] -- | Floating Postgres types. type PGFloating = '[ 'PGfloat4, 'PGfloat8, 'PGnumeric] -- | PGTypeOf forgets about NULL and any column -- constraints. -- | Ensure a type is a valid array type with a specific element type. -- | Ensure a type is a valid array type. -- | Ensure a type is a valid array type whose elements are text. type PGTextArray name arr = PGArrayOf name arr ( 'NotNull 'PGtext) -- | Is a type a valid JSON type? type PGJsonType = '[ 'PGjson, 'PGjsonb] -- | Is a type a valid JSON key? type PGJsonKey = '[ 'PGint2, 'PGint4, 'PGtext] -- | Equality constraint on the underlying PGType of two columns. class SamePGType (ty0 :: (Symbol, ColumnType)) (ty1 :: (Symbol, ColumnType)) -- | 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 -- NullityType. -- | NullifyRow is an idempotent that nullifies a RowType. -- | NullifyFrom is an idempotent that nullifies a FromType -- used to nullify the left or right hand side of an outer join in a -- FromClause. -- | TableToColumns removes table constraints. -- | Convert a table to a row type. instance GHC.Generics.Generic (Squeal.PostgreSQL.Schema.Enumerated enum) instance GHC.Read.Read enum => GHC.Read.Read (Squeal.PostgreSQL.Schema.Enumerated enum) instance GHC.Show.Show enum => GHC.Show.Show (Squeal.PostgreSQL.Schema.Enumerated enum) instance GHC.Classes.Ord enum => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Enumerated enum) instance GHC.Classes.Eq enum => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Enumerated enum) instance GHC.Generics.Generic (Squeal.PostgreSQL.Schema.Composite record) instance GHC.Read.Read record => GHC.Read.Read (Squeal.PostgreSQL.Schema.Composite record) instance GHC.Show.Show record => GHC.Show.Show (Squeal.PostgreSQL.Schema.Composite record) instance GHC.Classes.Ord record => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Composite record) instance GHC.Classes.Eq record => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Composite record) instance GHC.Generics.Generic (Squeal.PostgreSQL.Schema.Jsonb hask) instance GHC.Read.Read hask => GHC.Read.Read (Squeal.PostgreSQL.Schema.Jsonb hask) instance GHC.Show.Show hask => GHC.Show.Show (Squeal.PostgreSQL.Schema.Jsonb hask) instance GHC.Classes.Ord hask => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Jsonb hask) instance GHC.Classes.Eq hask => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Jsonb hask) instance GHC.Generics.Generic (Squeal.PostgreSQL.Schema.Json hask) instance GHC.Read.Read hask => GHC.Read.Read (Squeal.PostgreSQL.Schema.Json hask) instance GHC.Show.Show hask => GHC.Show.Show (Squeal.PostgreSQL.Schema.Json hask) instance GHC.Classes.Ord hask => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Json hask) instance GHC.Classes.Eq hask => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Json hask) 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 k (expression :: k -> *) (ty :: k) (alias :: GHC.Types.Symbol). GHC.Show.Show (expression ty) => GHC.Show.Show (Squeal.PostgreSQL.Schema.Aliased expression (alias Squeal.PostgreSQL.Schema.::: ty)) instance forall k (expression :: k -> *) (ty :: k) (alias :: GHC.Types.Symbol). GHC.Classes.Eq (expression ty) => GHC.Classes.Eq (Squeal.PostgreSQL.Schema.Aliased expression (alias Squeal.PostgreSQL.Schema.::: ty)) instance forall k (expression :: k -> *) (ty :: k) (alias :: GHC.Types.Symbol). GHC.Classes.Ord (expression ty) => GHC.Classes.Ord (Squeal.PostgreSQL.Schema.Aliased expression (alias Squeal.PostgreSQL.Schema.::: ty)) instance forall k (p :: k -> k -> *). Control.Category.Category (Squeal.PostgreSQL.Schema.AlignedList p) instance (label ~ label1) => Squeal.PostgreSQL.Schema.IsPGlabel label (Squeal.PostgreSQL.Schema.PGlabel label1) instance (labels ~ '[label]) => Squeal.PostgreSQL.Schema.IsPGlabel label (Generics.SOP.NP.NP Squeal.PostgreSQL.Schema.PGlabel labels) instance forall k (ty0 :: k) (ty1 :: k) (alias0 :: GHC.Types.Symbol) (def0 :: Squeal.PostgreSQL.Schema.ColumnConstraint) (nullity0 :: k -> Squeal.PostgreSQL.Schema.NullityType) (alias1 :: GHC.Types.Symbol) (def1 :: Squeal.PostgreSQL.Schema.ColumnConstraint) (nullity1 :: k -> Squeal.PostgreSQL.Schema.NullityType). (ty0 ~ ty1) => Squeal.PostgreSQL.Schema.SamePGType (alias0 Squeal.PostgreSQL.Schema.::: (def0 Squeal.PostgreSQL.Schema.:=> nullity0 ty0)) (alias1 Squeal.PostgreSQL.Schema.::: (def1 Squeal.PostgreSQL.Schema.:=> nullity1 ty1)) instance Squeal.PostgreSQL.Schema.IsQualified table column (Squeal.PostgreSQL.Schema.Alias table, Squeal.PostgreSQL.Schema.Alias column) instance forall kind (fields :: [(GHC.Types.Symbol, kind)]). Squeal.PostgreSQL.Schema.HasAll '[] fields '[] instance forall k (alias :: GHC.Types.Symbol) (fields :: [(GHC.Types.Symbol, k)]) (field :: k) (aliases :: [GHC.Types.Symbol]) (subfields :: [(GHC.Types.Symbol, k)]). (Squeal.PostgreSQL.Schema.Has alias fields field, Squeal.PostgreSQL.Schema.HasAll aliases fields subfields) => Squeal.PostgreSQL.Schema.HasAll (alias : aliases) fields ((alias Squeal.PostgreSQL.Schema.::: field) : subfields) instance forall kind (alias :: GHC.Types.Symbol) (field :: kind) (fields :: [(GHC.Types.Symbol, kind)]). GHC.TypeLits.KnownSymbol alias => Squeal.PostgreSQL.Schema.Has alias ((alias Squeal.PostgreSQL.Schema.::: field) : fields) field instance forall kind (alias :: GHC.Types.Symbol) (fields :: [(GHC.Types.Symbol, kind)]) (field :: kind) (field' :: (GHC.Types.Symbol, kind)). (GHC.TypeLits.KnownSymbol alias, Squeal.PostgreSQL.Schema.Has alias fields field) => Squeal.PostgreSQL.Schema.Has alias (field' : fields) field instance forall k (alias :: GHC.Types.Symbol) (alias1 :: GHC.Types.Symbol) (expression :: k -> *) (ty :: k). (GHC.TypeLits.KnownSymbol alias, alias ~ alias1) => Squeal.PostgreSQL.Schema.Aliasable alias (expression ty) (Squeal.PostgreSQL.Schema.Aliased expression (alias1 Squeal.PostgreSQL.Schema.::: ty)) instance forall k (alias :: GHC.Types.Symbol) (tys :: [(GHC.Types.Symbol, k)]) (ty :: k) (expression :: k -> *). (GHC.TypeLits.KnownSymbol alias, tys ~ '[alias Squeal.PostgreSQL.Schema.::: ty]) => Squeal.PostgreSQL.Schema.Aliasable alias (expression ty) (Generics.SOP.NP.NP (Squeal.PostgreSQL.Schema.Aliased expression) tys) instance (alias0 ~ alias1, alias0 ~ alias2, GHC.TypeLits.KnownSymbol alias2) => GHC.OverloadedLabels.IsLabel alias0 (Squeal.PostgreSQL.Schema.Aliased Squeal.PostgreSQL.Schema.Alias (alias1 Squeal.PostgreSQL.Schema.::: alias2)) instance (alias1 ~ alias2) => GHC.OverloadedLabels.IsLabel alias1 (Squeal.PostgreSQL.Schema.Alias alias2) instance (aliases ~ '[alias]) => GHC.OverloadedLabels.IsLabel alias (Generics.SOP.NP.NP Squeal.PostgreSQL.Schema.Alias aliases) instance GHC.TypeLits.KnownSymbol alias => Squeal.PostgreSQL.Render.RenderSQL (Squeal.PostgreSQL.Schema.Alias alias) instance (GHC.TypeLits.KnownSymbol table, GHC.TypeLits.KnownSymbol column) => Squeal.PostgreSQL.Schema.GroupedBy table column ('(table, column) : bys) instance forall a (table :: GHC.Types.Symbol) (column :: GHC.Types.Symbol) (bys :: [a]) (tabcol :: a). (GHC.TypeLits.KnownSymbol table, GHC.TypeLits.KnownSymbol column, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => Squeal.PostgreSQL.Schema.GroupedBy table column (tabcol : bys) instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGbool instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGint2 instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGint4 instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGint8 instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGfloat4 instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Schema.HasOid ('Squeal.PostgreSQL.Schema.PGchar n) instance Squeal.PostgreSQL.Schema.HasOid ('Squeal.PostgreSQL.Schema.PGvarchar n) instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGtext instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGbytea instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGtimestamp instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGtimestamptz instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGdate instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGtime instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGtimetz instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGinterval instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGuuid instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGinet instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGjson instance Squeal.PostgreSQL.Schema.HasOid 'Squeal.PostgreSQL.Schema.PGjsonb -- | 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 -- insertRow 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 (schema :: SchemaType) (from :: FromType) (grouping :: Grouping) (params :: [NullityType]) (ty :: NullityType) 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 KnownNat n => HasParameter (n :: Nat) (schema :: SchemaType) (params :: [NullityType]) (ty :: NullityType) | n params -> ty -- | parameter takes a Nat using type application and a -- TypeExpression. -- --
--   >>> let expr = parameter @1 int4 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
--   
--   >>> printSQL expr
--   ($1 :: int4)
--   
parameter :: HasParameter n schema params ty => TypeExpression schema ty -> Expression schema from grouping params ty -- | param takes a Nat using type application and for basic -- types, infers a TypeExpression. -- --
--   >>> let expr = param @1 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
--   
--   >>> printSQL expr
--   ($1 :: int4)
--   
param :: forall n schema params from grouping ty. (PGTyped schema ty, HasParameter n schema params ty) => Expression schema from grouping params ty -- | analagous to Nothing -- --
--   >>> printSQL null_
--   NULL
--   
null_ :: Expression schema rels grouping params ( 'Null ty) -- | analagous to Just -- --
--   >>> printSQL $ notNull true
--   TRUE
--   
notNull :: Expression schema rels grouping params ( 'NotNull ty) -> Expression schema rels grouping params ( 'Null ty) -- | return the leftmost value which is not NULL -- --
--   >>> printSQL $ coalesce [null_, true] false
--   COALESCE(NULL, TRUE, FALSE)
--   
coalesce :: [Expression schema from grouping params ( 'Null ty)] -> Expression schema from grouping params ( 'NotNull ty) -> Expression schema from grouping params ( 'NotNull ty) -- | analagous to fromMaybe using COALESCE -- --
--   >>> printSQL $ fromNull true null_
--   COALESCE(NULL, TRUE)
--   
fromNull :: Expression schema from grouping params ( 'NotNull ty) -> Expression schema from grouping params ( 'Null ty) -> Expression schema from grouping params ( 'NotNull ty) -- |
--   >>> printSQL $ null_ & isNull
--   NULL IS NULL
--   
isNull :: Expression schema from grouping params ( 'Null ty) -> Condition schema from grouping params -- |
--   >>> printSQL $ null_ & isNotNull
--   NULL IS NOT NULL
--   
isNotNull :: Expression schema from grouping params ( 'Null ty) -> Condition schema from grouping params -- | analagous to maybe using IS NULL -- --
--   >>> printSQL $ matchNull true not_ null_
--   CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
--   
matchNull :: Expression schema from grouping params (nullty) -> (Expression schema from grouping params ( 'NotNull ty) -> Expression schema from grouping params (nullty)) -> Expression schema from grouping params ( 'Null ty) -> Expression schema from grouping params (nullty) -- | right inverse to fromNull, if its arguments are equal then -- nullIf gives NULL. -- --
--   >>> :set -XTypeApplications -XDataKinds
--   
--   >>> let expr = nullIf false (param @1) :: Expression schema rels grp '[ 'NotNull 'PGbool] ('Null 'PGbool)
--   
--   >>> printSQL expr
--   NULL IF (FALSE, ($1 :: bool))
--   
nullIf :: Expression schema from grouping params ( 'NotNull ty) -> Expression schema from grouping params ( 'NotNull ty) -> Expression schema from grouping params ( 'Null ty) -- |
--   >>> printSQL $ array [null_, false, true]
--   ARRAY[NULL, FALSE, TRUE]
--   
array :: [Expression schema from grouping params ty] -> Expression schema from grouping params (nullity ( 'PGvararray ty)) -- |
--   >>> printSQL $ array [null_, false, true] & index 2
--   (ARRAY[NULL, FALSE, TRUE])[2]
--   
index :: Word64 -> Expression schema from grouping params (nullity ( 'PGvararray ty)) -> Expression schema from grouping params (NullifyType ty) -- | A row constructor is an expression that builds a row value (also -- called a composite value) using values for its member fields. -- --
--   >>> :{
--   type Complex = 'PGcomposite
--     '[ "real"      ::: 'NotNull 'PGfloat8
--      , "imaginary" ::: 'NotNull 'PGfloat8 ]
--   :}
--   
-- --
--   >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
--   
--   >>> printSQL i
--   ROW(0, 1)
--   
row :: SListI row => NP (Aliased (Expression schema from grouping params)) row -> Expression schema from grouping params (nullity ( 'PGcomposite row)) -- |
--   >>> :{
--   type Complex = 'PGcomposite
--     '[ "real"      ::: 'NotNull 'PGfloat8
--      , "imaginary" ::: 'NotNull 'PGfloat8 ]
--   :}
--   
-- --
--   >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression '["complex" ::: 'Typedef Complex] '[] 'Ungrouped '[] ('NotNull Complex)
--   
--   >>> printSQL $ i & field #complex #imaginary
--   (ROW(0, 1)::"complex")."imaginary"
--   
field :: (Has tydef schema ( 'Typedef ( 'PGcomposite row)), Has field row ty) => Alias tydef -> Alias field -> Expression schema from grouping params ( 'NotNull ( 'PGcomposite row)) -> Expression schema from grouping params ty -- |
--   >>> printSQL $ unsafeBinaryOp "OR" true false
--   (TRUE OR FALSE)
--   
unsafeBinaryOp :: ByteString -> Expression schema from grouping params (ty0) -> Expression schema from grouping params (ty1) -> Expression schema from grouping params (ty2) -- |
--   >>> printSQL $ unsafeUnaryOp "NOT" true
--   (NOT TRUE)
--   
unsafeUnaryOp :: ByteString -> Expression schema from grouping params (ty0) -> Expression schema from grouping params (ty1) -- |
--   >>> printSQL $ unsafeFunction "f" true
--   f(TRUE)
--   
unsafeFunction :: ByteString -> Expression schema from grouping params (xty) -> Expression schema from grouping params (yty) -- | Helper for defining variadic functions. unsafeVariadicFunction :: SListI elems => ByteString -> NP (Expression schema from grouping params) elems -> Expression schema from grouping params ret -- |
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGfloat4)
--     expression = atan2_ pi 2
--   in printSQL expression
--   :}
--   atan2(pi(), 2)
--   
atan2_ :: float `In` PGFloating => Expression schema from grouping params (nullity float) -> Expression schema from grouping params (nullity float) -> Expression schema from grouping params (nullity float) -- |
--   >>> printSQL $ true & cast int4
--   (TRUE :: int4)
--   
cast :: TypeExpression schema ty1 -> Expression schema from grouping params ty0 -> Expression schema from grouping params ty1 -- | integer division, truncates the result -- --
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGint2)
--     expression = 5 `quot_` 2
--   in printSQL expression
--   :}
--   (5 / 2)
--   
quot_ :: int `In` PGIntegral => Expression schema from grouping params (nullity int) -> Expression schema from grouping params (nullity int) -> Expression schema from grouping params (nullity int) -- | remainder upon integer division -- --
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGint2)
--     expression = 5 `rem_` 2
--   in printSQL expression
--   :}
--   (5 % 2)
--   
rem_ :: int `In` PGIntegral => Expression schema from grouping params (nullity int) -> Expression schema from grouping params (nullity int) -> Expression schema from grouping params (nullity int) -- |
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGfloat4)
--     expression = trunc pi
--   in printSQL expression
--   :}
--   trunc(pi())
--   
trunc :: frac `In` PGFloating => Expression schema from grouping params (nullity frac) -> Expression schema from grouping params (nullity frac) -- |
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGfloat4)
--     expression = round_ pi
--   in printSQL expression
--   :}
--   round(pi())
--   
round_ :: frac `In` PGFloating => Expression schema from grouping params (nullity frac) -> Expression schema from grouping params (nullity frac) -- |
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGfloat4)
--     expression = ceiling_ pi
--   in printSQL expression
--   :}
--   ceiling(pi())
--   
ceiling_ :: frac `In` PGFloating => Expression schema from grouping params (nullity frac) -> Expression schema from grouping params (nullity frac) -- |
--   >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
--   
--   >>> printSQL expr
--   GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
--   
greatest :: Expression schema from grouping params (nullty) -> [Expression schema from grouping params (nullty)] -> Expression schema from grouping params (nullty) -- |
--   >>> printSQL $ least currentTimestamp [null_]
--   LEAST(CURRENT_TIMESTAMP, NULL)
--   
least :: Expression schema from grouping params (nullty) -> [Expression schema from grouping params (nullty)] -> Expression schema from grouping params (nullty) -- |
--   >>> printSQL true
--   TRUE
--   
true :: Expression schema from grouping params (nullity 'PGbool) -- |
--   >>> printSQL false
--   FALSE
--   
false :: Expression schema from grouping params (nullity 'PGbool) -- |
--   >>> printSQL $ not_ true
--   (NOT TRUE)
--   
not_ :: Expression schema from grouping params (nullity 'PGbool) -> Expression schema from grouping params (nullity 'PGbool) -- |
--   >>> printSQL $ true .&& false
--   (TRUE AND FALSE)
--   
(.&&) :: Expression schema from grouping params (nullity 'PGbool) -> Expression schema from grouping params (nullity 'PGbool) -> Expression schema from grouping params (nullity 'PGbool) infixr 3 .&& -- |
--   >>> printSQL $ true .|| false
--   (TRUE OR FALSE)
--   
(.||) :: Expression schema from grouping params (nullity 'PGbool) -> Expression schema from grouping params (nullity 'PGbool) -> Expression schema from grouping params (nullity 'PGbool) infixr 2 .|| -- | A Condition is an Expression, which can evaluate to -- true, false or null_. This is because SQL uses a -- three valued logic. type Condition schema from grouping params = Expression schema from grouping params ( 'Null 'PGbool) -- |
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGint2)
--     expression = caseWhenThenElse [(true, 1), (false, 2)] 3
--   in printSQL expression
--   :}
--   CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
--   
caseWhenThenElse :: [(Condition schema from grouping params, Expression schema from grouping params ty)] -> Expression schema from grouping params ty -> Expression schema from grouping params ty -- |
--   >>> :{
--   let
--     expression :: Expression schema from grouping params (nullity 'PGint2)
--     expression = ifThenElse true 1 0
--   in printSQL expression
--   :}
--   CASE WHEN TRUE THEN 1 ELSE 0 END
--   
ifThenElse :: Condition schema from grouping params -> Expression schema from grouping params ty -> Expression schema from grouping params ty -> Expression schema from grouping params ty -- | Comparison operations like .==, ./=, .>, -- .>=, .< and .<= will produce -- NULLs if one of their arguments is NULL. -- --
--   >>> printSQL $ true .== null_
--   (TRUE = NULL)
--   
(.==) :: Expression schema from grouping params (nullity0 ty) -> Expression schema from grouping params (nullity1 ty) -> Condition schema from grouping params infix 4 .== -- |
--   >>> printSQL $ true ./= null_
--   (TRUE <> NULL)
--   
(./=) :: Expression schema from grouping params (nullity0 ty) -> Expression schema from grouping params (nullity1 ty) -> Condition schema from grouping params infix 4 ./= -- |
--   >>> printSQL $ true .>= null_
--   (TRUE >= NULL)
--   
(.>=) :: Expression schema from grouping params (nullity0 ty) -> Expression schema from grouping params (nullity1 ty) -> Condition schema from grouping params infix 4 .>= -- |
--   >>> printSQL $ true .< null_
--   (TRUE < NULL)
--   
(.<) :: Expression schema from grouping params (nullity0 ty) -> Expression schema from grouping params (nullity1 ty) -> Condition schema from grouping params infix 4 .< -- |
--   >>> printSQL $ true .<= null_
--   (TRUE <= NULL)
--   
(.<=) :: Expression schema from grouping params (nullity0 ty) -> Expression schema from grouping params (nullity1 ty) -> Condition schema from grouping params infix 4 .<= -- |
--   >>> printSQL $ true .> null_
--   (TRUE > NULL)
--   
(.>) :: Expression schema from grouping params (nullity0 ty) -> Expression schema from grouping params (nullity1 ty) -> Condition schema from grouping params infix 4 .> -- |
--   >>> printSQL currentDate
--   CURRENT_DATE
--   
currentDate :: Expression schema from grouping params (nullity 'PGdate) -- |
--   >>> printSQL currentTime
--   CURRENT_TIME
--   
currentTime :: Expression schema from grouping params (nullity 'PGtimetz) -- |
--   >>> printSQL currentTimestamp
--   CURRENT_TIMESTAMP
--   
currentTimestamp :: Expression schema from grouping params (nullity 'PGtimestamptz) -- |
--   >>> printSQL localTime
--   LOCALTIME
--   
localTime :: Expression schema from grouping params (nullity 'PGtime) -- |
--   >>> printSQL localTimestamp
--   LOCALTIMESTAMP
--   
localTimestamp :: Expression schema from grouping params (nullity 'PGtimestamp) -- |
--   >>> printSQL $ lower "ARRRGGG"
--   lower(E'ARRRGGG')
--   
lower :: Expression schema from grouping params (nullity 'PGtext) -> Expression schema from grouping params (nullity 'PGtext) -- |
--   >>> printSQL $ upper "eeee"
--   upper(E'eeee')
--   
upper :: Expression schema from grouping params (nullity 'PGtext) -> Expression schema from grouping params (nullity 'PGtext) -- |
--   >>> printSQL $ charLength "four"
--   char_length(E'four')
--   
charLength :: Expression schema from grouping params (nullity 'PGtext) -> Expression schema from grouping params (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. -- --
--   >>> printSQL $ "abc" `like` "a%"
--   (E'abc' LIKE E'a%')
--   
like :: Expression schema from grouping params (nullity 'PGtext) -> Expression schema from grouping params (nullity 'PGtext) -> Expression schema from grouping params (nullity 'PGbool) -- | Get JSON value (object field or array element) at a key. (.->) :: (json `In` PGJsonType, key `In` PGJsonKey) => Expression schema from grouping params (nullity json) -> Expression schema from grouping params (nullity key) -> Expression schema from grouping params ( 'Null json) infixl 8 .-> -- | Get JSON value (object field or array element) at a key, as text. (.->>) :: (json `In` PGJsonType, key `In` PGJsonKey) => Expression schema from grouping params (nullity json) -> Expression schema from grouping params (nullity key) -> Expression schema from grouping params ( 'Null 'PGtext) infixl 8 .->> -- | Get JSON value at a specified path. (.#>) :: (json `In` PGJsonType, PGTextArray "(.#>)" path) => Expression schema from grouping params (nullity json) -> Expression schema from grouping params (nullity path) -> Expression schema from grouping params ( 'Null json) infixl 8 .#> -- | Get JSON value at a specified path as text. (.#>>) :: (json `In` PGJsonType, PGTextArray "(.#>>)" path) => Expression schema from grouping params (nullity json) -> Expression schema from grouping params (nullity path) -> Expression schema from grouping params ( 'Null 'PGtext) infixl 8 .#>> -- | Does the left JSON value contain the right JSON path/value entries at -- the top level? (.@>) :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGjsonb) -> Condition schema from grouping params infixl 9 .@> -- | Are the left JSON path/value entries contained at the top level within -- the right JSON value? (.<@) :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGjsonb) -> Condition schema from grouping params infixl 9 .<@ -- | Does the string exist as a top-level key within the JSON value? (.?) :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGtext) -> Condition schema from grouping params infixl 9 .? -- | Do any of these array strings exist as top-level keys? (.?|) :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity ( 'PGvararray ( 'NotNull 'PGtext))) -> Condition schema from grouping params infixl 9 .?| -- | Do all of these array strings exist as top-level keys? (.?&) :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity ( 'PGvararray ( 'NotNull 'PGtext))) -> Condition schema from grouping params infixl 9 .?& -- | Delete a key or keys from a JSON object, or remove an array element. -- -- If the right operand is.. -- -- text : Delete keyvalue pair or string element from left -- operand. Keyvalue pairs are matched based on their key value. -- -- text[] : Delete multiple key/value pairs or string elements -- from left operand. Key/value pairs are matched based on their key -- value. -- -- integer : Delete the array element with specified index -- (Negative integers count from the end). Throws an error if top level -- container is not an array. (.-.) :: (key `In` '[ 'PGtext, 'PGvararray ( 'NotNull 'PGtext), 'PGint4, 'PGint2]) => Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity key) -> Expression schema from grouping params (nullity 'PGjsonb) infixl 6 .-. -- | Delete the field or element with specified path (for JSON arrays, -- negative integers count from the end) (#-.) :: PGTextArray "(#-.)" arrayty => Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity arrayty) -> Expression schema from grouping params (nullity 'PGjsonb) infixl 6 #-. -- | Literal JSON jsonLit :: ToJSON x => x -> Expression schema from grouping params (nullity 'PGjson) -- | Literal binary JSON jsonbLit :: ToJSON x => x -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns the value as json. Arrays and composites are converted -- (recursively) to arrays and objects; otherwise, if there is a cast -- from the type to json, the cast function will be used to perform the -- conversion; otherwise, a scalar value is produced. For any scalar type -- other than a number, a Boolean, or a null value, the text -- representation will be used, in such a fashion that it is a valid json -- value. toJson :: Expression schema from grouping params (nullity ty) -> Expression schema from grouping params (nullity 'PGjson) -- | Returns the value as jsonb. Arrays and composites are converted -- (recursively) to arrays and objects; otherwise, if there is a cast -- from the type to json, the cast function will be used to perform the -- conversion; otherwise, a scalar value is produced. For any scalar type -- other than a number, a Boolean, or a null value, the text -- representation will be used, in such a fashion that it is a valid -- jsonb value. toJsonb :: Expression schema from grouping params (nullity ty) -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns the array as a JSON array. A PostgreSQL multidimensional array -- becomes a JSON array of arrays. arrayToJson :: PGArray "arrayToJson" arr => Expression schema from grouping params (nullity arr) -> Expression schema from grouping params (nullity 'PGjson) -- | Returns the row as a JSON object. rowToJson :: Expression schema from grouping params (nullity ( 'PGcomposite ty)) -> Expression schema from grouping params (nullity 'PGjson) -- | Builds a possibly-heterogeneously-typed JSON array out of a variadic -- argument list. jsonBuildArray :: SListI elems => NP (Expression schema from grouping params) elems -> Expression schema from grouping params (nullity 'PGjson) -- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a -- variadic argument list. jsonbBuildArray :: SListI elems => NP (Expression schema from grouping params) elems -> Expression schema from grouping params (nullity 'PGjsonb) -- | Builds a possibly-heterogeneously-typed JSON object out of a variadic -- argument list. The elements of the argument list must alternate -- between text and values. jsonBuildObject :: All Top elems => NP (Aliased (Expression schema from grouping params)) elems -> Expression schema from grouping params (nullity 'PGjson) -- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a -- variadic argument list. The elements of the argument list must -- alternate between text and values. jsonbBuildObject :: All Top elems => NP (Aliased (Expression schema from grouping params)) elems -> Expression schema from grouping params (nullity 'PGjsonb) -- | Builds a JSON object out of a text array. The array must have either -- exactly one dimension with an even number of members, in which case -- they are taken as alternating key/value pairs, or two dimensions such -- that each inner array has exactly two elements, which are taken as a -- key/value pair. jsonObject :: PGArrayOf "jsonObject" arr ( 'NotNull 'PGtext) => Expression schema from grouping params (nullity arr) -> Expression schema from grouping params (nullity 'PGjson) -- | Builds a binary JSON object out of a text array. The array must have -- either exactly one dimension with an even number of members, in which -- case they are taken as alternating key/value pairs, or two dimensions -- such that each inner array has exactly two elements, which are taken -- as a key/value pair. jsonbObject :: PGArrayOf "jsonbObject" arr ( 'NotNull 'PGtext) => Expression schema from grouping params (nullity arr) -> Expression schema from grouping params (nullity 'PGjsonb) -- | This is an alternate form of jsonObject that takes two arrays; -- one for keys and one for values, that are zipped pairwise to create a -- JSON object. jsonZipObject :: (PGArrayOf "jsonZipObject" keysArray ( 'NotNull 'PGtext), PGArrayOf "jsonZipObject" valuesArray ( 'NotNull 'PGtext)) => Expression schema from grouping params (nullity keysArray) -> Expression schema from grouping params (nullity valuesArray) -> Expression schema from grouping params (nullity 'PGjson) -- | This is an alternate form of jsonObject that takes two arrays; -- one for keys and one for values, that are zipped pairwise to create a -- binary JSON object. jsonbZipObject :: (PGArrayOf "jsonbZipObject" keysArray ( 'NotNull 'PGtext), PGArrayOf "jsonbZipObject" valuesArray ( 'NotNull 'PGtext)) => Expression schema from grouping params (nullity keysArray) -> Expression schema from grouping params (nullity valuesArray) -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns the number of elements in the outermost JSON array. jsonArrayLength :: Expression schema from grouping params (nullity 'PGjson) -> Expression schema from grouping params (nullity 'PGint4) -- | Returns the number of elements in the outermost binary JSON array. jsonbArrayLength :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGint4) -- | Returns JSON value pointed to by the given path (equivalent to #> -- operator). jsonExtractPath :: SListI elems => Expression schema from grouping params (nullity 'PGjson) -> NP (Expression schema from grouping params) elems -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns JSON value pointed to by the given path (equivalent to #> -- operator). jsonbExtractPath :: SListI elems => Expression schema from grouping params (nullity 'PGjsonb) -> NP (Expression schema from grouping params) elems -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns JSON value pointed to by the given path (equivalent to #> -- operator), as text. jsonExtractPathAsText :: SListI elems => Expression schema from grouping params (nullity 'PGjson) -> NP (Expression schema from grouping params) elems -> Expression schema from grouping params (nullity 'PGjson) -- | Returns JSON value pointed to by the given path (equivalent to #> -- operator), as text. jsonbExtractPathAsText :: SListI elems => Expression schema from grouping params (nullity 'PGjsonb) -> NP (Expression schema from grouping params) elems -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns the type of the outermost JSON value as a text string. -- Possible types are object, array, string, number, boolean, and null. jsonTypeof :: Expression schema from grouping params (nullity 'PGjson) -> Expression schema from grouping params (nullity 'PGtext) -- | Returns the type of the outermost binary JSON value as a text string. -- Possible types are object, array, string, number, boolean, and null. jsonbTypeof :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGtext) -- | Returns its argument with all object fields that have null values -- omitted. Other null values are untouched. jsonStripNulls :: Expression schema from grouping params (nullity 'PGjson) -> Expression schema from grouping params (nullity 'PGjson) -- | Returns its argument with all object fields that have null values -- omitted. Other null values are untouched. jsonbStripNulls :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGjsonb) -- |
--   jsonbSet target path new_value create_missing
--   
-- -- Returns target with the section designated by path replaced by -- new_value, or with new_value added if create_missing is true ( default -- is true) and the item designated by path does not exist. As with the -- path orientated operators, negative integers that appear in path count -- from the end of JSON arrays. jsonbSet :: PGTextArray "jsonbSet" arr => Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity arr) -> Expression schema from grouping params (nullity 'PGjsonb) -> Maybe (Expression schema from grouping params (nullity 'PGbool)) -> Expression schema from grouping params (nullity 'PGjsonb) -- |
--   jsonbInsert target path new_value insert_after
--   
-- -- Returns target with new_value inserted. If target section designated -- by path is in a JSONB array, new_value will be inserted before target -- or after if insert_after is true (default is false). If target section -- designated by path is in JSONB object, new_value will be inserted only -- if target does not exist. As with the path orientated operators, -- negative integers that appear in path count from the end of JSON -- arrays. jsonbInsert :: PGTextArray "jsonbInsert" arr => Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity arr) -> Expression schema from grouping params (nullity 'PGjsonb) -> Maybe (Expression schema from grouping params (nullity 'PGbool)) -> Expression schema from grouping params (nullity 'PGjsonb) -- | Returns its argument as indented JSON text. jsonbPretty :: Expression schema from grouping params (nullity 'PGjsonb) -> Expression schema from grouping params (nullity 'PGtext) -- | escape hatch to define aggregate functions unsafeAggregate :: ByteString -> Expression schema from 'Ungrouped params (xty) -> Expression schema from ( 'Grouped bys) params (yty) -- | escape hatch to define aggregate functions over distinct values unsafeAggregateDistinct :: ByteString -> Expression schema from 'Ungrouped params (xty) -> Expression schema from ( 'Grouped bys) params (yty) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
--     expression = sum_ #col
--   in printSQL expression
--   :}
--   sum("col")
--   
sum_ :: ty `In` PGNum => Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity ty) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
--     expression = sumDistinct #col
--   in printSQL expression
--   :}
--   sum(DISTINCT "col")
--   
sumDistinct :: ty `In` PGNum => Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity ty) -- | A constraint for PGTypes that you can take averages of and the -- resulting PGType. class PGAvg ty avg | ty -> avg avg :: PGAvg ty avg => Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity avg) avgDistinct :: PGAvg ty avg => Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity avg) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
--     expression = bitAnd #col
--   in printSQL expression
--   :}
--   bit_and("col")
--   
bitAnd :: int `In` PGIntegral => Expression schema from 'Ungrouped params (nullity int) -> Expression schema from ( 'Grouped bys) params (nullity int) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
--     expression = bitOr #col
--   in printSQL expression
--   :}
--   bit_or("col")
--   
bitOr :: int `In` PGIntegral => Expression schema from 'Ungrouped params (nullity int) -> Expression schema from ( 'Grouped bys) params (nullity int) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
--     expression = boolAnd #col
--   in printSQL expression
--   :}
--   bool_and("col")
--   
boolAnd :: Expression schema from 'Ungrouped params (nullity 'PGbool) -> Expression schema from ( 'Grouped bys) params (nullity 'PGbool) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
--     expression = boolOr #col
--   in printSQL expression
--   :}
--   bool_or("col")
--   
boolOr :: Expression schema from 'Ungrouped params (nullity 'PGbool) -> Expression schema from ( 'Grouped bys) params (nullity 'PGbool) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
--     expression = bitAndDistinct #col
--   in printSQL expression
--   :}
--   bit_and(DISTINCT "col")
--   
bitAndDistinct :: int `In` PGIntegral => Expression schema from 'Ungrouped params (nullity int) -> Expression schema from ( 'Grouped bys) params (nullity int) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
--     expression = bitOrDistinct #col
--   in printSQL expression
--   :}
--   bit_or(DISTINCT "col")
--   
bitOrDistinct :: int `In` PGIntegral => Expression schema from 'Ungrouped params (nullity int) -> Expression schema from ( 'Grouped bys) params (nullity int) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
--     expression = boolAndDistinct #col
--   in printSQL expression
--   :}
--   bool_and(DISTINCT "col")
--   
boolAndDistinct :: Expression schema from 'Ungrouped params (nullity 'PGbool) -> Expression schema from ( 'Grouped bys) params (nullity 'PGbool) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
--     expression = boolOrDistinct #col
--   in printSQL expression
--   :}
--   bool_or(DISTINCT "col")
--   
boolOrDistinct :: Expression schema from 'Ungrouped params (nullity 'PGbool) -> Expression schema from ( 'Grouped bys) params (nullity 'PGbool) -- | A special aggregation that does not require an input -- --
--   >>> printSQL countStar
--   count(*)
--   
countStar :: Expression schema from ( 'Grouped bys) params ( 'NotNull 'PGint8) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
--     expression = count #col
--   in printSQL expression
--   :}
--   count("col")
--   
count :: Expression schema from 'Ungrouped params ty -> Expression schema from ( 'Grouped bys) params ( 'NotNull 'PGint8) -- |
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
--     expression = countDistinct #col
--   in printSQL expression
--   :}
--   count(DISTINCT "col")
--   
countDistinct :: Expression schema from 'Ungrouped params ty -> Expression schema from ( 'Grouped bys) params ( 'NotNull 'PGint8) -- | synonym for boolAnd -- --
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
--     expression = every #col
--   in printSQL expression
--   :}
--   every("col")
--   
every :: Expression schema from 'Ungrouped params (nullity 'PGbool) -> Expression schema from ( 'Grouped bys) params (nullity 'PGbool) -- | synonym for boolAndDistinct -- --
--   >>> :{
--   let
--     expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
--     expression = everyDistinct #col
--   in printSQL expression
--   :}
--   every(DISTINCT "col")
--   
everyDistinct :: Expression schema from 'Ungrouped params (nullity 'PGbool) -> Expression schema from ( 'Grouped bys) params (nullity 'PGbool) -- | minimum and maximum aggregation max_ :: Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity ty) -- | minimum and maximum aggregation maxDistinct :: Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity ty) -- | minimum and maximum aggregation min_ :: Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity ty) -- | minimum and maximum aggregation minDistinct :: Expression schema from 'Ungrouped params (nullity ty) -> Expression schema from ( 'Grouped bys) params (nullity ty) -- | TypeExpressions are used in casts and -- createTable commands. newtype TypeExpression (schema :: SchemaType) (ty :: NullityType) UnsafeTypeExpression :: ByteString -> TypeExpression [renderTypeExpression] :: TypeExpression -> ByteString -- | pgtype is a demoted version of a PGType class PGTyped schema (ty :: NullityType) pgtype :: PGTyped schema ty => TypeExpression schema ty -- | The enum or composite type in a Typedef can be expressed by its -- alias. typedef :: Has alias schema ( 'Typedef ty) => Alias alias -> TypeExpression schema (nullity ty) -- | The composite type corresponding to a Table definition can be -- expressed by its alias. typetable :: Has alias schema ( 'Table tab) => Alias alias -> TypeExpression schema (nullity ( 'PGcomposite (TableToRow tab))) -- | The composite type corresponding to a View definition can be -- expressed by its alias. typeview :: Has alias schema ( 'View view) => Alias alias -> TypeExpression schema (nullity ( 'PGcomposite view)) -- | logical Boolean (true/false) bool :: TypeExpression schema (nullity 'PGbool) -- | signed two-byte integer int2 :: TypeExpression schema (nullity 'PGint2) -- | signed two-byte integer smallint :: TypeExpression schema (nullity 'PGint2) -- | signed four-byte integer int4 :: TypeExpression schema (nullity 'PGint4) -- | signed four-byte integer int :: TypeExpression schema (nullity 'PGint4) -- | signed four-byte integer integer :: TypeExpression schema (nullity 'PGint4) -- | signed eight-byte integer int8 :: TypeExpression schema (nullity 'PGint8) -- | signed eight-byte integer bigint :: TypeExpression schema (nullity 'PGint8) -- | arbitrary precision numeric type numeric :: TypeExpression schema (nullity 'PGnumeric) -- | single precision floating-point number (4 bytes) float4 :: TypeExpression schema (nullity 'PGfloat4) -- | single precision floating-point number (4 bytes) real :: TypeExpression schema (nullity 'PGfloat4) -- | double precision floating-point number (8 bytes) float8 :: TypeExpression schema (nullity 'PGfloat8) -- | double precision floating-point number (8 bytes) doublePrecision :: TypeExpression schema (nullity 'PGfloat8) -- | variable-length character string text :: TypeExpression schema (nullity 'PGtext) -- | fixed-length character string char :: forall n schema nullity. (KnownNat n, 1 <= n) => TypeExpression schema (nullity ( 'PGchar n)) -- | fixed-length character string character :: forall n schema nullity. (KnownNat n, 1 <= n) => TypeExpression schema (nullity ( 'PGchar n)) -- | variable-length character string varchar :: forall n schema nullity. (KnownNat n, 1 <= n) => TypeExpression schema (nullity ( 'PGvarchar n)) -- | variable-length character string characterVarying :: forall n schema nullity. (KnownNat n, 1 <= n) => TypeExpression schema (nullity ( 'PGvarchar n)) -- | binary data ("byte array") bytea :: TypeExpression schema (nullity 'PGbytea) -- | date and time (no time zone) timestamp :: TypeExpression schema (nullity 'PGtimestamp) -- | date and time, including time zone timestampWithTimeZone :: TypeExpression schema (nullity 'PGtimestamptz) -- | calendar date (year, month, day) date :: TypeExpression schema (nullity 'PGdate) -- | time of day (no time zone) time :: TypeExpression schema (nullity 'PGtime) -- | time of day, including time zone timeWithTimeZone :: TypeExpression schema (nullity 'PGtimetz) -- | time span interval :: TypeExpression schema (nullity 'PGinterval) -- | universally unique identifier uuid :: TypeExpression schema (nullity 'PGuuid) -- | IPv4 or IPv6 host address inet :: TypeExpression schema (nullity 'PGinet) -- | textual JSON data json :: TypeExpression schema (nullity 'PGjson) -- | binary JSON data, decomposed jsonb :: TypeExpression schema (nullity 'PGjsonb) -- | variable length array vararray :: TypeExpression schema pg -> TypeExpression schema (nullity ( 'PGvararray pg)) -- | fixed length array -- --
--   >>> renderTypeExpression (fixarray @2 json)
--   "json[2]"
--   
fixarray :: forall n schema nullity pg. KnownNat n => TypeExpression schema pg -> TypeExpression schema (nullity ( 'PGfixarray n pg)) -- | & 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 $. -- --
--   >>> 5 & (+1) & show
--   "6"
--   
(&) :: () => 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 (a :: k -> *) (b :: [k]) :: forall k. () => k -> * -> [k] -> * [Nil] :: NP a ([] :: [k]) [:*] :: NP a x : xs instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.TypeExpression schema ty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.TypeExpression schema ty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.TypeExpression schema ty) instance GHC.Show.Show (Squeal.PostgreSQL.Expression.TypeExpression schema ty) instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.TypeExpression schema ty) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Expression.Expression schema from grouping params ty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Expression.Expression schema from grouping params ty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Expression.Expression schema from grouping params ty) instance GHC.Show.Show (Squeal.PostgreSQL.Expression.Expression schema from grouping params ty) instance GHC.Generics.Generic (Squeal.PostgreSQL.Expression.Expression schema from grouping params ty) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGbool) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGint2) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGint4) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGint8) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGnumeric) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGfloat4) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGfloat8) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGtext) instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Squeal.PostgreSQL.Expression.PGTyped schema (nullity ('Squeal.PostgreSQL.Schema.PGchar n)) instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Squeal.PostgreSQL.Expression.PGTyped schema (nullity ('Squeal.PostgreSQL.Schema.PGvarchar n)) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGbytea) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGtimestamp) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGtimestamptz) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGdate) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGtime) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGtimetz) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGinterval) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGuuid) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGjson) instance Squeal.PostgreSQL.Expression.PGTyped schema (nullity 'Squeal.PostgreSQL.Schema.PGjsonb) instance Squeal.PostgreSQL.Expression.PGTyped schema ty => Squeal.PostgreSQL.Expression.PGTyped schema (nullity ('Squeal.PostgreSQL.Schema.PGvararray ty)) instance (GHC.TypeNats.KnownNat n, Squeal.PostgreSQL.Expression.PGTyped schema ty) => Squeal.PostgreSQL.Expression.PGTyped schema (nullity ('Squeal.PostgreSQL.Schema.PGfixarray n ty)) instance Squeal.PostgreSQL.Expression.HasParameter 1 schema (ty1 : tys) ty1 instance (GHC.TypeNats.KnownNat n, Squeal.PostgreSQL.Expression.HasParameter (n GHC.TypeNats.- 1) schema params ty) => Squeal.PostgreSQL.Expression.HasParameter n schema (ty' : params) ty instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGint2 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGint4 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGint8 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGnumeric 'Squeal.PostgreSQL.Schema.PGnumeric instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGfloat4 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGfloat8 'Squeal.PostgreSQL.Schema.PGfloat8 instance Squeal.PostgreSQL.Expression.PGAvg 'Squeal.PostgreSQL.Schema.PGinterval 'Squeal.PostgreSQL.Schema.PGinterval instance Squeal.PostgreSQL.Render.RenderSQL (Squeal.PostgreSQL.Expression.Expression schema from grouping params ty) instance (Squeal.PostgreSQL.Schema.HasUnique table from columns, Squeal.PostgreSQL.Schema.Has column columns ty) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Expression.Expression schema from 'Squeal.PostgreSQL.Schema.Ungrouped params ty) instance (Squeal.PostgreSQL.Schema.HasUnique table from columns, Squeal.PostgreSQL.Schema.Has column columns ty) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from 'Squeal.PostgreSQL.Schema.Ungrouped params) (column Squeal.PostgreSQL.Schema.::: ty)) instance (Squeal.PostgreSQL.Schema.HasUnique table from columns, Squeal.PostgreSQL.Schema.Has column columns ty) => GHC.OverloadedLabels.IsLabel column (Generics.SOP.NP.NP (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from 'Squeal.PostgreSQL.Schema.Ungrouped params)) '[column Squeal.PostgreSQL.Schema.::: ty]) instance (Squeal.PostgreSQL.Schema.Has table from columns, Squeal.PostgreSQL.Schema.Has column columns ty) => Squeal.PostgreSQL.Schema.IsQualified table column (Squeal.PostgreSQL.Expression.Expression schema from 'Squeal.PostgreSQL.Schema.Ungrouped params ty) instance (Squeal.PostgreSQL.Schema.Has table from columns, Squeal.PostgreSQL.Schema.Has column columns ty) => Squeal.PostgreSQL.Schema.IsQualified table column (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from 'Squeal.PostgreSQL.Schema.Ungrouped params) (column Squeal.PostgreSQL.Schema.::: ty)) instance (Squeal.PostgreSQL.Schema.Has table from columns, Squeal.PostgreSQL.Schema.Has column columns ty) => Squeal.PostgreSQL.Schema.IsQualified table column (Generics.SOP.NP.NP (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from 'Squeal.PostgreSQL.Schema.Ungrouped params)) '[column Squeal.PostgreSQL.Schema.::: ty]) instance (Squeal.PostgreSQL.Schema.HasUnique table from columns, Squeal.PostgreSQL.Schema.Has column columns ty, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Expression.Expression schema from ('Squeal.PostgreSQL.Schema.Grouped bys) params ty) instance (Squeal.PostgreSQL.Schema.HasUnique table from columns, Squeal.PostgreSQL.Schema.Has column columns ty, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => GHC.OverloadedLabels.IsLabel column (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from ('Squeal.PostgreSQL.Schema.Grouped bys) params) (column Squeal.PostgreSQL.Schema.::: ty)) instance (Squeal.PostgreSQL.Schema.HasUnique table from columns, Squeal.PostgreSQL.Schema.Has column columns ty, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => GHC.OverloadedLabels.IsLabel column (Generics.SOP.NP.NP (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from ('Squeal.PostgreSQL.Schema.Grouped bys) params)) '[column Squeal.PostgreSQL.Schema.::: ty]) instance (Squeal.PostgreSQL.Schema.Has table from columns, Squeal.PostgreSQL.Schema.Has column columns ty, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => Squeal.PostgreSQL.Schema.IsQualified table column (Squeal.PostgreSQL.Expression.Expression schema from ('Squeal.PostgreSQL.Schema.Grouped bys) params ty) instance (Squeal.PostgreSQL.Schema.Has table from columns, Squeal.PostgreSQL.Schema.Has column columns ty, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => Squeal.PostgreSQL.Schema.IsQualified table column (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from ('Squeal.PostgreSQL.Schema.Grouped bys) params) (column Squeal.PostgreSQL.Schema.::: ty)) instance (Squeal.PostgreSQL.Schema.Has table from columns, Squeal.PostgreSQL.Schema.Has column columns ty, Squeal.PostgreSQL.Schema.GroupedBy table column bys) => Squeal.PostgreSQL.Schema.IsQualified table column (Generics.SOP.NP.NP (Squeal.PostgreSQL.Schema.Aliased (Squeal.PostgreSQL.Expression.Expression schema from ('Squeal.PostgreSQL.Schema.Grouped bys) params)) '[column Squeal.PostgreSQL.Schema.::: ty]) instance (GHC.TypeLits.KnownSymbol label, Squeal.PostgreSQL.Schema.In label labels) => Squeal.PostgreSQL.Schema.IsPGlabel label (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity ('Squeal.PostgreSQL.Schema.PGenum labels))) instance GHC.Base.Semigroup (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity ('Squeal.PostgreSQL.Schema.PGvararray ty))) instance GHC.Base.Monoid (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity ('Squeal.PostgreSQL.Schema.PGvararray ty))) instance Squeal.PostgreSQL.Schema.In ty Squeal.PostgreSQL.Schema.PGNum => GHC.Num.Num (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity ty)) instance (Squeal.PostgreSQL.Schema.In ty Squeal.PostgreSQL.Schema.PGNum, Squeal.PostgreSQL.Schema.In ty Squeal.PostgreSQL.Schema.PGFloating) => GHC.Real.Fractional (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity ty)) instance (Squeal.PostgreSQL.Schema.In ty Squeal.PostgreSQL.Schema.PGNum, Squeal.PostgreSQL.Schema.In ty Squeal.PostgreSQL.Schema.PGFloating) => GHC.Float.Floating (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity ty)) instance Data.String.IsString (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity 'Squeal.PostgreSQL.Schema.PGtext)) instance GHC.Base.Semigroup (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity 'Squeal.PostgreSQL.Schema.PGtext)) instance GHC.Base.Monoid (Squeal.PostgreSQL.Expression.Expression schema from grouping params (nullity 'Squeal.PostgreSQL.Schema.PGtext)) instance GHC.Base.Semigroup (Squeal.PostgreSQL.Expression.Expression schema from grouping param (nullity 'Squeal.PostgreSQL.Schema.PGjsonb)) -- | Squeal queries. module Squeal.PostgreSQL.Query -- | The process of retrieving or the command to retrieve data from a -- database is called a Query. Let's see some examples of queries. -- -- simple query: -- --
--   >>> :{
--   let
--     query :: Query
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[]
--       '["col" ::: 'Null 'PGint4]
--     query = selectStar (from (table #tab))
--   in printSQL query
--   :}
--   SELECT * FROM "tab" AS "tab"
--   
-- -- restricted query: -- --
--   >>> :{
--   let
--     query :: Query
--       '[ "tab" ::: 'Table ('[] :=>
--          '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--           , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])]
--       '[]
--       '[ "sum" ::: 'NotNull 'PGint4
--        , "col1" ::: 'NotNull 'PGint4 ]
--     query =
--       select
--         ((#col1 + #col2) `as` #sum :* #col1)
--         ( from (table #tab)
--           & where_ (#col1 .> #col2)
--           & where_ (#col2 .> 0) )
--   in printSQL query
--   :}
--   SELECT ("col1" + "col2") AS "sum", "col1" AS "col1" FROM "tab" AS "tab" WHERE (("col1" > "col2") AND ("col2" > 0))
--   
-- -- subquery: -- --
--   >>> :{
--   let
--     query :: Query
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[]
--       '["col" ::: 'Null 'PGint4]
--     query =
--       selectStar
--         (from (subquery (selectStar (from (table #tab)) `as` #sub)))
--   in printSQL query
--   :}
--   SELECT * FROM (SELECT * FROM "tab" AS "tab") AS "sub"
--   
-- -- limits and offsets: -- --
--   >>> :{
--   let
--     query :: Query
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[]
--       '["col" ::: 'Null 'PGint4]
--     query = selectStar
--       (from (table #tab) & limit 100 & offset 2 & limit 50 & offset 2)
--   in printSQL query
--   :}
--   SELECT * FROM "tab" AS "tab" LIMIT 50 OFFSET 4
--   
-- -- parameterized query: -- --
--   >>> :{
--   let
--     query :: Query
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGfloat8])]
--       '[ 'NotNull 'PGfloat8]
--       '["col" ::: 'NotNull 'PGfloat8]
--     query = selectStar
--       (from (table #tab) & where_ (#col .> param @1))
--   in printSQL query
--   :}
--   SELECT * FROM "tab" AS "tab" WHERE ("col" > ($1 :: float8))
--   
-- -- aggregation query: -- --
--   >>> :{
--   let
--     query :: Query
--       '[ "tab" ::: 'Table ('[] :=>
--          '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--           , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])]
--       '[]
--       '[ "sum" ::: 'NotNull 'PGint4
--        , "col1" ::: 'NotNull 'PGint4 ]
--     query =
--       select (sum_ #col2 `as` #sum :* #col1)
--       ( from (table (#tab `as` #table1))
--         & groupBy #col1
--         & having (#col1 + sum_ #col2 .> 1) )
--   in printSQL 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" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[]
--       '["col" ::: 'Null 'PGint4]
--     query = selectStar
--       (from (table #tab) & orderBy [#col & AscNullsFirst])
--   in printSQL query
--   :}
--   SELECT * FROM "tab" AS "tab" ORDER BY "col" ASC NULLS FIRST
--   
-- -- joins: -- --
--   >>> :set -XFlexibleContexts
--   
--   >>> :{
--   let
--     query :: Query
--       '[ "orders" ::: 'Table (
--            '["pk_orders" ::: PrimaryKey '["id"]
--             ,"fk_customers" ::: ForeignKey '["customer_id"] "customers" '["id"]
--             ,"fk_shippers" ::: ForeignKey '["shipper_id"] "shippers" '["id"]] :=>
--            '[ "id"    ::: 'NoDef :=> 'NotNull 'PGint4
--             , "price"   ::: 'NoDef :=> 'NotNull 'PGfloat4
--             , "customer_id" ::: 'NoDef :=> 'NotNull 'PGint4
--             , "shipper_id"  ::: 'NoDef :=> 'NotNull 'PGint4
--             ])
--        , "customers" ::: 'Table (
--            '["pk_customers" ::: PrimaryKey '["id"]] :=>
--            '[ "id" ::: 'NoDef :=> 'NotNull 'PGint4
--             , "name" ::: 'NoDef :=> 'NotNull 'PGtext
--             ])
--        , "shippers" ::: 'Table (
--            '["pk_shippers" ::: PrimaryKey '["id"]] :=>
--            '[ "id" ::: 'NoDef :=> 'NotNull 'PGint4
--             , "name" ::: 'NoDef :=> 'NotNull 'PGtext
--             ])
--        ]
--       '[]
--       '[ "order_price" ::: 'NotNull 'PGfloat4
--        , "customer_name" ::: 'NotNull 'PGtext
--        , "shipper_name" ::: 'NotNull 'PGtext
--        ]
--     query = select
--       ( #o ! #price `as` #order_price :*
--         #c ! #name `as` #customer_name :*
--         #s ! #name `as` #shipper_name )
--       ( 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 printSQL 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" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[]
--       '["col" ::: 'Null 'PGint4]
--     query = selectDotStar #t1
--       (from (table (#tab `as` #t1) & crossJoin (table (#tab `as` #t2))))
--   in printSQL query
--   :}
--   SELECT "t1".* FROM "tab" AS "t1" CROSS JOIN "tab" AS "t2"
--   
-- -- value queries: -- --
--   >>> :{
--   let
--     query :: Query '[] '[] '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--     query = values (1 `as` #foo :* true `as` #bar) [2 `as` #foo :* false `as` #bar]
--   in printSQL query
--   :}
--   SELECT * FROM (VALUES (1, TRUE), (2, FALSE)) AS t ("foo", "bar")
--   
-- -- set operations: -- --
--   >>> :{
--   let
--     query :: Query
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[]
--       '["col" ::: 'Null 'PGint4]
--     query =
--       selectStar (from (table #tab))
--       `unionAll`
--       selectStar (from (table #tab))
--   in printSQL query
--   :}
--   (SELECT * FROM "tab" AS "tab") UNION ALL (SELECT * FROM "tab" AS "tab")
--   
-- -- with queries: -- --
--   >>> :{
--   let
--     query :: Query
--       '[ "t1" ::: 'View
--          '[ "c1" ::: 'NotNull 'PGtext
--           , "c2" ::: 'NotNull 'PGtext] ]
--       '[]
--       '[ "c1" ::: 'NotNull 'PGtext
--        , "c2" ::: 'NotNull 'PGtext ]
--     query = with (
--       selectStar (from (view #t1)) `as` #t2 :>>
--       selectStar (from (view #t2)) `as` #t3
--       ) (selectStar (from (view #t3)))
--   in printSQL query
--   :}
--   WITH "t2" AS (SELECT * FROM "t1" AS "t1"), "t3" AS (SELECT * FROM "t2" AS "t2") SELECT * FROM "t3" AS "t3"
--   
newtype Query (schema :: SchemaType) (params :: [NullityType]) (columns :: RowType) UnsafeQuery :: ByteString -> Query [renderQuery] :: Query -> ByteString -- | 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 schema from grouping params)) (column : columns) -> TableExpression schema params from 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 schema from 'Ungrouped params)) (column : columns) -> TableExpression schema params from '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 from columns => TableExpression schema params from 'Ungrouped -> Query schema params columns -- | A selectDistinctStar emits all columns that the table -- expression produces and eliminates duplicate rows. selectDistinctStar :: HasUnique table from columns => TableExpression schema params from '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 :: Has table from columns => Alias table -> TableExpression schema params from 'Ungrouped -> Query schema params columns -- | A selectDistinctDotStar asks for all the columns of a -- particular table, and eliminates duplicate rows. selectDistinctDotStar :: Has table from columns => Alias table -> TableExpression schema params from 'Ungrouped -> Query schema params columns -- | values computes a row value or set of row values specified by -- value expressions. It is most commonly used to generate a “constant -- table” within a larger command, but it can be used on its own. -- --
--   >>> type Row = '["a" ::: 'NotNull 'PGint4, "b" ::: 'NotNull 'PGtext]
--   
--   >>> let query = values (1 `as` #a :* "one" `as` #b) [] :: Query '[] '[] Row
--   
--   >>> printSQL query
--   SELECT * FROM (VALUES (1, E'one')) AS t ("a", "b")
--   
values :: SListI cols => NP (Aliased (Expression schema '[] 'Ungrouped params)) cols -> [NP (Aliased (Expression schema '[] 'Ungrouped params)) cols] -> Query schema params cols -- | values_ computes a row value or set of row values specified by -- value expressions. values_ :: SListI cols => NP (Aliased (Expression schema '[] 'Ungrouped params)) cols -> Query schema params cols -- | 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 -- | with provides a way to write auxiliary statements for use in a -- larger query. These statements, referred to as -- CommonTableExpressions, can be thought of as defining temporary -- tables that exist just for one query. class With statement with :: With statement => AlignedList (CommonTableExpression statement params) schema0 schema1 -> statement schema1 params row -> statement schema0 params row -- | A CommonTableExpression is an auxiliary statement in a -- with clause. data CommonTableExpression statement (params :: [NullityType]) (schema0 :: SchemaType) (schema1 :: SchemaType) [CommonTableExpression] :: Aliased (statement schema params) (alias ::: cte) -> CommonTableExpression statement params schema (alias ::: 'View cte : schema) -- | render a CommonTableExpression. renderCommonTableExpression :: (forall sch ps row. statement ps sch row -> ByteString) -> CommonTableExpression statement params schema0 schema1 -> ByteString -- | render a non-empty AlignedList of -- CommonTableExpressions. renderCommonTableExpressions :: (forall sch ps row. statement ps sch row -> ByteString) -> CommonTableExpression statement params schema0 schema1 -> AlignedList (CommonTableExpression statement params) schema1 schema2 -> ByteString -- | Expands the outermost JSON object into a set of key/value pairs. jsonEach :: Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> Query schema params '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGjson] -- | Expands the outermost binary JSON object into a set of key/value -- pairs. jsonbEach :: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> Query schema params '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGjsonb] -- | Expands the outermost JSON object into a set of key/value pairs. jsonEachAsText :: Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> Query schema params '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGtext] -- | Expands the outermost binary JSON object into a set of key/value -- pairs. jsonbEachAsText :: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> Query schema params '["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGtext] -- | Returns set of keys in the outermost JSON object. jsonObjectKeys :: Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> Query schema params '["json_object_keys" ::: 'NotNull 'PGtext] -- | Returns set of keys in the outermost JSON object. jsonbObjectKeys :: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> Query schema params '["jsonb_object_keys" ::: 'NotNull 'PGtext] -- | Expands the JSON expression to a row whose columns match the record -- type defined by the given table. jsonPopulateRecord :: TypeExpression schema (nullity ( 'PGcomposite row)) -> Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> Query schema params row -- | Expands the binary JSON expression to a row whose columns match the -- record type defined by the given table. jsonbPopulateRecord :: TypeExpression schema (nullity ( 'PGcomposite row)) -> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> Query schema params row -- | Expands the outermost array of objects in the given JSON expression to -- a set of rows whose columns match the record type defined by the given -- table. jsonPopulateRecordSet :: TypeExpression schema (nullity ( 'PGcomposite row)) -> Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> Query schema params row -- | Expands the outermost array of objects in the given binary JSON -- expression to a set of rows whose columns match the record type -- defined by the given table. jsonbPopulateRecordSet :: TypeExpression schema (nullity ( 'PGcomposite row)) -> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> Query schema params row -- | Builds an arbitrary record from a JSON object. jsonToRecord :: SListI record => Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> NP (Aliased (TypeExpression schema)) record -> Query schema params record -- | Builds an arbitrary record from a binary JSON object. jsonbToRecord :: SListI record => Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> NP (Aliased (TypeExpression schema)) record -> Query schema params record -- | Builds an arbitrary set of records from a JSON array of objects. jsonToRecordSet :: SListI record => Expression schema '[] 'Ungrouped params (nullity 'PGjson) -> NP (Aliased (TypeExpression schema)) record -> Query schema params record -- | Builds an arbitrary set of records from a binary JSON array of -- objects. jsonbToRecordSet :: SListI record => Expression schema '[] 'Ungrouped params (nullity 'PGjsonb) -> NP (Aliased (TypeExpression schema)) record -> Query schema params record -- | 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 :: SchemaType) (params :: [NullityType]) (from :: FromType) (grouping :: Grouping) TableExpression :: FromClause schema params from -> [Condition schema from 'Ungrouped params] -> GroupByClause from grouping -> HavingClause schema from grouping params -> [SortExpression schema from 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 from -- | 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 schema from '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 from 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 schema from 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 schema from 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 from 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 from -> TableExpression schema params from 'Ungrouped -- | A where_ is an endomorphism of TableExpressions which -- adds a search condition to the whereClause. where_ :: Condition schema from 'Ungrouped params -> TableExpression schema params from grouping -> TableExpression schema params from grouping -- | A groupBy is a transformation of TableExpressions which -- switches its Grouping from Ungrouped to Grouped. -- Use group Nil to perform a "grand total" aggregation query. groupBy :: SListI bys => NP (By from) bys -> TableExpression schema params from 'Ungrouped -> TableExpression schema params from ( 'Grouped bys) -- | A having is an endomorphism of TableExpressions which -- adds a search condition to the havingClause. having :: Condition schema from ( 'Grouped bys) params -> TableExpression schema params from ( 'Grouped bys) -> TableExpression schema params from ( 'Grouped bys) -- | An orderBy is an endomorphism of TableExpressions which -- appends an ordering to the right of the orderByClause. orderBy :: [SortExpression schema from grouping params] -> TableExpression schema params from grouping -> TableExpression schema params from grouping -- | A limit is an endomorphism of TableExpressions which -- adds to the limitClause. limit :: Word64 -> TableExpression schema params from grouping -> TableExpression schema params from grouping -- | An offset is an endomorphism of TableExpressions which -- adds to the offsetClause. offset :: Word64 -> TableExpression schema params from grouping -> TableExpression schema params from grouping -- | A FromClause can be a table name, or a derived table such as a -- subquery, a JOIN construct, or complex combinations of these. newtype FromClause schema params from UnsafeFromClause :: ByteString -> FromClause schema params from [renderFromClause] :: FromClause schema params from -> ByteString -- | A real table is a table from the schema. table :: Has tab schema ( 'Table table) => Aliased Alias (alias ::: tab) -> FromClause schema params '[alias ::: TableToRow table] -- | subquery derives a table from a Query. subquery :: Aliased (Query schema params) rel -> FromClause schema params '[rel] -- | view derives a table from a View. view :: Has view schema ( 'View row) => Aliased Alias (alias ::: view) -> FromClause schema params '[alias ::: row] -- | left & crossJoin right. For every possible combination of -- rows from left and right (i.e., a Cartesian -- product), the joined table will contain a row consisting of all -- columns in left followed by all columns in right. If -- the tables have n and m rows respectively, the -- joined table will have n * m rows. crossJoin :: FromClause schema params right -> FromClause schema params left -> FromClause schema params (Join left right) -- | left & innerJoin right on. The joined table is filtered -- by the on condition. innerJoin :: FromClause schema params right -> Condition schema (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join left right) -- | left & leftOuterJoin right on. First, an inner join is -- performed. Then, for each row in left that does not satisfy -- the on condition with any row in right, a joined row -- is added with null values in columns of right. Thus, the -- joined table always has at least one row for each row in -- left. leftOuterJoin :: FromClause schema params right -> Condition schema (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join left (NullifyFrom right)) -- | left & rightOuterJoin right on. First, an inner join is -- performed. Then, for each row in right that does not satisfy -- the on condition with any row in left, a joined row -- is added with null values in columns of left. This is the -- converse of a left join: the result table will always have a row for -- each row in right. rightOuterJoin :: FromClause schema params right -> Condition schema (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join (NullifyFrom left) right) -- | left & fullOuterJoin right on. First, an inner join is -- performed. Then, for each row in left that does not satisfy -- the on condition with any row in right, a joined row -- is added with null values in columns of right. Also, for each -- row of right that does not satisfy the join condition with -- any row in left, a joined row with null values in the columns -- of left is added. fullOuterJoin :: FromClause schema params right -> Condition schema (Join left right) 'Ungrouped params -> FromClause schema params left -> FromClause schema params (Join (NullifyFrom left) (NullifyFrom right)) -- | 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 (from :: FromType) (by :: (Symbol, Symbol)) [By1] :: (HasUnique table from columns, Has column columns ty) => Alias column -> By from '(table, column) [By2] :: (Has table from columns, Has column columns ty) => Alias table -> Alias column -> By from '(table, column) -- | Renders a By. renderBy :: By from by -> 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. In general, all output -- Expressions in the complement of bys must be -- aggregated in Group bys. data GroupByClause from grouping [NoGroups] :: GroupByClause from 'Ungrouped [Group] :: SListI bys => NP (By from) bys -> GroupByClause from ( 'Grouped bys) -- | Renders a GroupByClause. renderGroupByClause :: GroupByClause from 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 schema from grouping params [NoHaving] :: HavingClause schema from 'Ungrouped params [Having] :: [Condition schema from ( 'Grouped bys) params] -> HavingClause schema from ( 'Grouped bys) params -- | Render a HavingClause. renderHavingClause :: HavingClause schema from 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 schema from grouping params [Asc] :: Expression schema from grouping params ( 'NotNull ty) -> SortExpression schema from grouping params [Desc] :: Expression schema from grouping params ( 'NotNull ty) -> SortExpression schema from grouping params [AscNullsFirst] :: Expression schema from grouping params ( 'Null ty) -> SortExpression schema from grouping params [AscNullsLast] :: Expression schema from grouping params ( 'Null ty) -> SortExpression schema from grouping params [DescNullsFirst] :: Expression schema from grouping params ( 'Null ty) -> SortExpression schema from grouping params [DescNullsLast] :: Expression schema from grouping params ( 'Null ty) -> SortExpression schema from grouping params -- | Render a SortExpression. renderSortExpression :: SortExpression schema from grouping params -> ByteString -- | The right-hand side is a subQuery, which must return exactly -- one column. The left-hand expression is evaluated and compared to each -- row of the subQuery result. The result of in_ is -- true if any equal subquery row is found. The result is -- false if no equal row is found (including the case where the -- subquery returns no rows). -- --
--   >>> printSQL $ true `in_` values_ (true `as` #foo)
--   TRUE IN (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
in_ :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- | The left-hand side of this form of rowIn is a row constructor. -- The right-hand side is a subQuery, which must return exactly as -- many columns as there are expressions in the left-hand row. The -- left-hand expressions are evaluated and compared row-wise to each row -- of the subquery result. The result of rowIn is true if -- any equal subquery row is found. The result is false if no -- equal row is found (including the case where the subquery returns no -- rows). -- --
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowIn` values_ myRow
--   ROW(1, FALSE) IN (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowIn :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `eqAll` values_ (true `as` #foo)
--   TRUE = ALL (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
eqAll :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowEqAll` values_ myRow
--   ROW(1, FALSE) = ALL (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowEqAll :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `eqAny` values_ (true `as` #foo)
--   TRUE = ANY (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
eqAny :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowEqAny` values_ myRow
--   ROW(1, FALSE) = ANY (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowEqAny :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `neqAll` values_ (true `as` #foo)
--   TRUE <> ALL (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
neqAll :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowNeqAll` values_ myRow
--   ROW(1, FALSE) <> ALL (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowNeqAll :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `neqAny` values_ (true `as` #foo)
--   TRUE <> ANY (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
neqAny :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowNeqAny` values_ myRow
--   ROW(1, FALSE) <> ANY (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowNeqAny :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `allLt` values_ (true `as` #foo)
--   TRUE ALL < (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
allLt :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowLtAll` values_ myRow
--   ROW(1, FALSE) ALL < (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowLtAll :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `ltAny` values_ (true `as` #foo)
--   TRUE ANY < (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
ltAny :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowLtAll` values_ myRow
--   ROW(1, FALSE) ALL < (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowLtAny :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `lteAll` values_ (true `as` #foo)
--   TRUE <= ALL (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
lteAll :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowLteAll` values_ myRow
--   ROW(1, FALSE) <= ALL (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowLteAll :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `lteAny` values_ (true `as` #foo)
--   TRUE <= ANY (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
lteAny :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowLteAny` values_ myRow
--   ROW(1, FALSE) <= ANY (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowLteAny :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `gtAll` values_ (true `as` #foo)
--   TRUE > ALL (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
gtAll :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowGtAll` values_ myRow
--   ROW(1, FALSE) > ALL (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowGtAll :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `gtAny` values_ (true `as` #foo)
--   TRUE > ANY (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
gtAny :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowGtAny` values_ myRow
--   ROW(1, FALSE) > ANY (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowGtAny :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `gteAll` values_ (true `as` #foo)
--   TRUE >= ALL (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
gteAll :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowGteAll` values_ myRow
--   ROW(1, FALSE) >= ALL (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowGteAll :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> printSQL $ true `gteAny` values_ (true `as` #foo)
--   TRUE >= ANY (SELECT * FROM (VALUES (TRUE)) AS t ("foo"))
--   
gteAny :: Expression schema from grp params ty -> Query schema params '[alias ::: ty] -> Expression schema from grp params (nullity 'PGbool) -- |
--   >>> let myRow = 1 `as` #foo :* false `as` #bar :: NP (Aliased (Expression '[] '[] 'Ungrouped '[])) '["foo" ::: 'NotNull 'PGint2, "bar" ::: 'NotNull 'PGbool]
--   
--   >>> printSQL $ myRow `rowGteAny` values_ myRow
--   ROW(1, FALSE) >= ANY (SELECT * FROM (VALUES (1, FALSE)) AS t ("foo", "bar"))
--   
rowGteAny :: SListI row => NP (Aliased (Expression schema from grp params)) row -> Query schema params row -> Expression schema from grp params (nullity 'PGbool) instance forall k1 (schema :: k1) k2 (params :: k2) k3 (from :: k3). Control.DeepSeq.NFData (Squeal.PostgreSQL.Query.FromClause schema params from) instance forall k1 (schema :: k1) k2 (params :: k2) k3 (from :: k3). GHC.Classes.Ord (Squeal.PostgreSQL.Query.FromClause schema params from) instance forall k1 (schema :: k1) k2 (params :: k2) k3 (from :: k3). GHC.Classes.Eq (Squeal.PostgreSQL.Query.FromClause schema params from) instance forall k1 (schema :: k1) k2 (params :: k2) k3 (from :: k3). GHC.Show.Show (Squeal.PostgreSQL.Query.FromClause schema params from) instance forall k1 (schema :: k1) k2 (params :: k2) k3 (from :: k3). GHC.Generics.Generic (Squeal.PostgreSQL.Query.FromClause schema params from) 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 from by) instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.By from by) instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.By from by) instance GHC.Show.Show (Squeal.PostgreSQL.Query.HavingClause schema from grouping params) instance GHC.Classes.Eq (Squeal.PostgreSQL.Query.HavingClause schema from grouping params) instance GHC.Classes.Ord (Squeal.PostgreSQL.Query.HavingClause schema from grouping params) instance GHC.Show.Show (Squeal.PostgreSQL.Query.SortExpression schema from grouping params) instance Squeal.PostgreSQL.Query.With Squeal.PostgreSQL.Query.Query instance (GHC.TypeLits.KnownSymbol alias, schema1 ~ ((alias Squeal.PostgreSQL.Schema.::: 'Squeal.PostgreSQL.Schema.View cte) : schema)) => Squeal.PostgreSQL.Schema.Aliasable alias (statement schema params cte) (Squeal.PostgreSQL.Query.CommonTableExpression statement params schema schema1) instance (GHC.TypeLits.KnownSymbol alias, schema1 ~ ((alias Squeal.PostgreSQL.Schema.::: 'Squeal.PostgreSQL.Schema.View cte) : schema)) => Squeal.PostgreSQL.Schema.Aliasable alias (statement schema params cte) (Squeal.PostgreSQL.Schema.AlignedList (Squeal.PostgreSQL.Query.CommonTableExpression statement params) schema schema1) instance (Squeal.PostgreSQL.Schema.HasUnique rel rels cols, Squeal.PostgreSQL.Schema.Has col cols ty, by ~ '(rel, col)) => GHC.OverloadedLabels.IsLabel col (Squeal.PostgreSQL.Query.By rels by) instance (Squeal.PostgreSQL.Schema.HasUnique rel rels cols, Squeal.PostgreSQL.Schema.Has col cols ty, bys ~ '['(rel, col)]) => GHC.OverloadedLabels.IsLabel col (Generics.SOP.NP.NP (Squeal.PostgreSQL.Query.By rels) bys) instance (Squeal.PostgreSQL.Schema.Has rel rels cols, Squeal.PostgreSQL.Schema.Has col cols ty, by ~ '(rel, col)) => Squeal.PostgreSQL.Schema.IsQualified rel col (Squeal.PostgreSQL.Query.By rels by) instance (Squeal.PostgreSQL.Schema.Has rel rels cols, Squeal.PostgreSQL.Schema.Has col cols ty, bys ~ '['(rel, col)]) => Squeal.PostgreSQL.Schema.IsQualified rel col (Generics.SOP.NP.NP (Squeal.PostgreSQL.Query.By rels) bys) instance Squeal.PostgreSQL.Render.RenderSQL (Squeal.PostgreSQL.Query.Query schema params columns) -- | 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 inserts, updates -- and deletes. A Query is also considered a Manipulation -- even though it does not modify data. -- -- simple insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'Def :=> 'NotNull 'PGint4 ])] '[] '[]
--     manipulation =
--       insertRow_ #tab (Set 2 `as` #col1 :* Default `as` #col2)
--   in printSQL manipulation
--   :}
--   INSERT INTO "tab" ("col1", "col2") VALUES (2, DEFAULT)
--   
-- -- parameterized insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])]
--       '[ 'NotNull 'PGint4, 'NotNull 'PGint4 ] '[]
--     manipulation =
--       insertRow_ #tab
--         (Set (param @1) `as` #col1 :* Set (param @2) `as` #col2)
--   in printSQL manipulation
--   :}
--   INSERT INTO "tab" ("col1", "col2") VALUES (($1 :: int4), ($2 :: int4))
--   
-- -- returning insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'Def :=> 'NotNull 'PGint4 ])] '[]
--       '["fromOnly" ::: 'NotNull 'PGint4]
--     manipulation =
--       insertRow #tab (Set 2 `as` #col1 :* Default `as` #col2)
--         OnConflictDoRaise (Returning (#col1 `as` #fromOnly))
--   in printSQL manipulation
--   :}
--   INSERT INTO "tab" ("col1", "col2") VALUES (2, DEFAULT) RETURNING "col1" AS "fromOnly"
--   
-- -- upsert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])]
--       '[] '[ "sum" ::: 'NotNull 'PGint4]
--     manipulation =
--       insertRows #tab
--         (Set 2 `as` #col1 :* Set 4 `as` #col2)
--         [Set 6 `as` #col1 :* Set 8 `as` #col2]
--         (OnConflictDoUpdate
--           (Set 2 `as` #col1 :* Same `as` #col2)
--           [#col1 .== #col2])
--         (Returning $ (#col1 + #col2) `as` #sum)
--   in printSQL 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"
--   
-- -- query insert: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'NoDef :=> 'NotNull 'PGint4
--          ])
--        , "other_tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'NoDef :=> 'NotNull 'PGint4
--          ])
--        ] '[] '[]
--     manipulation =
--       insertQuery_ #tab
--         (selectStar (from (table (#other_tab `as` #t))))
--   in printSQL manipulation
--   :}
--   INSERT INTO "tab" SELECT * FROM "other_tab" AS "t"
--   
-- -- update: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])] '[] '[]
--     manipulation =
--       update_ #tab (Set 2 `as` #col1 :* Same `as` #col2)
--         (#col1 ./= #col2)
--   in printSQL manipulation
--   :}
--   UPDATE "tab" SET "col1" = 2 WHERE ("col1" <> "col2")
--   
-- -- delete: -- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "tab" ::: 'Table ('[] :=>
--         '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ])] '[]
--       '[ "col1" ::: 'NotNull 'PGint4
--        , "col2" ::: 'NotNull 'PGint4 ]
--     manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar
--   in printSQL manipulation
--   :}
--   DELETE FROM "tab" WHERE ("col1" = "col2") RETURNING *
--   
-- -- with manipulation: -- --
--   >>> type ProductsTable = '[] :=> '["product" ::: 'NoDef :=> 'NotNull 'PGtext, "date" ::: 'Def :=> 'NotNull 'PGdate]
--   
-- --
--   >>> :{
--   let
--     manipulation :: Manipulation
--       '[ "products" ::: 'Table ProductsTable
--        , "products_deleted" ::: 'Table ProductsTable
--        ] '[ 'NotNull 'PGdate] '[]
--     manipulation = with
--       (deleteFrom #products (#date .< param @1) ReturningStar `as` #deleted_rows)
--       (insertQuery_ #products_deleted (selectStar (from (view (#deleted_rows `as` #t)))))
--   in printSQL manipulation
--   :}
--   WITH "deleted_rows" AS (DELETE FROM "products" WHERE ("date" < ($1 :: date)) RETURNING *) INSERT INTO "products_deleted" SELECT * FROM "deleted_rows" AS "t"
--   
newtype Manipulation (schema :: SchemaType) (params :: [NullityType]) (columns :: RowType) UnsafeManipulation :: ByteString -> Manipulation [renderManipulation] :: Manipulation -> ByteString -- | Convert a Query into a Manipulation. queryStatement :: Query schema params columns -> Manipulation schema params columns -- | ColumnValues are values to insert or update in a row. -- Same updates with the same value. Default inserts or -- updates with the DEFAULT value. Set sets a value to be -- an Expression, which can refer to existing value in the row for -- an update. data ColumnValue (schema :: SchemaType) (columns :: RowType) (params :: [NullityType]) (ty :: ColumnType) [Same] :: ColumnValue schema (column : columns) params ty [Default] :: ColumnValue schema columns params ( 'Def :=> ty) [Set] :: (forall table. Expression schema '[table ::: columns] 'Ungrouped params ty) -> ColumnValue schema columns params (constraint :=> ty) -- | 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 (schema :: SchemaType) (params :: [NullityType]) (row0 :: RowType) (row1 :: RowType) [ReturningStar] :: ReturningClause schema params row row [Returning] :: NP (Aliased (Expression schema '[table ::: row0] 'Ungrouped params)) row1 -> ReturningClause schema params row0 row1 -- | 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 (schema :: SchemaType) (table :: TableType) (params :: [NullityType]) [OnConflictDoRaise] :: ConflictClause schema table params [OnConflictDoNothing] :: ConflictClause schema table params [OnConflictDoUpdate] :: (row ~ TableToRow table, columns ~ TableToColumns table) => NP (Aliased (ColumnValue schema row params)) columns -> [Condition schema '[t ::: row] 'Ungrouped params] -> ConflictClause schema table params -- | Insert multiple rows. -- -- 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. insertRows :: (SListI columns, SListI results, Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> NP (Aliased (ColumnValue schema '[] params)) columns -> [NP (Aliased (ColumnValue schema '[] params)) columns] -> ConflictClause schema table params -> ReturningClause schema params row results -> Manipulation schema params results -- | Insert a single row. insertRow :: (SListI columns, SListI results, Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> NP (Aliased (ColumnValue schema '[] params)) columns -> ConflictClause schema table params -> ReturningClause schema params row results -> Manipulation schema params results -- | Insert multiple rows returning Nil and raising an error on -- conflicts. insertRows_ :: (SListI columns, Has tab schema ( 'Table table), columns ~ TableToColumns table) => Alias tab -> NP (Aliased (ColumnValue schema '[] params)) columns -> [NP (Aliased (ColumnValue schema '[] params)) columns] -> Manipulation schema params '[] -- | Insert a single row returning Nil and raising an error on -- conflicts. insertRow_ :: (SListI columns, Has tab schema ( 'Table table), columns ~ TableToColumns table) => Alias tab -> NP (Aliased (ColumnValue schema '[] params)) columns -> Manipulation schema params '[] -- | Insert a Query. insertQuery :: (SListI columns, SListI results, Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> Query schema params (TableToRow table) -> ConflictClause schema table params -> ReturningClause schema params row results -> Manipulation schema params results -- | Insert a Query returning Nil and raising an error on -- conflicts. insertQuery_ :: (SListI columns, Has tab schema ( 'Table table), columns ~ TableToColumns table) => Alias tab -> Query schema params (TableToRow table) -> Manipulation schema params '[] -- | Render a ReturningClause. renderReturningClause :: SListI results => ReturningClause schema params columns results -> ByteString -- | Render a ConflictClause. renderConflictClause :: SListI (TableToColumns table) => ConflictClause schema table params -> ByteString -- | An update command changes the values of the specified columns -- in all rows that satisfy the condition. update :: (SListI columns, SListI results, Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> NP (Aliased (ColumnValue schema row params)) columns -> (forall t. Condition schema '[t ::: row] 'Ungrouped params) -> ReturningClause schema params row results -> Manipulation schema params results -- | Update a row returning Nil. update_ :: (SListI columns, Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> NP (Aliased (ColumnValue schema row params)) columns -> (forall t. Condition schema '[t ::: row] 'Ungrouped params) -> Manipulation schema params '[] -- | Delete rows of a table. deleteFrom :: (SListI results, Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> Condition schema '[tab ::: row] 'Ungrouped params -> ReturningClause schema params row results -> Manipulation schema params results -- | Delete rows returning Nil. deleteFrom_ :: (Has tab schema ( 'Table table), row ~ TableToRow table, columns ~ TableToColumns table) => Alias tab -> (forall t. Condition schema '[t ::: row] 'Ungrouped params) -> Manipulation schema params '[] 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 Squeal.PostgreSQL.Render.RenderSQL (Squeal.PostgreSQL.Manipulation.Manipulation schema params columns) instance Squeal.PostgreSQL.Query.With Squeal.PostgreSQL.Manipulation.Manipulation -- | 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 :: SchemaType) (schema1 :: SchemaType) UnsafeDefinition :: ByteString -> Definition [renderDefinition] :: Definition -> ByteString -- | Left-to-right composition (>>>) :: Category cat => cat a b -> cat b c -> cat a c infixr 1 >>> -- | createTable adds a table to the schema. -- --
--   >>> :set -XOverloadedLabels
--   
--   >>> :{
--   type Table = '[] :=>
--     '[ "a" ::: 'NoDef :=> 'Null 'PGint4
--      , "b" ::: 'NoDef :=> 'Null 'PGfloat4 ]
--   :}
--   
-- --
--   >>> :{
--   let
--     setup :: Definition '[] '["tab" ::: 'Table Table]
--     setup = createTable #tab
--       (nullable int `as` #a :* nullable real `as` #b) Nil
--   in printSQL setup
--   :}
--   CREATE TABLE "tab" ("a" int NULL, "b" real NULL);
--   
createTable :: (KnownSymbol table, columns ~ (col : cols), SListI columns, SListI constraints, schema1 ~ Create table ( 'Table (constraints :=> columns)) schema0) => Alias table -> NP (Aliased (ColumnTypeExpression schema0)) columns -> NP (Aliased (TableConstraintExpression schema1 table)) constraints -> Definition schema0 schema1 -- | createTableIfNotExists creates a table if it doesn't exist, but -- does not add it to the schema. Instead, the schema already has the -- table so if the table did not yet exist, the schema was wrong. -- createTableIfNotExists fixes this. Interestingly, this property -- makes it an idempotent in the Category of Definitions. -- --
--   >>> :set -XOverloadedLabels -XTypeApplications
--   
--   >>> :{
--   type Table = '[] :=>
--     '[ "a" ::: 'NoDef :=> 'Null 'PGint4
--      , "b" ::: 'NoDef :=> 'Null 'PGfloat4 ]
--   :}
--   
-- --
--   >>> type Schema = '["tab" ::: 'Table Table]
--   
-- --
--   >>> :{
--   let
--     setup :: Definition Schema Schema
--     setup = createTableIfNotExists #tab
--       (nullable int `as` #a :* nullable real `as` #b) Nil
--   in printSQL setup
--   :}
--   CREATE TABLE IF NOT EXISTS "tab" ("a" int NULL, "b" real NULL);
--   
createTableIfNotExists :: (Has table schema ( 'Table (constraints :=> columns)), SListI columns, SListI constraints) => Alias table -> NP (Aliased (ColumnTypeExpression schema)) columns -> NP (Aliased (TableConstraintExpression schema table)) constraints -> Definition schema 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 TableConstraintExpression (schema :: SchemaType) (table :: Symbol) (tableConstraint :: TableConstraint) UnsafeTableConstraintExpression :: ByteString -> TableConstraintExpression [renderTableConstraintExpression] :: TableConstraintExpression -> 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. -- --
--   >>> :{
--   type Schema = '[
--     "tab" ::: 'Table ('[ "inequality" ::: 'Check '["a","b"]] :=> '[
--       "a" ::: 'NoDef :=> 'NotNull 'PGint4,
--       "b" ::: 'NoDef :=> 'NotNull 'PGint4
--     ])]
--   :}
--   
-- --
--   >>> :{
--   let
--     definition :: Definition '[] Schema
--     definition = createTable #tab
--       ( (int & notNullable) `as` #a :*
--         (int & notNullable) `as` #b )
--       ( check (#a :* #b) (#a .> #b) `as` #inequality )
--   :}
--   
-- --
--   >>> printSQL definition
--   CREATE TABLE "tab" ("a" int NOT NULL, "b" int NOT NULL, CONSTRAINT "inequality" CHECK (("a" > "b")));
--   
check :: (Has alias schema ( 'Table table), HasAll aliases (TableToRow table) subcolumns) => NP Alias aliases -> (forall tab. Condition schema '[tab ::: subcolumns] 'Ungrouped '[]) -> TableConstraintExpression schema alias ( 'Check aliases) -- | 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. -- --
--   >>> :{
--   type Schema = '[
--     "tab" ::: 'Table( '[ "uq_a_b" ::: 'Unique '["a","b"]] :=> '[
--       "a" ::: 'NoDef :=> 'Null 'PGint4,
--       "b" ::: 'NoDef :=> 'Null 'PGint4
--     ])]
--   :}
--   
-- --
--   >>> :{
--   let
--     definition :: Definition '[] Schema
--     definition = createTable #tab
--       ( (int & nullable) `as` #a :*
--         (int & nullable) `as` #b )
--       ( unique (#a :* #b) `as` #uq_a_b )
--   :}
--   
-- --
--   >>> printSQL definition
--   CREATE TABLE "tab" ("a" int NULL, "b" int NULL, CONSTRAINT "uq_a_b" UNIQUE ("a", "b"));
--   
unique :: (Has alias schema ( 'Table table), HasAll aliases (TableToRow table) subcolumns) => NP Alias aliases -> TableConstraintExpression schema alias ( 'Unique aliases) -- | 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. -- --
--   >>> :{
--   type Schema = '[
--     "tab" ::: 'Table ('[ "pk_id" ::: 'PrimaryKey '["id"]] :=> '[
--       "id" ::: 'Def :=> 'NotNull 'PGint4,
--       "name" ::: 'NoDef :=> 'NotNull 'PGtext
--     ])]
--   :}
--   
-- --
--   >>> :{
--   let
--     definition :: Definition '[] Schema
--     definition = createTable #tab
--       ( serial `as` #id :*
--         (text & notNullable) `as` #name )
--       ( primaryKey #id `as` #pk_id )
--   :}
--   
-- --
--   >>> printSQL definition
--   CREATE TABLE "tab" ("id" serial, "name" text NOT NULL, CONSTRAINT "pk_id" PRIMARY KEY ("id"));
--   
primaryKey :: (Has alias schema ( 'Table table), HasAll aliases (TableToColumns table) subcolumns, AllNotNull subcolumns) => NP Alias aliases -> TableConstraintExpression schema alias ( 'PrimaryKey aliases) -- | 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. -- --
--   >>> :{
--   type Schema =
--     '[ "users" ::: 'Table (
--          '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
--          '[ "id" ::: 'Def :=> 'NotNull 'PGint4
--           , "name" ::: 'NoDef :=> 'NotNull 'PGtext
--           ])
--      , "emails" ::: 'Table (
--          '[  "pk_emails" ::: 'PrimaryKey '["id"]
--           , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"]
--           ] :=>
--          '[ "id" ::: 'Def :=> 'NotNull 'PGint4
--           , "user_id" ::: 'NoDef :=> 'NotNull 'PGint4
--           , "email" ::: 'NoDef :=> 'Null 'PGtext
--           ])
--      ]
--   :}
--   
-- --
--   >>> :{
--   let
--     setup :: Definition '[] Schema
--     setup =
--      createTable #users
--        ( serial `as` #id :*
--          (text & notNullable) `as` #name )
--        ( primaryKey #id `as` #pk_users ) >>>
--      createTable #emails
--        ( serial `as` #id :*
--          (int & notNullable) `as` #user_id :*
--          (text & nullable) `as` #email )
--        ( primaryKey #id `as` #pk_emails :*
--          foreignKey #user_id #users #id
--            OnDeleteCascade OnUpdateCascade `as` #fk_user_id )
--   in printSQL setup
--   :}
--   CREATE TABLE "users" ("id" serial, "name" text NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"));
--   CREATE TABLE "emails" ("id" serial, "user_id" int NOT NULL, "email" text NULL, CONSTRAINT "pk_emails" PRIMARY KEY ("id"), CONSTRAINT "fk_user_id" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE);
--   
-- -- A foreignKey can even be a table self-reference. -- --
--   >>> :{
--   type Schema =
--     '[ "employees" ::: 'Table (
--          '[ "employees_pk"          ::: 'PrimaryKey '["id"]
--           , "employees_employer_fk" ::: 'ForeignKey '["employer_id"] "employees" '["id"]
--           ] :=>
--          '[ "id"          :::   'Def :=> 'NotNull 'PGint4
--           , "name"        ::: 'NoDef :=> 'NotNull 'PGtext
--           , "employer_id" ::: 'NoDef :=>    'Null 'PGint4
--           ])
--      ]
--   :}
--   
-- --
--   >>> :{
--   let
--     setup :: Definition '[] Schema
--     setup =
--      createTable #employees
--        ( serial `as` #id :*
--          (text & notNullable) `as` #name :*
--          (integer & nullable) `as` #employer_id )
--        ( primaryKey #id `as` #employees_pk :*
--          foreignKey #employer_id #employees #id
--            OnDeleteCascade OnUpdateCascade `as` #employees_employer_fk )
--   in printSQL setup
--   :}
--   CREATE TABLE "employees" ("id" serial, "name" text NOT NULL, "employer_id" integer NULL, CONSTRAINT "employees_pk" PRIMARY KEY ("id"), CONSTRAINT "employees_employer_fk" FOREIGN KEY ("employer_id") REFERENCES "employees" ("id") ON DELETE CASCADE ON UPDATE CASCADE);
--   
foreignKey :: (ForeignKeyed schema child parent table reftable columns refcolumns constraints cols reftys tys) => NP Alias columns -> Alias parent -> NP Alias refcolumns -> OnDeleteClause -> OnUpdateClause -> TableConstraintExpression schema child ( 'ForeignKey columns parent refcolumns) -- | A constraint synonym between types involved in a foreign key -- constraint. type ForeignKeyed schema child parent table reftable columns refcolumns constraints cols reftys tys = (Has child schema ( 'Table table), Has parent schema ( 'Table reftable), HasAll columns (TableToColumns table) tys, reftable ~ (constraints :=> cols), HasAll refcolumns cols reftys, AllZip SamePGType tys reftys, Uniquely refcolumns constraints) -- | OnDeleteClause 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 OnDeleteClause there is also OnUpdateClause -- 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. -- --
--   >>> :{
--   let
--     definition :: Definition '["muh_table" ::: 'Table t] '[]
--     definition = dropTable #muh_table
--   :}
--   
-- --
--   >>> printSQL definition
--   DROP TABLE "muh_table";
--   
dropTable :: Has table schema ( 'Table t) => Alias table -> Definition schema (Drop table schema) -- | alterTable changes the definition of a table from the schema. alterTable :: KnownSymbol alias => Alias alias -> AlterTable alias table schema -> Definition schema (Alter alias ( 'Table table) schema) -- | alterTableRename changes the name of a table from the schema. -- --
--   >>> printSQL $ 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 AlterTable describes the alteration to perform on the -- columns of a table. newtype AlterTable (alias :: Symbol) (table :: TableType) (schema :: SchemaType) UnsafeAlterTable :: ByteString -> AlterTable [renderAlterTable] :: AlterTable -> ByteString -- | An addConstraint adds a table constraint. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--       '["tab" ::: 'Table ('["positive" ::: Check '["col"]] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--     definition = alterTable #tab (addConstraint #positive (check #col (#col .> 0)))
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ADD CONSTRAINT "positive" CHECK (("col" > 0));
--   
addConstraint :: (KnownSymbol alias, Has tab schema ( 'Table table0), table0 ~ (constraints :=> columns), table1 ~ (Create alias constraint constraints :=> columns)) => Alias alias -> TableConstraintExpression schema tab constraint -> AlterTable tab table1 schema -- | A dropConstraint drops a table constraint. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('["positive" ::: Check '["col"]] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--     definition = alterTable #tab (dropConstraint #positive)
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" DROP CONSTRAINT "positive";
--   
dropConstraint :: (KnownSymbol constraint, Has tab schema ( 'Table table0), table0 ~ (constraints :=> columns), table1 ~ (Drop constraint constraints :=> columns)) => Alias constraint -> AlterTable tab table1 schema -- | An AddColumn is either NULL or has DEFAULT. class AddColumn ty -- | addColumn adds a new column, initially filled with whatever -- default value is given or with NULL. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["col1" ::: 'NoDef :=> 'Null 'PGint4])]
--       '["tab" ::: 'Table ('[] :=>
--          '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
--           , "col2" ::: 'Def :=> 'Null 'PGtext ])]
--     definition = alterTable #tab (addColumn #col2 (text & nullable & default_ "foo"))
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ADD COLUMN "col2" text NULL DEFAULT E'foo';
--   
-- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["col1" ::: 'NoDef :=> 'Null 'PGint4])]
--       '["tab" ::: 'Table ('[] :=>
--          '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
--           , "col2" ::: 'NoDef :=> 'Null 'PGtext ])]
--     definition = alterTable #tab (addColumn #col2 (text & nullable))
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ADD COLUMN "col2" text NULL;
--   
addColumn :: (AddColumn ty, KnownSymbol column, Has tab schema ( 'Table table0), table0 ~ (constraints :=> columns), table1 ~ (constraints :=> Create column ty columns)) => Alias column -> ColumnTypeExpression schema ty -> AlterTable tab table1 schema -- | 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" ::: 'Table ('[] :=>
--          '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
--           , "col2" ::: 'NoDef :=> 'Null 'PGtext ])]
--       '["tab" ::: 'Table ('[] :=> '["col1" ::: 'NoDef :=> 'Null 'PGint4])]
--     definition = alterTable #tab (dropColumn #col2)
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" DROP COLUMN "col2";
--   
dropColumn :: (KnownSymbol column, Has tab schema ( 'Table table0), table0 ~ (constraints :=> columns), table1 ~ (constraints :=> Drop column columns)) => Alias column -> AlterTable tab table1 schema -- | A renameColumn renames a column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["foo" ::: 'NoDef :=> 'Null 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["bar" ::: 'NoDef :=> 'Null 'PGint4])]
--     definition = alterTable #tab (renameColumn #foo #bar)
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" RENAME COLUMN "foo" TO "bar";
--   
renameColumn :: (KnownSymbol column0, KnownSymbol column1, Has tab schema ( 'Table table0), table0 ~ (constraints :=> columns), table1 ~ (constraints :=> Rename column0 column1 columns)) => Alias column0 -> Alias column1 -> AlterTable tab table1 schema -- | An alterColumn alters a single column. alterColumn :: (KnownSymbol column, Has tab schema ( 'Table table0), table0 ~ (constraints :=> columns), Has column columns ty0, tables1 ~ (constraints :=> Alter column ty1 columns)) => Alias column -> AlterColumn schema ty0 ty1 -> AlterTable tab table1 schema -- | An AlterColumn describes the alteration to perform on a single -- column. newtype AlterColumn (schema :: SchemaType) (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 insert and update commands. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'Def :=> 'Null 'PGint4])]
--     definition = alterTable #tab (alterColumn #col (setDefault 5))
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ALTER COLUMN "col" SET DEFAULT 5;
--   
setDefault :: Expression schema '[] 'Ungrouped '[] ty -> AlterColumn schema (constraint :=> ty) ( 'Def :=> ty) -- | A dropDefault removes any default value for a column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'Def :=> 'Null 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--     definition = alterTable #tab (alterColumn #col dropDefault)
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ALTER COLUMN "col" DROP DEFAULT;
--   
dropDefault :: AlterColumn schema ( 'Def :=> ty) ( 'NoDef :=> 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" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--     definition = alterTable #tab (alterColumn #col setNotNull)
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ALTER COLUMN "col" SET NOT NULL;
--   
setNotNull :: AlterColumn schema (constraint :=> 'Null ty) (constraint :=> 'NotNull ty) -- | A dropNotNull drops a NOT NULL constraint from a -- column. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4])]
--     definition = alterTable #tab (alterColumn #col dropNotNull)
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ALTER COLUMN "col" DROP NOT NULL;
--   
dropNotNull :: AlterColumn schema (constraint :=> 'NotNull ty) (constraint :=> '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" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4])]
--       '["tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGnumeric])]
--     definition =
--       alterTable #tab (alterColumn #col (alterType (numeric & notNullable)))
--   in printSQL definition
--   :}
--   ALTER TABLE "tab" ALTER COLUMN "col" TYPE numeric NOT NULL;
--   
alterType :: ColumnTypeExpression schema ty -> AlterColumn schema ty0 ty -- | Create a view. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '[ "abc" ::: 'Table ('[] :=> '["a" ::: 'NoDef :=> 'Null 'PGint4, "b" ::: 'NoDef :=> 'Null 'PGint4, "c" ::: 'NoDef :=> 'Null 'PGint4])]
--       '[ "abc" ::: 'Table ('[] :=> '["a" ::: 'NoDef :=> 'Null 'PGint4, "b" ::: 'NoDef :=> 'Null 'PGint4, "c" ::: 'NoDef :=> 'Null 'PGint4])
--        , "bc"  ::: 'View ('["b" ::: 'Null 'PGint4, "c" ::: 'Null 'PGint4])]
--     definition =
--       createView #bc (select (#b :* #c) (from (table #abc)))
--   in printSQL definition
--   :}
--   CREATE VIEW "bc" AS SELECT "b" AS "b", "c" AS "c" FROM "abc" AS "abc";
--   
createView :: KnownSymbol view => Alias view -> Query schema '[] row -> Definition schema (Create view ( 'View row) schema) -- | Drop a view. -- --
--   >>> :{
--   let
--     definition :: Definition
--       '[ "abc" ::: 'Table ('[] :=> '["a" ::: 'NoDef :=> 'Null 'PGint4, "b" ::: 'NoDef :=> 'Null 'PGint4, "c" ::: 'NoDef :=> 'Null 'PGint4])
--        , "bc"  ::: 'View ('["b" ::: 'Null 'PGint4, "c" ::: 'Null 'PGint4])]
--       '[ "abc" ::: 'Table ('[] :=> '["a" ::: 'NoDef :=> 'Null 'PGint4, "b" ::: 'NoDef :=> 'Null 'PGint4, "c" ::: 'NoDef :=> 'Null 'PGint4])]
--     definition = dropView #bc
--   in printSQL definition
--   :}
--   DROP VIEW "bc";
--   
dropView :: Has view schema ( 'View v) => Alias view -> Definition schema (Drop view schema) -- | Enumerated types are created using the createTypeEnum command, -- for example -- --
--   >>> printSQL $ createTypeEnum #mood (label @"sad" :* label @"ok" :* label @"happy")
--   CREATE TYPE "mood" AS ENUM ('sad', 'ok', 'happy');
--   
createTypeEnum :: (KnownSymbol enum, All KnownSymbol labels) => Alias enum -> NP PGlabel labels -> Definition schema (Create enum ( 'Typedef ( 'PGenum labels)) schema) -- | Enumerated types can also be generated from a Haskell type, for -- example -- --
--   >>> data Schwarma = Beef | Lamb | Chicken deriving GHC.Generic
--   
--   >>> instance SOP.Generic Schwarma
--   
--   >>> instance SOP.HasDatatypeInfo Schwarma
--   
--   >>> printSQL $ createTypeEnumFrom @Schwarma #schwarma
--   CREATE TYPE "schwarma" AS ENUM ('Beef', 'Lamb', 'Chicken');
--   
createTypeEnumFrom :: forall hask enum schema. (Generic hask, All KnownSymbol (LabelsPG hask), KnownSymbol enum) => Alias enum -> Definition schema (Create enum ( 'Typedef (PG (Enumerated hask))) schema) -- | createTypeComposite creates a composite type. The composite -- type is specified by a list of attribute names and data types. -- --
--   >>> :{
--   type PGcomplex = 'PGcomposite
--     '[ "real"      ::: 'NotNull 'PGfloat8
--      , "imaginary" ::: 'NotNull 'PGfloat8 ]
--   :}
--   
-- --
--   >>> :{
--   let
--     setup :: Definition '[] '["complex" ::: 'Typedef PGcomplex]
--     setup = createTypeComposite #complex
--       (float8 `as` #real :* float8 `as` #imaginary)
--   in printSQL setup
--   :}
--   CREATE TYPE "complex" AS ("real" float8, "imaginary" float8);
--   
createTypeComposite :: (KnownSymbol ty, SListI fields) => Alias ty -> NP (Aliased (TypeExpression schema)) fields -> Definition schema (Create ty ( 'Typedef ( 'PGcomposite fields)) schema) -- | Composite types can also be generated from a Haskell type, for example -- --
--   >>> data Complex = Complex {real :: Double, imaginary :: Double} deriving GHC.Generic
--   
--   >>> instance SOP.Generic Complex
--   
--   >>> instance SOP.HasDatatypeInfo Complex
--   
--   >>> printSQL $ createTypeCompositeFrom @Complex #complex
--   CREATE TYPE "complex" AS ("real" float8, "imaginary" float8);
--   
createTypeCompositeFrom :: forall hask ty schema. (All (FieldTyped schema) (RowPG hask), KnownSymbol ty) => Alias ty -> Definition schema (Create ty ( 'Typedef (PG (Composite hask))) schema) -- | Drop a type. -- --
--   >>> data Schwarma = Beef | Lamb | Chicken deriving GHC.Generic
--   
--   >>> instance SOP.Generic Schwarma
--   
--   >>> instance SOP.HasDatatypeInfo Schwarma
--   
--   >>> printSQL (dropType #schwarma :: Definition '["schwarma" ::: 'Typedef (PG (Enumerated Schwarma))] '[])
--   DROP TYPE "schwarma";
--   
dropType :: Has tydef schema ( 'Typedef ty) => Alias tydef -> Definition schema (Drop tydef schema) -- | ColumnTypeExpressions are used in createTable commands. newtype ColumnTypeExpression (schema :: SchemaType) (ty :: ColumnType) UnsafeColumnTypeExpression :: ByteString -> ColumnTypeExpression [renderColumnTypeExpression] :: ColumnTypeExpression -> ByteString -- | used in createTable commands as a column constraint to note -- that NULL may be present in a column nullable :: TypeExpression schema (nullity ty) -> ColumnTypeExpression schema ( 'NoDef :=> 'Null ty) -- | used in createTable commands as a column constraint to ensure -- NULL is not present in a column notNullable :: TypeExpression schema (nullity ty) -> ColumnTypeExpression schema ( 'NoDef :=> 'NotNull ty) -- | used in createTable commands as a column constraint to give a -- default default_ :: Expression schema '[] 'Ungrouped '[] ty -> ColumnTypeExpression schema ( 'NoDef :=> ty) -> ColumnTypeExpression schema ( 'Def :=> ty) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type PGint2 serial2 :: ColumnTypeExpression schema ( 'Def :=> 'NotNull 'PGint2) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type PGint2 smallserial :: ColumnTypeExpression schema ( 'Def :=> 'NotNull 'PGint2) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type PGint4 serial4 :: ColumnTypeExpression schema ( 'Def :=> 'NotNull 'PGint4) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type PGint4 serial :: ColumnTypeExpression schema ( 'Def :=> 'NotNull 'PGint4) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type PGint8 serial8 :: ColumnTypeExpression schema ( 'Def :=> 'NotNull 'PGint8) -- | not a true type, but merely a notational convenience for creating -- unique identifier columns with type PGint8 bigserial :: ColumnTypeExpression schema ( 'Def :=> 'NotNull 'PGint8) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.ColumnTypeExpression schema ty) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.ColumnTypeExpression schema ty) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.ColumnTypeExpression schema ty) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.ColumnTypeExpression schema ty) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.ColumnTypeExpression schema ty) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.AlterColumn schema ty0 ty1) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.AlterColumn schema ty0 ty1) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.AlterColumn schema ty0 ty1) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.AlterColumn schema ty0 ty1) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.AlterColumn schema ty0 ty1) instance Control.DeepSeq.NFData (Squeal.PostgreSQL.Definition.AlterTable alias table schema) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.AlterTable alias table schema) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.AlterTable alias table schema) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.AlterTable alias table schema) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.AlterTable alias table schema) 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.TableConstraintExpression schema table tableConstraint) instance GHC.Classes.Ord (Squeal.PostgreSQL.Definition.TableConstraintExpression schema table tableConstraint) instance GHC.Classes.Eq (Squeal.PostgreSQL.Definition.TableConstraintExpression schema table tableConstraint) instance GHC.Show.Show (Squeal.PostgreSQL.Definition.TableConstraintExpression schema table tableConstraint) instance GHC.Generics.Generic (Squeal.PostgreSQL.Definition.TableConstraintExpression schema table tableConstraint) 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 Squeal.PostgreSQL.Definition.AddColumn ('Squeal.PostgreSQL.Schema.Def Squeal.PostgreSQL.Schema.:=> ty) instance Squeal.PostgreSQL.Definition.AddColumn ('Squeal.PostgreSQL.Schema.NoDef Squeal.PostgreSQL.Schema.:=> 'Squeal.PostgreSQL.Schema.Null ty) instance (GHC.TypeLits.KnownSymbol alias, Squeal.PostgreSQL.Expression.PGTyped schema ty) => Squeal.PostgreSQL.Definition.FieldTyped schema (alias Squeal.PostgreSQL.Schema.::: ty) instance Control.DeepSeq.NFData Squeal.PostgreSQL.Definition.OnUpdateClause instance Control.DeepSeq.NFData Squeal.PostgreSQL.Definition.OnDeleteClause instance Squeal.PostgreSQL.Render.RenderSQL (Squeal.PostgreSQL.Definition.Definition schema0 schema1) instance Control.Category.Category Squeal.PostgreSQL.Definition.Definition -- | This module provides binary encoding and decoding between Haskell and -- PostgreSQL types. -- -- Instances are governed by the Generic and -- HasDatatypeInfo typeclasses, so you absolutely do not need to -- define your own instances to decode retrieved rows into Haskell values -- or to encode Haskell values into statement parameters. -- -- Let's see some examples. We'll need some imports -- --
--   >>> import Data.Int (Int16)
--   
--   >>> import Data.Text (Text)
--   
--   >>> import Control.Monad (void)
--   
--   >>> import Control.Monad.Base (liftBase)
--   
--   >>> import Squeal.PostgreSQL
--   
-- -- Define a Haskell datatype Row that will serve as both the -- input and output of a simple round trip query. -- --
--   >>> data Row = Row { col1 :: Int16, col2 :: Text, col3 :: Maybe Bool } deriving (Eq, GHC.Generic)
--   
--   >>> instance Generic Row
--   
--   >>> instance HasDatatypeInfo Row
--   
--   >>> :{
--   let
--     roundTrip :: Query '[] (TuplePG Row) (RowPG Row)
--     roundTrip = values_ $
--       parameter @1 int2 `as` #col1 :*
--       parameter @2 text `as` #col2 :*
--       parameter @3 bool `as` #col3
--   :}
--   
-- -- So long as we can encode the parameters and then decode the result of -- the query, the input and output should be equal. -- --
--   >>> let input = Row 2 "hi" (Just True)
--   
--   >>> :{
--   void . withConnection "host=localhost port=5432 dbname=exampledb" $ do
--     result <- runQueryParams roundTrip input
--     Just output <- firstRow result
--     liftBase . print $ input == output
--   :}
--   True
--   
-- -- In addition to being able to encode and decode basic Haskell types -- like Int16 and Text, Squeal permits you to encode and -- decode Haskell types to Postgres array, enumerated and composite types -- and json. Let's see another example, this time using the Vector -- type which corresponds to variable length arrays and homogeneous -- tuples which correspond to fixed length arrays. We can even create -- multi-dimensional fixed length arrays. -- --
--   >>> :{
--   data Row = Row
--     { col1 :: Vector Int16
--     , col2 :: (Maybe Int16,Maybe Int16)
--     , col3 :: ((Int16,Int16),(Int16,Int16),(Int16,Int16))
--     } deriving (Eq, GHC.Generic)
--   :}
--   
-- --
--   >>> instance Generic Row
--   
--   >>> instance HasDatatypeInfo Row
--   
-- -- Once again, we define a simple round trip query. -- --
--   >>> :{
--   let
--     roundTrip :: Query '[] (TuplePG Row) (RowPG Row)
--     roundTrip = values_ $
--       parameter @1 (int2 & vararray)                  `as` #col1 :*
--       parameter @2 (int2 & fixarray @2)               `as` #col2 :*
--       parameter @3 (int2 & fixarray @2 & fixarray @3) `as` #col3
--   :}
--   
-- --
--   >>> :set -XOverloadedLists
--   
--   >>> let input = Row [1,2] (Just 1,Nothing) ((1,2),(3,4),(5,6))
--   
--   >>> :{
--   void . withConnection "host=localhost port=5432 dbname=exampledb" $ do
--     result <- runQueryParams roundTrip input
--     Just output <- firstRow result
--     liftBase . print $ input == output
--   :}
--   True
--   
-- -- Enumerated (enum) types are data types that comprise a static, ordered -- set of values. They are equivalent to Haskell algebraic data types -- whose constructors are nullary. An example of an enum type might be -- the days of the week, or a set of status values for a piece of data. -- --
--   >>> data Schwarma = Beef | Lamb | Chicken deriving (Eq, Show, GHC.Generic)
--   
--   >>> instance Generic Schwarma
--   
--   >>> instance HasDatatypeInfo Schwarma
--   
-- -- A composite type represents the structure of a row or record; it is -- essentially just a list of field names and their data types. -- --
--   >>> data Person = Person {name :: Text, age :: Int32} deriving (Eq, Show, GHC.Generic)
--   
--   >>> instance Generic Person
--   
--   >>> instance HasDatatypeInfo Person
--   
--   >>> instance Aeson.FromJSON Person
--   
--   >>> instance Aeson.ToJSON Person
--   
-- -- We can create the equivalent Postgres types directly from their -- Haskell types. -- --
--   >>> :{
--   type Schema =
--     '[ "schwarma" ::: 'Typedef (PG (Enumerated Schwarma))
--      , "person" ::: 'Typedef (PG (Composite Person))
--      ]
--   :}
--   
-- --
--   >>> :{
--   let
--     setup :: Definition '[] Schema
--     setup =
--       createTypeEnumFrom @Schwarma #schwarma >>>
--       createTypeCompositeFrom @Person #person
--   :}
--   
-- -- Let's demonstrate how to associate our Haskell types Schwarma -- and Person with enumerated, composite or json types in -- Postgres. First create a Haskell Row type using the -- Enumerated, Composite and Json newtypes as -- fields. -- --
--   >>> :{
--   data Row = Row
--     { schwarma :: Enumerated Schwarma
--     , person1 :: Composite Person
--     , person2 :: Json Person
--     } deriving (Eq, GHC.Generic)
--   :}
--   
-- --
--   >>> instance Generic Row
--   
--   >>> instance HasDatatypeInfo Row
--   
--   >>> :{
--   let
--     input = Row
--       (Enumerated Chicken)
--       (Composite (Person "Faisal" 24))
--       (Json (Person "Ahmad" 48))
--   :}
--   
-- -- Once again, define a round trip query. -- --
--   >>> :{
--   let
--     roundTrip :: Query Schema (TuplePG Row) (RowPG Row)
--     roundTrip = values_ $
--       parameter @1 (typedef #schwarma) `as` #schwarma :*
--       parameter @2 (typedef #person)   `as` #person1  :*
--       parameter @3 json                `as` #person2
--   :}
--   
-- -- Finally, we can drop our type definitions. -- --
--   >>> :{
--   let
--     teardown :: Definition Schema '[]
--     teardown = dropType #schwarma >>> dropType #person
--   :}
--   
-- -- Now let's run it. -- --
--   >>> :{
--   let
--     session = do
--       result <- runQueryParams roundTrip input
--       Just output <- firstRow result
--       liftBase . print $ input == output
--   in
--     void . withConnection "host=localhost port=5432 dbname=exampledb" $
--       define setup
--       & pqThen session
--       & pqThen (define teardown)
--   :}
--   True
--   
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 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 :: [NullityType]) -- |
--   >>> type Params = '[ 'NotNull 'PGbool, 'Null 'PGint2]
--   
--   >>> toParams @(Bool, Maybe Int16) @'[ 'NotNull 'PGbool, 'Null 'PGint2] (False, Just 0)
--   K (Just "\NUL") :* K (Just "\NUL\NUL") :* Nil
--   
-- --
--   >>> :set -XDeriveGeneric
--   
--   >>> data Tuple = Tuple { p1 :: Bool, p2 :: Maybe Int16} deriving GHC.Generic
--   
--   >>> instance Generic Tuple
--   
--   >>> toParams @Tuple @Params (Tuple False (Just 0))
--   K (Just "\NUL") :* K (Just "\NUL\NUL") :* Nil
--   
toParams :: ToParams x tys => x -> NP (K (Maybe Encoding)) 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 = Id <$> fromValue @'PGint2
--   
fromValue :: FromValue pg y => Value y -- | A FromRow constraint generically sequences the parsings of the -- columns of a RowType 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 result => FromRow (result :: RowType) y -- |
--   >>> :set -XOverloadedStrings
--   
--   >>> import Data.Text
--   
--   >>> newtype UserId = UserId { getUserId :: Int16 } deriving Show
--   
--   >>> instance FromValue 'PGint2 UserId where fromValue = UserId <$> fromValue @'PGint2
--   
--   >>> data UserRow = UserRow { userId :: UserId, userName :: Maybe Text } deriving (Show, GHC.Generic)
--   
--   >>> instance Generic UserRow
--   
--   >>> instance HasDatatypeInfo UserRow
--   
--   >>> type User = '["userId" ::: 'NotNull 'PGint2, "userName" ::: 'Null 'PGtext]
--   
--   >>> fromRow @User @UserRow (K (Just "\NUL\SOH") :* K (Just "bloodninja") :* Nil)
--   Right (UserRow {userId = UserId {getUserId = 1}, userName = Just "bloodninja"})
--   
fromRow :: FromRow result y => NP (K (Maybe ByteString)) result -> Either Text 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)) @'[ 'Null 'PGtext] (Only (Just "foo"))
--   K (Just "foo") :* Nil
--   
-- --
--   >>> fromRow @'["fromOnly" ::: 'Null 'PGtext] @(Only (Maybe Text)) (K (Just "bar") :* Nil)
--   Right (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 Squeal.PostgreSQL.Binary.FromRow fields y => Squeal.PostgreSQL.Binary.FromValue ('Squeal.PostgreSQL.Schema.PGcomposite fields) (Squeal.PostgreSQL.Schema.Composite y) instance (Generics.SOP.Sing.SListI result, Generics.SOP.Record.IsRecord y ys, Generics.SOP.Constraint.AllZip Squeal.PostgreSQL.Binary.FromField result ys) => Squeal.PostgreSQL.Binary.FromRow result y instance Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGvararray ty)) y => Squeal.PostgreSQL.Binary.FromValue ('Squeal.PostgreSQL.Schema.PGvararray ty) y instance Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGfixarray n ty)) y => Squeal.PostgreSQL.Binary.FromValue ('Squeal.PostgreSQL.Schema.PGfixarray n ty) y instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.NotNull pg) y instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.Null pg) (GHC.Base.Maybe y) instance Squeal.PostgreSQL.Binary.FromArray array y => Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGvararray array)) (Data.Vector.Vector y) instance Squeal.PostgreSQL.Binary.FromArray array y => Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.Null ('Squeal.PostgreSQL.Schema.PGvararray array)) (GHC.Base.Maybe (Data.Vector.Vector y)) instance (Squeal.PostgreSQL.Binary.FromArray array y, Generics.SOP.Constraint.All ((Data.Type.Equality.~) y) ys, Generics.SOP.Sing.SListI ys, Generics.SOP.Universe.IsProductType product ys) => Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGfixarray n array)) product instance (Squeal.PostgreSQL.Binary.FromArray array y, Generics.SOP.Constraint.All ((Data.Type.Equality.~) y) ys, Generics.SOP.Sing.SListI ys, Generics.SOP.Universe.IsProductType product ys) => Squeal.PostgreSQL.Binary.FromArray ('Squeal.PostgreSQL.Schema.Null ('Squeal.PostgreSQL.Schema.PGfixarray n array)) (GHC.Base.Maybe product) instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromField (column Squeal.PostgreSQL.Schema.::: 'Squeal.PostgreSQL.Schema.NotNull pg) (column Squeal.PostgreSQL.Schema.::: y) instance Squeal.PostgreSQL.Binary.FromValue pg y => Squeal.PostgreSQL.Binary.FromField (column Squeal.PostgreSQL.Schema.::: 'Squeal.PostgreSQL.Schema.Null pg) (column Squeal.PostgreSQL.Schema.::: 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.PGtext GHC.Base.String 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 Data.Aeson.Types.FromJSON.FromJSON x => Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGjson (Squeal.PostgreSQL.Schema.Json x) instance Data.Aeson.Types.FromJSON.FromJSON x => Squeal.PostgreSQL.Binary.FromValue 'Squeal.PostgreSQL.Schema.PGjsonb (Squeal.PostgreSQL.Schema.Jsonb x) instance (Generics.SOP.Universe.IsEnumType y, Generics.SOP.Universe.HasDatatypeInfo y, Squeal.PostgreSQL.Schema.LabelsPG y ~ labels) => Squeal.PostgreSQL.Binary.FromValue ('Squeal.PostgreSQL.Schema.PGenum labels) (Squeal.PostgreSQL.Schema.Enumerated y) instance (Generics.SOP.Sing.SListI tys, Generics.SOP.Universe.IsProductType x xs, Generics.SOP.Constraint.AllZip Squeal.PostgreSQL.Binary.ToNullityParam xs tys) => Squeal.PostgreSQL.Binary.ToParams x tys instance Squeal.PostgreSQL.Binary.ToArray x ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGvararray ty)) => Squeal.PostgreSQL.Binary.ToParam x ('Squeal.PostgreSQL.Schema.PGvararray ty) instance Squeal.PostgreSQL.Binary.ToArray x ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGfixarray n ty)) => Squeal.PostgreSQL.Binary.ToParam x ('Squeal.PostgreSQL.Schema.PGfixarray n ty) instance (Squeal.PostgreSQL.Schema.HasOid pg, Squeal.PostgreSQL.Binary.ToParam x pg) => Squeal.PostgreSQL.Binary.ToArray x ('Squeal.PostgreSQL.Schema.NotNull pg) instance (Squeal.PostgreSQL.Schema.HasOid pg, Squeal.PostgreSQL.Binary.ToParam x pg) => Squeal.PostgreSQL.Binary.ToArray (GHC.Base.Maybe x) ('Squeal.PostgreSQL.Schema.Null pg) instance Squeal.PostgreSQL.Binary.ToArray x array => Squeal.PostgreSQL.Binary.ToArray (Data.Vector.Vector x) ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGvararray array)) instance Squeal.PostgreSQL.Binary.ToArray x array => Squeal.PostgreSQL.Binary.ToArray (GHC.Base.Maybe (Data.Vector.Vector x)) ('Squeal.PostgreSQL.Schema.Null ('Squeal.PostgreSQL.Schema.PGvararray array)) instance (Generics.SOP.Universe.IsProductType product xs, Squeal.PostgreSQL.Schema.Length xs ~ n, Generics.SOP.Constraint.All ((Data.Type.Equality.~) x) xs, Squeal.PostgreSQL.Binary.ToArray x array) => Squeal.PostgreSQL.Binary.ToArray product ('Squeal.PostgreSQL.Schema.NotNull ('Squeal.PostgreSQL.Schema.PGfixarray n array)) instance (Generics.SOP.Universe.IsProductType product xs, Squeal.PostgreSQL.Schema.Length xs ~ n, Generics.SOP.Constraint.All ((Data.Type.Equality.~) x) xs, Squeal.PostgreSQL.Binary.ToArray x array) => Squeal.PostgreSQL.Binary.ToArray (GHC.Base.Maybe product) ('Squeal.PostgreSQL.Schema.Null ('Squeal.PostgreSQL.Schema.PGfixarray n array)) instance (Generics.SOP.Sing.SListI fields, Generics.SOP.Record.IsRecord x xs, Generics.SOP.Constraint.AllZip Squeal.PostgreSQL.Binary.ToField xs fields, Generics.SOP.Constraint.All Squeal.PostgreSQL.Binary.HasAliasedOid fields) => Squeal.PostgreSQL.Binary.ToParam (Squeal.PostgreSQL.Schema.Composite x) ('Squeal.PostgreSQL.Schema.PGcomposite fields) instance Squeal.PostgreSQL.Binary.ToNullityParam x ty => Squeal.PostgreSQL.Binary.ToField (alias Squeal.PostgreSQL.Schema.::: x) (alias Squeal.PostgreSQL.Schema.::: ty) instance Squeal.PostgreSQL.Binary.ToParam x pg => Squeal.PostgreSQL.Binary.ToNullityParam x ('Squeal.PostgreSQL.Schema.NotNull pg) instance Squeal.PostgreSQL.Binary.ToParam x pg => Squeal.PostgreSQL.Binary.ToNullityParam (GHC.Base.Maybe x) ('Squeal.PostgreSQL.Schema.Null pg) instance Squeal.PostgreSQL.Schema.HasOid ty => Squeal.PostgreSQL.Binary.HasAliasedOid (alias Squeal.PostgreSQL.Schema.::: nullity ty) 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 GHC.Base.String '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 instance Data.Aeson.Types.ToJSON.ToJSON x => Squeal.PostgreSQL.Binary.ToParam (Squeal.PostgreSQL.Schema.Json x) 'Squeal.PostgreSQL.Schema.PGjson instance Data.Aeson.Types.ToJSON.ToJSON x => Squeal.PostgreSQL.Binary.ToParam (Squeal.PostgreSQL.Schema.Jsonb x) 'Squeal.PostgreSQL.Schema.PGjsonb instance (Generics.SOP.Universe.IsEnumType x, Generics.SOP.Universe.HasDatatypeInfo x, Squeal.PostgreSQL.Schema.LabelsPG x ~ labels) => Squeal.PostgreSQL.Binary.ToParam (Squeal.PostgreSQL.Schema.Enumerated x) ('Squeal.PostgreSQL.Schema.PGenum labels) -- | This module is where Squeal commands actually get executed by -- LibPQ. It containts two typeclasses, -- IndexedMonadTransPQ for executing a Definition and -- MonadPQ for executing a Manipulation or Query, -- and a PQ type with instances for them. -- -- Using Squeal in your application will come down to defining the -- schema of your database and including PQ schema -- schema in your application's monad transformer stack, giving it -- an instance of MonadPQ. -- -- This module also provides functions for retrieving rows from the -- Result of executing Squeal commands. module Squeal.PostgreSQL.PQ -- | Connection encapsulates a connection to the backend. data 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 -XPolyKinds
--   
--   >>> :set -XTypeOperators
--   
--   >>> type Schema = '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> '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 (K Connection schema) -- | Closes the connection to the server. finish :: MonadBase IO io => K Connection schema -> io () -- | Do connectdb and finish before and after a computation. withConnection :: forall schema0 schema1 io x. MonadBaseControl IO io => ByteString -> PQ schema0 schema1 io x -> io x -- | Safely lowerConnection to a smaller schema. lowerConnection :: K Connection (table : schema) -> K Connection schema -- | We keep track of the schema via an Atkey indexed state monad -- transformer, PQ. newtype PQ (schema0 :: SchemaType) (schema1 :: SchemaType) (m :: Type -> Type) (x :: Type) PQ :: K Connection schema0 -> m (K x schema1) -> PQ [unPQ] :: PQ -> K Connection schema0 -> m (K x schema1) -- | Run a PQ and keep the result and the Connection. runPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m (x, K Connection schema1) -- | Execute a PQ and discard the result but keep the -- Connection. execPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m (K Connection schema1) -- | Evaluate a PQ and discard the Connection but keep the -- result. evalPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m x -- | An Atkey indexed monad is a Functor enriched -- category. An indexed monad transformer transforms a Monad -- into an indexed monad. And, IndexedMonadTransPQ is a class for -- indexed monad transformers that support running Definitions -- using define and embedding a computation in a larger schema -- using pqEmbed. class IndexedMonadTransPQ pq -- | indexed analog of <*> pqAp :: (IndexedMonadTransPQ pq, Monad m) => pq schema0 schema1 m (x -> y) -> pq schema1 schema2 m x -> pq schema0 schema2 m y -- | indexed analog of join pqJoin :: (IndexedMonadTransPQ pq, Monad m) => pq schema0 schema1 m (pq schema1 schema2 m y) -> pq schema0 schema2 m y -- | indexed analog of =<< pqBind :: (IndexedMonadTransPQ pq, Monad m) => (x -> pq schema1 schema2 m y) -> pq schema0 schema1 m x -> pq schema0 schema2 m y -- | indexed analog of flipped >> pqThen :: (IndexedMonadTransPQ pq, Monad m) => pq schema1 schema2 m y -> pq schema0 schema1 m x -> pq schema0 schema2 m y -- | indexed analog of <=< pqAndThen :: (IndexedMonadTransPQ pq, Monad m) => (y -> pq schema1 schema2 m z) -> (x -> pq schema0 schema1 m y) -> x -> pq schema0 schema2 m z -- | Safely embed a computation in a larger schema. pqEmbed :: (IndexedMonadTransPQ pq, Monad m) => pq schema0 schema1 m x -> pq (table : schema0) (table : schema1) m x -- | Run a Definition with exec, we expect that libpq obeys -- the law -- --
--   define statement1 & pqThen (define statement2) = define (statement1 >>> statement2)
--   
define :: (IndexedMonadTransPQ pq, MonadBase IO io) => Definition schema0 schema1 -> pq schema0 schema1 io (K 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 (K Result ys) manipulateParams :: (MonadPQ schema pq, MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => ToParams x params => Manipulation schema params ys -> x -> pq (K Result ys) manipulate :: MonadPQ schema pq => Manipulation schema '[] ys -> pq (K Result ys) runQueryParams :: (MonadPQ schema pq, ToParams x params) => Query schema params ys -> x -> pq (K Result ys) runQuery :: MonadPQ schema pq => Query schema '[] ys -> pq (K Result ys) traversePrepared :: (MonadPQ schema pq, ToParams x params, Traversable list) => Manipulation schema params ys -> list x -> pq (list (K 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 (K Result ys)) forPrepared :: (MonadPQ schema pq, ToParams x params, Traversable list) => list x -> Manipulation schema params ys -> pq (list (K 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 (K x schema) -- | Helper function in defining MonadBaseControl instance for -- PQ. pqliftWith :: Functor m => (PQRun schema -> m a) -> PQ schema schema m a -- | Result encapsulates the result of a query (or more precisely, -- of a single SQL command --- a query string given to sendQuery -- can contain multiple commands and thus return multiple instances of -- Result. data Result data Row -- | Returns the number of rows (tuples) in the query result. ntuples :: MonadBase IO io => K Result columns -> io Row -- | Get a row corresponding to a given row number from a Result, -- throwing an exception if the row number is out of bounds. getRow :: (FromRow columns y, MonadBase IO io) => Row -> K Result columns -> io y -- | Get all rows from a Result. getRows :: (FromRow columns y, MonadBase IO io) => K Result columns -> io [y] -- | 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) => Row -> K Result columns -> Row -> io (Maybe (Row, y)) -- | Get the first row if possible from a Result. firstRow :: (FromRow columns y, MonadBase IO io) => K Result columns -> io (Maybe y) -- | Lifts actions on results from LibPQ. liftResult :: MonadBase IO io => (Result -> IO x) -> K Result results -> io x data ExecStatus -- | The string sent to the server was empty. EmptyQuery :: ExecStatus -- | Successful completion of a command returning no data. CommandOk :: ExecStatus -- | Successful completion of a command returning data (such as a SELECT or -- SHOW). TuplesOk :: ExecStatus -- | Copy Out (from server) data transfer started. CopyOut :: ExecStatus -- | Copy In (to server) data transfer started. CopyIn :: ExecStatus -- | Copy In/Out data transfer started. CopyBoth :: ExecStatus -- | The server's response was not understood. BadResponse :: ExecStatus -- | A nonfatal error (a notice or warning) occurred. NonfatalError :: ExecStatus -- | A fatal error occurred. FatalError :: ExecStatus -- | The PGresult contains a single result tuple from the current command. -- This status occurs only when single-row mode has been selected for the -- query. SingleTuple :: ExecStatus -- | Returns the result status of the command. resultStatus :: MonadBase IO io => K Result results -> io ExecStatus -- | Returns the error message most recently generated by an operation on -- the connection. resultErrorMessage :: MonadBase IO io => K Result results -> io (Maybe ByteString) -- | Returns the error code most recently generated by an operation on the -- connection. -- -- -- https://www.postgresql.org/docs/current/static/errcodes-appendix.html resultErrorCode :: MonadBase IO io => K Result results -> io (Maybe ByteString) -- | Exceptions that can be thrown by Squeal. data SquealException PQException :: ExecStatus -> Maybe ByteString -> Maybe ByteString -> SquealException [sqlExecStatus] :: SquealException -> ExecStatus -- | -- https://www.postgresql.org/docs/current/static/errcodes-appendix.html [sqlStateCode] :: SquealException -> Maybe ByteString [sqlErrorMessage] :: SquealException -> Maybe ByteString ResultException :: Text -> SquealException ParseException :: Text -> SquealException -- | Catch SquealExceptions. catchSqueal :: MonadBaseControl IO io => io a -> (SquealException -> io a) -> io a -- | Handle SquealExceptions. handleSqueal :: MonadBaseControl IO io => (SquealException -> io a) -> io a -> io a instance GHC.Show.Show Squeal.PostgreSQL.PQ.SquealException instance GHC.Classes.Eq Squeal.PostgreSQL.PQ.SquealException instance Squeal.PostgreSQL.PQ.IndexedMonadTransPQ Squeal.PostgreSQL.PQ.PQ instance (Control.Monad.Base.MonadBase GHC.Types.IO io, schema0 ~ schema, schema1 ~ schema) => Squeal.PostgreSQL.PQ.MonadPQ schema (Squeal.PostgreSQL.PQ.PQ schema0 schema1 io) instance GHC.Exception.Exception Squeal.PostgreSQL.PQ.SquealException 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 (GHC.Base.Monad m, schema0 ~ schema1) => GHC.Base.Applicative (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m) instance (GHC.Base.Monad m, schema0 ~ schema1) => GHC.Base.Monad (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m) instance GHC.Base.Monad m => GHC.Base.Functor (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m) instance (schema0 ~ schema1) => Control.Monad.Morph.MFunctor (Squeal.PostgreSQL.PQ.PQ schema0 schema1) instance (schema0 ~ schema1) => Control.Monad.Trans.Class.MonadTrans (Squeal.PostgreSQL.PQ.PQ schema0 schema1) instance (schema0 ~ schema1) => Control.Monad.Morph.MMonad (Squeal.PostgreSQL.PQ.PQ schema0 schema1) instance (Control.Monad.Base.MonadBase b m, schema0 ~ schema1) => Control.Monad.Base.MonadBase b (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m) instance (Control.Monad.Trans.Control.MonadBaseControl b m, schema0 ~ schema1) => Control.Monad.Trans.Control.MonadBaseControl b (Squeal.PostgreSQL.PQ.PQ schema0 schema1 m) -- | A MonadPQ for pooled connections. module Squeal.PostgreSQL.Pool -- | PoolPQ schema should be a drop-in replacement for -- PQ schema schema. -- -- Typical use case would be to create your pool using -- createConnectionPool and run anything that requires the pool -- connection with it. -- -- Here's a simplified example: -- --
--   type Schema = '[ "tab" ::: 'Table ('[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint2])]
--   
--   someQuery :: Manipulation Schema '[ 'NotNull 'PGint2] '[]
--   someQuery = insertRow #tab
--    (Set (param @1) `As` #col :* Nil)
--   OnConflictDoNothing (Returning Nil)
--   
--   insertOne :: (MonadBaseControl IO m, MonadPQ Schema m) => m ()
--   insertOne = void $ manipulateParams someQuery . Only $ (1 :: Int16)
--   
--   insertOneInPool :: ByteString -> IO ()
--   insertOneInPool connectionString = do
--     pool <- createConnectionPool connectionString 1 0.5 10
--     liftIO $ runPoolPQ (insertOne) pool
--   
newtype PoolPQ (schema :: SchemaType) m x PoolPQ :: Pool (K Connection schema) -> m x -> PoolPQ m x [runPoolPQ] :: PoolPQ m x -> Pool (K Connection schema) -> m x -- | Create a striped pool of connections. Although the garbage collector -- will destroy all idle connections when the pool is garbage collected -- it's recommended to manually destroyAllResources when you're -- done with the pool so that the connections are freed up as soon as -- possible. createConnectionPool :: MonadBase IO io => ByteString -> Int -> NominalDiffTime -> Int -> io (Pool (K Connection schema)) data Pool a -- | Destroy all resources in all stripes in the pool. Note that this will -- ignore any exceptions in the destroy function. -- -- This function is useful when you detect that all resources in the pool -- are broken. For example after a database has been restarted all -- connections opened before the restart will be broken. In that case -- it's better to close those connections so that takeResource -- won't take a broken connection from the pool but will open a new -- connection instead. -- -- Another use-case for this function is that when you know you are done -- with the pool you can destroy all idle resources immediately instead -- of waiting on the garbage collector to destroy them, thus freeing up -- those resources sooner. destroyAllResources :: () => Pool a -> IO () -- | A snapshot of the state of a PoolPQ computation. type PoolPQRun schema = forall m x. Monad m => PoolPQ schema m x -> m x -- | Helper function in defining MonadBaseControl instance for -- PoolPQ. poolpqliftWith :: Functor m => (PoolPQRun schema -> m a) -> PoolPQ schema m a instance GHC.Base.Functor m => GHC.Base.Functor (Squeal.PostgreSQL.Pool.PoolPQ schema m) instance GHC.Base.Monad m => GHC.Base.Applicative (Squeal.PostgreSQL.Pool.PoolPQ schema m) instance GHC.Base.Monad m => GHC.Base.Monad (Squeal.PostgreSQL.Pool.PoolPQ schema m) instance Control.Monad.Trans.Class.MonadTrans (Squeal.PostgreSQL.Pool.PoolPQ schema) instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Squeal.PostgreSQL.Pool.PoolPQ schema m) instance Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO io => Squeal.PostgreSQL.PQ.MonadPQ schema (Squeal.PostgreSQL.Pool.PoolPQ schema io) instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Squeal.PostgreSQL.Pool.PoolPQ schema m) -- | Squeal transaction control language. module Squeal.PostgreSQL.Transaction -- | Run a schema invariant computation transactionally. transactionally :: (MonadBaseControl IO tx, MonadPQ schema tx) => TransactionMode -> tx x -> tx x -- | Run a schema invariant computation transactionally_ in -- defaultMode. transactionally_ :: (MonadBaseControl IO tx, MonadPQ schema tx) => tx x -> tx x -- | BEGIN a transaction. begin :: MonadPQ schema tx => TransactionMode -> tx (K Result ('[] :: RowType)) -- | COMMIT a schema invariant transaction. commit :: MonadPQ schema tx => tx (K Result ('[] :: RowType)) -- | ROLLBACK a schema invariant transaction. rollback :: MonadPQ schema tx => tx (K Result ('[] :: RowType)) -- | Run a schema changing computation transactionallySchema. transactionallySchema :: MonadBaseControl IO io => TransactionMode -> PQ schema0 schema1 io x -> PQ schema0 schema1 io x -- | Run a schema changing computation transactionallySchema_ in -- DefaultMode. transactionallySchema_ :: MonadBaseControl IO io => PQ schema0 schema1 io x -> PQ schema0 schema1 io x -- | The available transaction characteristics are the transaction -- IsolationLevel, the transaction AccessMode -- (ReadWrite or ReadOnly), and the DeferrableMode. data TransactionMode TransactionMode :: IsolationLevel -> AccessMode -> DeferrableMode -> TransactionMode [isolationLevel] :: TransactionMode -> IsolationLevel [accessMode] :: TransactionMode -> AccessMode [deferrableMode] :: TransactionMode -> DeferrableMode -- | TransactionMode with a Serializable -- IsolationLevel, ReadWrite AccessMode and -- NotDeferrable DeferrableMode. defaultMode :: TransactionMode -- | TransactionMode with a Serializable -- IsolationLevel, ReadOnly AccessMode and -- Deferrable DeferrableMode. This mode is well suited for -- long-running reports or backups. longRunningMode :: TransactionMode -- | The SQL standard defines four levels of transaction isolation. The -- most strict is Serializable, which is defined by the standard -- in a paragraph which says that any concurrent execution of a set of -- Serializable transactions is guaranteed to produce the same -- effect as running them one at a time in some order. The other three -- levels are defined in terms of phenomena, resulting from interaction -- between concurrent transactions, which must not occur at each level. -- The phenomena which are prohibited at various levels are: -- -- Dirty read: A transaction reads data written by a concurrent -- uncommitted transaction. -- -- Nonrepeatable read: A transaction re-reads data it has -- previously read and finds that data has been modified by another -- transaction (that committed since the initial read). -- -- Phantom read: A transaction re-executes a query returning a set -- of rows that satisfy a search condition and finds that the set of rows -- satisfying the condition has changed due to another recently-committed -- transaction. -- -- Serialization anomaly: The result of successfully committing a -- group of transactions is inconsistent with all possible orderings of -- running those transactions one at a time. -- -- In PostgreSQL, you can request any of the four standard transaction -- isolation levels, but internally only three distinct isolation levels -- are implemented, i.e. PostgreSQL's ReadUncommitted mode behaves -- like ReadCommitted. This is because it is the only sensible way -- to map the standard isolation levels to PostgreSQL's multiversion -- concurrency control architecture. data IsolationLevel -- | Dirty read is not possible. Nonrepeatable read is not possible. -- Phantom read is not possible. Serialization anomaly is not possible. Serializable :: IsolationLevel -- | Dirty read is not possible. Nonrepeatable read is not possible. -- Phantom read is not possible. Serialization anomaly is possible. RepeatableRead :: IsolationLevel -- | Dirty read is not possible. Nonrepeatable read is possible. Phantom -- read is possible. Serialization anomaly is possible. ReadCommitted :: IsolationLevel -- | Dirty read is not possible. Nonrepeatable read is possible. Phantom -- read is possible. Serialization anomaly is possible. ReadUncommitted :: IsolationLevel -- | Render an IsolationLevel. renderIsolationLevel :: IsolationLevel -> ByteString -- | The transaction access mode determines whether the transaction is -- ReadWrite or ReadOnly. ReadWrite is the default. -- When a transaction is ReadOnly, the following SQL commands are -- disallowed: INSERT, UPDATE, DELETE, and -- COPY FROM if the table they would write to is not a temporary -- table; all CREATE, ALTER, and DROP -- commands; COMMENT, GRANT, REVOKE, -- TRUNCATE; and EXPLAIN ANALYZE and EXECUTE -- if the command they would execute is among those listed. This is a -- high-level notion of ReadOnly that does not prevent all writes -- to disk. data AccessMode ReadWrite :: AccessMode ReadOnly :: AccessMode -- | Render an AccessMode. renderAccessMode :: AccessMode -> ByteString -- | The Deferrable transaction property has no effect unless the -- transaction is also Serializable and ReadOnly. When all -- three of these properties are selected for a transaction, the -- transaction may block when first acquiring its snapshot, after which -- it is able to run without the normal overhead of a Serializable -- transaction and without any risk of contributing to or being canceled -- by a serialization failure. This longRunningMode is well suited -- for long-running reports or backups. data DeferrableMode Deferrable :: DeferrableMode NotDeferrable :: DeferrableMode -- | Render a DeferrableMode. renderDeferrableMode :: DeferrableMode -> ByteString instance GHC.Classes.Eq Squeal.PostgreSQL.Transaction.TransactionMode instance GHC.Show.Show Squeal.PostgreSQL.Transaction.TransactionMode instance GHC.Classes.Eq Squeal.PostgreSQL.Transaction.DeferrableMode instance GHC.Show.Show Squeal.PostgreSQL.Transaction.DeferrableMode instance GHC.Classes.Eq Squeal.PostgreSQL.Transaction.AccessMode instance GHC.Show.Show Squeal.PostgreSQL.Transaction.AccessMode instance GHC.Classes.Eq Squeal.PostgreSQL.Transaction.IsolationLevel instance GHC.Show.Show Squeal.PostgreSQL.Transaction.IsolationLevel -- | 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. -- --
--   >>> :set -XDataKinds -XDeriveGeneric -XOverloadedLabels
--   
--   >>> :set -XOverloadedStrings -XTypeApplications -XTypeOperators
--   
-- -- We'll need some imports. -- --
--   >>> import Control.Monad (void)
--   
--   >>> import Control.Monad.Base (liftBase)
--   
--   >>> import Data.Int (Int32)
--   
--   >>> import Data.Text (Text)
--   
--   >>> import Squeal.PostgreSQL
--   
--   >>> import Squeal.PostgreSQL.Render
--   
-- -- 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. -- --
--   >>> :{
--   type Schema =
--     '[ "users" ::: 'Table (
--         '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
--         '[ "id"   :::   'Def :=> 'NotNull 'PGint4
--          , "name" ::: 'NoDef :=> 'NotNull 'PGtext
--          ])
--     , "emails" ::: 'Table (
--         '[ "pk_emails"  ::: 'PrimaryKey '["id"]
--          , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"]
--          ] :=>
--         '[ "id"      :::   'Def :=> 'NotNull 'PGint4
--          , "user_id" ::: 'NoDef :=> 'NotNull 'PGint4
--          , "email"   ::: 'NoDef :=>    'Null 'PGtext
--          ])
--     ]
--   :}
--   
-- -- Notice the use of type operators. -- -- ::: is used to pair an alias Symbol with a -- SchemumType, a TableConstraint or a ColumnType. -- It is intended to connote Haskell's :: operator. -- -- :=> is used to pair TableConstraints with a -- ColumnsType, yielding a TableType, or to pair a -- ColumnConstraint with a NullityType, yielding a -- ColumnType. It is intended to connote Haskell's => -- operator -- -- Next, we'll write Definitions to set up and tear down the -- schema. In Squeal, a Definition like createTable, -- alterTable or dropTable 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. -- --
--   >>> :{
--   let
--     setup :: Definition '[] Schema
--     setup = 
--       createTable #users
--         ( serial `as` #id :*
--           (text & notNullable) `as` #name )
--         ( primaryKey #id `as` #pk_users ) >>>
--       createTable #emails
--         ( serial `as` #id :*
--           (int & notNullable) `as` #user_id :*
--           (text & nullable) `as` #email )
--         ( primaryKey #id `as` #pk_emails :*
--           foreignKey #user_id #users #id
--             OnDeleteCascade OnUpdateCascade `as` #fk_user_id )
--   :}
--   
-- -- We can easily see the generated SQL is unsurprising looking. -- --
--   >>> printSQL setup
--   CREATE TABLE "users" ("id" serial, "name" text NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"));
--   CREATE TABLE "emails" ("id" serial, "user_id" int NOT NULL, "email" text NULL, CONSTRAINT "pk_emails" PRIMARY KEY ("id"), CONSTRAINT "fk_user_id" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE);
--   
-- -- 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 teardown Definition -- is simpler. -- --
--   >>> :{
--   let
--     teardown :: Definition Schema '[]
--     teardown = dropTable #emails >>> dropTable #users
--   :}
--   
-- --
--   >>> printSQL teardown
--   DROP TABLE "emails";
--   DROP TABLE "users";
--   
-- -- Next, we'll write Manipulations to insert data into our two -- tables. A Manipulation like insertRow, update or -- deleteFrom 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 serial, 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. -- --
--   >>> :{
--   let
--     insertUser :: Manipulation Schema '[ 'NotNull 'PGtext ] '[ "fromOnly" ::: 'NotNull 'PGint4 ]
--     insertUser = insertRow #users
--       (Default `as` #id :* Set (param @1) `as` #name)
--       OnConflictDoNothing (Returning (#id `as` #fromOnly))
--   :}
--   
-- --
--   >>> :{
--   let
--     insertEmail :: Manipulation Schema '[ 'NotNull 'PGint4, 'Null 'PGtext] '[]
--     insertEmail = insertRow #emails
--       ( Default `as` #id :*
--         Set (param @1) `as` #user_id :*
--         Set (param @2) `as` #email )
--       OnConflictDoNothing (Returning Nil)
--   :}
--   
-- --
--   >>> printSQL insertUser
--   INSERT INTO "users" ("id", "name") VALUES (DEFAULT, ($1 :: text)) ON CONFLICT DO NOTHING RETURNING "id" AS "fromOnly"
--   
--   >>> printSQL insertEmail
--   INSERT INTO "emails" ("id", "user_id", "email") VALUES (DEFAULT, ($1 :: int4), ($2 :: text)) ON CONFLICT DO NOTHING
--   
-- -- 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. -- --
--   >>> :{
--   let
--     getUsers :: Query Schema '[]
--       '[ "userName"  ::: 'NotNull 'PGtext
--        , "userEmail" :::    'Null 'PGtext ]
--     getUsers = select
--       (#u ! #name `as` #userName :* #e ! #email `as` #userEmail)
--       ( from (table (#users `as` #u)
--         & innerJoin (table (#emails `as` #e))
--           (#u ! #id .== #e ! #user_id)) )
--   :}
--   
-- --
--   >>> printSQL getUsers
--   SELECT "u"."name" AS "userName", "e"."email" AS "userEmail" FROM "users" AS "u" INNER JOIN "emails" AS "e" ON ("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. -- --
--   >>> :{
--   let
--     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. -- --
--   >>> :{
--   let
--     session :: PQ Schema Schema IO ()
--     session = do
--       idResults <- traversePrepared insertUser (Only . userName <$> users)
--       ids <- traverse (fmap fromOnly . getRow 0) idResults
--       traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail <$> users))
--       usersResult <- runQuery getUsers
--       usersRows <- getRows usersResult
--       liftBase $ print (usersRows :: [User])
--   in
--     void . withConnection "host=localhost port=5432 dbname=exampledb" $
--       define setup
--       & pqThen session
--       & pqThen (define teardown)
--   :}
--   [User {userName = "Alice", userEmail = Just "alice@gmail.com"},User {userName = "Bob", userEmail = Nothing},User {userName = "Carole", userEmail = Just "carole@hotmail.com"}]
--   
module Squeal.PostgreSQL -- | This module defines a Migration type to safely change the -- schema of your database over time. Let's see an example! -- --
--   >>> :set -XDataKinds -XOverloadedLabels
--   
--   >>> :set -XOverloadedStrings -XFlexibleContexts -XTypeOperators
--   
--   >>> :{
--   type UsersTable =
--     '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
--     '[ "id" ::: 'Def :=> 'NotNull 'PGint4
--      , "name" ::: 'NoDef :=> 'NotNull 'PGtext
--      ]
--   :}
--   
-- --
--   >>> :{
--   type EmailsTable =
--     '[  "pk_emails" ::: 'PrimaryKey '["id"]
--      , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"]
--      ] :=>
--     '[ "id" ::: 'Def :=> 'NotNull 'PGint4
--      , "user_id" ::: 'NoDef :=> 'NotNull 'PGint4
--      , "email" ::: 'NoDef :=> 'Null 'PGtext
--      ]
--   :}
--   
-- --
--   >>> :{
--   let
--     makeUsers :: Migration IO '[] '["users" ::: 'Table UsersTable]
--     makeUsers = Migration
--       { name = "make users table"
--       , up = void . define $
--           createTable #users
--           ( serial `as` #id :*
--             (text & notNullable) `as` #name )
--           ( primaryKey #id `as` #pk_users )
--       , down = void . define $ dropTable #users
--       }
--   :}
--   
-- --
--   >>> :{
--   let
--     makeEmails :: Migration IO '["users" ::: 'Table UsersTable]
--       '["users" ::: 'Table UsersTable, "emails" ::: 'Table EmailsTable]
--     makeEmails = Migration
--       { name = "make emails table"
--       , up = void . define $
--           createTable #emails
--             ( serial `as` #id :*
--               (int & notNullable) `as` #user_id :*
--               (text & nullable) `as` #email )
--             ( primaryKey #id `as` #pk_emails :*
--               foreignKey #user_id #users #id
--                 OnDeleteCascade OnUpdateCascade `as` #fk_user_id )
--       , down = void . define $ dropTable #emails
--       }
--   :}
--   
-- -- Now that we have a couple migrations we can chain them together. -- --
--   >>> let migrations = makeUsers :>> makeEmails :>> Done
--   
-- --
--   >>> :{
--   let
--     numMigrations
--       :: Has "schema_migrations" schema ('Table MigrationsTable)
--       => PQ schema schema IO ()
--     numMigrations = do
--       result <- runQuery (selectStar (from (table (#schema_migrations `as` #m))))
--       num <- ntuples result
--       liftBase $ print num
--   :}
--   
-- --
--   >>> :{
--   withConnection "host=localhost port=5432 dbname=exampledb" $
--     manipulate (UnsafeManipulation "SET client_min_messages TO WARNING;")
--       -- suppress notices
--     & pqThen (migrateUp migrations)
--     & pqThen numMigrations
--     & pqThen (migrateDown migrations)
--     & pqThen numMigrations
--   :}
--   Row 2
--   Row 0
--   
module Squeal.PostgreSQL.Migration -- | A Migration should contain an inverse pair of up and -- down instructions and a unique name. data Migration io schema0 schema1 Migration :: Text -> PQ schema0 schema1 io () -> PQ schema1 schema0 io () -> Migration io schema0 schema1 -- | The name of a Migration. Each name in a -- Migration should be unique. [name] :: Migration io schema0 schema1 -> Text -- | The up instruction of a Migration. [up] :: Migration io schema0 schema1 -> PQ schema0 schema1 io () -- | The down instruction of a Migration. [down] :: Migration io schema0 schema1 -> PQ schema1 schema0 io () -- | Run Migrations by creating the MigrationsTable if it -- does not exist and then in a transaction, for each each -- Migration query to see if the Migration is executed. If -- not, then execute the Migration and insert its row in the -- MigrationsTable. migrateUp :: MonadBaseControl IO io => AlignedList (Migration io) schema0 schema1 -> PQ ("schema_migrations" ::: 'Table MigrationsTable : schema0) ("schema_migrations" ::: 'Table MigrationsTable : schema1) io () -- | Rewind Migrations by creating the MigrationsTable if it -- does not exist and then in a transaction, for each each -- Migration query to see if the Migration is executed. If -- it is, then rewind the Migration and delete its row in the -- MigrationsTable. migrateDown :: MonadBaseControl IO io => AlignedList (Migration io) schema0 schema1 -> PQ ("schema_migrations" ::: 'Table MigrationsTable : schema1) ("schema_migrations" ::: 'Table MigrationsTable : schema0) io () -- | The TableType for a Squeal migration. type MigrationsTable = '["migrations_unique_name" ::: 'Unique '["name"]] :=> '["name" ::: 'NoDef :=> 'NotNull 'PGtext, "executed_at" ::: 'Def :=> 'NotNull 'PGtimestamptz] -- | Creates a MigrationsTable if it does not already exist. createMigrations :: Has "schema_migrations" schema ( 'Table MigrationsTable) => Definition schema schema -- | Inserts a Migration into the MigrationsTable insertMigration :: Has "schema_migrations" schema ( 'Table MigrationsTable) => Manipulation schema '[ 'NotNull 'PGtext] '[] -- | Deletes a Migration from the MigrationsTable deleteMigration :: Has "schema_migrations" schema ( 'Table MigrationsTable) => Manipulation schema '[ 'NotNull 'PGtext] '[] -- | Selects a Migration from the MigrationsTable, returning -- the time at which it was executed. selectMigration :: Has "schema_migrations" schema ( 'Table MigrationsTable) => Query schema '[ 'NotNull 'PGtext] '["executed_at" ::: 'NotNull 'PGtimestamptz]