-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An API binding Web.Spock to Database.Beam -- -- An API binding Web.Spock to Database.Beam @package tsweb @version 0.1.1 -- | Spock likes to store its session RAM, which is mostly great unless you -- need persistence or multiple machines. This doesn't do anything -- interesting with Spock's session manager, but just defines enough of a -- table to be able to store Spock's core session information. module TsWeb.Tables.Session -- | A generic Beam table to store a Spock session. The _sessionData -- should be your useful info, like a logged-in user or whatever. See -- TsWeb.Tables.Session.Test for a type-checking but not very -- function idea of what _sessionData could look like, or the code -- under main for a fully-functional (but dumb) webapp using all -- this stuff. data SessionT d f Session :: C f Text -> C f Text -> C f UTCTime -> d f -> SessionT d f -- | Spock-generated session ID [_sessionId] :: SessionT d f -> C f Text -- | Session's CSRF token [_sessionCsrf] :: SessionT d f -> C f Text -- | Expiration date for this session [_sessionExpires] :: SessionT d f -> C f UTCTime -- | User-defined session data [_sessionData] :: SessionT d f -> d f -- | Concrete session type Session d = SessionT d Identity -- | Session primary key type SessionId d = PrimaryKey (SessionT d) Identity instance GHC.Generics.Generic (TsWeb.Tables.Session.SessionT d f) instance GHC.Generics.Generic (Database.Beam.Schema.Tables.PrimaryKey (TsWeb.Tables.Session.SessionT d) f) instance GHC.Show.Show (Database.Beam.Schema.Tables.PrimaryKey (TsWeb.Tables.Session.SessionT d) Data.Functor.Identity.Identity) instance GHC.Show.Show (d Data.Functor.Identity.Identity) => GHC.Show.Show (TsWeb.Tables.Session.SessionT d Data.Functor.Identity.Identity) instance GHC.Classes.Eq (Database.Beam.Schema.Tables.PrimaryKey (TsWeb.Tables.Session.SessionT d) Data.Functor.Identity.Identity) instance GHC.Classes.Eq (d Data.Functor.Identity.Identity) => GHC.Classes.Eq (TsWeb.Tables.Session.SessionT d Data.Functor.Identity.Identity) instance GHC.Classes.Ord (Database.Beam.Schema.Tables.PrimaryKey (TsWeb.Tables.Session.SessionT d) Data.Functor.Identity.Identity) instance GHC.Classes.Ord (d Data.Functor.Identity.Identity) => GHC.Classes.Ord (TsWeb.Tables.Session.SessionT d Data.Functor.Identity.Identity) instance Database.Beam.Schema.Tables.Beamable (Database.Beam.Schema.Tables.PrimaryKey (TsWeb.Tables.Session.SessionT d)) instance Database.Beam.Schema.Tables.Beamable d => Database.Beam.Schema.Tables.Beamable (TsWeb.Tables.Session.SessionT d) instance (Database.Beam.Schema.Tables.Beamable d, Data.Typeable.Internal.Typeable d) => Database.Beam.Schema.Tables.Table (TsWeb.Tables.Session.SessionT d) -- | These are the base wrappers around Spock's contexts and state monad. -- The main thing that TsWeb does is force in a Context type that -- is a wrapper around a Rec and a HVect. The Rec is used -- to store tagged URL paths, while the HVect stores contextual data for -- views, such as a database connection or authentication information. module TsWeb.Types -- | A container for a Rec of tagged Spock paths and a HVect -- of view contextual data. -- -- The paths are built with path and friends, and are queried -- using getPath / showPath. -- -- Context extras are currently populated using dbwrite and -- auth; probably more will be added as needed. data Context lts vec Context :: Rec lts -> HVect vec -> Context lts vec -- | Tagged paths for web context [ctxPaths] :: Context lts vec -> Rec lts -- | Free-form extras for web context [ctxExtras] :: Context lts vec -> HVect vec -- | Wrapper around WebStateM to suppress spock's database and -- web_state type TsWebStateM sessdata = WebStateM () sessdata () -- | Wrapper around ActionCtxT to use Context and -- TsWebStateM type TsActionCtxT lts xs sessdata a = ActionCtxT (Context lts xs) (TsWebStateM sessdata) a -- | Wrapper around SpockCtxT to use Context and -- TsWebStateM type TsSpockCtxT lts xs sessdata = SpockCtxT (Context lts xs) (TsWebStateM sessdata) -- | Various functions for reading data from the current Spock Action's -- context. Currently that's just reading URL path info and auth data. module TsWeb.Action -- | Look up a tagged path in a view. If we have a route looking like -- --
-- runroute ro rw $ path #user ("users" <//> var) (get user)
--
--
-- then a view could access that user path with
--
-- -- users <- getPath #user -- let txt = renderRoute users "bob" --getPath :: Has l lts v => FldProxy l -> TsActionCtxT lts xs sess v -- | Look up a path and render it. This returns a sort-of variadic function -- that can be provided with the right number of arguments in order to -- render a path. As with the above example, a route like this: -- --
-- runroute ro rw $ path #user ("users" <//> var) (get user)
--
--
-- could be rendered like this:
--
-- -- usersfn <- showPath #user -- let txt = usersfn "bob" ---- -- or, more succinctly: -- --
-- txt <- ($ "bob") <$> showPath $user --showPath :: (AllHave ToHttpApiData as, Has l lts v, v ~ Path as 'Open) => FldProxy l -> TsActionCtxT lts vec sess (HVectElim as Text) -- | Look up data that was put into the ctxExtras part of the -- action's context. This is pretty bound up with type signatures and -- other verbosity, but if we have a database-writing view like so: -- --
-- runroute ro rw $ path #root root (dbwrite $ get index) ---- -- then that index view could be written like so: -- --
-- index :: ListContains n ReadWritePool xs => TsActionCtxT lts xs sess a -- index = do -- db :: ReadWritePool <- getExtra -- ... --getExtra :: (MonadIO m, ListContains n v xs) => ActionCtxT (Context lts xs) m v -- | TsWeb has a strong notion that postgres should be configured in a -- warm-standby mode, with read-only queries being shipped to synchronous -- standbys whenever possible. This module defines types for -- descriminating between read-only and read-write connections, and also -- functions for making postgres connections, pools, etc. The -- connect function is working well enough for me, but will -- undoubtedly need to be improved to support the full depth of -- postgresql connection options. module TsWeb.Types.Db -- | Wrapper for some sort of Postgres connection; a raw `SomeConn t` -- represents either a read-only or a read-write connection, but the -- concrete ReadOnlyConn and ReadWriteConn are probably -- more useful in general. type SomeConn t = Tagged t Connection -- | Concrete read-only connection. Instantiate with connect type ReadOnlyConn = SomeConn ReadOnly -- | Concrete read-write connection. Instantiate with connect type ReadWriteConn = SomeConn ReadWrite -- | Pool of read-only connections. Instantiate with pool type ReadOnlyPool = Pool ReadOnlyConn -- | Pool of read-write connections. Instantiate with pool type ReadWritePool = Pool ReadWriteConn -- | Empty type to mark read-only db connections data ReadOnly -- | Empty type to mark read-write db connections data ReadWrite -- | String alias for the postgres host to connect to type HostName = String -- | String alias for the postgres database to connect to type DbName = String -- | Int alias for the createPool function numStripes -- argument type SubPools = Int -- | Int alias for the createPool function maxResources -- argument type KeepOpen = Int -- | An example of how Database.Beam does counts; this really -- doesn't belong here, and was just written for preliminary testing. count :: ProjectibleWithPredicate AnyType Postgres (WithExprContext (BeamSqlBackendExpressionSyntax' Postgres)) t => Q Postgres db (QNested s0) t -> Q Postgres db s0 (QGenExpr QValueContext Postgres s0 Int) -- | Create a resource pool of either read-only or read-write postgres -- connections. The docs for createPool give the best description -- for how this works. pool :: HostName -> DbName -> String -> SubPools -> NominalDiffTime -> KeepOpen -> IO (Pool (SomeConn t)) -- | Run an action in a Pool connection withConnection :: Pool (SomeConn a) -> (SomeConn a -> IO b) -> IO b -- | Create a ReadOnly or ReadWrite postgres connection. This -- doesn't actually check whether the connection is read-only or -- read-write, so it's really just to help with type juggling. connect :: HostName -> DbName -> String -> IO (SomeConn t) -- | Run an action within a postgresql savepoint withSavepoint :: SomeConn t -> IO a -> IO a -- | Run an action within a postgresql transaction withTransaction :: SomeConn t -> IO a -> IO a -- | Run a read-only query; this will actually run any query at all, so -- higher-level logic should ensure that only read-only queries hit this -- function. readOnly :: SomeConn t -> Pg a -> IO a -- | Same as readOnly, but prints any SQL that it runs. readOnlyDebug :: SomeConn t -> Pg a -> IO a -- | Run a query against a ReadWriteConn readWrite :: ReadWriteConn -> Pg a -> IO a -- | Same as readWrite, but printing all the SQL that gets executed. readWriteDebug :: ReadWriteConn -> Pg a -> IO a -- | This provides one essential function, patchConfig to replace -- Spock's default in-RAM session implementation with a Beam/postgres -- one. module TsWeb.Session -- | Update a spock configuration stanza to replace its default session -- with one backed by postgres. This will typically be used like so: -- --
-- spockCfg <- -- patchConfig (_dbSession db) ropool rwpool $ -- defaultSpockCfg sess PCNoDatabase () -- runSpock port (spock spockCfg routes) -- where -- sess = ... -- routes = ... --patchConfig :: (FromBackendRow Postgres (sessdata Identity), Beamable sessdata, Typeable sessdata, Database Postgres db, UserData (sessdata Identity), FieldsFulfillConstraint (HasSqlValueSyntax PgValueSyntax) sessdata) => DatabaseEntity Postgres db (TableEntity (SessionT sessdata)) -> Pool ReadOnlyConn -> Pool ReadWriteConn -> SpockCfg conn (sessdata Identity) st -> SpockCfg conn (sessdata Identity) st -- | Typeclass for user-supplied data. We really just need to know whether -- the user has set a remember-me indicator upon login so that the -- session's lifespan can be intelligently controlled. If your session -- never needs to be remembers, then rememberMe = const False -- should suffice. class UserData c -- | Should the associated session be stored permanently? rememberMe :: UserData c => c -> Bool instance GHC.Show.Show sessdata => GHC.Show.Show (TsWeb.Session.TxProgram (Web.Spock.Internal.Types.Session conn sessdata st) a) instance GHC.Base.Functor f => GHC.Base.Functor (TsWeb.Session.Free f) instance GHC.Base.Functor f => GHC.Base.Applicative (TsWeb.Session.Free f) instance GHC.Base.Functor f => GHC.Base.Monad (TsWeb.Session.Free f) instance GHC.Base.Functor (TsWeb.Session.TxAction s) module TsWeb.Tables.Session.Test -- | Some sample user info data UsersMixin f Address :: C f Int -> C f Int -> C f Bool -> UsersMixin f [loginid] :: UsersMixin f -> C f Int [masqid] :: UsersMixin f -> C f Int [remember] :: UsersMixin f -> C f Bool -- | Concrete type for users type Users = UsersMixin Identity -- | Spock session alias to use our User type Sess conn st = Session conn Users st -- | Beam database definition to hold our session data Db f Db :: f (TableEntity (SessionT UsersMixin)) -> Db f [session] :: Db f -> f (TableEntity (SessionT UsersMixin)) -- | Beam database instance db :: DatabaseSettings be Db -- | Sample of patch to be sure that all the types work enough to make a -- spock config wrapper patch :: Pool ReadOnlyConn -> Pool ReadWriteConn -> SpockCfg conn Users st -> SpockCfg conn Users st instance GHC.Generics.Generic (TsWeb.Tables.Session.Test.Db f) instance GHC.Generics.Generic (TsWeb.Tables.Session.Test.UsersMixin f) instance Database.Beam.Schema.Tables.Database be TsWeb.Tables.Session.Test.Db instance TsWeb.Session.UserData TsWeb.Tables.Session.Test.Users instance Database.Beam.Schema.Tables.Beamable TsWeb.Tables.Session.Test.UsersMixin -- | A generic authentication hook for TsWeb routing. The goal here is to -- be able to specify authentication requirements in a view's type, so -- that the routing statically guarantees that a view can only be entered -- when session preconditions are met. A full example of this is under -- the Example module of this source tree, but a synopsis follows. Given -- a session/user definition like so: -- --
-- data UserT f = User
-- { _userId :: C f Int
-- , _userLogin :: C f Text
-- } deriving (Generic)
-- ...
-- data SessionDataT f = SessionData
-- { _sdUser :: PrimaryKey UserT (Nullable f)
-- , _sdRemember :: C f Bool
-- } deriving (Generic)
-- ...
--
-- userP :: Proxy User
-- userP = Proxy
--
--
-- then we can define a logged-in Authorize check as
--
-- -- instance Authorize SessionData User where -- checkAuth _ = -- _sdUser <$> readSession >>= case -- UserId Nothing -> pure Nothing -- UserId (Just uid) -> -- queryMaybe (select $ q uid) >>= case -- QSimply (Just user) -> pure $ Just user -- _ -> pure Nothing -- where -- q uid = do -- u <- all_ $ _dbUser db -- guard_ $ _userId u ==. val_ uid -- pure u ---- -- A view requiring an authenticated user would have a signature like -- --
-- authd :: ListContains n User xs => TsActionCtxT lts xs SessionData a -- authd = do -- user :: User <- getExtra -- ... ---- -- Finally, the route for only allowing logged-in users would look like -- --
-- runroute ro rw $ path #authd "authd" $ get $ auth userP authd ---- -- That view is statically defined to only be accessible to logged-in -- users; any anonymous session will either go to an alternate (non-auth) -- view, or get a 404. module TsWeb.Routing.Auth -- | A class for session data that needs to be statically verified against -- routes. This could be checks for optional session info, or to validate -- the value of that session information. class Authorize sess perm -- | Load a value out of the session or return Nothing. Used in the context -- of auth, the wrapped view will only be called when this returns -- Just; a Nothing value will cause the wrapped view to be skipped. checkAuth :: (Authorize sess perm, ListContains n ReadOnlyPool xs) => Proxy perm -> TsActionCtxT lts xs sess (Maybe perm) -- | Guarantee that the Spock session hold some verified piece of data. If -- the requisite data can be loaded, then the view is called with the -- data in its ctxExtras; otherwise jumpNext is called and the -- view is skipped. auth :: (Authorize sess perm, ListContains n ReadOnlyPool xs, Authorize sess perm) => Proxy perm -> TsActionCtxT lts (perm : xs) sess () -> TsActionCtxT lts xs sess () -- | This module builds on Spock's "reroute" library by associating a -- GHC.OverloadedLabels label to each route, which views can then -- use to reverse routes in a type-safe manner. It also uses some -- ridiculous function chaining to almost create an indexed monad, but -- not quite because I can't figure out quite how to make that work. A -- fairly function example follows: -- -- First, we'll define a couple of views: -- --
-- index :: Has "users" lts (Path '[] 'Open) => TsActionCtxT lts xs sess a -- index = showPath #users >>= 'Spock.text -- -- users :: Has "root" lts (Path '[] 'Open) => TsActionCtxT lts xs sess a -- users = do -- root <- showPath #root -- text $ "GET users, root is, " <> root -- -- usersPost :: TsActionCtxT lts xs sess a -- usersPost = text "POST to users!" ---- -- Then, routing to those views looks like this: -- --
-- runroute ropool rwpool $ -- path #root root (getpost index) . -- path #users "users" (do get users -- post usersPost) ---- -- Notice the (.) after the getpost index. We're chaining -- functions together and then passing that chained function to -- runroute in order to generate an actual Spock RouteM. module TsWeb.Routing -- | Reader monad to pass one Path to potentially multiple different -- 'get'/'post'/etc calls. type RoutingM as lts xs sess = ReaderT (Path as 'Open, ReadWritePool) (TsSpockCtxT lts xs sess) -- | Convert a chain of path calls into a RouteM instance. -- This takes a ReadOnlyPool and a ReadWritePool in order -- to operate the auth and dbwrite calls. runroute :: (Applicative f, MonadIO m, RouteM t) => ReadOnlyPool -> ReadWritePool -> ((ReadWritePool, Rec '[], f ()) -> (ReadWritePool, Rec lts, t (Context lts '[ReadOnlyPool]) m ())) -> t ctx m () -- | Describe a path for routing. This both builds up the RouteM -- monad and associates the given label with the URL so that views can -- look up the URL using showPath &c. path :: (KnownNat ((RecSize (Sort ((l := Path as 'Open) : lts)) - RecTyIdxH 0 l (Sort ((l := Path as 'Open) : lts))) - 1), RecCopy lts lts (Sort ((l := Path as 'Open) : lts)), KnownNat (RecSize lts), KeyDoesNotExist l lts, KnownSymbol l) => FldProxy l -> Path as 'Open -> RoutingM as lts0 xs sess a -> (ReadWritePool, Rec lts, TsSpockCtxT lts0 xs sess a) -> (ReadWritePool, Record ((l := Path as 'Open) : lts), TsSpockCtxT lts0 xs sess a) -- | Raise up a RoutingM to have ReadWritePool in its extras -- record. dbwrite :: RoutingM as lts (ReadWritePool : xs) sess () -> RoutingM as lts xs sess () -- | Run this view whether the client did a GET or a POST request getpost :: HasRep as => HVectElim as (TsActionCtxT lts xs sess ()) -> RoutingM as lts xs sess () -- | Run this view only on GET requests get :: HasRep as => HVectElim as (TsActionCtxT lts xs sess ()) -> RoutingM as lts xs sess () -- | Run this view only on POST requests post :: HasRep as => HVectElim as (TsActionCtxT lts xs sess ()) -> RoutingM as lts xs sess () -- | This defines a helper function, clay, which will serve a -- Css instance from a labeled URL prefix. module TsWeb.Routing.Clay -- | Serve a Css instance. The rendered CSS will be served from a -- .css file whose name is derived from the rendered sheet's contents. -- This has two results: changing the stylesheet will change the sheet's -- full URL, and the stylesheet really needs to be referenced by label, -- using something like showPath. The first one of those is -- actually really nice, since browsers are so aggressive about caching -- css. The second one is more convenient anyhow, so this function is -- just pretty nice. clay :: (KeyDoesNotExist l lts, RecCopy lts lts (Sort ((l := Path '[] 'Open) : lts)), KnownNat (RecSize lts), KnownNat ((RecSize (Sort ((l := Path '[] 'Open) : lts)) - RecTyIdxH 0 l (Sort ((l := Path '[] 'Open) : lts))) - 1), KnownSymbol l) => FldProxy l -> String -> Css -> (ReadWritePool, Rec lts, TsSpockCtxT lts0 xs sess ()) -> (ReadWritePool, Record ((l := Path '[] 'Open) : lts), TsSpockCtxT lts0 xs sess ()) -- | This builds on TsWeb.Types.Db's read-only/read-write -- discrimination by providing query functions to perform read-only -- operations, and an execute function to run updates, inserts, -- and deletes (and also selects as appropriate). All of these are -- performed as TsActionCtxT actions so as to nicely integrate -- with Spock. Finally, because I'm not a fan of exceptions, all of these -- functions trap Postgres errors and convert them into sum-type results. -- -- I'm not yet providing shortcuts for the beam-postgres specific -- functions. I'm not actually sure that I need to (IIRC they all build -- Pg actions), but I will be adding them if necessary. module TsWeb.Db -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable (a :: k) -- | Representable types of kind *. This class is derivable in GHC -- with the DeriveGeneric flag on. -- -- A Generic instance must satisfy the following laws: -- --
-- from . to ≡ id -- to . from ≡ id --class Generic a -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | Identity functor and monad. (a non-strict monad) data Identity a -- | Run a SqlDelete in a MonadBeam runDelete :: (BeamSqlBackend be, MonadBeam be m) => SqlDelete be table -> m () -- | Build a SqlDelete from a table and a way to build a -- WHERE clause delete :: BeamSqlBackend be => DatabaseEntity be db (TableEntity table) -> (forall s. () => (forall s'. () => table (QExpr be s')) -> QExpr be s Bool) -> SqlDelete be table -- | Run a SqlUpdate in a MonadBeam. runUpdate :: (BeamSqlBackend be, MonadBeam be m) => SqlUpdate be tbl -> m () -- | Generate a SqlUpdate that will update the given table row with -- the given value. -- -- The SQL UPDATE that is generated will set every non-primary -- key field for the row where each primary key field is exactly what is -- given. -- -- Note: This is a pure SQL UPDATE command. This does not upsert -- or merge values. save :: (Table table, BeamSqlBackend be, SqlValableTable be (PrimaryKey table), SqlValableTable be table, HasTableEquality be (PrimaryKey table)) => DatabaseEntity be db (TableEntity table) -> table Identity -> SqlUpdate be table -- | Use with set to optionally set a fiield to a new value, -- calculated based on one or more fields from the existing row toUpdatedValueMaybe :: () => (forall s. () => table (QExpr be s) -> Maybe (QExpr be s a)) -> QFieldAssignment be table a -- | Use with set to set a field to a new value that is calculated -- based on one or more fields from the existing row toUpdatedValue :: () => (forall s. () => table (QExpr be s) -> QExpr be s a) -> QFieldAssignment be table a -- | Use with set to not modify the field toOldValue :: () => QFieldAssignment be table a -- | Use with set to set a field to an explicit new value that does -- not depend on any other value toNewValue :: () => (forall s. () => QExpr be s a) -> QFieldAssignment be table a setFieldsTo :: Table table => (forall s. () => table (QExpr be s)) -> table (QFieldAssignment be table') set :: Beamable table => table (QFieldAssignment be table') -- | Convenience form of updateTable that generates a WHERE -- clause that matches only the already existing entity updateTableRow :: (BeamSqlBackend be, Table table, HasTableEquality be (PrimaryKey table), SqlValableTable be (PrimaryKey table)) => DatabaseEntity be db (TableEntity table) -> table Identity -> table (QFieldAssignment be table) -> SqlUpdate be table -- | A specialization of update that is more convenient for normal -- tables. updateTable :: (BeamSqlBackend be, Beamable table) => DatabaseEntity be db (TableEntity table) -> table (QFieldAssignment be table) -> (forall s. () => table (QExpr be s) -> QExpr be s Bool) -> SqlUpdate be table -- | A specialization of update that matches the given (already -- existing) row updateRow :: (BeamSqlBackend be, Table table, HasTableEquality be (PrimaryKey table), SqlValableTable be (PrimaryKey table)) => DatabaseEntity be db (TableEntity table) -> table Identity -> (forall s. () => table (QField s) -> QAssignment be s) -> SqlUpdate be table -- | Build a SqlUpdate given a table, a list of assignments, and a -- way to build a WHERE clause. -- -- See the '(<-.)' operator for ways to build assignments. The -- argument to the second argument is a the table parameterized over -- QField, which represents the left hand side of assignments. -- Sometimes, you'd like to also get the current value of a particular -- column. You can use the current_ function to convert a -- QField to a QGenExpr. update :: (BeamSqlBackend be, Beamable table) => DatabaseEntity be db (TableEntity table) -> (forall s. () => table (QField s) -> QAssignment be s) -> (forall s. () => table (QExpr be s) -> QExpr be s Bool) -> SqlUpdate be table -- | Build a SqlInsertValues from a SqlSelect that returns -- the same table insertFrom :: (BeamSqlBackend be, HasQBuilder be, Projectible be r) => Q be db QBaseScope r -> SqlInsertValues be r -- | Build a SqlInsertValues from arbitrarily shaped data containing -- expressions insertData :: (Projectible be r, BeamSqlBackend be) => [r] -> SqlInsertValues be r -- | Build a SqlInsertValues from concrete table values insertValues :: (BeamSqlBackend be, Beamable table, FieldsFulfillConstraint (BeamSqlBackendCanSerialize be) table) => [table Identity] -> SqlInsertValues be (table (QExpr be s)) -- | Build a SqlInsertValues from series of expressions in tables insertExpressions :: (BeamSqlBackend be, Beamable table) => (forall s'. () => [table (QExpr be s')]) -> SqlInsertValues be (table (QExpr be s)) -- | Run a SqlInsert in a MonadBeam runInsert :: (BeamSqlBackend be, MonadBeam be m) => SqlInsert be table -> m () -- | Generate a SqlInsert given a table and a source of values. insert :: (BeamSqlBackend be, ProjectibleWithPredicate AnyType () Text (table (QField s))) => DatabaseEntity be db (TableEntity table) -> SqlInsertValues be (table (QExpr be s)) -> SqlInsert be table -- | Generate a SqlInsert over only certain fields of a table insertOnly :: (BeamSqlBackend be, ProjectibleWithPredicate AnyType () Text (QExprToField r)) => DatabaseEntity be db (TableEntity table) -> (table (QField s) -> QExprToField r) -> SqlInsertValues be r -> SqlInsert be table -- | Use a special debug syntax to print out an ANSI Standard -- SELECT statement that may be generated for a given Q. dumpSqlSelect :: Projectible (MockSqlBackend SqlSyntaxBuilder) res => Q (MockSqlBackend SqlSyntaxBuilder) db QBaseScope res -> IO () -- | Convenience function to generate a SqlSelect that looks up a -- table row given a primary key. lookup_ :: (Database be db, Table table, BeamSqlBackend be, HasQBuilder be, SqlValableTable be (PrimaryKey table), HasTableEquality be (PrimaryKey table)) => DatabaseEntity be db (TableEntity table) -> PrimaryKey table Identity -> SqlSelect be (table Identity) -- | Create a SqlSelect for a query which may have common table -- expressions. See the documentation of With for more details. selectWith :: (BeamSqlBackend be, BeamSql99CommonTableExpressionBackend be, HasQBuilder be, Projectible be res) => With be db (Q be db QBaseScope res) -> SqlSelect be (QExprToIdentity res) -- | Build a SqlSelect for the given Q. select :: (BeamSqlBackend be, HasQBuilder be, Projectible be res) => Q be db QBaseScope res -> SqlSelect be (QExprToIdentity res) data QBaseScope -- | A version of the table where each field is a QGenExpr type QGenExprTable ctxt be s (tbl :: Type -> Type -> Type) = tbl QGenExpr ctxt be s type QExprTable be s (tbl :: Type -> Type -> Type) = QGenExprTable QValueContext be s tbl -- | Represents a select statement in the given backend, returning rows of -- type a. newtype SqlSelect be a SqlSelect :: BeamSqlBackendSelectSyntax be -> SqlSelect be a -- | Represents a SQL INSERT command that has not yet been run data SqlInsert be (table :: Type -> Type -> Type) SqlInsert :: !TableSettings table -> !BeamSqlBackendInsertSyntax be -> SqlInsert be SqlInsertNoRows :: SqlInsert be -- | Represents a source of values that can be inserted into a table shaped -- like tbl. data SqlInsertValues be proj SqlInsertValues :: BeamSqlBackendInsertValuesSyntax be -> SqlInsertValues be proj SqlInsertValuesEmpty :: SqlInsertValues be proj -- | Represents a SQL UPDATE statement for the given -- table. data SqlUpdate be (table :: Type -> Type -> Type) SqlUpdate :: !TableSettings table -> !BeamSqlBackendUpdateSyntax be -> SqlUpdate be SqlIdentityUpdate :: SqlUpdate be -- | Represents a SQL DELETE statement for the given -- table data SqlDelete be (table :: Type -> Type -> Type) SqlDelete :: !TableSettings table -> !BeamSqlBackendDeleteSyntax be -> SqlDelete be regrSXY_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrSYY_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrSXX_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrAvgX_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrAvgY_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrRSquared_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrCount_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrIntercept_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrSlope_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b corr_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b covarSamp_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b covarPop_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QExpr be s a -> QExpr be s b regrSXYOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrSYYOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrSXXOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrAvgXOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrAvgYOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrRSquaredOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrCountOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrInterceptOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b regrSlopeOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b corrOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b covarSampOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b covarPopOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QExpr be s a -> QExpr be s b varSamp_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QAgg be s b varPop_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QAgg be s b stddevSamp_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QAgg be s b stddevPop_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => QExpr be s a -> QAgg be s b varSampOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s b varPopOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s b stddevSampOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s b stddevPopOver_ :: (Num a, Floating b, BeamSqlBackend be, BeamSqlT621Backend be) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s b (**.) :: (Floating a, BeamSqlBackend be, BeamSqlT621Backend be) => QGenExpr ctxt be s a -> QGenExpr ctxt be s a -> QGenExpr ctxt be s a infixr 8 **. floor_ :: (RealFrac a, Integral b, BeamSqlBackend be, BeamSqlT621Backend be) => QGenExpr ctxt be s a -> QGenExpr ctxt be s b ceiling_ :: (RealFrac a, Integral b, BeamSqlBackend be, BeamSqlT621Backend be) => QGenExpr ctxt be s a -> QGenExpr ctxt be s b sqrt_ :: (Floating a, BeamSqlBackend be, BeamSqlT621Backend be) => QGenExpr ctxt be s a -> QGenExpr ctxt be s a exp_ :: (Floating a, BeamSqlBackend be, BeamSqlT621Backend be) => QGenExpr ctxt be s a -> QGenExpr ctxt be s a ln_ :: (Floating a, BeamSqlBackend be, BeamSqlT621Backend be) => QGenExpr ctxt be s a -> QGenExpr ctxt be s a nthValue_ :: (BeamSqlBackend be, BeamSqlT618Backend be) => QExpr be s a -> QExpr be s Int -> QAgg be s a lastValue_ :: (BeamSqlBackend be, BeamSqlT616Backend be) => QExpr be s a -> QAgg be s a firstValue_ :: (BeamSqlBackend be, BeamSqlT616Backend be) => QExpr be s a -> QAgg be s a lagWithDefault_ :: (BeamSqlBackend be, BeamSqlT615Backend be) => QExpr be s a -> QExpr be s Int -> QExpr be s a -> QAgg be s a leadWithDefault_ :: (BeamSqlBackend be, BeamSqlT615Backend be) => QExpr be s a -> QExpr be s Int -> QExpr be s a -> QAgg be s a lag_ :: (BeamSqlBackend be, BeamSqlT615Backend be) => QExpr be s a -> QExpr be s Int -> QAgg be s a lead_ :: (BeamSqlBackend be, BeamSqlT615Backend be) => QExpr be s a -> QExpr be s Int -> QAgg be s a lag1_ :: (BeamSqlBackend be, BeamSqlT615Backend be) => QExpr be s a -> QAgg be s a lead1_ :: (BeamSqlBackend be, BeamSqlT615Backend be) => QExpr be s a -> QAgg be s a ntile_ :: (BeamSqlBackend be, BeamSqlT614Backend be) => QExpr be s Int -> QAgg be s a -- | SQL99 ANY(ALL ..) function (but without the explicit ALL) any_ :: BeamSql99AggregationBackend be => QExpr be s SqlBool -> QAgg be s SqlBool -- | SQL99 SOME(ALL ..) function (but without the explicit ALL) some_ :: BeamSql99AggregationBackend be => QExpr be s SqlBool -> QAgg be s SqlBool -- | SQL99 EVERY(ALL ..) function (but without the explicit ALL) every_ :: BeamSql99AggregationBackend be => QExpr be s SqlBool -> QAgg be s SqlBool -- | Like filterWhere_ but accepting SqlBool. filterWhere_' :: BeamSqlT611Backend be => QAgg be s a -> QExpr be s SqlBool -> QAgg be s a -- | Support for FILTER (WHERE ...) syntax for aggregates. Part of SQL2003 -- Elementary OLAP operations feature (T611). -- -- See filterWhere_' for a version that accepts SqlBool. filterWhere_ :: BeamSqlT611Backend be => QAgg be s a -> QExpr be s Bool -> QAgg be s a -- | SQL EVERY, SOME, and ANY aggregates. -- Operates over SqlBool only, as the result can be NULL, -- even if all inputs are known (no input rows). anyOver_ :: BeamSql99AggregationBackend be => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s SqlBool -> QAgg be s SqlBool -- | SQL EVERY, SOME, and ANY aggregates. -- Operates over SqlBool only, as the result can be NULL, -- even if all inputs are known (no input rows). someOver_ :: BeamSql99AggregationBackend be => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s SqlBool -> QAgg be s SqlBool -- | SQL EVERY, SOME, and ANY aggregates. -- Operates over SqlBool only, as the result can be NULL, -- even if all inputs are known (no input rows). everyOver_ :: BeamSql99AggregationBackend be => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s SqlBool -> QAgg be s SqlBool countOver_ :: (BeamSqlBackend be, Integral b) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s b sumOver_ :: (BeamSqlBackend be, Num a) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s (Maybe a) avgOver_ :: (BeamSqlBackend be, Num a) => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s (Maybe a) maxOver_ :: BeamSqlBackend be => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s (Maybe a) minOver_ :: BeamSqlBackend be => Maybe (BeamSqlBackendAggregationQuantifierSyntax be) -> QExpr be s a -> QAgg be s (Maybe a) -- | SQL2003 RANK function (Requires T611 Elementary OLAP -- operations support) rank_ :: BeamSqlT611Backend be => QAgg be s Int -- | SQL2003 ROW_NUMBER function rowNumber_ :: BeamSql2003ExpressionBackend be => QAgg be s Int -- | SQL2003 DENSE_RANK function (Requires T612 Advanced OLAP -- operations support) denseRank_ :: BeamSqlT612Backend be => QAgg be s Int -- | SQL2003 PERCENT_RANK function (Requires T612 Advanced OLAP -- operations support) percentRank_ :: BeamSqlT612Backend be => QAgg be s Double -- | SQL2003 CUME_DIST function (Requires T612 Advanced OLAP -- operations support) cumeDist_ :: BeamSqlT612Backend be => QAgg be s Double -- | SQL COUNT(ALL ..) function (but without the explicit ALL) count_ :: (BeamSqlBackend be, Integral b) => QExpr be s a -> QAgg be s b -- | SQL COUNT(*) function countAll_ :: BeamSqlBackend be => QAgg be s Int -- | SQL SUM(ALL ..) function (but without the explicit ALL) sum_ :: (BeamSqlBackend be, Num a) => QExpr be s a -> QAgg be s (Maybe a) -- | SQL AVG(ALL ..) function (but without the explicit ALL) avg_ :: (BeamSqlBackend be, Num a) => QExpr be s a -> QAgg be s (Maybe a) -- | SQL MAX(ALL ..) function (but without the explicit ALL) max_ :: BeamSqlBackend be => QExpr be s a -> QAgg be s (Maybe a) -- | SQL MIN(ALL ..) function (but without the explicit ALL) min_ :: BeamSqlBackend be => QExpr be s a -> QAgg be s (Maybe a) -- | Compute an aggregate over all values in a group. Corresponds to the -- AGG(ALL ..) syntax. Note that ALL is the default for -- most aggregations, so you don't normally explicitly specify -- ALL. However, if you need to, you can use this function. To -- be explicit about quantification in the beam query DSL, but not -- produce an explicit ALL, use allInGroup_. -- allInGroup_ has the same semantic meaning, but does not produce -- an explicit ALL. allInGroupExplicitly_ :: IsSql92AggregationSetQuantifierSyntax s => Maybe s -- | Compute an aggregate only over distinct values in a group. Corresponds -- to the AGG(DISTINCT ..) syntax. distinctInGroup_ :: IsSql92AggregationSetQuantifierSyntax s => Maybe s -- | Compute an aggregate over all values in a group. Corresponds -- semantically to the AGG(ALL ..) syntax, but doesn't produce -- an explicit ALL. To produce ALL expicitly, see -- allInGroupExplicitly_. allInGroup_ :: IsSql92AggregationSetQuantifierSyntax s => Maybe s -- | Compute an aggregate over a query. -- -- The supplied aggregate projection should return an aggregate -- expression (an expression containing an aggregate function such as -- count_, sum_, countAll_, etc), a grouping key -- (specified with the group_ function), or a combination of -- tuples of the above. -- -- Appropriate instances are provided up to 8-tuples. -- -- Semantically, all grouping expressions in the projection will be added -- to a SQL GROUP BY clause and all aggregate expressions will -- be computed. -- -- The return value will be the type of the aggregate projection, but -- transformed to be in the normal value context (i.e., everything will -- become QGenExprs). -- -- For usage examples, see the manual. aggregate_ :: (BeamSqlBackend be, Aggregable be a, Projectible be r, Projectible be a, ContextRewritable a, ThreadRewritable (QNested s) (WithRewrittenContext a QValueContext)) => (r -> a) -> Q be db (QNested s) r -> Q be db s (WithRewrittenThread (QNested s) s (WithRewrittenContext a QValueContext)) -- | Type class for grouping keys. expr is the type of the -- grouping key after projection. grouped is the type of the -- grouping key in the aggregate expression (usually something that -- contains QGenExprs in the QGroupingContext). class QGroupable expr grouped | expr -> grouped, grouped -> expr group_ :: QGroupable expr grouped => expr -> grouped -- | Used to define many-to-many relationships with additional data. Takes -- the join table and two key extraction functions from that table to the -- related tables. Also takes two Qs representing the table -- sources to relate. -- -- See the manual for more indformation. manyToManyPassthrough_ :: (Database be db, Table joinThrough, Table left, Table right, BeamSqlBackend be, SqlEq (QExpr be s) (PrimaryKey left (QExpr be s)), SqlEq (QExpr be s) (PrimaryKey right (QExpr be s))) => DatabaseEntity be db (TableEntity joinThrough) -> (joinThrough (QExpr be s) -> PrimaryKey left (QExpr be s)) -> (joinThrough (QExpr be s) -> PrimaryKey right (QExpr be s)) -> Q be db s (left (QExpr be s)) -> Q be db s (right (QExpr be s)) -> Q be db s (joinThrough (QExpr be s), left (QExpr be s), right (QExpr be s)) -- | Used to define many-to-many relationships without any additional data. -- Takes the join table and two key extraction functions from that table -- to the related tables. Also takes two Qs representing the table -- sources to relate. -- -- See the manual for more indformation. manyToMany_ :: (Database be db, Table joinThrough, Table left, Table right, BeamSqlBackend be, SqlEq (QExpr be s) (PrimaryKey left (QExpr be s)), SqlEq (QExpr be s) (PrimaryKey right (QExpr be s))) => DatabaseEntity be db (TableEntity joinThrough) -> (joinThrough (QExpr be s) -> PrimaryKey left (QExpr be s)) -> (joinThrough (QExpr be s) -> PrimaryKey right (QExpr be s)) -> Q be db s (left (QExpr be s)) -> Q be db s (right (QExpr be s)) -> Q be db s (left (QExpr be s), right (QExpr be s)) -- | Used to define one-to-many (or one-to-one) relationships with a -- nullable foreign key. Takes the table to fetch, a way to extract the -- foreign key from that table, and the table to relate to. oneToMaybe_ :: (BeamSqlBackend be, Database be db, Table tbl, Table rel, HasTableEqualityNullable be (PrimaryKey tbl)) => DatabaseEntity be db (TableEntity rel) -> (rel (QExpr be s) -> PrimaryKey tbl (Nullable (QExpr be s))) -> tbl (QExpr be s) -> Q be db s (rel (Nullable (QExpr be s))) -- | Used to define one-to-many (or one-to-one) relationships with a -- nullable foreign key. Takes the table to fetch, a way to extract the -- foreign key from that table, and the table to relate to. oneToManyOptional_ :: (BeamSqlBackend be, Database be db, Table tbl, Table rel, HasTableEqualityNullable be (PrimaryKey tbl)) => DatabaseEntity be db (TableEntity rel) -> (rel (QExpr be s) -> PrimaryKey tbl (Nullable (QExpr be s))) -> tbl (QExpr be s) -> Q be db s (rel (Nullable (QExpr be s))) -- | Used to define one-to-many (or one-to-one) relationships. Takes the -- table to fetch, a way to extract the foreign key from that table, and -- the table to relate to. oneToOne_ :: (Database be db, BeamSqlBackend be, HasTableEquality be (PrimaryKey tbl), Table tbl, Table rel) => DatabaseEntity be db (TableEntity rel) -> (rel (QExpr be s) -> PrimaryKey tbl (QExpr be s)) -> tbl (QExpr be s) -> Q be db s (rel (QExpr be s)) -- | Used to define one-to-many (or one-to-one) relationships. Takes the -- table to fetch, a way to extract the foreign key from that table, and -- the table to relate to. oneToMany_ :: (Database be db, BeamSqlBackend be, HasTableEquality be (PrimaryKey tbl), Table tbl, Table rel) => DatabaseEntity be db (TableEntity rel) -> (rel (QExpr be s) -> PrimaryKey tbl (QExpr be s)) -> tbl (QExpr be s) -> Q be db s (rel (QExpr be s)) -- | Synonym of OneToMany. Useful for giving more meaningful types, -- when the relationship is meant to be one-to-one. type OneToOne be (db :: Type -> Type -> Type) s (one :: Type -> Type -> Type) (many :: Type -> Type -> Type) = OneToMany be db s one many -- | Convenience type to declare one-to-many relationships. See the manual -- section on relationships for more information type OneToMany be (db :: Type -> Type -> Type) s (one :: Type -> Type -> Type) (many :: Type -> Type -> Type) = BeamSqlBackend be -> BeamSqlBackendCanSerialize be Bool -> one QExpr be s -> Q be db s many QExpr be s -- | Synonym of OneToManyOptional. Useful for giving more meaningful -- types, when the relationship is meant to be one-to-one. type OneToMaybe be (db :: Type -> Type -> Type) s (tbl :: Type -> Type -> Type) (rel :: Type -> Type -> Type) = OneToManyOptional be db s tbl rel -- | Convenience type to declare one-to-many relationships with a nullable -- foreign key. See the manual section on relationships for more -- information type OneToManyOptional be (db :: Type -> Type -> Type) s (tbl :: Type -> Type -> Type) (rel :: Type -> Type -> Type) = BeamSqlBackend be -> BeamSqlBackendCanSerialize be Bool -> BeamSqlBackendCanSerialize be SqlNull -> tbl QExpr be s -> Q be db s rel Nullable QExpr be s -- | Convenience type to declare many-to-many relationships. See the manual -- section on relationships for more information type ManyToMany be (db :: Type -> Type -> Type) (left :: Type -> Type -> Type) (right :: Type -> Type -> Type) = forall s. (BeamSqlBackend be, SqlEq QExpr be s PrimaryKey left QExpr be s, SqlEq QExpr be s PrimaryKey right QExpr be s) => Q be db s left QExpr be s -> Q be db s right QExpr be s -> Q be db s (left QExpr be s, right QExpr be s) -- | Convenience type to declare many-to-many relationships with additional -- data. See the manual section on relationships for more -- information type ManyToManyThrough be (db :: Type -> Type -> Type) (through :: Type -> Type -> Type) (left :: Type -> Type -> Type) (right :: Type -> Type -> Type) = forall s. (BeamSqlBackend be, SqlEq QExpr be s PrimaryKey left QExpr be s, SqlEq QExpr be s PrimaryKey right QExpr be s) => Q be db s left QExpr be s -> Q be db s right QExpr be s -> Q be db s (through QExpr be s, left QExpr be s, right QExpr be s) (<|>.) :: (SqlJustable a (QGenExpr ctxt syntax s y), SqlDeconstructMaybe syntax (QGenExpr ctxt syntax s y) a s) => QGenExpr ctxt syntax s y -> QGenExpr ctxt syntax s y -> QGenExpr ctxt syntax s y infixl 3 <|>. -- | Converta a Maybe value to a concrete value, by suppling a -- default fromMaybe_ :: BeamSqlBackend be => QGenExpr ctxt be s a -> QGenExpr ctxt be s (Maybe a) -> QGenExpr ctxt be s a -- | SQL COALESCE support coalesce_ :: BeamSqlBackend be => [QGenExpr ctxt be s (Maybe a)] -> QGenExpr ctxt be s a -> QGenExpr ctxt be s a if_ :: BeamSqlBackend be => [QIfCond context be s a] -> QIfElse context be s a -> QGenExpr context be s a else_ :: () => QGenExpr context be s a -> QIfElse context be s a then_' :: () => QGenExpr context be s SqlBool -> QGenExpr context be s a -> QIfCond context be s a then_ :: () => QGenExpr context be s Bool -> QGenExpr context be s a -> QIfCond context be s a -- | Produce a QOrd corresponding to a SQL DESC ordering desc_ :: BeamSqlBackend be => QExpr be s a -> QOrd be s a -- | Produce a QOrd corresponding to a SQL ASC ordering asc_ :: BeamSqlBackend be => QExpr be s a -> QOrd be s a nullsLast_ :: IsSql2003OrderingElementaryOLAPOperationsSyntax (BeamSqlBackendOrderingSyntax be) => QOrd be s a -> QOrd be s a nullsFirst_ :: IsSql2003OrderingElementaryOLAPOperationsSyntax (BeamSqlBackendOrderingSyntax be) => QOrd be s a -> QOrd be s a -- | Order by the given expressions. The return type of the ordering key -- should either be the result of asc_ or desc_ (or another -- ordering QOrd generated by a backend-specific ordering) or an -- (possibly nested) tuple of results of the former. -- -- The manual section has more information. orderBy_ :: (Projectible be a, SqlOrderable be ordering, ThreadRewritable (QNested s) a) => (a -> ordering) -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | Compute a query over windows. -- -- The first function builds window frames using the frame_, -- partitionBy_, etc functions. The return type can be a single -- frame, tuples of frame, or any arbitrarily nested tuple of the above. -- Instances up to 8-tuples are provided. -- -- The second function builds the resulting projection using the result -- of the subquery as well as the window frames built in the first -- function. In this function, window expressions can be included in the -- output using the over_ function. withWindow_ :: (ProjectibleWithPredicate WindowFrameContext be (WithExprContext (BeamSqlBackendWindowFrameSyntax' be)) window, Projectible be r, Projectible be a, ContextRewritable a, ThreadRewritable (QNested s) (WithRewrittenContext a QValueContext)) => (r -> window) -> (r -> window -> a) -> Q be db (QNested s) r -> Q be db s (WithRewrittenThread (QNested s) s (WithRewrittenContext a QValueContext)) -- | Produce a window expression given an aggregate function and a window. over_ :: BeamSql2003ExpressionBackend be => QAgg be s a -> QWindow be s -> QWindowExpr be s a -- | Specify a window frame with all the options frame_ :: (BeamSql2003ExpressionBackend be, SqlOrderable be ordering, Projectible be partition) => Maybe partition -> Maybe ordering -> QFrameBounds be -> QWindow be s orderPartitionBy_ :: () => partition -> Maybe partition partitionBy_ :: () => partition -> Maybe partition noOrder_ :: () => Maybe (QOrd be s Int) noPartition_ :: () => Maybe (QExpr be s Int) nrows_ :: BeamSql2003ExpressionBackend be => Int -> QFrameBound be unbounded_ :: BeamSql2003ExpressionBackend be => QFrameBound be bounds_ :: BeamSql2003ExpressionBackend be => QFrameBound be -> Maybe (QFrameBound be) -> QFrameBounds be fromBound_ :: BeamSql2003ExpressionBackend be => QFrameBound be -> QFrameBounds be noBounds_ :: () => QFrameBounds be default_ :: BeamSqlBackend be => QGenExpr ctxt be s a -- | Convenience function that allows you to use type applications to -- specify the result of a QGenExpr. -- -- Useful to disambiguate the types of QGenExprs without having to -- provide a complete type signature. As an example, the -- countAll_ aggregate can return a result of any -- Integral type. Without further constraints, the type is -- ambiguous. You can use as_ to disambiguate the return type. -- -- For example, this is ambiguous -- --
-- aggregate_ (\_ -> countAll_) .. ---- -- But this is not -- --
-- aggregate_ (\_ -> as_ @Int countAll_) .. --as_ :: () => QGenExpr ctxt be s a -> QGenExpr ctxt be s a -- | SQL EXCEPT ALL operator exceptAll_ :: (BeamSqlBackend be, Projectible be a, ThreadRewritable (QNested s) a) => Q be db (QNested s) a -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | SQL EXCEPT operator except_ :: (BeamSqlBackend be, Projectible be a, ThreadRewritable (QNested s) a) => Q be db (QNested s) a -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | SQL INTERSECT ALL operator intersectAll_ :: (BeamSqlBackend be, Projectible be a, ThreadRewritable (QNested s) a) => Q be db (QNested s) a -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | SQL INTERSECT operator intersect_ :: (BeamSqlBackend be, Projectible be a, ThreadRewritable (QNested s) a) => Q be db (QNested s) a -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | SQL UNION ALL operator unionAll_ :: (BeamSqlBackend be, Projectible be a, ThreadRewritable (QNested s) a) => Q be db (QNested s) a -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | SQL UNION operator union_ :: (BeamSqlBackend be, Projectible be a, ThreadRewritable (QNested s) a) => Q be db (QNested s) a -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | Extract an expression representing the current (non-UPDATEd) value of -- a QField current_ :: BeamSqlBackend be => QField s ty -> QExpr be s ty -- | SQL TRIM function trim_ :: (BeamSqlBackendIsString be text, BeamSqlBackend be) => QGenExpr context be s text -> QGenExpr context be s text -- | SQL UPPER function upper_ :: (BeamSqlBackendIsString be text, BeamSqlBackend be) => QGenExpr context be s text -> QGenExpr context be s text -- | SQL LOWER function lower_ :: (BeamSqlBackendIsString be text, BeamSqlBackend be) => QGenExpr context be s text -> QGenExpr context be s text -- | SQL POSITION(.. IN ..) function position_ :: (BeamSqlBackendIsString be text, BeamSqlBackend be, Integral b) => QExpr be s text -> QExpr be s text -> QExpr be s b -- | SQL CURRENT_TIMESTAMP function currentTimestamp_ :: BeamSqlBackend be => QGenExpr ctxt be s LocalTime -- | SQL BIT_LENGTH function bitLength_ :: BeamSqlBackend be => QGenExpr context be s SqlBitString -> QGenExpr context be s Int -- | SQL OCTET_LENGTH function octetLength_ :: (BeamSqlBackend be, BeamSqlBackendIsString be text) => QGenExpr context be s text -> QGenExpr context be s Int -- | SQL CHAR_LENGTH function charLength_ :: (BeamSqlBackend be, BeamSqlBackendIsString be text) => QGenExpr context be s text -> QGenExpr context be s Int -- | Project the (presumably) singular result of the given query as an -- expression subquery_ :: (BeamSqlBackend be, HasQBuilder be, Projectible be (QExpr be s a)) => Q be db s (QExpr be s a) -> QGenExpr ctxt be s a -- | Use the SQL99 DISTINCT operator to determine if the given -- query produces a distinct result distinct_ :: (BeamSqlBackend be, BeamSql99ExpressionBackend be, HasQBuilder be, Projectible be a) => Q be db s a -> QExpr be s Bool -- | Use the SQL UNIQUE operator to determine if the given query -- produces a unique result unique_ :: (BeamSqlBackend be, HasQBuilder be, Projectible be a) => Q be db s a -> QExpr be s Bool -- | Use the SQL EXISTS operator to determine if the given query -- returns any results exists_ :: (BeamSqlBackend be, HasQBuilder be, Projectible be a) => Q be db s a -> QExpr be s Bool -- | Drop the first offset' results. offset_ :: (Projectible be a, ThreadRewritable (QNested s) a) => Integer -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | Limit the number of results returned by a query. limit_ :: (Projectible be a, ThreadRewritable (QNested s) a) => Integer -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a) -- | Only return distinct values from a query nub_ :: (BeamSqlBackend be, Projectible be r) => Q be db s r -> Q be db s r -- | Generate an appropriate boolean QGenExpr comparing the given -- foreign key to the given table. Useful for creating join conditions. references_ :: (Table t, BeamSqlBackend be, HasTableEquality be (PrimaryKey t)) => PrimaryKey t (QGenExpr ctxt be s) -> t (QGenExpr ctxt be s) -> QGenExpr ctxt be s Bool -- | Introduce all entries of the given table which for which the -- expression (which can depend on the queried table returns true) relatedBy_' :: (Database be db, Table rel, BeamSqlBackend be) => DatabaseEntity be db (TableEntity rel) -> (rel (QExpr be s) -> QExpr be s SqlBool) -> Q be db s (rel (QExpr be s)) -- | Introduce all entries of the given table which for which the -- expression (which can depend on the queried table returns true) relatedBy_ :: (Database be db, Table rel, BeamSqlBackend be) => DatabaseEntity be db (TableEntity rel) -> (rel (QExpr be s) -> QExpr be s Bool) -> Q be db s (rel (QExpr be s)) -- | Introduce all entries of the given table which are referenced by the -- given PrimaryKey related_ :: (Database be db, Table rel, BeamSqlBackend be, HasTableEquality be (PrimaryKey rel)) => DatabaseEntity be db (TableEntity rel) -> PrimaryKey rel (QExpr be s) -> Q be db s (rel (QExpr be s)) -- | Synonym for clause >>= x -> guard_' (mkExpr x)>> -- pure x. Use filter_ for comparisons with Bool filter_' :: BeamSqlBackend be => (r -> QExpr be s SqlBool) -> Q be db s r -> Q be db s r -- | Synonym for clause >>= x -> guard_ (mkExpr x)>> -- pure x. Use filter_' for comparisons with SqlBool filter_ :: BeamSqlBackend be => (r -> QExpr be s Bool) -> Q be db s r -> Q be db s r -- | Only allow results for which the QGenExpr yields TRUE. -- -- This function operates over SqlBool, which are like haskell -- Bools, except for the special UNKNOWN value that -- occurs when comparisons include NULL. For a version that -- operates over known non-NULL booleans, see guard_. guard_' :: BeamSqlBackend be => QExpr be s SqlBool -> Q be db s () -- | Only allow results for which the QGenExpr yields True. -- For a version that operates over possibly NULL -- SqlBools, see guard_'. guard_ :: BeamSqlBackend be => QExpr be s Bool -> Q be db s () subselect_ :: (ThreadRewritable (QNested s) r, Projectible be r) => Q be db (QNested s) r -> Q be db s (WithRewrittenThread (QNested s) s r) -- | Like leftJoin_, but accepts an ON clause returning -- SqlBool. leftJoin_' :: (BeamSqlBackend be, Projectible be r, ThreadRewritable (QNested s) r, Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s r)) => Q be db (QNested s) r -> (WithRewrittenThread (QNested s) s r -> QExpr be s SqlBool) -> Q be db s (Retag Nullable (WithRewrittenThread (QNested s) s r)) -- | Introduce a table using a left join. The ON clause is required -- here.Because this is not an inner join, the resulting table is made -- nullable. This means that each field that would normally have type -- 'QExpr x' will now have type 'QExpr (Maybe x)'. -- -- The ON condition given must return Bool. For a version -- that accepts an ON condition returning SqlBool, see -- leftJoin_'. leftJoin_ :: (BeamSqlBackend be, Projectible be r, ThreadRewritable (QNested s) r, Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s r)) => Q be db (QNested s) r -> (WithRewrittenThread (QNested s) s r -> QExpr be s Bool) -> Q be db s (Retag Nullable (WithRewrittenThread (QNested s) s r)) -- | Like outerJoin_, but accepting SqlBool. Pairs of rows -- for which the join condition is unknown are considered to be -- unrelated, by SQL compliant databases at least. outerJoin_' :: (BeamSqlBackend be, BeamSqlBackendSupportsOuterJoin be, Projectible be a, Projectible be b, ThreadRewritable (QNested s) a, ThreadRewritable (QNested s) b, Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s a), Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s b)) => Q be db (QNested s) a -> Q be db (QNested s) b -> ((WithRewrittenThread (QNested s) s a, WithRewrittenThread (QNested s) s b) -> QExpr be s SqlBool) -> Q be db s (Retag Nullable (WithRewrittenThread (QNested s) s a), Retag Nullable (WithRewrittenThread (QNested s) s b)) -- | Outer join. every row of each table, returning NULL for any -- row of either table for which the join condition finds no related -- rows. -- -- This expects a join expression returning Bool, for a version -- that accepts a SqlBool (a possibly UNKNOWN boolean, -- that maps more closely to the SQL standard), see outerJoin_' outerJoin_ :: (BeamSqlBackend be, BeamSqlBackendSupportsOuterJoin be, Projectible be a, Projectible be b, ThreadRewritable (QNested s) a, ThreadRewritable (QNested s) b, Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s a), Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s b)) => Q be db (QNested s) a -> Q be db (QNested s) b -> ((WithRewrittenThread (QNested s) s a, WithRewrittenThread (QNested s) s b) -> QExpr be s Bool) -> Q be db s (Retag Nullable (WithRewrittenThread (QNested s) s a), Retag Nullable (WithRewrittenThread (QNested s) s b)) -- | Introduce a table using a left join with no ON clause. Because this is -- not an inner join, the resulting table is made nullable. This means -- that each field that would normally have type 'QExpr x' will now have -- type 'QExpr (Maybe x)'. perhaps_ :: (Projectible be r, BeamSqlBackend be, ThreadRewritable (QNested s) r, Retaggable (QExpr be s) (WithRewrittenThread (QNested s) s r)) => Q be db (QNested s) r -> Q be db s (Retag Nullable (WithRewrittenThread (QNested s) s r)) -- | Like join_, but accepting an ON condition that returns -- SqlBool join_' :: (Database be db, Table table, BeamSqlBackend be) => DatabaseEntity be db (TableEntity table) -> (table (QExpr be s) -> QExpr be s SqlBool) -> Q be db s (table (QExpr be s)) -- | Introduce all entries of a table into the Q monad based on the -- given QExpr. The join condition is expected to return a Bool. -- For a version that takes SqlBool (a possibly UNKNOWN -- boolean, that maps more closely to the SQL standard), see -- join_'. join_ :: (Database be db, Table table, BeamSqlBackend be) => DatabaseEntity be db (TableEntity table) -> (table (QExpr be s) -> QExpr be s Bool) -> Q be db s (table (QExpr be s)) values_ :: (Projectible be a, BeamSqlBackend be) => [a] -> Q be db s a -- | Introduce all entries of a view into the Q monad allFromView_ :: (Database be db, Beamable table, BeamSqlBackend be) => DatabaseEntity be db (ViewEntity table) -> Q be db s (table (QExpr be s)) -- | Introduce all entries of a table into the Q monad all_ :: (Database be db, BeamSqlBackend be) => DatabaseEntity be db (TableEntity table) -> Q be db s (table (QExpr be s)) type family HaskellLiteralForQExpr x = (a :: Type) type SqlValableTable be (table :: Type -> Type -> Type) = (Beamable table, FieldsFulfillConstraint HasSqlValueSyntax BeamSqlBackendValueSyntax be table) class SqlValable a val_ :: SqlValable a => HaskellLiteralForQExpr a -> a class SqlOrderable be a | a -> be -- | Type class for things that can be nullable. This includes 'QExpr -- (Maybe a)', 'tbl (Nullable QExpr)', and 'PrimaryKey tbl (Nullable -- QExpr)' class SqlJustable a b | b -> a -- | Given something of type 'QExpr a', 'tbl QExpr', or 'PrimaryKey tbl -- QExpr', turn it into a 'QExpr (Maybe a)', 'tbl (Nullable QExpr)', or -- 'PrimaryKey t (Nullable QExpr)' respectively that contains the same -- values. just_ :: SqlJustable a b => a -> b -- | Return either a 'QExpr (Maybe x)' representing Nothing or a -- nullable Table or PrimaryKey filled with Nothing. nothing_ :: SqlJustable a b => b data QIfCond context be s a data QIfElse context be s a -- | Type class for anything which can be checked for null-ness. This -- includes 'QExpr (Maybe a)' as well as Tables or -- PrimaryKeys over 'Nullable QExpr'. class BeamSqlBackend be => SqlDeconstructMaybe be a nonNullA s | a s -> be, a -> nonNullA, a -> s, nonNullA -> s -- | Returns a QGenExpr that evaluates to true when the first -- argument is not null isJust_ :: SqlDeconstructMaybe be a nonNullA s => a -> QGenExpr ctxt be s Bool -- | Returns a QGenExpr that evaluates to true when the first -- argument is null isNothing_ :: SqlDeconstructMaybe be a nonNullA s => a -> QGenExpr ctxt be s Bool -- | Given an object (third argument) which may or may not be null, return -- the default value if null (first argument), or transform the value -- that could be null to yield the result of the expression (second -- argument) maybe_ :: SqlDeconstructMaybe be a nonNullA s => QGenExpr ctxt be s y -> (nonNullA -> QGenExpr ctxt be s y) -> a -> QGenExpr ctxt be s y reuse :: () => ReusableQ be db res -> Q be db s (WithRewrittenThread QAnyScope s res) selecting :: (BeamSql99CommonTableExpressionBackend be, HasQBuilder be, Projectible be res, ThreadRewritable QAnyScope res) => Q be db QAnyScope res -> With be db (ReusableQ be db res) data With be (db :: Type -> Type -> Type) a data ReusableQ be (db :: Type -> Type -> Type) res -- | Force a QGenExpr to be typed as an aggregate. Useful for -- defining custom aggregates for use in aggregate_. agg_ :: () => QAgg be s a -> QAgg be s a -- | Force a QGenExpr to be typed as a value expression (a -- QGenExpr). Useful for getting around type-inference errors with -- supplying the entire type. valueExpr_ :: () => QExpr be s a -> QExpr be s a -- | A type-class for expression syntaxes that can embed custom -- expressions. class (Monoid CustomSqlSyntax syntax, Semigroup CustomSqlSyntax syntax, IsString CustomSqlSyntax syntax) => IsCustomSqlSyntax syntax where { data family CustomSqlSyntax syntax :: Type; } -- | Given an arbitrary string-like expression, produce a syntax -- that represents the ByteString as a SQL expression. customExprSyntax :: IsCustomSqlSyntax syntax => CustomSqlSyntax syntax -> syntax -- | Given an arbitrary syntax, produce a string-like value that -- corresponds to how that syntax would look when rendered in the -- backend. renderSyntax :: IsCustomSqlSyntax syntax => syntax -> CustomSqlSyntax syntax class IsCustomExprFn fn res | res -> fn customExpr_ :: IsCustomExprFn fn res => fn -> res -- | Haskell requires DataTypes to match exactly. Use this function -- to convert a DataType that expects a concrete value to one -- expecting a Maybe maybeType :: () => DataType be a -> DataType be (Maybe a) -- | SQL99 array data types array :: (Typeable a, BeamSql99DataTypeBackend be) => DataType be a -> Int -> DataType be (Vector a) -- | SQL99 BLOB data type binaryLargeObject :: BeamSql99DataTypeBackend be => DataType be Text -- | SQL99 CLOB data type characterLargeObject :: BeamSql99DataTypeBackend be => DataType be Text -- | SQL99 BOOLEAN data type boolean :: BeamSql99DataTypeBackend be => DataType be Bool -- | SQL92 TIME data type time :: BeamSqlBackend be => Maybe Word -> DataType be TimeOfDay -- | SQL92 TIMESTAMP WITHOUT TIME ZONE data type timestamp :: BeamSqlBackend be => DataType be LocalTime -- | SQL92 TIMESTAMP WITH TIME ZONE data type timestamptz :: BeamSqlBackend be => DataType be LocalTime -- | SQL92 NUMERIC data type numeric :: BeamSqlBackend be => Maybe (Word, Maybe Word) -> DataType be Scientific -- | SQL92 DOUBLE data type double :: BeamSqlBackend be => DataType be Double -- | SQL92 NATIONAL CHARACTER data type nationalChar :: BeamSqlBackend be => Maybe Word -> DataType be Text -- | SQL92 NATIONAL CHARACTER VARYING data type nationalVarchar :: BeamSqlBackend be => Maybe Word -> DataType be Text -- | SQL92 VARCHAR data type varchar :: BeamSqlBackend be => Maybe Word -> DataType be Text -- | SQL92 CHAR data type char :: BeamSqlBackend be => Maybe Word -> DataType be Text -- | SQL92 DATE data type date :: BeamSqlBackend be => DataType be Day -- | SQL2003 Optional VARBINARY data type varbinary :: (BeamSqlBackend be, BeamSqlT021Backend be) => Maybe Word -> DataType be Integer -- | SQL2003 Optional BINARY data type binary :: (BeamSqlBackend be, BeamSqlT021Backend be) => Maybe Word -> DataType be Integer -- | SQL2008 Optional BIGINT data type bigint :: (BeamSqlBackend be, BeamSqlT071Backend be, Integral a) => DataType be a -- | SQL92 SMALLINT data type smallint :: (BeamSqlBackend be, Integral a) => DataType be a -- | SQL92 INTEGER data type int :: (BeamSqlBackend be, Integral a) => DataType be a -- | Cast a value to a specific data type, specified using DataType. -- -- Note: this may fail at run-time if the cast is invalid for a -- particular value cast_ :: BeamSqlBackend be => QGenExpr ctxt be s a -> DataType be b -> QGenExpr ctxt be s b -- | A data type in a given IsSql92DataTypeSyntax which describes a -- SQL type mapping to the Haskell type a newtype DataType be a DataType :: BeamSqlBackendCastTargetSyntax be -> DataType be a day_ :: (BeamSqlBackend be, HasSqlDate tgt) => ExtractField be tgt Double month_ :: (BeamSqlBackend be, HasSqlDate tgt) => ExtractField be tgt Double year_ :: (BeamSqlBackend be, HasSqlDate tgt) => ExtractField be tgt Double -- | Extracts the hours, minutes, or seconds from any timestamp or time -- field seconds_ :: (BeamSqlBackend be, HasSqlTime tgt) => ExtractField be tgt Double -- | Extracts the hours, minutes, or seconds from any timestamp or time -- field minutes_ :: (BeamSqlBackend be, HasSqlTime tgt) => ExtractField be tgt Double -- | Extracts the hours, minutes, or seconds from any timestamp or time -- field hour_ :: (BeamSqlBackend be, HasSqlTime tgt) => ExtractField be tgt Double -- | Extracts the given field from the target expression extract_ :: BeamSqlBackend be => ExtractField be tgt a -> QGenExpr ctxt be s tgt -> QGenExpr cxt be s a -- | A field that can be extracted from SQL expressions of type -- tgt that results in a type a, in backend -- be. newtype ExtractField be tgt a ExtractField :: Sql92ExtractFieldSyntax (BeamSqlBackendSyntax be) -> ExtractField be tgt a -- | Type-class for types that contain a time component class HasSqlTime tgt -- | Type-class for types that contain a date component class HasSqlDate tgt -- | SQL IN predicate in_ :: BeamSqlBackend be => QGenExpr context be s a -> [QGenExpr context be s a] -> QGenExpr context be s Bool infix 4 `in_` -- | SQL BETWEEN clause between_ :: BeamSqlBackend be => QGenExpr context be s a -> QGenExpr context be s a -> QGenExpr context be s a -> QGenExpr context be s Bool infix 4 `between_` -- | A QQuantified representing a SQL ANY(..) for use with -- a quantified comparison operator -- -- Accepts an explicit list of typed expressions. Use anyOf_ for a -- subquery anyIn_ :: BeamSqlBackend be => [QExpr be s a] -> QQuantified be s a -- | A QQuantified representing a SQL ANY(..) for use with -- a quantified comparison operator -- -- Accepts a subquery. Use anyIn_ for an explicit list anyOf_ :: (BeamSqlBackend be, HasQBuilder be) => Q be db (QNested s) (QExpr be (QNested s) a) -> QQuantified be s a -- | A QQuantified representing a SQL ALL(..) for use with -- a quantified comparison operator -- -- Accepts an explicit list of typed expressions. Use allOf_ for a -- subquery allIn_ :: BeamSqlBackend be => [QExpr be s a] -> QQuantified be s a -- | A QQuantified representing a SQL ALL(..) for use with -- a quantified comparison operator -- -- Accepts a subquery. Use allIn_ for an explicit list allOf_ :: (BeamSqlBackend be, HasQBuilder be) => Q be db (QNested s) (QExpr be (QNested s) a) -> QQuantified be s a -- | Convert a possibly NULL Bool to a SqlBool. fromPossiblyNullBool_ :: () => QGenExpr context be s (Maybe Bool) -> QGenExpr context be s SqlBool -- | Retrieve a SqlBool value as a potentially NULL -- Bool. This is useful if you want to get the value of a SQL -- boolean expression directly, without having to specify what to do on -- UNKNOWN. Note that both NULL and UNKNOWN -- will be returned as Nothing. possiblyNullBool_ :: () => QGenExpr context be s SqlBool -> QGenExpr context be s (Maybe Bool) -- | Return the first argument if the expression has the unknown SQL value -- See sqlBool_ for the inverse unknownAs_ :: BeamSqlBackend be => Bool -> QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | SQL IS NOT UNKNOWN operator isNotUnknown_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | SQL IS UNKNOWN operator isUnknown_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | SQL IS NOT FALSE operator isNotFalse_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | SQL IS FALSE operator isFalse_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | SQL IS NOT TRUE operator isNotTrue_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | SQL IS TRUE operator isTrue_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s Bool -- | Convert a known not null bool to a SqlBool. See -- unknownAs_ for the inverse sqlBool_ :: () => QGenExpr context syntax s Bool -> QGenExpr context syntax s SqlBool -- | A data structure representing the set to quantify a comparison -- operator over. data QQuantified be s r -- | Class for expression types or expression containers for which there is -- a notion of equality. -- -- Instances are provided to check the equality of expressions of the -- same type as well as entire Beamable types parameterized over -- QGenExpr class SqlEq (expr :: Type -> Type) a | a -> expr -- | Given two expressions, returns whether they are equal, using Haskell -- semantics (NULLs handled properly) (==.) :: SqlEq expr a => a -> a -> expr Bool -- | Given two expressions, returns whether they are not equal, using -- Haskell semantics (NULLs handled properly) (/=.) :: SqlEq expr a => a -> a -> expr Bool -- | Given two expressions, returns the SQL tri-state boolean when -- compared for equality (==?.) :: SqlEq expr a => a -> a -> expr SqlBool -- | Given two expressions, returns the SQL tri-state boolean when -- compared for inequality (/=?.) :: SqlEq expr a => a -> a -> expr SqlBool infix 4 ==. infix 4 /=. -- | Class for expression types for which there is a notion of -- quantified equality. class SqlEq expr a => SqlEqQuantified (expr :: Type -> Type) quantified a | a -> expr quantified -- | Quantified equality and inequality using SQL semantics -- (tri-state boolean) (==*.) :: SqlEqQuantified expr quantified a => a -> quantified -> expr SqlBool -- | Quantified equality and inequality using SQL semantics -- (tri-state boolean) (/=*.) :: SqlEqQuantified expr quantified a => a -> quantified -> expr SqlBool infix 4 ==*. infix 4 /=*. -- | Class for Haskell types that can be compared for equality in the given -- backend class BeamSqlBackend be => HasSqlEqualityCheck be a sqlEqE :: HasSqlEqualityCheck be a => Proxy a -> Proxy be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be sqlNeqE :: HasSqlEqualityCheck be a => Proxy a -> Proxy be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -- | Tri-state equality sqlEqTriE :: HasSqlEqualityCheck be a => Proxy a -> Proxy be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -- | Tri-state equality sqlNeqTriE :: HasSqlEqualityCheck be a => Proxy a -> Proxy be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -- | Class for Haskell types that can be compared for quantified equality -- in the given backend class HasSqlEqualityCheck be a => HasSqlQuantifiedEqualityCheck be a sqlQEqE :: HasSqlQuantifiedEqualityCheck be a => Proxy a -> Proxy be -> Maybe (BeamSqlBackendExpressionQuantifierSyntax be) -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be sqlQNeqE :: HasSqlQuantifiedEqualityCheck be a => Proxy a -> Proxy be -> Maybe (BeamSqlBackendExpressionQuantifierSyntax be) -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -> BeamSqlBackendExpressionSyntax be -- | Class for expression types or expression containers for which there is -- a notion of ordering. -- -- Instances are provided to check the ordering of expressions of the -- same type. Since there is no universal notion of ordering for an -- arbitrary number of expressions, no instance is provided for -- Beamable types. class SqlOrd (expr :: Type -> Type) e | e -> expr (<.) :: SqlOrd expr e => e -> e -> expr Bool (>.) :: SqlOrd expr e => e -> e -> expr Bool (<=.) :: SqlOrd expr e => e -> e -> expr Bool (>=.) :: SqlOrd expr e => e -> e -> expr Bool infix 4 <. infix 4 >. infix 4 <=. infix 4 >=. -- | Class for things which can be quantifiably compared. class SqlOrd expr e => SqlOrdQuantified (expr :: Type -> Type) quantified e | e -> expr quantified (<*.) :: SqlOrdQuantified expr quantified e => e -> quantified -> expr Bool (>*.) :: SqlOrdQuantified expr quantified e => e -> quantified -> expr Bool (<=*.) :: SqlOrdQuantified expr quantified e => e -> quantified -> expr Bool (>=*.) :: SqlOrdQuantified expr quantified e => e -> quantified -> expr Bool infix 4 <*. infix 4 >*. infix 4 <=*. infix 4 >=*. -- | SQL CONCAT function concat_ :: BeamSql99ConcatExpressionBackend be => [QGenExpr context be s Text] -> QGenExpr context be s Text -- | SQL % operator mod_ :: (Integral a, BeamSqlBackend be) => QGenExpr context be s a -> QGenExpr context be s a -> QGenExpr context be s a infixl 7 `mod_` -- | SQL / operator div_ :: (Integral a, BeamSqlBackend be) => QGenExpr context be s a -> QGenExpr context be s a -> QGenExpr context be s a infixl 7 `div_` -- | SQL NOT operator, but operating on SqlBool instead sqlNot_ :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool -- | SQL NOT operator not_ :: BeamSqlBackend be => QGenExpr context be s Bool -> QGenExpr context be s Bool -- | SQL99 SIMILAR TO operator similarTo_ :: (BeamSqlBackendIsString be text, BeamSql99ExpressionBackend be) => QGenExpr ctxt be s text -> QGenExpr ctxt be s text -> QGenExpr ctxt be s text infix 4 `similarTo_` -- | SQL LIKE operator like_ :: (BeamSqlBackendIsString be text, BeamSqlBackend be) => QGenExpr ctxt be s text -> QGenExpr ctxt be s text -> QGenExpr ctxt be s Bool infix 4 `like_` -- | SQL OR operator (||?.) :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool infixr 2 ||?. -- | SQL AND operator for SqlBool (&&?.) :: BeamSqlBackend be => QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool infixr 3 &&?. -- | SQL OR operator (||.) :: BeamSqlBackend be => QGenExpr context be s Bool -> QGenExpr context be s Bool -> QGenExpr context be s Bool infixr 2 ||. -- | SQL AND operator (&&.) :: BeamSqlBackend be => QGenExpr context be s Bool -> QGenExpr context be s Bool -> QGenExpr context be s Bool infixr 3 &&. -- | Phantom type representing a SQL Tri-state boolean -- true, -- false, and unknown -- -- This type has no values because it cannot be sent to or retrieved from -- the database directly. Use isTrue_, isFalse_, -- isNotTrue_, isNotFalse_, isUnknown_, -- isNotUnknown_, and unknownAs_ to retrieve the -- corresponding Bool value. data SqlBool type family QExprToIdentity x :: Type type family QExprToField x :: Type class BeamSqlBackend be => HasQBuilder be buildSqlQuery :: (HasQBuilder be, Projectible be a) => TablePrefix -> Q be db s a -> BeamSqlBackendSelectSyntax be -- | The type of queries over the database db returning results of -- type a. The s argument is a threading argument meant -- to restrict cross-usage of QGenExprs. syntax -- represents the SQL syntax that this query is building. data Q be (db :: Type -> Type -> Type) s a data QField s ty data QAssignment be s data QFieldAssignment be (tbl :: Type -> Type -> Type) a data QAggregateContext data QGroupingContext data QValueContext data QWindowingContext data QWindowFrameContext -- | The type of lifted beam expressions that will yield the haskell type -- t. -- -- context is a type-level representation of the types of -- expressions this can contain. For example, QAggregateContext -- represents expressions that may contain aggregates, and -- QWindowingContext represents expressions that may contain -- OVER. -- -- syntax is the expression syntax being built (usually a type -- that implements IsSql92ExpressionSyntax at least, but not -- always). -- -- s is a state threading parameter that prevents -- QGenExprs from incompatible sources to be combined. For -- example, this is used to prevent monadic joins from depending on the -- result of previous joins (so-called LATERAL joins). newtype QGenExpr context be s t QExpr :: (TablePrefix -> BeamSqlBackendExpressionSyntax be) -> QGenExpr context be s t -- | QGenExprs represent expressions not containing aggregates. type QExpr = QGenExpr QValueContext data QWindow be s type Projectible be = ProjectibleWithPredicate AnyType be WithExprContext BeamSqlBackendExpressionSyntax' be -- | Like tableLenses but for types that are instances of -- Database. Instead of pattern matching on LensFor, -- pattern match on TableLens. dbLenses :: (Generic (db (TableLens f db)), Generic (db f), GDatabaseLenses (db f) (Rep (db f)) (Rep (db (TableLens f db)))) => db (TableLens f db) -- | Automatically deduce lenses for a table over any column tag. lenses at -- global level by doing a top-level pattern match on tableLenses, -- replacing every column in the pattern with `LensFor -- nameOfLensForField'. The lenses are generated per-column, not -- per field in the record. Thus if you have nested Beamable -- types, lenses are generated for each nested field. -- -- For example, -- --
-- data AuthorT f = AuthorT
-- { _authorEmail :: Columnar f Text
-- , _authorFirstName :: Columnar f Text
-- , _authorLastName :: Columnar f Text }
-- deriving Generic
--
-- data BlogPostT f = BlogPost
-- { _blogPostSlug :: Columnar f Text
-- , _blogPostBody :: Columnar f Text
-- , _blogPostDate :: Columnar f UTCTime
-- , _blogPostAuthor :: PrimaryKey AuthorT f
-- , _blogPostTagline :: Columnar f (Maybe Text) }
-- deriving Generic
-- instance Table BlogPostT where
-- data PrimaryKey BlogPostT f = BlogPostId (Columnar f Text)
-- primaryKey = BlogPostId . _blogPostSlug
-- instance Table AuthorT where
-- data PrimaryKey AuthorT f = AuthorId (Columnar f Text)
-- primaryKey = AuthorId . _authorEmail
--
--
-- -- BlogPost (LensFor blogPostSlug -- (LensFor blogPostBody) -- (LensFor blogPostDate) -- (AuthorId (LensFor blogPostAuthorEmail)) -- (LensFor blogPostTagLine) = tableLenses ---- -- Note: In order to have GHC deduce the right type, you will need to -- turn off the monomorphism restriction. This is a part of the Haskell -- standard that specifies that top-level definitions must be inferred to -- have a monomorphic type. However, lenses need a polymorphic type to -- work properly. You can turn off the monomorphism restriction by -- enabling the NoMonomorphismRestriction extension. You can do -- this per-file by using the {--} pragma at the top of the file. You can -- also pass the -XNoMonomorphismRestriction command line flag -- to GHC during compilation. tableLenses :: (lensType ~ Lenses t f, Generic (t lensType), Generic (t f), GTableLenses t f (Rep (t f)) (Rep (t lensType))) => t (Lenses t f) newtype TableLens (f :: k -> Type) (db :: k -> Type -> Type) (x :: k) :: forall k. () => k -> Type -> k -> Type -> Type -> k -> Type TableLens :: Lens' (db f) (f x) -> TableLens -- | Return a TableSettings for the appropriate table type -- where each column has been given its default name. See the -- manual for information on the default naming convention. defTblFieldSettings :: (Generic (TableSettings table), GDefaultTableFieldSettings (Rep (TableSettings table) ())) => TableSettings table -- | Synonym for primaryKey pk :: Table t => t f -> PrimaryKey t f -- | Van Laarhoven lens to retrieve or set the field name from a -- TableField. fieldName :: () => Lens' (TableField table ty) Text -- | A field modification to rename the field. Also offered under the -- IsString instance for 'FieldModification (TableField tbl) a' -- for convenience. fieldNamed :: () => Text -> FieldModification (TableField tbl) a -- | Construct an EntityModification to rename the fields of a -- TableEntity modifyTableFields :: () => tbl (FieldModification (TableField tbl)) -> EntityModification (DatabaseEntity be db) be (TableEntity tbl) -- | Change the entity name without consulting the beam-assigned one setEntityName :: IsDatabaseEntity be entity => Text -> EntityModification (DatabaseEntity be db) be entity -- | Construct an EntityModification to rename any database entity modifyEntityName :: IsDatabaseEntity be entity => (Text -> Text) -> EntityModification (DatabaseEntity be db) be entity -- | Provide an EntityModification for TableEntitys. Allows -- you to modify the name of the table and provide a modification for -- each field in the table. See the examples for -- withDbModification for more. modifyTable :: (Beamable tbl, Table tbl) => (Text -> Text) -> tbl (FieldModification (TableField tbl)) -> EntityModification (DatabaseEntity be db) be (TableEntity tbl) -- | Modify a table according to the given field modifications. Invoked by -- modifyTable to apply the modification in the database. Not used -- as often in user code, but provided for completeness. withTableModification :: Beamable tbl => tbl (FieldModification f) -> tbl f -> tbl f -- | Modify a database according to a given modification. Most useful for -- DatabaseSettings to change the name mappings of tables and -- fields. For example, you can use this to modify the default names of a -- table -- --
-- db :: DatabaseSettings MyDb
-- db = defaultDbSettings `withDbModification`
-- dbModification {
-- -- Change default name "table1" to "Table_1". Change the name of "table1Field1" to "first_name"
-- table1 = modifyTable (\_ -> "Table_1") (tableModification { table1Field1 = "first_name" }
-- }
--
withDbModification :: Database be db => db (entity be db) -> DatabaseModification (entity be db) be db -> db (entity be db)
-- | Return a table modification (for use with modifyTable) that
-- does nothing. Useful if you only want to change the table name, or if
-- you only want to modify a few fields.
--
-- For example,
--
--
-- tableModification { field1 = "Column1" }
--
--
-- is a table modification (where 'f ~ TableField tbl') that changes the
-- column name of field1 to Column1.
tableModification :: Beamable tbl => tbl (FieldModification f)
-- | Return a DatabaseModification that does nothing. This is useful
-- if you only want to rename one table. You can do
--
--
-- dbModification { tbl1 = modifyTable (\oldNm -> "NewTableName") tableModification }
--
dbModification :: Database be db => DatabaseModification f be db
-- | Automatically provide names for tables, and descriptions for tables
-- (using defTblFieldSettings). Your database must implement
-- Generic, and must be auto-derivable. For more information on
-- name generation, see the manual
defaultDbSettings :: (Generic (DatabaseSettings be db), GAutoDbSettings (Rep (DatabaseSettings be db) ())) => DatabaseSettings be db
-- | Allows introspection into database types.
--
-- All database types must be of kind '(* -> *) -> *'. If the type
-- parameter is named f, each field must be of the type of
-- f applied to some type for which an IsDatabaseEntity
-- instance exists.
--
-- The be type parameter is necessary so that the compiler can
-- ensure that backend-specific entities only work on the proper backend.
--
-- Entities are documented under the corresponding section and in
-- the manual
class Database be (db :: Type -> Type -> Type)
-- | A helper data type that lets you modify a database schema. Converts
-- all entities in the database into functions from that entity to
-- itself.
type DatabaseModification (f :: Type -> Type) be (db :: Type -> Type -> Type) = db EntityModification f be
-- | A newtype wrapper around 'f e -> f e' (i.e., an endomorphism
-- between entity types in f). You usually want to use
-- modifyTable or another function to contstruct these for you.
data EntityModification (f :: Type -> Type) be e
-- | A newtype wrapper around 'Columnar f a -> Columnar f ' (i.e., an
-- endomorphism between Columnars over f). You usually
-- want to use fieldNamed or the IsString instance to
-- rename the field, when 'f ~ TableField'
data FieldModification (f :: Type -> Type) a
-- | An entity tag for tables. See the documentation for Table or
-- consult the manual for more.
data TableEntity (tbl :: Type -> Type -> Type)
-- | Represents a meta-description of a particular entityType. Mostly, a
-- wrapper around 'DatabaseEntityDescriptor be entityType', but carries
-- around the IsDatabaseEntity dictionary.
data DatabaseEntity be (db :: Type -> Type -> Type) entityType
-- | When parameterized by this entity tag, a database type will hold
-- meta-information on the Haskell mappings of database entities. Under
-- the hood, each entity type is transformed into its
-- DatabaseEntityDescriptor type. For tables this includes the
-- table name as well as the corresponding TableSettings, which
-- provides names for each column.
type DatabaseSettings be (db :: Type -> Type -> Type) = db DatabaseEntity be db
data Lenses (t :: Type -> Type -> Type) (f :: Type -> Type) x
data LensFor t x
[LensFor] :: forall t x. Generic t => Lens' t x -> LensFor t x
-- | A type family that we use to "tag" columns in our table datatypes.
--
-- This is what allows us to use the same table type to hold table data,
-- describe table settings, derive lenses, and provide expressions.
--
-- The basic rules are
--
-- -- Columnar Identity x = x ---- -- Thus, any Beam table applied to Identity will yield a -- simplified version of the data type, that contains just what you'd -- expect. -- -- The Nullable type is used when referencing PrimaryKeys -- that we want to include optionally. For example, if we have a table -- with a PrimaryKey, like the following -- --
-- data BeamTableT f = BeamTableT
-- { _refToAnotherTable :: PrimaryKey AnotherTableT f
-- , ... }
--
--
-- we would typically be required to provide values for the
-- PrimaryKey embedded into BeamTableT. We can use
-- Nullable to lift this constraint.
--
--
-- data BeamTableT f = BeamTableT
-- { _refToAnotherTable :: PrimaryKey AnotherTableT (Nullable f)
-- , ... }
--
--
-- Now we can use justRef and nothingRef to refer to
-- this table optionally. The embedded PrimaryKey in
-- _refToAnotherTable automatically has its fields converted
-- into Maybe using Nullable.
--
-- The last Columnar rule is
--
-- -- Columnar f x = f x ---- -- Use this rule if you'd like to parameterize your table type over any -- other functor. For example, this is used in the query modules to write -- expressions such as 'TableT QExpr', which returns a table whose fields -- have been turned into query expressions. -- -- The other rules are used within Beam to provide lenses and to expose -- the inner structure of the data type. type family Columnar (f :: Type -> Type) x :: Type -- | A short type-alias for Columnar. May shorten your schema -- definitions type C (f :: Type -> Type) a = Columnar f a -- | If you declare a function 'Columnar f a -> b' and try to constrain -- your function by a type class for f, GHC will complain, -- because f is ambiguous in 'Columnar f a'. For example, -- 'Columnar Identity (Maybe a) ~ Maybe a' and 'Columnar (Nullable -- Identity) a ~ Maybe a', so given a type 'Columnar f a', we cannot know -- the type of f. -- -- Thus, if you need to know f, you can instead use -- Columnar'. Since its a newtype, it carries around the -- f paramater unambiguously. Internally, it simply wraps -- 'Columnar f a' data Columnar' (f :: Type -> Type) a -- | Metadata for a field of type ty in table. -- -- Essentially a wrapper over the field name, but with a phantom type -- parameter, so that it forms an appropriate column tag. -- -- Usually you use the defaultDbSettings function to generate an -- appropriate naming convention for you, and then modify it with -- withDbModification if necessary. Under this scheme, the field n -- be renamed using the IsString instance for TableField, -- or the fieldNamed function. data TableField (table :: Type -> Type -> Type) ty -- | Represents a table that contains metadata on its fields. In -- particular, each field of type 'Columnar f a' is transformed into -- 'TableField table a'. You can get or update the name of each field by -- using the fieldName lens. type TableSettings (table :: Type -> Type -> Type) = table TableField table -- | The regular Haskell version of the table. Equivalent to 'tbl Identity' type HaskellTable (table :: Type -> Type -> Type) = table Identity -- | The big Kahuna! All beam tables implement this class. -- -- The kind of all table types is '(* -> *) -> *'. This is because -- all table types are actually table type constructors. Every -- table type takes in another type constructor, called the column -- tag, and uses that constructor to instantiate the column types. -- See the documentation for Columnar. -- -- This class is mostly Generic-derivable. You need only specify a type -- for the table's primary key and a method to extract the primary key -- given the table. -- -- An example table: -- --
-- data BlogPostT f = BlogPost
-- { _blogPostSlug :: Columnar f Text
-- , _blogPostBody :: Columnar f Text
-- , _blogPostDate :: Columnar f UTCTime
-- , _blogPostAuthor :: PrimaryKey AuthorT f
-- , _blogPostTagline :: Columnar f (Maybe Text)
-- , _blogPostImageGallery :: PrimaryKey ImageGalleryT (Nullable f) }
-- deriving Generic
-- instance Beamable BlogPostT
-- instance Table BlogPostT where
-- data PrimaryKey BlogPostT f = BlogPostId (Columnar f Text) deriving Generic
-- primaryKey = BlogPostId . _blogPostSlug
-- instance Beamable (PrimaryKey BlogPostT)
--
--
-- We can interpret this as follows:
--
--
-- data MyTable f = MyTable
-- { nullableRef :: PrimaryKey AnotherTable (Nullable f)
-- , ... }
-- deriving (Generic, Typeable)
--
--
-- See Columnar for more information.
data Nullable (c :: Type -> Type) x
-- | Update a QField or Beamable type containing
-- QFields with the given QGenExpr or Beamable type
-- containing QGenExpr
(<-.) :: SqlUpdatable be s lhs rhs => lhs -> rhs -> QAssignment be s
infix 4 <-.
-- | Transaction option: provide WithTx to wrap operations in BEGIN/COMMIT,
-- or NoTx to skip that.
data TxOpt
NoTx :: TxOpt
WithTx :: TxOpt
-- | Result of a select operation. This will either succeed with a QSimply,
-- or fail with a QError (probably then an error in the db connection or
-- table definitions).
data QueryResult a
QSimply :: a -> QueryResult a
QError :: SqlError -> QueryResult a
-- | The result of a select, insert, update, or delete operation. This adds
-- a constraint error to the QueryResult, making it nicer to
-- filter out conflicts when handling errors.
data ExecResult a
ESimply :: a -> ExecResult a
EConstraint :: SqlError -> ConstraintViolation -> ExecResult a
EError :: SqlError -> ExecResult a
runSelectReturningList :: (ReadOnlyM m, FromBackendRow Postgres a) => Sel a -> m [a]
runSelectReturningOne :: (ReadOnlyM m, FromBackendRow Postgres a) => Sel a -> m (Maybe a)
-- | Run one or many Beam runSelectReturningList or
-- runSelectReturningOne operation(s) against a view's
-- ReadOnlyPool.
query :: ListContains n ReadOnlyPool xs => TxOpt -> RoPg a -> TsActionCtxT lts xs sessdata (QueryResult a)
-- | Run a single Beam select, returning a single (Maybe) value
queryMaybe :: (ListContains n ReadOnlyPool xs, FromBackendRow Postgres a) => Sel a -> TsActionCtxT lts xs sessdata (QueryResult (Maybe a))
-- | Run a single Beam select, returning a list of values
queryList :: (ListContains n ReadOnlyPool xs, FromBackendRow Postgres a) => Sel a -> TsActionCtxT lts xs sessdata (QueryResult [a])
-- | Run any arbitrary Pg monad in the context of a view, returning
-- an ExecResult
execute :: ListContains n ReadWritePool xs => TxOpt -> Pg a -> TsActionCtxT lts xs sessdata (ExecResult a)
instance GHC.Show.Show a => GHC.Show.Show (TsWeb.Db.ExecResult a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (TsWeb.Db.ExecResult a)
instance GHC.Show.Show a => GHC.Show.Show (TsWeb.Db.QueryResult a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (TsWeb.Db.QueryResult a)
instance GHC.Show.Show TsWeb.Db.TxOpt
instance GHC.Enum.Bounded TsWeb.Db.TxOpt
instance GHC.Enum.Enum TsWeb.Db.TxOpt
instance GHC.Classes.Ord TsWeb.Db.TxOpt
instance GHC.Classes.Eq TsWeb.Db.TxOpt
instance GHC.Base.Monad TsWeb.Db.RoPg
instance GHC.Base.Applicative TsWeb.Db.RoPg
instance GHC.Base.Functor TsWeb.Db.RoPg
instance TsWeb.Db.ReadOnlyM TsWeb.Db.RoPg
instance TsWeb.Db.ReadOnlyM Database.Beam.Postgres.Connection.Pg