-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Monad classes for running queries with Persistent and Esqueleto -- -- This package introduces two classes: MonadSqlBackend for monadic -- contexts in which a SqlBackend is available, and MonadSqlTx for -- contexts in which we can execute a SQL transaction. -- -- Additionally, this package provides variants of query-running -- utilities from Persistent and Esqueleto which are concretized to use -- SqlBackend, generalized to a MonadSqlBackend m constraint rather than -- "ReaderT backend", and wrapped in checkpointCallStack so that -- exceptions will include call stacks. @package persistent-sql-lifted @version 0.3.0.0 module Database.Persist.Sql.Lifted.Expression.Bool not_ :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -- | This operator translates to the SQL operator AND. -- -- Example: -- --
--   where_ $
--           user ^. UserName ==. val Matt
--       &&. user ^. UserAge >=. val 21
--   
(&&.) :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -> SqlExpr (Value Bool) infixr 3 &&. -- | This operator translates to the SQL operator AND. -- -- Example: -- --
--   where_ $
--           user ^. UserName ==. val Matt
--       ||. user ^. UserName ==. val John
--   
(||.) :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -> SqlExpr (Value Bool) infixr 2 ||. module Database.Persist.Sql.Lifted.Expression.Case -- | CASE statement. For example: -- --
--   select $
--   return $
--   case_
--      [ when_
--          (exists $
--          from $ \p -> do
--          where_ (p ^. PersonName ==. val "Mike"))
--        then_
--          (subSelect $
--          from $ \v -> do
--          let sub =
--                  from $ \c -> do
--                  where_ (c ^. PersonName ==. val "Mike")
--                  return (c ^. PersonFavNum)
--          where_ (just (v ^. PersonFavNum) >. subSelect sub)
--          return $ count (v ^. PersonName) +. val (1 :: Int)) ]
--      (else_ $ val (-1))
--   
-- -- This query is a bit complicated, but basically it checks if a person -- named "Mike" exists, and if that person does, run the -- subquery to find out how many people have a ranking (by Fav Num) -- higher than "Mike". -- -- NOTE: There are a few things to be aware about this statement. -- -- case_ :: PersistField a => [(SqlExpr (Value Bool), SqlExpr (Value a))] -> SqlExpr (Value a) -> SqlExpr (Value a) -- | Syntax sugar for case_. when_ :: expr (Value Bool) -> () -> expr a -> (expr (Value Bool), expr a) -- | Syntax sugar for case_. then_ :: () -- | Syntax sugar for case_. else_ :: expr a -> expr a module Database.Persist.Sql.Lifted.Expression.Comparison -- | This operator produces the SQL operator =, which is used to -- compare values for equality. -- -- Example: -- --
--   query :: UserId -> SqlPersistT IO [Entity User]
--   query userId = select $ do
--       user <- from $ table @User
--       where_ (user ^. UserId ==. val userId)
--       pure user
--   
-- -- This would generate the following SQL: -- --
--   SELECT user.*
--   FROM user
--   WHERE user.id = ?
--   
(==.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 ==. -- | This operator translates to the SQL operator !=. -- -- Example: -- --
--   where_ $ user ^. UserName !=. val Bob
--   
(!=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 !=. -- | This operator translates to the SQL operator >=. -- -- Example: -- --
--   where_ $ user ^. UserAge >=. val 21
--   
(>=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 >=. -- | This operator translates to the SQL operator >. -- -- Example: -- --
--   where_ $ user ^. UserAge >. val 20
--   
(>.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 >. -- | This operator translates to the SQL operator <=. -- -- Example: -- --
--   where_ $ val 21 <=. user ^. UserAge
--   
(<=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 <=. -- | This operator translates to the SQL operator <. -- -- Example: -- --
--   where_ $ val 20 <. user ^. UserAge
--   
(<.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 <. -- | a between (b, c) translates to the SQL expression -- a >= b AND a <= c. It does not use a SQL -- BETWEEN operator. -- -- @since: 3.1.0 between :: PersistField a => SqlExpr (Value a) -> (SqlExpr (Value a), SqlExpr (Value a)) -> SqlExpr (Value Bool) module Database.Persist.Sql.Lifted.Expression.Constant -- | Lift a constant value from Haskell-land to the query. val :: PersistField typ => typ -> SqlExpr (Value typ) module Database.Persist.Sql.Lifted.Expression.Count -- | COUNT. count :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a) -- | COUNT(*) value. countRows :: Num a => SqlExpr (Value a) -- | COUNT(DISTINCT x). countDistinct :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a) module Database.Persist.Sql.Lifted.Expression.Exists -- | EXISTS operator. For example: -- --
--   select $
--   from $ \person -> do
--   where_ $ exists $
--            from $ \post -> do
--            where_ (post ^. BlogPostAuthorId ==. person ^. PersonId)
--   return person
--   
exists :: SqlQuery () -> SqlExpr (Value Bool) -- | NOT EXISTS operator. notExists :: SqlQuery () -> SqlExpr (Value Bool) module Database.Persist.Sql.Lifted.Expression.Insert -- | Apply a PersistField constructor to SqlExpr Value -- arguments. (<#) :: (a -> b) -> SqlExpr (Value a) -> SqlExpr (Insertion b) -- | Apply extra SqlExpr Value arguments to a PersistField -- constructor (<&>) :: SqlExpr (Insertion (a -> b)) -> SqlExpr (Value a) -> SqlExpr (Insertion b) module Database.Persist.Sql.Lifted.Expression.Key -- | Convert an entity's key into another entity's. -- -- This function is to be used when you change an entity's Id to -- be that of another entity. For example: -- --
--   Bar
--     barNum Int
--   Foo
--     bar BarId
--     fooNum Int
--     Primary bar
--   
-- -- In this example, Bar is said to be the BaseEnt(ity), and Foo the -- child. To model this in Esqueleto, declare: -- --
--   instance ToBaseId Foo where
--     type BaseEnt Foo = Bar
--     toBaseIdWitness barId = FooKey barId
--   
-- -- Now you're able to write queries such as: -- --
--   select $
--   from $ (bar `InnerJoin` foo) -> do
--   on (toBaseId (foo ^. FooId) ==. bar ^. BarId)
--   return (bar, foo)
--   
-- -- Note: this function may be unsafe to use in conditions not like the -- one of the example above. toBaseId :: ToBaseId ent => SqlExpr (Value (Key ent)) -> SqlExpr (Value (Key (BaseEnt ent))) -- | Class that enables one to use toBaseId to convert an entity's -- key on a query into another (cf. toBaseId). class () => ToBaseId ent where { -- | e.g. type BaseEnt MyBase = MyChild type family BaseEnt ent; } -- | Convert from the key of the BaseEnt(ity) to the key of the child -- entity. This function is not actually called, but that it typechecks -- proves this operation is safe. toBaseIdWitness :: ToBaseId ent => Key (BaseEnt ent) -> Key ent module Database.Persist.Sql.Lifted.Expression.List -- | IN operator. For example if you want to select all -- Persons by a list of IDs: -- --
--   SELECT *
--   FROM Person
--   WHERE Person.id IN (?)
--   
-- -- In esqueleto, we may write the same query above as: -- --
--   select $
--   from $ \person -> do
--   where_ $ person ^. PersonId `in_` valList personIds
--   return person
--   
-- -- Where personIds is of type [Key Person]. in_ :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> SqlExpr (Value Bool) -- | NOT IN operator. notIn :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> SqlExpr (Value Bool) -- | Execute a subquery SELECT in an SqlExpression. Returns a list -- of values. subList_select :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a) -- | Lift a list of constant value from Haskell-land to the query. valList :: PersistField typ => [typ] -> SqlExpr (ValueList typ) -- | Same as just but for ValueList. Most of the time you -- won't need it, though, because you can use just from inside -- subList_select or Just from inside valList. justList :: SqlExpr (ValueList typ) -> SqlExpr (ValueList (Maybe typ)) module Database.Persist.Sql.Lifted.Expression.Maybe -- | IS NULL comparison. -- -- For IS NOT NULL, you can negate this with not_, as in -- not_ (isNothing (person ^. PersonAge)) -- -- Warning: Persistent and Esqueleto have different behavior for != -- Nothing: -- -- TODO: table -- -- In SQL, = NULL and != NULL return NULL instead of -- true or false. For this reason, you very likely do not want to use -- !=. Nothing in Esqueleto. You may find these -- hlint rules helpful to enforce this: -- --
--   - error: {lhs: v Database.Esqueleto.==. Database.Esqueleto.nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing}
--   - error: {lhs: v Database.Esqueleto.==. Database.Esqueleto.val Nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing}
--   - error: {lhs: v Database.Esqueleto.!=. Database.Esqueleto.nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing}
--   - error: {lhs: v Database.Esqueleto.!=. Database.Esqueleto.val Nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing}
--   
isNothing :: PersistField typ => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool) -- | An alias for isNothing that avoids clashing with the function -- from Data.Maybe isNothing. isNothing_ :: PersistField typ => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool) -- | Analogous to Just, promotes a value of type typ into -- one of type Maybe typ. It should hold that val . -- Just === just . val. -- -- This function will try not to produce a nested Maybe. This is -- in accord with how SQL represents NULL. That means that -- just . just = just. This behavior was -- changed in v3.6.0.0. If you want to produce nested Maybe, see -- just'. just :: NullableFieldProjection typ typ' => SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ')) -- | NULL value. nothing :: SqlExpr (Value (Maybe typ)) -- | Join nested Maybes in a Value into one. This is useful -- when calling aggregate functions on nullable fields. -- -- As of v3.6.0.0, this function will attempt to work on both -- SqlExpr (Value (Maybe a)) as well as -- SqlExpr (Value (Maybe (Maybe a))) -- inputs to make transitioning to NullableFieldProjection easier. -- This may make type inference worse in some cases. If you want the -- monomorphic variant, see joinV' joinV :: NullableFieldProjection typ typ' => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value (Maybe typ')) -- | COALESCE function. Evaluates the arguments in order and -- returns the value of the first non-NULL SqlExpression, or NULL -- (Nothing) otherwise. Some RDBMSs (such as SQLite) require at least two -- arguments; please refer to the appropriate documentation. coalesce :: (PersistField a, NullableFieldProjection a a') => [SqlExpr (Value (Maybe a))] -> SqlExpr (Value (Maybe a')) -- | Like coalesce, but takes a non-nullable SqlExpression placed -- at the end of the SqlExpression list, which guarantees a non-NULL -- result. coalesceDefault :: PersistField a => [SqlExpr (Value (Maybe a))] -> SqlExpr (Value a) -> SqlExpr (Value a) module Database.Persist.Sql.Lifted.Expression.Number -- | This operator translates to the SQL operator +. -- -- This does not require or assume anything about the SQL values. -- Interpreting what +. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge +. val 10
--   
(+.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 6 +. -- | This operator translates to the SQL operator -. -- -- This does not require or assume anything about the SQL values. -- Interpreting what -. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge -. val 10
--   
(-.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 6 -. -- | This operator translates to the SQL operator /. -- -- This does not require or assume anything about the SQL values. -- Interpreting what /. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge /. val 10
--   
(/.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 7 /. -- | This operator translates to the SQL operator *. -- -- This does not require or assume anything about the SQL values. -- Interpreting what *. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge *. val 10
--   
(*.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 7 *. round_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) ceiling_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) floor_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) min_ :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value (Maybe (Nullable a))) max_ :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value (Maybe (Nullable a))) sum_ :: (PersistField a, PersistField b) => SqlExpr (Value a) -> SqlExpr (Value (Maybe b)) avg_ :: (PersistField a, PersistField b) => SqlExpr (Value a) -> SqlExpr (Value (Maybe b)) -- | Allow a number of one type to be used as one of another type via an -- implicit cast. An explicit cast is not made, this function changes -- only the types on the Haskell side. -- -- Caveat: Trying to use castNum from Double to -- Int will not result in an integer, the original fractional -- number will still be used! Use round_, ceiling_ or -- floor_ instead. -- -- Safety: This operation is mostly safe due to the Num -- constraint between the types and the fact that RDBMSs usually allow -- numbers of different types to be used interchangeably. However, there -- may still be issues with the query not being accepted by the RDBMS or -- persistent not being able to parse it. castNum :: (Num a, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) -- | Same as castNum, but for nullable values. castNumM :: (Num a, Num b) => SqlExpr (Value (Maybe a)) -> SqlExpr (Value (Maybe b)) module Database.Persist.Sql.Lifted.Expression.OrderBy -- | Ascending order of this field or SqlExpression. asc :: PersistField a => SqlExpr (Value a) -> SqlExpr OrderBy -- | Descending order of this field or SqlExpression. desc :: PersistField a => SqlExpr (Value a) -> SqlExpr OrderBy module Database.Persist.Sql.Lifted.Expression.Projection -- | Project a field of an entity. (^.) :: forall typ val. (PersistEntity val, PersistField typ) => SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ) infixl 9 ^. -- | Project an EntityField of a nullable entity. The result type -- will be Nullable, meaning that nested Maybe won't be -- produced here. -- -- As of v3.6.0.0, this will attempt to combine nested Maybe. If -- you want to keep nested Maybe, then see ??.. (?.) :: (PersistEntity val, PersistField typ) => SqlExpr (Maybe (Entity val)) -> EntityField val typ -> SqlExpr (Value (Maybe (Nullable typ))) infixl 9 ?. module Database.Persist.Sql.Lifted.Expression.String -- | LOWER function. lower_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | UPPER function. @since 3.3.0 upper_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | TRIM function. @since 3.3.0 trim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | LTRIM function. @since 3.3.0 ltrim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | RTRIM function. @since 3.3.0 rtrim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | LENGTH function. @since 3.3.0 length_ :: (SqlString s, Num a) => SqlExpr (Value s) -> SqlExpr (Value a) -- | LEFT function. @since 3.3.0 left_ :: (SqlString s, Num a) => (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s) -- | RIGHT function. @since 3.3.0 right_ :: (SqlString s, Num a) => (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s) -- | LIKE operator. like :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool) infixr 2 `like` -- | ILIKE operator (case-insensitive LIKE). -- -- Supported by PostgreSQL only. Deprecated in version 3.6.0 in favor of -- the version available from Database.Esqueleto.PostgreSQL. ilike :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool) infixr 2 `ilike` -- | The string %. May be useful while using like -- and concatenation (concat_ or ++., depending on your -- database). Note that you always have to type the parenthesis, for -- example: -- --
--   name `like` (%) ++. val "John" ++. (%)
--   
(%) :: SqlString s => SqlExpr (Value s) -- | The CONCAT function with a variable number of parameters. -- Supported by MySQL and PostgreSQL. SQLite supports this in versions -- after 3.44.0, and persistent-sqlite supports this in versions -- 2.13.3.0 and after. concat_ :: SqlString s => [SqlExpr (Value s)] -> SqlExpr (Value s) -- | The || string concatenation operator (named after Haskell's -- ++ in order to avoid naming clash with ||.). -- -- Supported by SQLite and PostgreSQL. -- -- MySQL support requires setting the SQL mode to -- PIPES_AS_CONCAT or ANSI - see this StackOverflow -- answer. (++.) :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s) infixr 5 ++. -- | Cast a string type into Text. This function is very useful if -- you want to use newtypes, or if you want to apply functions -- such as like to strings of different types. -- -- Safety: This is a slightly unsafe function, especially if you -- have defined your own instances of SqlString. Also, since -- Maybe is an instance of SqlString, it's possible to turn -- a nullable value into a non-nullable one. Avoid using this function if -- possible. castString :: (SqlString s, SqlString r) => SqlExpr (Value s) -> SqlExpr (Value r) module Database.Persist.Sql.Lifted.Expression.SubSelect -- | Execute a subquery SELECT in a SqlExpr. The query -- passed to this function will only return a single result - it has a -- LIMIT 1 passed in to the query to make it safe, and the -- return type is Maybe to indicate that the subquery might result -- in 0 rows. -- -- If you find yourself writing joinV . subSelect, -- then consider using subSelectMaybe. -- -- If you're performing a countRows, then you can use -- subSelectCount which is safe. -- -- If you know that the subquery will always return exactly one row (eg a -- foreign key constraint guarantees that you'll get exactly one row), -- then consider subSelectUnsafe, along with a comment explaining -- why it is safe. subSelect :: (PersistField a, NullableFieldProjection a a') => SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value (Maybe a')) -- | Execute a subquery SELECT in a SqlExpr. This function -- is a shorthand for the common joinV . subSelect -- idiom, where you are calling subSelect on an expression that -- would be Maybe already. -- -- As an example, you would use this function when calling sum_ or -- max_, which have Maybe in the result type (for a 0 row -- query). subSelectMaybe :: PersistField a => SqlQuery (SqlExpr (Value (Maybe a))) -> SqlExpr (Value (Maybe a)) -- | Performs a COUNT of the given query in a subSelect -- manner. This is always guaranteed to return a result value, and is -- completely safe. subSelectCount :: (Num a, PersistField a) => SqlQuery ignored -> SqlExpr (Value a) -- | Performs a sub-select using the given foreign key on the entity. This -- is useful to extract values that are known to be present by the -- database schema. -- -- As an example, consider the following persistent definition: -- --
--   User
--     profile ProfileId
--   
--   Profile
--     name    Text
--   
-- -- The following query will return the name of the user. -- --
--   getUserWithName =
--       select $
--       from $ user ->
--       pure (user, subSelectForeign user UserProfile (^. ProfileName)
--   
subSelectForeign :: (BackendCompatible SqlBackend (PersistEntityBackend val1), PersistEntity val1, PersistEntity val2, PersistField a) => SqlExpr (Entity val2) -> EntityField val2 (Key val1) -> (SqlExpr (Entity val1) -> SqlExpr (Value a)) -> SqlExpr (Value a) -- | Execute a subquery SELECT in a SqlExpr that returns a -- list. This is an alias for subList_select and is provided for -- symmetry with the other safe subselect functions. subSelectList :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a) -- | Execute a subquery SELECT in a SqlExpr. This function -- is unsafe, because it can throw runtime exceptions in two cases: -- --
    --
  1. If the query passed has 0 result rows, then it will return a -- NULL value. The persistent parsing operations will -- fail on an unexpected NULL.
  2. --
  3. If the query passed returns more than one row, then the SQL engine -- will fail with an error like "More than one row returned by a subquery -- used as an expression".
  4. --
-- -- This function is safe if you guarantee that exactly one row will be -- returned, or if the result already has a Maybe type for some -- reason. -- -- For variants with the safety encoded already, see subSelect and -- subSelectMaybe. For the most common safe use of this, see -- subSelectCount. subSelectUnsafe :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a) module Database.Persist.Sql.Lifted.Expression.Table -- | Get the first table of a given type from a chain of tables joined with -- (:&). -- -- This can make it easier to write queries with a large number of join -- clauses: -- --
--   select $ do
--   (people :& followers :& blogPosts) <-
--       from $ table @Person
--       `innerJoin` table @Follow
--       `on` (\(person :& follow) ->
--               person ^. PersonId ==. follow ^. FollowFollowed)
--       `innerJoin` table @BlogPost
--       `on` (\((getTable @Follow -> follow) :& blogPost) ->
--               blogPost ^. BlogPostAuthorId ==. follow ^. FollowFollower)
--   where_ (people1 ^. PersonName ==. val "John")
--   pure (followers, people2)
--   
-- -- This example is a bit trivial, but once you've joined five or six -- tables it becomes enormously helpful. The above example uses a -- ViewPattern to call the function and assign the variable -- directly, but you can also imagine it being written like this: -- --
--   `on` (\(prev :& blogPost) ->
--           let
--               follow = getTable @Follow prev
--            in
--               blogPost ^. BlogPostAuthorId ==. follow ^. FollowFollower)
--   
-- -- This function will pluck out the first table that matches the applied -- type, so if you join on the same table multiple times, it will always -- select the first one provided. -- -- The (:&) operator associates so that the left hand side can -- be a wildcard for an arbitrary amount of nesting, and the "most -- recent" or "newest" table in a join sequence is always available on -- the rightmost - so (prev :& bar) is a pattern that -- matches bar table (the most recent table added) and -- prev tables (all prior tables in the join match). -- -- By calling getTable on the prev, you can select -- exactly the table you want, allowing you to omit a large number of -- spurious pattern matches. Consider a query that does several LEFT -- JOIN on a first table: -- --
--   SELECT *
--   FROM person
--   LEFT JOIN car
--     ON person.id = car.person_id
--   LEFT JOIN bike
--     ON person.id = bike.person_id
--   LEFT JOIN food
--     ON person.id = food.person_id
--   LEFT JOIN address
--     ON person.id = address.person_id
--   
-- -- The final on clause in esqueleto would look like this: -- --
--   `on` do
--       \(person :& _car :& _bike :& _food :& address) ->
--           person.id ==. address.personId
--   
-- -- First, we can change it to a prev :& newest match. We can -- do this because of the operator associativity. This is kind of like -- how a list : operator associates, but in the other direction: -- a : (b : c) = a : b : c. -- --
--   `on` do
--       \(prev :& address) ->
--           let (person :& _car :& _bike :& _food) = prev
--            in person.id ==. address.personId
--   
-- -- Then, we can use getTable to select the Person table -- directly, instead of pattern matching manually. -- --
--   `on` do
--       \(prev :& address) ->
--           let person = getTable @Person prev
--            in person.id ==. address.personId
--   
-- -- Finally, we can use a ViewPattern language extension to -- "inline" the access. -- --
--   `on` do
--       \((getTable @Person -> person) :& address) ->
--          person.id ==. address.personId
--   
-- -- With this form, you do not need to be concerned about the number and -- wildcard status of tables that do not matter to the specific -- ON clause. getTable :: GetFirstTable (SqlExpr (Entity t)) ts => ts -> SqlExpr (Entity t) -- | A variant of getTable that operates on possibly-null entities. getTableMaybe :: GetFirstTable (SqlExpr (Maybe (Entity t))) ts => ts -> SqlExpr (Maybe (Entity t)) module Database.Persist.Sql.Lifted.Expression.Type -- | An expression on the SQL backend. -- -- Raw expression: Contains a SqlExprMeta and a function for -- building the expr. It recieves a parameter telling it whether it is in -- a parenthesized context, and takes information about the SQL -- connection (mainly for escaping names) and returns both an string -- (Builder) and a list of values to be interpolated by the SQL -- backend. data () => SqlExpr a module Database.Persist.Sql.Lifted.Expression.Update (=.) :: (PersistEntity val, PersistField typ) => EntityField val typ -> SqlExpr (Value typ) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 =. (+=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 +=. (-=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 -=. (*=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 *=. (/=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 /=. module Database.Persist.Sql.Lifted.Expression -- | An expression on the SQL backend. -- -- Raw expression: Contains a SqlExprMeta and a function for -- building the expr. It recieves a parameter telling it whether it is in -- a parenthesized context, and takes information about the SQL -- connection (mainly for escaping names) and returns both an string -- (Builder) and a list of values to be interpolated by the SQL -- backend. data () => SqlExpr a -- | Lift a constant value from Haskell-land to the query. val :: PersistField typ => typ -> SqlExpr (Value typ) not_ :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -- | This operator translates to the SQL operator AND. -- -- Example: -- --
--   where_ $
--           user ^. UserName ==. val Matt
--       &&. user ^. UserAge >=. val 21
--   
(&&.) :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -> SqlExpr (Value Bool) infixr 3 &&. -- | This operator translates to the SQL operator AND. -- -- Example: -- --
--   where_ $
--           user ^. UserName ==. val Matt
--       ||. user ^. UserName ==. val John
--   
(||.) :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -> SqlExpr (Value Bool) infixr 2 ||. -- | CASE statement. For example: -- --
--   select $
--   return $
--   case_
--      [ when_
--          (exists $
--          from $ \p -> do
--          where_ (p ^. PersonName ==. val "Mike"))
--        then_
--          (subSelect $
--          from $ \v -> do
--          let sub =
--                  from $ \c -> do
--                  where_ (c ^. PersonName ==. val "Mike")
--                  return (c ^. PersonFavNum)
--          where_ (just (v ^. PersonFavNum) >. subSelect sub)
--          return $ count (v ^. PersonName) +. val (1 :: Int)) ]
--      (else_ $ val (-1))
--   
-- -- This query is a bit complicated, but basically it checks if a person -- named "Mike" exists, and if that person does, run the -- subquery to find out how many people have a ranking (by Fav Num) -- higher than "Mike". -- -- NOTE: There are a few things to be aware about this statement. -- -- case_ :: PersistField a => [(SqlExpr (Value Bool), SqlExpr (Value a))] -> SqlExpr (Value a) -> SqlExpr (Value a) -- | Syntax sugar for case_. when_ :: expr (Value Bool) -> () -> expr a -> (expr (Value Bool), expr a) -- | Syntax sugar for case_. then_ :: () -- | Syntax sugar for case_. else_ :: expr a -> expr a -- | This operator produces the SQL operator =, which is used to -- compare values for equality. -- -- Example: -- --
--   query :: UserId -> SqlPersistT IO [Entity User]
--   query userId = select $ do
--       user <- from $ table @User
--       where_ (user ^. UserId ==. val userId)
--       pure user
--   
-- -- This would generate the following SQL: -- --
--   SELECT user.*
--   FROM user
--   WHERE user.id = ?
--   
(==.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 ==. -- | This operator translates to the SQL operator !=. -- -- Example: -- --
--   where_ $ user ^. UserName !=. val Bob
--   
(!=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 !=. -- | This operator translates to the SQL operator >=. -- -- Example: -- --
--   where_ $ user ^. UserAge >=. val 21
--   
(>=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 >=. -- | This operator translates to the SQL operator >. -- -- Example: -- --
--   where_ $ user ^. UserAge >. val 20
--   
(>.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 >. -- | This operator translates to the SQL operator <=. -- -- Example: -- --
--   where_ $ val 21 <=. user ^. UserAge
--   
(<=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 <=. -- | This operator translates to the SQL operator <. -- -- Example: -- --
--   where_ $ val 20 <. user ^. UserAge
--   
(<.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool) infix 4 <. -- | a between (b, c) translates to the SQL expression -- a >= b AND a <= c. It does not use a SQL -- BETWEEN operator. -- -- @since: 3.1.0 between :: PersistField a => SqlExpr (Value a) -> (SqlExpr (Value a), SqlExpr (Value a)) -> SqlExpr (Value Bool) -- | COUNT. count :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a) -- | COUNT(*) value. countRows :: Num a => SqlExpr (Value a) -- | COUNT(DISTINCT x). countDistinct :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a) -- | EXISTS operator. For example: -- --
--   select $
--   from $ \person -> do
--   where_ $ exists $
--            from $ \post -> do
--            where_ (post ^. BlogPostAuthorId ==. person ^. PersonId)
--   return person
--   
exists :: SqlQuery () -> SqlExpr (Value Bool) -- | NOT EXISTS operator. notExists :: SqlQuery () -> SqlExpr (Value Bool) -- | Apply a PersistField constructor to SqlExpr Value -- arguments. (<#) :: (a -> b) -> SqlExpr (Value a) -> SqlExpr (Insertion b) -- | Apply extra SqlExpr Value arguments to a PersistField -- constructor (<&>) :: SqlExpr (Insertion (a -> b)) -> SqlExpr (Value a) -> SqlExpr (Insertion b) -- | Convert an entity's key into another entity's. -- -- This function is to be used when you change an entity's Id to -- be that of another entity. For example: -- --
--   Bar
--     barNum Int
--   Foo
--     bar BarId
--     fooNum Int
--     Primary bar
--   
-- -- In this example, Bar is said to be the BaseEnt(ity), and Foo the -- child. To model this in Esqueleto, declare: -- --
--   instance ToBaseId Foo where
--     type BaseEnt Foo = Bar
--     toBaseIdWitness barId = FooKey barId
--   
-- -- Now you're able to write queries such as: -- --
--   select $
--   from $ (bar `InnerJoin` foo) -> do
--   on (toBaseId (foo ^. FooId) ==. bar ^. BarId)
--   return (bar, foo)
--   
-- -- Note: this function may be unsafe to use in conditions not like the -- one of the example above. toBaseId :: ToBaseId ent => SqlExpr (Value (Key ent)) -> SqlExpr (Value (Key (BaseEnt ent))) -- | Class that enables one to use toBaseId to convert an entity's -- key on a query into another (cf. toBaseId). class () => ToBaseId ent where { -- | e.g. type BaseEnt MyBase = MyChild type family BaseEnt ent; } -- | Convert from the key of the BaseEnt(ity) to the key of the child -- entity. This function is not actually called, but that it typechecks -- proves this operation is safe. toBaseIdWitness :: ToBaseId ent => Key (BaseEnt ent) -> Key ent -- | IN operator. For example if you want to select all -- Persons by a list of IDs: -- --
--   SELECT *
--   FROM Person
--   WHERE Person.id IN (?)
--   
-- -- In esqueleto, we may write the same query above as: -- --
--   select $
--   from $ \person -> do
--   where_ $ person ^. PersonId `in_` valList personIds
--   return person
--   
-- -- Where personIds is of type [Key Person]. in_ :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> SqlExpr (Value Bool) -- | NOT IN operator. notIn :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> SqlExpr (Value Bool) -- | Execute a subquery SELECT in an SqlExpression. Returns a list -- of values. subList_select :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a) -- | Lift a list of constant value from Haskell-land to the query. valList :: PersistField typ => [typ] -> SqlExpr (ValueList typ) -- | Same as just but for ValueList. Most of the time you -- won't need it, though, because you can use just from inside -- subList_select or Just from inside valList. justList :: SqlExpr (ValueList typ) -> SqlExpr (ValueList (Maybe typ)) -- | IS NULL comparison. -- -- For IS NOT NULL, you can negate this with not_, as in -- not_ (isNothing (person ^. PersonAge)) -- -- Warning: Persistent and Esqueleto have different behavior for != -- Nothing: -- -- TODO: table -- -- In SQL, = NULL and != NULL return NULL instead of -- true or false. For this reason, you very likely do not want to use -- !=. Nothing in Esqueleto. You may find these -- hlint rules helpful to enforce this: -- --
--   - error: {lhs: v Database.Esqueleto.==. Database.Esqueleto.nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing}
--   - error: {lhs: v Database.Esqueleto.==. Database.Esqueleto.val Nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing}
--   - error: {lhs: v Database.Esqueleto.!=. Database.Esqueleto.nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing}
--   - error: {lhs: v Database.Esqueleto.!=. Database.Esqueleto.val Nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing}
--   
isNothing :: PersistField typ => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool) -- | An alias for isNothing that avoids clashing with the function -- from Data.Maybe isNothing. isNothing_ :: PersistField typ => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool) -- | Analogous to Just, promotes a value of type typ into -- one of type Maybe typ. It should hold that val . -- Just === just . val. -- -- This function will try not to produce a nested Maybe. This is -- in accord with how SQL represents NULL. That means that -- just . just = just. This behavior was -- changed in v3.6.0.0. If you want to produce nested Maybe, see -- just'. just :: NullableFieldProjection typ typ' => SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ')) -- | NULL value. nothing :: SqlExpr (Value (Maybe typ)) -- | Join nested Maybes in a Value into one. This is useful -- when calling aggregate functions on nullable fields. -- -- As of v3.6.0.0, this function will attempt to work on both -- SqlExpr (Value (Maybe a)) as well as -- SqlExpr (Value (Maybe (Maybe a))) -- inputs to make transitioning to NullableFieldProjection easier. -- This may make type inference worse in some cases. If you want the -- monomorphic variant, see joinV' joinV :: NullableFieldProjection typ typ' => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value (Maybe typ')) -- | COALESCE function. Evaluates the arguments in order and -- returns the value of the first non-NULL SqlExpression, or NULL -- (Nothing) otherwise. Some RDBMSs (such as SQLite) require at least two -- arguments; please refer to the appropriate documentation. coalesce :: (PersistField a, NullableFieldProjection a a') => [SqlExpr (Value (Maybe a))] -> SqlExpr (Value (Maybe a')) -- | Like coalesce, but takes a non-nullable SqlExpression placed -- at the end of the SqlExpression list, which guarantees a non-NULL -- result. coalesceDefault :: PersistField a => [SqlExpr (Value (Maybe a))] -> SqlExpr (Value a) -> SqlExpr (Value a) -- | This operator translates to the SQL operator +. -- -- This does not require or assume anything about the SQL values. -- Interpreting what +. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge +. val 10
--   
(+.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 6 +. -- | This operator translates to the SQL operator -. -- -- This does not require or assume anything about the SQL values. -- Interpreting what -. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge -. val 10
--   
(-.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 6 -. -- | This operator translates to the SQL operator /. -- -- This does not require or assume anything about the SQL values. -- Interpreting what /. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge /. val 10
--   
(/.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 7 /. -- | This operator translates to the SQL operator *. -- -- This does not require or assume anything about the SQL values. -- Interpreting what *. means for a given type is left to the -- database engine. -- -- Example: -- --
--   user ^. UserAge *. val 10
--   
(*.) :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a) infixl 7 *. round_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) ceiling_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) floor_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) min_ :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value (Maybe (Nullable a))) max_ :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value (Maybe (Nullable a))) sum_ :: (PersistField a, PersistField b) => SqlExpr (Value a) -> SqlExpr (Value (Maybe b)) avg_ :: (PersistField a, PersistField b) => SqlExpr (Value a) -> SqlExpr (Value (Maybe b)) -- | Allow a number of one type to be used as one of another type via an -- implicit cast. An explicit cast is not made, this function changes -- only the types on the Haskell side. -- -- Caveat: Trying to use castNum from Double to -- Int will not result in an integer, the original fractional -- number will still be used! Use round_, ceiling_ or -- floor_ instead. -- -- Safety: This operation is mostly safe due to the Num -- constraint between the types and the fact that RDBMSs usually allow -- numbers of different types to be used interchangeably. However, there -- may still be issues with the query not being accepted by the RDBMS or -- persistent not being able to parse it. castNum :: (Num a, Num b) => SqlExpr (Value a) -> SqlExpr (Value b) -- | Same as castNum, but for nullable values. castNumM :: (Num a, Num b) => SqlExpr (Value (Maybe a)) -> SqlExpr (Value (Maybe b)) -- | Ascending order of this field or SqlExpression. asc :: PersistField a => SqlExpr (Value a) -> SqlExpr OrderBy -- | Descending order of this field or SqlExpression. desc :: PersistField a => SqlExpr (Value a) -> SqlExpr OrderBy -- | Project a field of an entity. (^.) :: forall typ val. (PersistEntity val, PersistField typ) => SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ) infixl 9 ^. -- | Project an EntityField of a nullable entity. The result type -- will be Nullable, meaning that nested Maybe won't be -- produced here. -- -- As of v3.6.0.0, this will attempt to combine nested Maybe. If -- you want to keep nested Maybe, then see ??.. (?.) :: (PersistEntity val, PersistField typ) => SqlExpr (Maybe (Entity val)) -> EntityField val typ -> SqlExpr (Value (Maybe (Nullable typ))) infixl 9 ?. -- | LOWER function. lower_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | UPPER function. @since 3.3.0 upper_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | TRIM function. @since 3.3.0 trim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | LTRIM function. @since 3.3.0 ltrim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | RTRIM function. @since 3.3.0 rtrim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -- | LENGTH function. @since 3.3.0 length_ :: (SqlString s, Num a) => SqlExpr (Value s) -> SqlExpr (Value a) -- | LEFT function. @since 3.3.0 left_ :: (SqlString s, Num a) => (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s) -- | RIGHT function. @since 3.3.0 right_ :: (SqlString s, Num a) => (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s) -- | LIKE operator. like :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool) infixr 2 `like` -- | ILIKE operator (case-insensitive LIKE). -- -- Supported by PostgreSQL only. Deprecated in version 3.6.0 in favor of -- the version available from Database.Esqueleto.PostgreSQL. ilike :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool) infixr 2 `ilike` -- | The string %. May be useful while using like -- and concatenation (concat_ or ++., depending on your -- database). Note that you always have to type the parenthesis, for -- example: -- --
--   name `like` (%) ++. val "John" ++. (%)
--   
(%) :: SqlString s => SqlExpr (Value s) -- | The CONCAT function with a variable number of parameters. -- Supported by MySQL and PostgreSQL. SQLite supports this in versions -- after 3.44.0, and persistent-sqlite supports this in versions -- 2.13.3.0 and after. concat_ :: SqlString s => [SqlExpr (Value s)] -> SqlExpr (Value s) -- | The || string concatenation operator (named after Haskell's -- ++ in order to avoid naming clash with ||.). -- -- Supported by SQLite and PostgreSQL. -- -- MySQL support requires setting the SQL mode to -- PIPES_AS_CONCAT or ANSI - see this StackOverflow -- answer. (++.) :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s) infixr 5 ++. -- | Cast a string type into Text. This function is very useful if -- you want to use newtypes, or if you want to apply functions -- such as like to strings of different types. -- -- Safety: This is a slightly unsafe function, especially if you -- have defined your own instances of SqlString. Also, since -- Maybe is an instance of SqlString, it's possible to turn -- a nullable value into a non-nullable one. Avoid using this function if -- possible. castString :: (SqlString s, SqlString r) => SqlExpr (Value s) -> SqlExpr (Value r) -- | Execute a subquery SELECT in a SqlExpr. The query -- passed to this function will only return a single result - it has a -- LIMIT 1 passed in to the query to make it safe, and the -- return type is Maybe to indicate that the subquery might result -- in 0 rows. -- -- If you find yourself writing joinV . subSelect, -- then consider using subSelectMaybe. -- -- If you're performing a countRows, then you can use -- subSelectCount which is safe. -- -- If you know that the subquery will always return exactly one row (eg a -- foreign key constraint guarantees that you'll get exactly one row), -- then consider subSelectUnsafe, along with a comment explaining -- why it is safe. subSelect :: (PersistField a, NullableFieldProjection a a') => SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value (Maybe a')) -- | Execute a subquery SELECT in a SqlExpr. This function -- is a shorthand for the common joinV . subSelect -- idiom, where you are calling subSelect on an expression that -- would be Maybe already. -- -- As an example, you would use this function when calling sum_ or -- max_, which have Maybe in the result type (for a 0 row -- query). subSelectMaybe :: PersistField a => SqlQuery (SqlExpr (Value (Maybe a))) -> SqlExpr (Value (Maybe a)) -- | Performs a COUNT of the given query in a subSelect -- manner. This is always guaranteed to return a result value, and is -- completely safe. subSelectCount :: (Num a, PersistField a) => SqlQuery ignored -> SqlExpr (Value a) -- | Performs a sub-select using the given foreign key on the entity. This -- is useful to extract values that are known to be present by the -- database schema. -- -- As an example, consider the following persistent definition: -- --
--   User
--     profile ProfileId
--   
--   Profile
--     name    Text
--   
-- -- The following query will return the name of the user. -- --
--   getUserWithName =
--       select $
--       from $ user ->
--       pure (user, subSelectForeign user UserProfile (^. ProfileName)
--   
subSelectForeign :: (BackendCompatible SqlBackend (PersistEntityBackend val1), PersistEntity val1, PersistEntity val2, PersistField a) => SqlExpr (Entity val2) -> EntityField val2 (Key val1) -> (SqlExpr (Entity val1) -> SqlExpr (Value a)) -> SqlExpr (Value a) -- | Execute a subquery SELECT in a SqlExpr that returns a -- list. This is an alias for subList_select and is provided for -- symmetry with the other safe subselect functions. subSelectList :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a) -- | Execute a subquery SELECT in a SqlExpr. This function -- is unsafe, because it can throw runtime exceptions in two cases: -- --
    --
  1. If the query passed has 0 result rows, then it will return a -- NULL value. The persistent parsing operations will -- fail on an unexpected NULL.
  2. --
  3. If the query passed returns more than one row, then the SQL engine -- will fail with an error like "More than one row returned by a subquery -- used as an expression".
  4. --
-- -- This function is safe if you guarantee that exactly one row will be -- returned, or if the result already has a Maybe type for some -- reason. -- -- For variants with the safety encoded already, see subSelect and -- subSelectMaybe. For the most common safe use of this, see -- subSelectCount. subSelectUnsafe :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a) -- | Get the first table of a given type from a chain of tables joined with -- (:&). -- -- This can make it easier to write queries with a large number of join -- clauses: -- --
--   select $ do
--   (people :& followers :& blogPosts) <-
--       from $ table @Person
--       `innerJoin` table @Follow
--       `on` (\(person :& follow) ->
--               person ^. PersonId ==. follow ^. FollowFollowed)
--       `innerJoin` table @BlogPost
--       `on` (\((getTable @Follow -> follow) :& blogPost) ->
--               blogPost ^. BlogPostAuthorId ==. follow ^. FollowFollower)
--   where_ (people1 ^. PersonName ==. val "John")
--   pure (followers, people2)
--   
-- -- This example is a bit trivial, but once you've joined five or six -- tables it becomes enormously helpful. The above example uses a -- ViewPattern to call the function and assign the variable -- directly, but you can also imagine it being written like this: -- --
--   `on` (\(prev :& blogPost) ->
--           let
--               follow = getTable @Follow prev
--            in
--               blogPost ^. BlogPostAuthorId ==. follow ^. FollowFollower)
--   
-- -- This function will pluck out the first table that matches the applied -- type, so if you join on the same table multiple times, it will always -- select the first one provided. -- -- The (:&) operator associates so that the left hand side can -- be a wildcard for an arbitrary amount of nesting, and the "most -- recent" or "newest" table in a join sequence is always available on -- the rightmost - so (prev :& bar) is a pattern that -- matches bar table (the most recent table added) and -- prev tables (all prior tables in the join match). -- -- By calling getTable on the prev, you can select -- exactly the table you want, allowing you to omit a large number of -- spurious pattern matches. Consider a query that does several LEFT -- JOIN on a first table: -- --
--   SELECT *
--   FROM person
--   LEFT JOIN car
--     ON person.id = car.person_id
--   LEFT JOIN bike
--     ON person.id = bike.person_id
--   LEFT JOIN food
--     ON person.id = food.person_id
--   LEFT JOIN address
--     ON person.id = address.person_id
--   
-- -- The final on clause in esqueleto would look like this: -- --
--   `on` do
--       \(person :& _car :& _bike :& _food :& address) ->
--           person.id ==. address.personId
--   
-- -- First, we can change it to a prev :& newest match. We can -- do this because of the operator associativity. This is kind of like -- how a list : operator associates, but in the other direction: -- a : (b : c) = a : b : c. -- --
--   `on` do
--       \(prev :& address) ->
--           let (person :& _car :& _bike :& _food) = prev
--            in person.id ==. address.personId
--   
-- -- Then, we can use getTable to select the Person table -- directly, instead of pattern matching manually. -- --
--   `on` do
--       \(prev :& address) ->
--           let person = getTable @Person prev
--            in person.id ==. address.personId
--   
-- -- Finally, we can use a ViewPattern language extension to -- "inline" the access. -- --
--   `on` do
--       \((getTable @Person -> person) :& address) ->
--          person.id ==. address.personId
--   
-- -- With this form, you do not need to be concerned about the number and -- wildcard status of tables that do not matter to the specific -- ON clause. getTable :: GetFirstTable (SqlExpr (Entity t)) ts => ts -> SqlExpr (Entity t) -- | A variant of getTable that operates on possibly-null entities. getTableMaybe :: GetFirstTable (SqlExpr (Maybe (Entity t))) ts => ts -> SqlExpr (Maybe (Entity t)) (=.) :: (PersistEntity val, PersistField typ) => EntityField val typ -> SqlExpr (Value typ) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 =. (+=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 +=. (-=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 -=. (*=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 *=. (/=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Entity val) -> SqlExpr Update infixr 3 /=. module Database.Persist.Sql.Lifted.Filter -- | Filters which are available for select, updateWhere -- and deleteWhere. Each filter constructor specifies the field -- being filtered on, the type of comparison applied (equals, not equals, -- etc) and the argument for the comparison. -- -- Persistent users use combinators to create these. -- -- Note that it's important to be careful about the PersistFilter -- that you are using, if you use this directly. For example, using the -- In PersistFilter requires that you have an array- or -- list-shaped EntityField. It is possible to construct values -- using this that will create malformed runtime values. data () => Filter record -- | Check for equality. -- --

Examples

-- --
--   selectSPJ :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectSPJ = selectList [UserName ==. "SPJ" ] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   
(==.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v infix 4 ==. -- | Non-equality check. -- --

Examples

-- --
--   selectSimon :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectSimon = selectList [UserName !=. "SPJ" ] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   
(!=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v infix 4 !=. -- | Less-than check. -- --

Examples

-- --
--   selectLessAge :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectLessAge = selectList [UserAge <. 41 ] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   
(<.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v infix 4 <. -- | Greater-than check. -- --

Examples

-- --
--   selectGreaterAge :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectGreaterAge = selectList [UserAge >. 40 ] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   
(>.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v infix 4 >. -- | Less-than or equal check. -- --

Examples

-- --
--   selectLessEqualAge :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectLessEqualAge = selectList [UserAge <=. 40 ] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   
(<=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v infix 4 <=. -- | Greater-than or equal check. -- --

Examples

-- --
--   selectGreaterEqualAge :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectGreaterEqualAge = selectList [UserAge >=. 41 ] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   
(>=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v infix 4 >=. -- | Check if value is in given list. -- --

Examples

-- --
--   selectUsers :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectUsers = selectList [UserAge <-. [40, 41]] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   
-- --
--   selectSPJ :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectSPJ = selectList [UserAge <-. [40]] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   
(<-.) :: forall v typ. PersistField typ => EntityField v typ -> [typ] -> Filter v infix 4 <-. -- | Check if value is not in given list. -- --

Examples

-- --
--   selectSimon :: MonadIO m => ReaderT SqlBackend m [Entity User]
--   selectSimon = selectList [UserAge /<-. [40]] []
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   
(/<-.) :: forall v typ. PersistField typ => EntityField v typ -> [typ] -> Filter v infix 4 /<-. -- | The OR of two lists of filters. For example: -- --
--   selectList
--       ([ PersonAge >. 25
--        , PersonAge <. 30 ] ||.
--        [ PersonIncome >. 15000
--        , PersonIncome <. 25000 ])
--       []
--   
-- -- will filter records where a person's age is between 25 and 30 -- or a person's income is between (15000 and 25000). -- -- If you are looking for an (&&.) operator to do (A -- AND B AND (C OR D)) you can use the (++) operator -- instead as there is no (&&.). For example: -- --
--   selectList
--       ([ PersonAge >. 25
--        , PersonAge <. 30 ] ++
--       ([PersonCategory ==. 1] ||.
--        [PersonCategory ==. 5]))
--       []
--   
-- -- will filter records where a person's age is between 25 and 30 -- and (person's category is either 1 or 5). (||.) :: [Filter v] -> [Filter v] -> [Filter v] infixl 3 ||. module Database.Persist.Sql.Lifted.From -- | Data type defining the From language. This should not -- constructed directly in application code. -- -- A From is a SqlQuery which returns a reference to the result -- of calling from and a function that produces a portion of a FROM -- clause. This gets passed to the FromRaw FromClause constructor -- directly when converting from a From to a SqlQuery -- using from data () => From a -- | FROM clause, used to bring entities into scope. -- -- Internally, this function uses the From datatype. Unlike the -- old from, this does not take a function as a parameter, but -- rather a value that represents a JOIN tree constructed out of -- instances of From. This implementation eliminates certain types -- of runtime errors by preventing the construction of invalid SQL (e.g. -- illegal nested-from). from :: ToFrom a a' => a -> SqlQuery a' -- | Bring a PersistEntity into scope from a table -- --
--   select $ from $ table @People
--   
table :: PersistEntity ent => From (SqlExpr (Entity ent)) -- | A left-precedence pair. Pronounced "and". Used to represent -- expressions that have been joined together. -- -- The precedence behavior can be demonstrated by: -- --
--   a :& b :& c == ((a :& b) :& c)
--   
-- -- See the examples at the beginning of this module to see how this -- operator is used in JOIN operations. data () => a :& b (:&) :: a -> b -> (:&) a b infixl 2 :& infixl 2 :& -- | An ON clause that describes how two tables are related. This -- should be used as an infix operator after a JOIN. For -- example, -- --
--   select $
--   from $ table @Person
--   `innerJoin` table @BlogPost
--   `on` (\(p :& bP) ->
--           p ^. PersonId ==. bP ^. BlogPostAuthorId)
--   
on :: ValidOnClause a => a -> (b -> SqlExpr (Value Bool)) -> (a, b -> SqlExpr (Value Bool)) infix 9 `on` -- | INNER JOIN -- -- Used as an infix operator `innerJoin` -- --
--   select $
--   from $ table @Person
--   `innerJoin` table @BlogPost
--   `on` (\(p :& bp) ->
--           p ^. PersonId ==. bp ^. BlogPostAuthorId)
--   
innerJoin :: (ToFrom a a', ToFrom b b', HasOnClause rhs (a' :& b'), rhs ~ (b, (a' :& b') -> SqlExpr (Value Bool))) => a -> rhs -> From (a' :& b') infixl 2 `innerJoin` -- | INNER JOIN LATERAL -- -- A Lateral subquery join allows the joined query to reference entities -- from the left hand side of the join. Discards rows that don't match -- the on clause -- -- Used as an infix operator `innerJoinLateral` -- -- See example 6 innerJoinLateral :: (ToFrom a a', HasOnClause rhs (a' :& b), SqlSelect b r, ToAlias b, ToAliasReference b, rhs ~ (a' -> SqlQuery b, (a' :& b) -> SqlExpr (Value Bool))) => a -> rhs -> From (a' :& b) infixl 2 `innerJoinLateral` -- | LEFT OUTER JOIN -- -- Join where the right side may not exist. If the on clause fails then -- the right side will be NULL'ed Because of this the right side needs to -- be handled as a Maybe -- -- Used as an infix operator `leftJoin` -- --
--   select $
--   from $ table @Person
--   `leftJoin` table @BlogPost
--   `on` (\(p :& bp) ->
--           just (p ^. PersonId) ==. bp ?. BlogPostAuthorId)
--   
leftJoin :: (ToFrom a a', ToFrom b b', ToMaybe b', HasOnClause rhs (a' :& ToMaybeT b'), rhs ~ (b, (a' :& ToMaybeT b') -> SqlExpr (Value Bool))) => a -> rhs -> From (a' :& ToMaybeT b') infixl 2 `leftJoin` -- | LEFT OUTER JOIN LATERAL -- -- Lateral join where the right side may not exist. In the case that the -- query returns nothing or the on clause fails the right side of the -- join will be NULL'ed Because of this the right side needs to be -- handled as a Maybe -- -- Used as an infix operator `leftJoinLateral` -- -- See example 6 for how to use LATERAL leftJoinLateral :: (ToFrom a a', SqlSelect b r, HasOnClause rhs (a' :& ToMaybeT b), ToAlias b, ToAliasReference b, ToMaybe b, rhs ~ (a' -> SqlQuery b, (a' :& ToMaybeT b) -> SqlExpr (Value Bool))) => a -> rhs -> From (a' :& ToMaybeT b) infixl 2 `leftJoinLateral` -- | RIGHT OUTER JOIN -- -- Join where the left side may not exist. If the on clause fails then -- the left side will be NULL'ed Because of this the left side needs to -- be handled as a Maybe -- -- Used as an infix operator `rightJoin` -- --
--   select $
--   from $ table @Person
--   `rightJoin` table @BlogPost
--   `on` (\(p :& bp) ->
--           p ?. PersonId ==. bp ^. BlogPostAuthorId)
--   
rightJoin :: (ToFrom a a', ToFrom b b', ToMaybe a', HasOnClause rhs (ToMaybeT a' :& b'), rhs ~ (b, (ToMaybeT a' :& b') -> SqlExpr (Value Bool))) => a -> rhs -> From (ToMaybeT a' :& b') infixl 2 `rightJoin` -- | FULL OUTER JOIN -- -- Join where both sides of the join may not exist. Because of this the -- result needs to be handled as a Maybe -- -- Used as an infix operator `fullOuterJoin` -- --
--   select $
--   from $ table @Person
--   `fullOuterJoin` table @BlogPost
--   `on` (\(p :& bp) ->
--           p ?. PersonId ==. bp ?. BlogPostAuthorId)
--   
fullOuterJoin :: (ToFrom a a', ToFrom b b', ToMaybe a', ToMaybe b', HasOnClause rhs (ToMaybeT a' :& ToMaybeT b'), rhs ~ (b, (ToMaybeT a' :& ToMaybeT b') -> SqlExpr (Value Bool))) => a -> rhs -> From (ToMaybeT a' :& ToMaybeT b') infixl 2 `fullOuterJoin` -- | CROSS JOIN -- -- Used as an infix `crossJoin` -- --
--   select $ do
--   from $ table @Person
--   `crossJoin` table @BlogPost
--   
crossJoin :: (ToFrom a a', ToFrom b b') => a -> b -> From (a' :& b') infixl 2 `crossJoin` -- | CROSS JOIN LATERAL -- -- A Lateral subquery join allows the joined query to reference entities -- from the left hand side of the join. -- -- Used as an infix operator `crossJoinLateral` -- -- See example 6 crossJoinLateral :: (ToFrom a a', SqlSelect b r, ToAlias b, ToAliasReference b) => a -> (a' -> SqlQuery b) -> From (a' :& b) infixl 2 `crossJoinLateral` module Database.Persist.Sql.Lifted.HasSqlBackend class HasSqlBackend a getSqlBackend :: HasSqlBackend a => a -> SqlBackend instance Database.Persist.Sql.Lifted.HasSqlBackend.HasSqlBackend Database.Persist.SqlBackend.Internal.SqlBackend module Database.Persist.Sql.Lifted.MonadSqlBackend -- | A monadic context in which a SQL backend is available for running -- database queries class MonadUnliftIO m => MonadSqlBackend m getSqlBackendM :: MonadSqlBackend m => m SqlBackend -- | Generalize from SqlPersistT to MonadSqlBackend liftSql :: (MonadSqlBackend m, HasCallStack) => ReaderT SqlBackend m a -> m a instance (Database.Persist.Sql.Lifted.HasSqlBackend.HasSqlBackend r, Control.Monad.IO.Unlift.MonadUnliftIO m) => Database.Persist.Sql.Lifted.MonadSqlBackend.MonadSqlBackend (Control.Monad.Trans.Reader.ReaderT r m) module Database.Persist.Sql.Lifted.MonadSqlTx -- | The constraint MonadSqlTx db m indicates that -- m is a monadic context that can run db actions, -- usually as a SQL transaction. Typically, this means that db -- needs a connection and m can provide one, e.g. from a -- connection pool. class (MonadSqlBackend db, MonadUnliftIO m) => MonadSqlTx db m | m -> db -- | Runs the action in a SQL transaction runSqlTx :: (MonadSqlTx db m, HasCallStack) => db a -> m a module Database.Persist.Sql.Lifted.Core -- | The constraint MonadSqlTx db m indicates that -- m is a monadic context that can run db actions, -- usually as a SQL transaction. Typically, this means that db -- needs a connection and m can provide one, e.g. from a -- connection pool. class (MonadSqlBackend db, MonadUnliftIO m) => MonadSqlTx db m | m -> db -- | Runs the action in a SQL transaction runSqlTx :: (MonadSqlTx db m, HasCallStack) => db a -> m a class HasSqlBackend a getSqlBackend :: HasSqlBackend a => a -> SqlBackend -- | A SqlBackend represents a handle or connection to a database. -- It contains functions and values that allow databases to have more -- optimized implementations, as well as references that benefit -- performance and sharing. -- -- Instead of using the SqlBackend constructor directly, use the -- mkSqlBackend function. -- -- A SqlBackend is *not* thread-safe. You should not assume that a -- SqlBackend can be shared among threads and run concurrent -- queries. This *will* result in problems. Instead, you should create a -- Pool SqlBackend, known as a -- ConnectionPool, and pass that around in multi-threaded -- applications. -- -- To run actions in the persistent library, you should use the -- runSqlConn function. If you're using a multithreaded -- application, use the runSqlPool function. data () => SqlBackend -- | A monadic context in which a SQL backend is available for running -- database queries class MonadUnliftIO m => MonadSqlBackend m getSqlBackendM :: MonadSqlBackend m => m SqlBackend -- | Generalize from SqlPersistT to MonadSqlBackend liftSql :: (MonadSqlBackend m, HasCallStack) => ReaderT SqlBackend m a -> m a -- | Wrappers that apply liftSql to Esqueleto utilities of the same -- name. module Database.Persist.Sql.Lifted.Esqueleto -- | Execute an Esqueleto DELETE query delete :: forall m. (MonadSqlBackend m, HasCallStack) => SqlQuery () -> m () -- | Execute an Esqueleto DELETE query deleteCount :: forall m. (MonadSqlBackend m, HasCallStack) => SqlQuery () -> m Int64 -- | Delete a specific record by identifier -- -- Does nothing if record does not exist. deleteKey :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m () -- | Insert a PersistField for every selected value insertSelect :: forall a m. (PersistEntity a, MonadSqlBackend m, HasCallStack) => SqlQuery (SqlExpr (Insertion a)) -> m () -- | Insert a PersistField for every selected value, returning the -- count insertSelectCount :: forall a m. (PersistEntity a, MonadSqlBackend m, HasCallStack) => SqlQuery (SqlExpr (Insertion a)) -> m Int64 -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryDelete :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryInsertInto :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQuerySelect :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryToText :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => Mode -> SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryUpdate :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Execute an Esqueleto SELECT query select :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m [r] -- | Execute an Esqueleto SELECT query, getting only the first row selectOne :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Maybe r) -- | Execute an Esqueleto UPDATE query update :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => (SqlExpr (Entity a) -> SqlQuery ()) -> m () -- | Execute an Esqueleto UPDATE query, returning the count updateCount :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => (SqlExpr (Entity a) -> SqlQuery ()) -> m Int64 -- | Wrappers that apply liftSql to Persistent utilities of the same -- name. module Database.Persist.Sql.Lifted.Persistent -- | Check whether there are any conflicts for unique keys with this entity -- and existing entities in the database checkUnique :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Unique a)) -- | Check whether there are any conflicts for unique keys with this entity -- and existing entities in the database -- -- This is useful for updating because it ignores conflicts when the -- particular entity already exists. checkUniqueUpdateable :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Entity a -> m (Maybe (Unique a)) -- | The total number of records fulfilling the given criteria count :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> m Int -- | Delete a specific record by identifier -- -- Does nothing if record does not exist. delete :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m () -- | Delete a specific record by unique key -- -- Does nothing if no record matches. deleteBy :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Unique a -> m () -- | Delete all records matching the given criteria deleteWhere :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> m () -- | Check if there is at least one record fulfilling the given criteria exists :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> m Bool -- | Get a record by identifier, if available get :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m (Maybe a) -- | Get a record by unique key, if available, returning both the -- identifier and the record getBy :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Unique a -> m (Maybe (Entity a)) getByValue :: forall a m. (PersistEntityBackend a ~ SqlBackend, AtLeastOneUniqueKey a, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Entity a)) -- | Get a record by identifier, if available getEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m (Maybe (Entity a)) -- | Get a record by identifier, if available, for a non-null (not -- Maybe) foreign key -- -- Unsafe unless your database is enforcing that the foreign key is -- valid. getJust :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m a -- | Get a record by identifier, if available, for a non-null (not -- Maybe) foreign key -- -- Unsafe unless your database is enforcing that the foreign key is -- valid. getJustEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m (Entity a) -- | Get many records by their respective identifiers, if available getMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Key a] -> m (Map (Key a) a) -- | Create a new record in the database insert :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Key a) -- | Create a new record in the database insert_ :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m () -- | Insert a value, checking for conflicts with any unique constraints insertBy :: forall a m. (PersistEntityBackend a ~ SqlBackend, AtLeastOneUniqueKey a, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Either (Entity a) (Key a)) -- | Create a new record in the database, returning an auto-increment ID -- and the inserted record insertEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Entity a) -- | Create multiple records in the database, with specified keys insertEntityMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Entity a] -> m () -- | Create a new record in the database using the given key insertKey :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> a -> m () -- | Create multiple records in the database and return their Keys insertMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => [a] -> m [Key a] -- | Create multiple records in the database insertMany_ :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => [a] -> m () -- | Create a new record in the database insertRecord :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m a -- | Create a new record in the database insertUnique :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Key a)) -- | Create a new record in the database insertUniqueEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Entity a)) -- | Return the single unique key for a record onlyUnique :: forall a m. (PersistEntityBackend a ~ SqlBackend, OnlyOneUniqueKey a, MonadSqlBackend m, HasCallStack) => a -> m (Unique a) -- | Put many records into the database -- -- putMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => [a] -> m () -- | Replace the record in the database with the given key -- -- The result is undefined if such record does not exist. replace :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> a -> m () -- | Attempt to replace the record of the given key with the given new -- record -- -- First query the unique fields to make sure the replacement maintains -- uniqueness constraints. replaceUnique :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, Eq (Unique a), MonadSqlBackend m, HasCallStack) => Key a -> a -> m (Maybe (Unique a)) -- | Put the record in the database with the given key -- -- If a record with the given key does not exist then a new record will -- be inserted. repsert :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> a -> m () -- | Put many entities into the database -- -- For each item, if a record with the given key does not exist then a -- new record will be inserted. repsertMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [(Key a, a)] -> m () -- | Get just the first record for the criteria selectFirst :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [SelectOpt a] -> m (Maybe (Entity a)) -- | Get the Keys of all records matching the given criteria selectKeys :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, MonadResource m, HasCallStack) => [Filter a] -> [SelectOpt a] -> ConduitT () (Key a) m () -- | Get the Keys of all records matching the given criteria selectKeysList :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [SelectOpt a] -> m [Key a] selectList :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [SelectOpt a] -> m [Entity a] -- | Commit the current transaction and begin a new one transactionSave :: forall m. (MonadSqlBackend m, HasCallStack) => m () -- | Commit the current transaction and begin a new one transactionSaveWithIsolation :: forall m. (MonadSqlBackend m, HasCallStack) => IsolationLevel -> m () -- | Roll back the current transaction and begin a new one transactionUndo :: forall m. (MonadSqlBackend m, HasCallStack) => m () -- | Roll back the current transaction and begin a new one transactionUndoWithIsolation :: forall m. (MonadSqlBackend m, HasCallStack) => IsolationLevel -> m () -- | Update individual fields on a specific record update :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> [Update a] -> m () -- | Update individual fields on a specific record, and retrieve the -- updated value from the database -- -- This function will throw an exception if the given key is not found in -- the database. updateGet :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> [Update a] -> m a -- | Update individual fields on any record matching the given criteria updateWhere :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [Update a] -> m () -- | Update based on a uniqueness constraint or insert: -- -- upsert :: forall a m. (PersistEntityBackend a ~ SqlBackend, SafeToInsert a, OnlyOneUniqueKey a, MonadSqlBackend m, HasCallStack) => a -> [Update a] -> m (Entity a) -- | Update based on a given uniqueness constraint or insert: -- -- upsertBy :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => Unique a -> a -> [Update a] -> m (Entity a) -- | Re-exports from: -- -- -- -- There are a few name conflicts between Persistent and Esqueleto. Where -- conflicts occur, this module gives preference to Esqueleto. The -- following Persistent definitions are renamed: -- -- module Database.Persist.Sql.Lifted -- | The constraint MonadSqlTx db m indicates that -- m is a monadic context that can run db actions, -- usually as a SQL transaction. Typically, this means that db -- needs a connection and m can provide one, e.g. from a -- connection pool. class (MonadSqlBackend db, MonadUnliftIO m) => MonadSqlTx db m | m -> db -- | Runs the action in a SQL transaction runSqlTx :: (MonadSqlTx db m, HasCallStack) => db a -> m a class HasSqlBackend a getSqlBackend :: HasSqlBackend a => a -> SqlBackend -- | A SqlBackend represents a handle or connection to a database. -- It contains functions and values that allow databases to have more -- optimized implementations, as well as references that benefit -- performance and sharing. -- -- Instead of using the SqlBackend constructor directly, use the -- mkSqlBackend function. -- -- A SqlBackend is *not* thread-safe. You should not assume that a -- SqlBackend can be shared among threads and run concurrent -- queries. This *will* result in problems. Instead, you should create a -- Pool SqlBackend, known as a -- ConnectionPool, and pass that around in multi-threaded -- applications. -- -- To run actions in the persistent library, you should use the -- runSqlConn function. If you're using a multithreaded -- application, use the runSqlPool function. data () => SqlBackend -- | A monadic context in which a SQL backend is available for running -- database queries class MonadUnliftIO m => MonadSqlBackend m getSqlBackendM :: MonadSqlBackend m => m SqlBackend -- | Generalize from SqlPersistT to MonadSqlBackend liftSql :: (MonadSqlBackend m, HasCallStack) => ReaderT SqlBackend m a -> m a -- | Get a record by identifier, if available get :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m (Maybe a) -- | Get a record by unique key, if available, returning both the -- identifier and the record getBy :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Unique a -> m (Maybe (Entity a)) getByValue :: forall a m. (PersistEntityBackend a ~ SqlBackend, AtLeastOneUniqueKey a, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Entity a)) -- | Get a record by identifier, if available getEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m (Maybe (Entity a)) -- | Get a record by identifier, if available, for a non-null (not -- Maybe) foreign key -- -- Unsafe unless your database is enforcing that the foreign key is -- valid. getJust :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m a -- | Get a record by identifier, if available, for a non-null (not -- Maybe) foreign key -- -- Unsafe unless your database is enforcing that the foreign key is -- valid. getJustEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m (Entity a) -- | Get many records by their respective identifiers, if available getMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Key a] -> m (Map (Key a) a) -- | Execute an Esqueleto SELECT query select :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m [r] -- | Execute an Esqueleto SELECT query, getting only the first row selectOne :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Maybe r) -- | Get just the first record for the criteria selectFirst :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [SelectOpt a] -> m (Maybe (Entity a)) -- | Get the Keys of all records matching the given criteria selectKeys :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, MonadResource m, HasCallStack) => [Filter a] -> [SelectOpt a] -> ConduitT () (Key a) m () -- | Get the Keys of all records matching the given criteria selectKeysList :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [SelectOpt a] -> m [Key a] selectList :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [SelectOpt a] -> m [Entity a] -- | The total number of records fulfilling the given criteria count :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> m Int -- | Check if there is at least one record fulfilling the given criteria exists :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> m Bool -- | Insert a PersistField for every selected value insertSelect :: forall a m. (PersistEntity a, MonadSqlBackend m, HasCallStack) => SqlQuery (SqlExpr (Insertion a)) -> m () -- | Insert a PersistField for every selected value, returning the -- count insertSelectCount :: forall a m. (PersistEntity a, MonadSqlBackend m, HasCallStack) => SqlQuery (SqlExpr (Insertion a)) -> m Int64 -- | Create a new record in the database insert :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Key a) -- | Create a new record in the database insert_ :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m () -- | Insert a value, checking for conflicts with any unique constraints insertBy :: forall a m. (PersistEntityBackend a ~ SqlBackend, AtLeastOneUniqueKey a, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Either (Entity a) (Key a)) -- | Create a new record in the database, returning an auto-increment ID -- and the inserted record insertEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Entity a) -- | Create multiple records in the database, with specified keys insertEntityMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Entity a] -> m () -- | Create a new record in the database using the given key insertKey :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> a -> m () -- | Create multiple records in the database and return their Keys insertMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => [a] -> m [Key a] -- | Create multiple records in the database insertMany_ :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => [a] -> m () -- | Create a new record in the database insertRecord :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m a -- | Create a new record in the database insertUnique :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Key a)) -- | Create a new record in the database insertUniqueEntity :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Entity a)) -- | Execute an Esqueleto UPDATE query update :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => (SqlExpr (Entity a) -> SqlQuery ()) -> m () -- | Execute an Esqueleto UPDATE query, returning the count updateCount :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => (SqlExpr (Entity a) -> SqlQuery ()) -> m Int64 -- | Update individual fields on a specific record update' :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> [Update a] -> m () -- | Update individual fields on a specific record, and retrieve the -- updated value from the database -- -- This function will throw an exception if the given key is not found in -- the database. updateGet :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> [Update a] -> m a -- | Update individual fields on any record matching the given criteria updateWhere :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> [Update a] -> m () -- | Replace the record in the database with the given key -- -- The result is undefined if such record does not exist. replace :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> a -> m () -- | Attempt to replace the record of the given key with the given new -- record -- -- First query the unique fields to make sure the replacement maintains -- uniqueness constraints. replaceUnique :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, Eq (Unique a), MonadSqlBackend m, HasCallStack) => Key a -> a -> m (Maybe (Unique a)) -- | Put the record in the database with the given key -- -- If a record with the given key does not exist then a new record will -- be inserted. repsert :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> a -> m () -- | Put many entities into the database -- -- For each item, if a record with the given key does not exist then a -- new record will be inserted. repsertMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [(Key a, a)] -> m () -- | Update based on a uniqueness constraint or insert: -- -- upsert :: forall a m. (PersistEntityBackend a ~ SqlBackend, SafeToInsert a, OnlyOneUniqueKey a, MonadSqlBackend m, HasCallStack) => a -> [Update a] -> m (Entity a) -- | Update based on a given uniqueness constraint or insert: -- -- upsertBy :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => Unique a -> a -> [Update a] -> m (Entity a) -- | Put many records into the database -- -- putMany :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, SafeToInsert a, MonadSqlBackend m, HasCallStack) => [a] -> m () -- | Check whether there are any conflicts for unique keys with this entity -- and existing entities in the database checkUnique :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => a -> m (Maybe (Unique a)) -- | Check whether there are any conflicts for unique keys with this entity -- and existing entities in the database -- -- This is useful for updating because it ignores conflicts when the -- particular entity already exists. checkUniqueUpdateable :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Entity a -> m (Maybe (Unique a)) -- | Return the single unique key for a record onlyUnique :: forall a m. (PersistEntityBackend a ~ SqlBackend, OnlyOneUniqueKey a, MonadSqlBackend m, HasCallStack) => a -> m (Unique a) -- | Execute an Esqueleto DELETE query delete :: forall m. (MonadSqlBackend m, HasCallStack) => SqlQuery () -> m () -- | Delete a specific record by identifier -- -- Does nothing if record does not exist. deleteKey :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Key a -> m () -- | Delete a specific record by unique key -- -- Does nothing if no record matches. deleteBy :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => Unique a -> m () -- | Delete all records matching the given criteria deleteWhere :: forall a m. (PersistEntity a, PersistEntityBackend a ~ SqlBackend, MonadSqlBackend m, HasCallStack) => [Filter a] -> m () -- | Execute an Esqueleto DELETE query deleteCount :: forall m. (MonadSqlBackend m, HasCallStack) => SqlQuery () -> m Int64 -- | Commit the current transaction and begin a new one transactionSave :: forall m. (MonadSqlBackend m, HasCallStack) => m () -- | Commit the current transaction and begin a new one transactionSaveWithIsolation :: forall m. (MonadSqlBackend m, HasCallStack) => IsolationLevel -> m () -- | Roll back the current transaction and begin a new one transactionUndo :: forall m. (MonadSqlBackend m, HasCallStack) => m () -- | Roll back the current transaction and begin a new one transactionUndoWithIsolation :: forall m. (MonadSqlBackend m, HasCallStack) => IsolationLevel -> m () -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryDelete :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryInsertInto :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQuerySelect :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryToText :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => Mode -> SqlQuery a -> m (Text, [PersistValue]) -- | Renders a SqlQuery to Text along with the list of -- PersistValues that would be supplied to the database for -- ? placeholders renderQueryUpdate :: forall a r m. (SqlSelect a r, MonadSqlBackend m, HasCallStack) => SqlQuery a -> m (Text, [PersistValue]) module Database.Persist.Sql.Lifted.Query.Aggregate -- | GROUP BY clause. You can enclose multiple columns in a tuple. -- --
--   select $ from \(foo `InnerJoin` bar) -> do
--     on (foo ^. FooBarId ==. bar ^. BarId)
--     groupBy (bar ^. BarId, bar ^. BarName)
--     return (bar ^. BarId, bar ^. BarName, countRows)
--   
-- -- With groupBy you can sort by aggregate functions, like so (we used -- let to restrict the more general countRows to -- SqlSqlExpr (Value Int) to avoid ambiguity---the second use of -- countRows has its type restricted by the :: Int -- below): -- --
--   r <- select $ from \(foo `InnerJoin` bar) -> do
--     on (foo ^. FooBarId ==. bar ^. BarId)
--     groupBy $ bar ^. BarName
--     let countRows' = countRows
--     orderBy [asc countRows']
--     return (bar ^. BarName, countRows')
--   forM_ r $ \(Value name, Value count) -> do
--     print name
--     print (count :: Int)
--   
-- --

Need more columns?

-- -- The ToSomeValues class is defined for SqlExpr and tuples -- of SqlExprs. We only have definitions for up to 8 elements in a -- tuple right now, so it's possible that you may need to have more than -- 8 elements. -- -- For example, consider a query with a groupBy call like this: -- --
--   groupBy (e0, e1, e2, e3, e4, e5, e6, e7)
--   
-- -- This is the biggest you can get with a single tuple. However, you can -- easily nest the tuples to add more: -- --
--   groupBy ((e0, e1, e2, e3, e4, e5, e6, e7), e8, e9)
--   
groupBy :: ToSomeValues a => a -> SqlQuery () -- | An alias for groupBy that avoids conflict with the term from -- Data.List groupBy. groupBy_ :: ToSomeValues a => a -> SqlQuery () -- | HAVING. having :: SqlExpr (Value Bool) -> SqlQuery () module Database.Persist.Sql.Lifted.Query.CommonTableExpressions -- | WITH clause used to introduce a Common Table Expression -- (CTE). CTEs are supported in most modern SQL engines and can be -- useful in performance tuning. In Esqueleto, CTEs should be used as a -- subquery memoization tactic. When writing plain SQL, CTEs are -- sometimes used to organize the SQL code, in Esqueleto, this is better -- achieved through function that return SqlQuery values. -- --
--   select $ do
--   cte <- with subQuery
--   cteResult <- from cte
--   where_ $ cteResult ...
--   pure cteResult
--   
-- -- WARNING: In some SQL engines using a CTE can diminish -- performance. In these engines the CTE is treated as an optimization -- fence. You should always verify that using a CTE will in fact improve -- your performance over a regular subquery. -- -- Notably, in PostgreSQL prior to version 12, CTEs are always fully -- calculated, which can potentially significantly pessimize queries. As -- of PostgreSQL 12, non-recursive and side-effect-free queries may be -- inlined and optimized accordingly if not declared -- MATERIALIZED to get the previous behaviour. See the -- PostgreSQL CTE documentation, section Materialization, for more -- information. To use a MATERIALIZED query in Esquelto, see -- functions withMaterialized and -- withRecursiveMaterialized. -- -- Since: 3.4.0.0 with :: (ToAlias a, ToAliasReference a, SqlSelect a r) => SqlQuery a -> SqlQuery (From a) -- | WITH RECURSIVE allows one to make a recursive -- subquery, which can reference itself. Like WITH, this is -- supported in most modern SQL engines. Useful for hierarchical, -- self-referential data, like a tree of data. -- --
--   select $ do
--   cte <- withRecursive
--            (do
--                person <- from $ table @Person
--                where_ $ person ^. PersonId ==. val personId
--                pure person
--            )
--            unionAll_
--            (\self -> do
--                (p :& f :& p2 :& pSelf) <- from self
--                         `innerJoin` $ table @Follow
--                         `on` (\(p :& f) ->
--                                 p ^. PersonId ==. f ^. FollowFollower)
--                         `innerJoin` $ table @Person
--                         `on` (\(p :& f :& p2) ->
--                                 f ^. FollowFollowed ==. p2 ^. PersonId)
--                         `leftJoin` self
--                         `on` (\(_ :& _ :& p2 :& pSelf) ->
--                                 just (p2 ^. PersonId) ==. pSelf ?. PersonId)
--                where_ $ isNothing (pSelf ?. PersonId)
--                groupBy (p2 ^. PersonId)
--                pure p2
--            )
--   from cte
--   
-- -- Since: 3.4.0.0 withRecursive :: (ToAlias a, ToAliasReference a, SqlSelect a r) => SqlQuery a -> UnionKind -> (From a -> SqlQuery a) -> SqlQuery (From a) module Database.Persist.Sql.Lifted.Query.Core -- | SQL backend for esqueleto using SqlPersistT. data () => SqlQuery a -- | WHERE clause: restrict the query's result. where_ :: SqlExpr (Value Bool) -> SqlQuery () -- | LIMIT. Limit the number of returned rows. limit :: Int64 -> SqlQuery () -- | OFFSET. Usually used with limit. offset :: Int64 -> SqlQuery () -- | DISTINCT. Change the current SELECT into SELECT -- DISTINCT. For example: -- --
--   select $ distinct $
--     from \foo -> do
--     ...
--   
-- -- Note that this also has the same effect: -- --
--   select $
--     from \foo -> do
--     distinct (return ())
--     ...
--   
distinct :: SqlQuery a -> SqlQuery a -- | DISTINCT ON. Change the current SELECT into -- SELECT DISTINCT ON (SqlExpressions). For example: -- --
--   select $
--     from \foo ->
--     distinctOn [don (foo ^. FooName), don (foo ^. FooState)] $ do
--     ...
--   
-- -- You can also chain different calls to distinctOn. The above is -- equivalent to: -- --
--   select $
--     from \foo ->
--     distinctOn [don (foo ^. FooName)] $
--     distinctOn [don (foo ^. FooState)] $ do
--     ...
--   
-- -- Each call to distinctOn adds more SqlExpressions. Calls to -- distinctOn override any calls to distinct. -- -- Note that PostgreSQL requires the SqlExpressions on DISTINCT -- ON to be the first ones to appear on a ORDER BY. This is -- not managed automatically by esqueleto, keeping its spirit of trying -- to be close to raw SQL. -- -- Supported by PostgreSQL only. distinctOn :: [SqlExpr DistinctOn] -> SqlQuery a -> SqlQuery a -- | ORDER BY clause. See also asc and desc. -- -- Multiple calls to orderBy get concatenated on the final query, -- including distinctOnOrderBy. orderBy :: [SqlExpr OrderBy] -> SqlQuery () -- | Erase an SqlExpression's type so that it's suitable to be used by -- distinctOn. don :: SqlExpr (Value a) -> SqlExpr DistinctOn -- | A convenience function that calls both distinctOn and -- orderBy. In other words, -- --
--   distinctOnOrderBy [asc foo, desc bar, desc quux] $ do
--     ...
--   
-- -- is the same as: -- --
--   distinctOn [don foo, don  bar, don  quux] $ do
--     orderBy  [asc foo, desc bar, desc quux]
--     ...
--   
distinctOnOrderBy :: [SqlExpr OrderBy] -> SqlQuery a -> SqlQuery a -- | Project an SqlExpression that may be null, guarding against null -- cases. withNonNull :: PersistField typ => SqlExpr (Value (Maybe typ)) -> (SqlExpr (Value typ) -> SqlQuery a) -> SqlQuery a module Database.Persist.Sql.Lifted.Query.Locking -- | Add a locking clause to the query. Please read LockingKind -- documentation and your RDBMS manual. Unsafe since not all locking -- clauses are implemented for every RDBMS -- -- If multiple calls to locking are made on the same query, the -- last one is used. locking :: LockingKind -> SqlQuery () -- | Different kinds of locking clauses supported by locking. -- -- Note that each RDBMS has different locking support. The constructors -- of this datatype specify only the syntax of the locking -- mechanism, not its semantics. For example, even though both -- MySQL and PostgreSQL support ForUpdate, there are no guarantees -- that they will behave the same. data () => LockingKind -- | FOR UPDATE syntax. Supported by MySQL, Oracle and PostgreSQL. ForUpdate :: LockingKind -- | FOR UPDATE SKIP LOCKED syntax. Supported by MySQL, Oracle and -- PostgreSQL. ForUpdateSkipLocked :: LockingKind -- | FOR SHARE syntax. Supported by PostgreSQL. ForShare :: LockingKind -- | LOCK IN SHARE MODE syntax. Supported by MySQL. LockInShareMode :: LockingKind module Database.Persist.Sql.Lifted.Query.SetOperations -- | UNION SQL set operation. Can be used as an infix function -- between SqlQuery values. union_ :: Union_ a => a -- | UNION ALL SQL set operation. Can be used as an infix -- function between SqlQuery values. unionAll_ :: UnionAll_ a => a -- | EXCEPT SQL set operation. Can be used as an infix function -- between SqlQuery values. except_ :: (ToSqlSetOperation a a', ToSqlSetOperation b a') => a -> b -> SqlSetOperation a' -- | INTERSECT SQL set operation. Can be used as an infix function -- between SqlQuery values. intersect_ :: (ToSqlSetOperation a a', ToSqlSetOperation b a') => a -> b -> SqlSetOperation a' module Database.Persist.Sql.Lifted.Query.Update -- | SET clause used on UPDATEs. Note that while it's not -- a type error to use this function on a SELECT, it will most -- certainly result in a runtime error. set :: PersistEntity val => SqlExpr (Entity val) -> [SqlExpr (Entity val) -> SqlExpr Update] -> SqlQuery () module Database.Persist.Sql.Lifted.Query -- | SQL backend for esqueleto using SqlPersistT. data () => SqlQuery a -- | WHERE clause: restrict the query's result. where_ :: SqlExpr (Value Bool) -> SqlQuery () -- | GROUP BY clause. You can enclose multiple columns in a tuple. -- --
--   select $ from \(foo `InnerJoin` bar) -> do
--     on (foo ^. FooBarId ==. bar ^. BarId)
--     groupBy (bar ^. BarId, bar ^. BarName)
--     return (bar ^. BarId, bar ^. BarName, countRows)
--   
-- -- With groupBy you can sort by aggregate functions, like so (we used -- let to restrict the more general countRows to -- SqlSqlExpr (Value Int) to avoid ambiguity---the second use of -- countRows has its type restricted by the :: Int -- below): -- --
--   r <- select $ from \(foo `InnerJoin` bar) -> do
--     on (foo ^. FooBarId ==. bar ^. BarId)
--     groupBy $ bar ^. BarName
--     let countRows' = countRows
--     orderBy [asc countRows']
--     return (bar ^. BarName, countRows')
--   forM_ r $ \(Value name, Value count) -> do
--     print name
--     print (count :: Int)
--   
-- --

Need more columns?

-- -- The ToSomeValues class is defined for SqlExpr and tuples -- of SqlExprs. We only have definitions for up to 8 elements in a -- tuple right now, so it's possible that you may need to have more than -- 8 elements. -- -- For example, consider a query with a groupBy call like this: -- --
--   groupBy (e0, e1, e2, e3, e4, e5, e6, e7)
--   
-- -- This is the biggest you can get with a single tuple. However, you can -- easily nest the tuples to add more: -- --
--   groupBy ((e0, e1, e2, e3, e4, e5, e6, e7), e8, e9)
--   
groupBy :: ToSomeValues a => a -> SqlQuery () -- | An alias for groupBy that avoids conflict with the term from -- Data.List groupBy. groupBy_ :: ToSomeValues a => a -> SqlQuery () -- | HAVING. having :: SqlExpr (Value Bool) -> SqlQuery () -- | LIMIT. Limit the number of returned rows. limit :: Int64 -> SqlQuery () -- | OFFSET. Usually used with limit. offset :: Int64 -> SqlQuery () -- | DISTINCT. Change the current SELECT into SELECT -- DISTINCT. For example: -- --
--   select $ distinct $
--     from \foo -> do
--     ...
--   
-- -- Note that this also has the same effect: -- --
--   select $
--     from \foo -> do
--     distinct (return ())
--     ...
--   
distinct :: SqlQuery a -> SqlQuery a -- | DISTINCT ON. Change the current SELECT into -- SELECT DISTINCT ON (SqlExpressions). For example: -- --
--   select $
--     from \foo ->
--     distinctOn [don (foo ^. FooName), don (foo ^. FooState)] $ do
--     ...
--   
-- -- You can also chain different calls to distinctOn. The above is -- equivalent to: -- --
--   select $
--     from \foo ->
--     distinctOn [don (foo ^. FooName)] $
--     distinctOn [don (foo ^. FooState)] $ do
--     ...
--   
-- -- Each call to distinctOn adds more SqlExpressions. Calls to -- distinctOn override any calls to distinct. -- -- Note that PostgreSQL requires the SqlExpressions on DISTINCT -- ON to be the first ones to appear on a ORDER BY. This is -- not managed automatically by esqueleto, keeping its spirit of trying -- to be close to raw SQL. -- -- Supported by PostgreSQL only. distinctOn :: [SqlExpr DistinctOn] -> SqlQuery a -> SqlQuery a -- | ORDER BY clause. See also asc and desc. -- -- Multiple calls to orderBy get concatenated on the final query, -- including distinctOnOrderBy. orderBy :: [SqlExpr OrderBy] -> SqlQuery () -- | Erase an SqlExpression's type so that it's suitable to be used by -- distinctOn. don :: SqlExpr (Value a) -> SqlExpr DistinctOn -- | A convenience function that calls both distinctOn and -- orderBy. In other words, -- --
--   distinctOnOrderBy [asc foo, desc bar, desc quux] $ do
--     ...
--   
-- -- is the same as: -- --
--   distinctOn [don foo, don  bar, don  quux] $ do
--     orderBy  [asc foo, desc bar, desc quux]
--     ...
--   
distinctOnOrderBy :: [SqlExpr OrderBy] -> SqlQuery a -> SqlQuery a -- | SET clause used on UPDATEs. Note that while it's not -- a type error to use this function on a SELECT, it will most -- certainly result in a runtime error. set :: PersistEntity val => SqlExpr (Entity val) -> [SqlExpr (Entity val) -> SqlExpr Update] -> SqlQuery () -- | Project an SqlExpression that may be null, guarding against null -- cases. withNonNull :: PersistField typ => SqlExpr (Value (Maybe typ)) -> (SqlExpr (Value typ) -> SqlQuery a) -> SqlQuery a -- | Add a locking clause to the query. Please read LockingKind -- documentation and your RDBMS manual. Unsafe since not all locking -- clauses are implemented for every RDBMS -- -- If multiple calls to locking are made on the same query, the -- last one is used. locking :: LockingKind -> SqlQuery () -- | Different kinds of locking clauses supported by locking. -- -- Note that each RDBMS has different locking support. The constructors -- of this datatype specify only the syntax of the locking -- mechanism, not its semantics. For example, even though both -- MySQL and PostgreSQL support ForUpdate, there are no guarantees -- that they will behave the same. data () => LockingKind -- | FOR UPDATE syntax. Supported by MySQL, Oracle and PostgreSQL. ForUpdate :: LockingKind -- | FOR UPDATE SKIP LOCKED syntax. Supported by MySQL, Oracle and -- PostgreSQL. ForUpdateSkipLocked :: LockingKind -- | FOR SHARE syntax. Supported by PostgreSQL. ForShare :: LockingKind -- | LOCK IN SHARE MODE syntax. Supported by MySQL. LockInShareMode :: LockingKind -- | UNION SQL set operation. Can be used as an infix function -- between SqlQuery values. union_ :: Union_ a => a -- | UNION ALL SQL set operation. Can be used as an infix -- function between SqlQuery values. unionAll_ :: UnionAll_ a => a -- | EXCEPT SQL set operation. Can be used as an infix function -- between SqlQuery values. except_ :: (ToSqlSetOperation a a', ToSqlSetOperation b a') => a -> b -> SqlSetOperation a' -- | INTERSECT SQL set operation. Can be used as an infix function -- between SqlQuery values. intersect_ :: (ToSqlSetOperation a a', ToSqlSetOperation b a') => a -> b -> SqlSetOperation a' -- | WITH clause used to introduce a Common Table Expression -- (CTE). CTEs are supported in most modern SQL engines and can be -- useful in performance tuning. In Esqueleto, CTEs should be used as a -- subquery memoization tactic. When writing plain SQL, CTEs are -- sometimes used to organize the SQL code, in Esqueleto, this is better -- achieved through function that return SqlQuery values. -- --
--   select $ do
--   cte <- with subQuery
--   cteResult <- from cte
--   where_ $ cteResult ...
--   pure cteResult
--   
-- -- WARNING: In some SQL engines using a CTE can diminish -- performance. In these engines the CTE is treated as an optimization -- fence. You should always verify that using a CTE will in fact improve -- your performance over a regular subquery. -- -- Notably, in PostgreSQL prior to version 12, CTEs are always fully -- calculated, which can potentially significantly pessimize queries. As -- of PostgreSQL 12, non-recursive and side-effect-free queries may be -- inlined and optimized accordingly if not declared -- MATERIALIZED to get the previous behaviour. See the -- PostgreSQL CTE documentation, section Materialization, for more -- information. To use a MATERIALIZED query in Esquelto, see -- functions withMaterialized and -- withRecursiveMaterialized. -- -- Since: 3.4.0.0 with :: (ToAlias a, ToAliasReference a, SqlSelect a r) => SqlQuery a -> SqlQuery (From a) -- | WITH RECURSIVE allows one to make a recursive -- subquery, which can reference itself. Like WITH, this is -- supported in most modern SQL engines. Useful for hierarchical, -- self-referential data, like a tree of data. -- --
--   select $ do
--   cte <- withRecursive
--            (do
--                person <- from $ table @Person
--                where_ $ person ^. PersonId ==. val personId
--                pure person
--            )
--            unionAll_
--            (\self -> do
--                (p :& f :& p2 :& pSelf) <- from self
--                         `innerJoin` $ table @Follow
--                         `on` (\(p :& f) ->
--                                 p ^. PersonId ==. f ^. FollowFollower)
--                         `innerJoin` $ table @Person
--                         `on` (\(p :& f :& p2) ->
--                                 f ^. FollowFollowed ==. p2 ^. PersonId)
--                         `leftJoin` self
--                         `on` (\(_ :& _ :& p2 :& pSelf) ->
--                                 just (p2 ^. PersonId) ==. pSelf ?. PersonId)
--                where_ $ isNothing (pSelf ?. PersonId)
--                groupBy (p2 ^. PersonId)
--                pure p2
--            )
--   from cte
--   
-- -- Since: 3.4.0.0 withRecursive :: (ToAlias a, ToAliasReference a, SqlSelect a r) => SqlQuery a -> UnionKind -> (From a -> SqlQuery a) -> SqlQuery (From a) module Database.Persist.Sql.Lifted.Update -- | Updating a database entity. -- -- Persistent users use combinators to create these. data () => Update record -- | Assign a field a value. -- --

Examples

-- --
--   updateAge :: MonadIO m => ReaderT SqlBackend m ()
--   updateAge = updateWhere [UserName ==. "SPJ" ] [UserAge =. 45]
--   
-- -- Similar to updateWhere which is shown in the above example you -- can use other functions present in the module -- Database.Persist.Class. Note that the first parameter of -- updateWhere is [Filter val] and second parameter is -- [Update val]. By comparing this with the type of ==. and -- =., you can see that they match up in the above usage. -- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+--------+
--   |id   |name |age     |
--   +-----+-----+--------+
--   |1    |SPJ  |40 -> 45|
--   +-----+-----+--------+
--   |2    |Simon|41      |
--   +-----+-----+--------+
--   
(=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v infixr 3 =. -- | Assign a field by addition (+=). -- --

Examples

-- --
--   addAge :: MonadIO m => ReaderT SqlBackend m ()
--   addAge = updateWhere [UserName ==. "SPJ" ] [UserAge +=. 1]
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+---------+
--   |id   |name |age      |
--   +-----+-----+---------+
--   |1    |SPJ  |40 -> 41 |
--   +-----+-----+---------+
--   |2    |Simon|41       |
--   +-----+-----+---------+
--   
(+=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v infixr 3 +=. -- | Assign a field by subtraction (-=). -- --

Examples

-- --
--   subtractAge :: MonadIO m => ReaderT SqlBackend m ()
--   subtractAge = updateWhere [UserName ==. "SPJ" ] [UserAge -=. 1]
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+---------+
--   |id   |name |age      |
--   +-----+-----+---------+
--   |1    |SPJ  |40 -> 39 |
--   +-----+-----+---------+
--   |2    |Simon|41       |
--   +-----+-----+---------+
--   
(-=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v infixr 3 -=. -- | Assign a field by multiplication (*=). -- --

Examples

-- --
--   multiplyAge :: MonadIO m => ReaderT SqlBackend m ()
--   multiplyAge = updateWhere [UserName ==. "SPJ" ] [UserAge *=. 2]
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+--------+
--   |id   |name |age     |
--   +-----+-----+--------+
--   |1    |SPJ  |40 -> 80|
--   +-----+-----+--------+
--   |2    |Simon|41      |
--   +-----+-----+--------+
--   
(*=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v infixr 3 *=. -- | Assign a field by division (/=). -- --

Examples

-- --
--   divideAge :: MonadIO m => ReaderT SqlBackend m ()
--   divideAge = updateWhere [UserName ==. "SPJ" ] [UserAge /=. 2]
--   
-- -- The above query when applied on dataset-1, will produce this: -- --
--   +-----+-----+---------+
--   |id   |name |age      |
--   +-----+-----+---------+
--   |1    |SPJ  |40 -> 20 |
--   +-----+-----+---------+
--   |2    |Simon|41       |
--   +-----+-----+---------+
--   
(/=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v infixr 3 /=.