WHERE clause: restrict the query's result.
Moduleesqueleto-3.6.0.3Haskell2010
Database.Esqueleto.Legacy
WARNING
This module is introduced in version 3.5.0.0 to provide a smooth migration
experience from this legacy syntax to the new and improved syntax. If you've
imported this module, it means you've decided to use the old syntax for
a little bit longer, rather than migrate to the new stuff. That's fine!
But you should know that this module, and all of the legacy syntax, will be
completely removed from the library in version 4.0.0.0.
The esqueleto EDSL (embedded domain specific language).
This module replaces Database.Persist, so instead of
importing that module you should just import this one:
-- For a module using just esqueleto.
import Database.Esqueleto
If you need to use persistent's default support for queries
as well, either import it qualified:
-- For a module that mostly uses esqueleto.
import Database.Esqueleto
import qualified Database.Persist as P
or import esqueleto itself qualified:
-- For a module that uses esqueleto just on some queries.
import Database.Persist
import qualified Database.Esqueleto as E
Other than identifier name clashes, esqueleto does not
conflict with persistent in any way.
- 82 types
- 25 classes
- 249 values
- Packageesqueleto-3.6.0.3
- Exports371
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceLegacy.hs
Setup
0 declarationsIf you're already using persistent, then you're ready to use
esqueleto, no further setup is needed. If you're just
starting a new project and would like to use esqueleto, take
a look at persistent's book first
(http://www.yesodweb.com/book/persistent) to learn how to
define your schema.
Introduction
0 declarationsThe main goals of esqueleto are to:
Be easily translatable to SQL. When you take a look at a
esqueletoquery, you should be able to know exactly how the SQL query will end up. (As opposed to being a relational algebra EDSL such as HaskellDB, which is non-trivial to translate into SQL.)Support the most widely used SQL features. We'd like you to be able to use
esqueletofor all of your queries, no exceptions. Send a pull request or open an issue on our project page (https://github.com/prowdsponsor/esqueleto) if there's anything missing that you'd like to see.Be as type-safe as possible. We strive to provide as many type checks as possible. If you get bitten by some invalid code that type-checks, please open an issue on our project page so we can take a look.
However, it is not a goal to be able to write portable SQL.
We do not try to hide the differences between DBMSs from you,
and esqueleto code that works for one database may not work
on another. This is a compromise we have to make in order to
give you as much control over the raw SQL as possible without
losing too much convenience. This also means that you may
type-check a query that doesn't work on your DBMS.
Getting started
0 declarationsWe like clean, easy-to-read EDSLs. However, in order to achieve this goal we've used a lot of type hackery, leading to some hard-to-read type signatures. On this section, we'll try to build some intuition about the syntax.
For the following examples, we'll use this example schema:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
Person
name String
age Int Maybe
deriving Eq Show
BlogPost
title String
authorId PersonId
deriving Eq Show
Follow
follower PersonId
followed PersonId
deriving Eq Show
|]
Most of esqueleto was created with SELECT statements in
mind, not only because they're the most common but also
because they're the most complex kind of statement. The most
simple kind of SELECT would be:
SELECT *
FROM Person
In esqueleto, we may write the same query above as:
do people <- select $
from $ \person -> do
return person
liftIO $ mapM_ (putStrLn . personName . entityVal) people
The expression above has type SqlPersist m (), while
people has type [Entity Person]. The query above will be
translated into exactly the same query we wrote manually, but
instead of SELECT * it will list all entity fields (using
* is not robust). Note that esqueleto knows that we want
an Entity Person just because of the personName that we're
printing later.
However, most of the time we need to filter our queries using
WHERE. For example:
SELECT *
FROM Person
WHERE Person.name = "John"
In esqueleto, we may write the same query above as:
select $
from $ \p -> do
where_ (p ^. PersonName ==. val "John")
return p
Although esqueleto's code is a bit more noisy, it's has
almost the same structure (save from the return). The
(^.) operator is used to project a field from an entity.
The field name is the same one generated by persistent's
Template Haskell functions. We use val to lift a constant
Haskell value into the SQL query.
Another example would be:
SELECT *
FROM Person
WHERE Person.age >= 18
In esqueleto, we may write the same query above as:
select $
from $ \p -> do
where_ (p ^. PersonAge >=. just (val 18))
return p
Since age is an optional Person field, we use just to lift
val 18 :: SqlExpr (Value Int) into just (val 18) ::
SqlExpr (Value (Maybe Int)).
Implicit joins are represented by tuples. For example, to get the list of all blog posts and their authors, we could write:
SELECT BlogPost.*, Person.*
FROM BlogPost, Person
WHERE BlogPost.authorId = Person.id
ORDER BY BlogPost.title ASC
In esqueleto, we may write the same query above as:
select $
from $ \(b, p) -> do
where_ (b ^. BlogPostAuthorId ==. p ^. PersonId)
orderBy [asc (b ^. BlogPostTitle)]
return (b, p)
However, you may want your results to include people who don't
have any blog posts as well using a LEFT OUTER JOIN:
SELECT Person.*, BlogPost.*
FROM Person LEFT OUTER JOIN BlogPost
ON Person.id = BlogPost.authorId
ORDER BY Person.name ASC, BlogPost.title ASC
In esqueleto, we may write the same query above as:
select $
from $ \(p `LeftOuterJoin` mb) -> do
on (just (p ^. PersonId) ==. mb ?. BlogPostAuthorId)
orderBy [asc (p ^. PersonName), asc (mb ?. BlogPostTitle)]
return (p, mb)
On a LEFT OUTER JOIN the entity on the right hand side may
not exist (i.e. there may be a Person without any
BlogPosts), so while p :: SqlExpr (Entity Person), we have
mb :: SqlExpr (Maybe (Entity BlogPost)). The whole
expression above has type SqlPersist m [(Entity Person, Maybe
(Entity BlogPost))]. Instead of using (^.), we used
(?.) to project a field from a Maybe (Entity a).
We are by no means limited to joins of two tables, nor by
joins of different tables. For example, we may want a list
of the Follow entity:
SELECT P1.*, Follow.*, P2.*
FROM Person AS P1
INNER JOIN Follow ON P1.id = Follow.follower
INNER JOIN Person AS P2 ON P2.id = Follow.followed
In esqueleto, we may write the same query above as:
select $
from $ \(p1 `InnerJoin` f `InnerJoin` p2) -> do
on (p1 ^. PersonId ==. f ^. FollowFollower)
on (p2 ^. PersonId ==. f ^. FollowFollowed)
return (p1, f, p2)
We also currently support UPDATE and DELETE statements.
For example:
do update $ \p -> do
set p [ PersonName =. val "João" ]
where_ (p ^. PersonName ==. val "Joao")
delete $
from $ \p -> do
where_ (p ^. PersonAge <. just (val 14))
The results of queries can also be used for insertions.
In SQL, we might write the following, inserting a new blog
post for every user:
INSERT INTO BlogPost
SELECT ('Group Blog Post', id)
FROM Person
In esqueleto, we may write the same query above as:
insertSelect $ from $ \p->
return $ BlogPost <# "Group Blog Post" <&> (p ^. PersonId)
Individual insertions can be performed through Persistent's insert function, reexported for convenience.
esqueleto's Language
104 declarationsAn ON clause, useful to describe how two tables are related. Cross joins
and tuple-joins do not need an on clause, but InnerJoin and the various
outer joins do.
Database.Esqueleto.Experimental in version 4.0.0.0 of the library. The
Experimental module has a dramatically improved means for introducing
tables and entities that provides more power and less potential for runtime
errors.
If you don't include an on clause (or include too many!) then a runtime exception will be thrown.
As an example, consider this simple join:
select $
from $ \(foo `InnerJoin` bar) -> do
on (foo ^. FooId ==. bar ^. BarFooId)
...
We need to specify the clause for joining the two columns together. If we had this:
select $
from $ \(foo `CrossJoin` bar) -> do
...
Then we can safely omit the on clause, because the cross join will make pairs of all records possible.
You can do multiple on clauses in a query. This query joins three tables, and has two on clauses:
select $
from $ \(foo `InnerJoin` bar `InnerJoin` baz) -> do
on (baz ^. BazId ==. bar ^. BarBazId)
on (foo ^. FooId ==. bar ^. BarFooId)
...
Old versions of esqueleto required that you provide the on clauses in reverse order. This restriction has been lifted - you can now provide on clauses in any order, and the SQL should work itself out. The above query is now totally equivalent to this:
select $
from $ \(foo `InnerJoin` bar `InnerJoin` baz) -> do
on (foo ^. FooId ==. bar ^. BarFooId)
on (baz ^. BazId ==. bar ^. BarBazId)
...
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)
ORDER BY clause. See also asc and desc.
Multiple calls to orderBy get concatenated on the final query, including distinctOnOrderBy.
Ascending order of this field or SqlExpression.
Descending order of this field or SqlExpression.
LIMIT. Limit the number of returned rows.
OFFSET. Usually used with limit.
Deprecated. This function is deprecated, as it is only supported in Postgresql. Please use the variant in Database.Esqueleto.PostgreSQL instead.
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.
Erase an SqlExpression's type so that it's suitable to be used by distinctOn.
Deprecated. This function is deprecated, as it is only supported in Postgresql. Please use the function defined in Database.Esqueleto.PostgreSQL instead.
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]
...
HAVING.
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.
Project a field of an entity.
Lift a constant value from Haskell-land to the query.
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:
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}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'.
NULL value.
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'
Project an SqlExpression that may be null, guarding against null cases.
COUNT(*) value.
COUNT.
COUNT(DISTINCT x).
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 = ?
This operator translates to the SQL operator >=.
Example:
where_ $ user ^. UserAge >=. val 21
This operator translates to the SQL operator >.
Example:
where_ $ user ^. UserAge >. val 20
This operator translates to the SQL operator <=.
Example:
where_ $ val 21 <=. user ^. UserAge
This operator translates to the SQL operator <.
Example:
where_ $ val 20 <. user ^. UserAge
This operator translates to the SQL operator !=.
Example:
where_ $ user ^. UserName !=. val Bob
This operator translates to the SQL operator AND.
Example:
where_ $
user ^. UserName ==. val Matt
&&. user ^. UserAge >=. val 21
This operator translates to the SQL operator AND.
Example:
where_ $
user ^. UserName ==. val Matt
||. user ^. UserName ==. val John
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
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
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
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
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
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.
Same as castNum, but for nullable values.
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.
Like coalesce, but takes a non-nullable SqlExpression
placed at the end of the SqlExpression list, which guarantees
a non-NULL result.
LOWER function.
UPPER function.
@since 3.3.0
TRIM function.
@since 3.3.0
LTRIM function.
@since 3.3.0
RTRIM function.
@since 3.3.0
LENGTH function.
@since 3.3.0
LEFT function.
@since 3.3.0
RIGHT function.
@since 3.3.0
LIKE operator.
Deprecated. Since 3.6.0: ilike is only supported on Postgres. Please import it from 'Database.Esqueleto.PostgreSQL.
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.
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.
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.
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.
Execute a subquery SELECT in an SqlExpression. Returns a
list of values.
Lift a list of constant value from Haskell-land to the query.
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].
NOT IN operator.
NOT EXISTS operator.
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.
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.
This only implements the full CASE statement, it does not implement the "simple" CASE statement.
At least one when_ and then_ is mandatory otherwise it will emit an error.
The else_ is also mandatory, unlike the SQL statement in which if the
ELSEis omitted it will return aNULL. You can reproduce this via nothing.
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.
The inverse of toBaseId. Note that this is somewhat less "safe" than toBaseId. Calling toBaseId will usually mean that a foreign key constraint is present that guarantees the presence of the base ID. fromBaseId has no such guarantee. Consider the code example given in toBaseId:
Bar
barNum Int
Foo
bar BarId
fooNum Int
Primary bar
instance ToBaseId Foo where
type BaseEnt Foo = Bar
toBaseIdWitness barId = FooKey barId
The type of toBaseId for Foo would be:
toBaseId :: SqlExpr (Value FooId) -> SqlExpr (Value BarId)
The foreign key constraint on Foo means that every FooId points to
a BarId in the database. However, fromBaseId will not have this:
fromBaseId :: SqlExpr (Value BarId) -> SqlExpr (Value FooId)
As fromBaseId, but works on Maybe keys.
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.
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).
Performs a COUNT of the given query in a subSelect manner. This is
always guaranteed to return a result value, and is completely safe.
subSelectForeign :: (BackendCompatible SqlBackend (PersistEntityBackend val1), PersistEntity val1, PersistEntity val2, PersistField a)=> SqlExpr (Entity val2)An expression representing the table you have access to now.
-> EntityField val2 (Key val1)The foreign key field on the table.
-> (SqlExpr (Entity val1) -> SqlExpr (Value a))A function to extract a value from the foreign reference table.
-> 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)
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.
Execute a subquery SELECT in a SqlExpr. This function is unsafe,
because it can throw runtime exceptions in two cases:
If the query passed has 0 result rows, then it will return a
NULLvalue. Thepersistentparsing operations will fail on an unexpectedNULL.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".
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.
Class that enables one to use toBaseId to convert an entity's key on a query into another (cf. toBaseId).
Associated types
type family BaseEnt ente.g.
type BaseEnt MyBase = MyChild
Methods
toBaseIdWitness :: Key (BaseEnt ent) -> Key entConvert 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.
Syntax sugar for case_.
Syntax sugar for case_.
Syntax sugar for case_.
FROM clause: bring entities into scope.
Note that this function will be replaced by the one in
Database.Esqueleto.Experimental in version 4.0.0.0 of the library. The
Experimental module has a dramatically improved means for introducing
tables and entities that provides more power and less potential for runtime
errors.
This function internally uses two type classes in order to provide some flexibility of how you may call it. Internally we refer to these type classes as the two different magics.
The innermost magic allows you to use from with the
following types:
expr (Entity val), which brings a single entity into scope.expr (Maybe (Entity val)), which brings a single entity that may beNULLinto scope. Used forOUTER JOINs.A
JOINof any other two types allowed by the innermost magic, where aJOINmay be an InnerJoin, a CrossJoin, a LeftOuterJoin, a RightOuterJoin, or a FullOuterJoin. TheJOINshave left fixity.
The outermost magic allows you to use from on any tuples of
types supported by innermost magic (and also tuples of tuples,
and so on), up to 8-tuples.
Note that using from for the same entity twice does work and
corresponds to a self-join. You don't even need to use two
different calls to from, you may use a JOIN or a tuple.
The following are valid examples of uses of from (the types
of the arguments of the lambda are inside square brackets):
from $ \person -> ...
from $ \(person, blogPost) -> ...
from $ \(p `LeftOuterJoin` mb) -> ...
from $ \(p1 `InnerJoin` f `InnerJoin` p2) -> ...
from $ \((p1 `InnerJoin` f) `InnerJoin` p2) -> ...
The types of the arguments to the lambdas above are, respectively:
person
:: ( Esqueleto query expr backend
, PersistEntity Person
, PersistEntityBackend Person ~ backend
) => expr (Entity Person)
(person, blogPost)
:: (...) => (expr (Entity Person), expr (Entity BlogPost))
(p `LeftOuterJoin` mb)
:: (...) => InnerJoin (expr (Entity Person)) (expr (Maybe (Entity BlogPost)))
(p1 `InnerJoin` f `InnerJoin` p2)
:: (...) => InnerJoin
(InnerJoin (expr (Entity Person))
(expr (Entity Follow)))
(expr (Entity Person))
(p1 `InnerJoin` (f `InnerJoin` p2)) ::
:: (...) => InnerJoin
(expr (Entity Person))
(InnerJoin (expr (Entity Follow))
(expr (Entity Person)))
Note that some backends may not support all kinds of JOINs.
Instances18Monad, Functor, Applicative, Foldable, Traversable, HasField, …
Monad ValueDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFunctor ValueDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalApplicative ValueDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFoldable ValueDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalTraversable ValueDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(PersistEntity rec, PersistField typ, SymbolToField sym rec typ) => HasField sym (SqlExpr (Entity rec)) (SqlExpr (Value typ))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalThis instance allows you to use
record.fieldnotation with GHC 9.2'sOverloadedRecordDotextension.Example:
-- persistent model: BlogPost authorId PersonId title Text -- query: select $ do bp <- from $table@BlogPost pure $ bp.titleThis is exactly equivalent to the following:
blogPost :: SqlExpr (Entity BlogPost) blogPost ^. BlogPostTitle blogPost ^. #title blogPost.titleThere's another instance defined on
SqlExpr (Entity (Maybe rec)), which allows you to project from aLEFT JOINed entity.(PersistEntity rec, PersistField typ, PersistField typ', SymbolToField sym rec typ, NullableFieldProjection typ typ', HasField sym (SqlExpr (Maybe (Entity rec))) (SqlExpr (Value (Maybe typ')))) => HasField sym (SqlExpr (Maybe (Entity rec))) (SqlExpr (Value (Maybe typ')))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalThis instance allows you to use
record.fieldnotation with GC 9.2'sOverloadedRecordDotextension.Example:
-- persistent model: Person name Text BlogPost title Text authorId PersonId -- query: select $ do (p :& bp) <- from $tablePersonBlogPost on do \(p :& bp) -> just p.id ==. bp.authorId pure (p.name, bp.title)leftJointableThe following forms are all equivalent:
blogPost :: SqlExpr (Maybe (Entity BlogPost)) blogPost ?. BlogPostTitle blogPost ?. #title blogPost.title(ToFrom a a', SqlSelect b r, ToAlias b, ToAliasReference b, d ~ (a' :& b)) => DoInnerJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) dDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join(ToFrom a a', ToMaybe b, d ~ (a' :& ToMaybeT b), SqlSelect b r, ToAlias b, ToAliasReference b) => DoLeftJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) dDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.JoinEq a => Eq (Value a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalOrd a => Ord (Value a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalShow a => Show (Value a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalToAlias (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasToAliasReference (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasReferenceToMaybe (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybeToSomeValues (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistField a => SqlSelect (SqlExpr (Value a)) (Value a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalYou may return any single value (i.e. a single column) from a select query.
type ToMaybeT (SqlExpr (Value a)) = SqlExpr (Value (Maybe (Nullable a)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybe
A list of single values. There's a limited set of functions able to work with this data type (such as subList_select, valList, in_ and exists).
Constructors
Instances3Eq, Ord, Show
Phantom type used by distinctOn and don.
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.
Constructors
ForUpdateFOR UPDATEsyntax. Supported by MySQL, Oracle and PostgreSQL.ForUpdateSkipLockedFOR UPDATE SKIP LOCKEDsyntax. Supported by MySQL, Oracle and PostgreSQL.
FOR UPDATE SKIP LOCKED syntax.
locking forUpdateSkipLocked
Lockable entity
Example use:
select $ do
(p :& bp) <- from $
table Person
innerJoin table BlogPost
on do
(p :& bp) -> p ^. PersonId ==. b ^. BlogPostAuthorId
forUpdateOf (p :& b) skipLocked
return p
Methods
Instances2LockableEntity
PersistEntity val => LockableEntity (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(LockableEntity a, LockableEntity b) => LockableEntity (a :& b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal
Phantom class of data types that are treated as strings by the RDBMS. It has no methods because it's only used to avoid type errors such as trying to concatenate integers.
If you have a custom data type or newtype, feel free to make
it an instance of this class.
Instances6SqlString
SqlString HtmlDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalSqlString ByteStringDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalSqlString TextDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalSqlString TextDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalSqlString a => SqlString (Maybe a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internala ~ Char => SqlString [a]Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal
Joins
Data type that represents an INNER JOIN (see LeftOuterJoin for an example).
Constructors
InnerJoin a binfixl 2
Instances3IsJoinKind, From, ToFrom
IsJoinKind InnerJoinDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (InnerJoin a b) => From (InnerJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(DoInnerJoin lateral lhs rhs r, lateral ~ IsLateral rhs) => ToFrom (InnerJoin lhs rhs) rDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join · orphan
Data type that represents a CROSS JOIN (see LeftOuterJoin for an example).
Constructors
CrossJoin a binfixl 2
Instances3IsJoinKind, From, ToFrom
IsJoinKind CrossJoinDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (CrossJoin a b) => From (CrossJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(DoCrossJoin lateral lhs rhs r, IsLateral rhs ~ lateral) => ToFrom (CrossJoin lhs rhs) rDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join · orphan
Data type that represents a LEFT OUTER JOIN. For example,
select $
from $ \(person `LeftOuterJoin` pet) ->
...
is translated into
SELECT ...
FROM Person LEFT OUTER JOIN Pet
...
See also: from.
Constructors
LeftOuterJoin a binfixl 2
Instances3IsJoinKind, From, ToFrom
IsJoinKind LeftOuterJoinDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (LeftOuterJoin a b) => From (LeftOuterJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(DoLeftJoin lateral lhs rhs r, lateral ~ IsLateral rhs) => ToFrom (LeftOuterJoin lhs rhs) rDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join · orphan
Data type that represents a RIGHT OUTER JOIN (see LeftOuterJoin for an example).
Constructors
RightOuterJoin a binfixl 2
Instances3IsJoinKind, From, ToFrom
IsJoinKind RightOuterJoinDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (RightOuterJoin a b) => From (RightOuterJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(ToFrom a a', ToFrom b b', ToMaybe a', ToMaybeT a' ~ ma, HasOnClause rhs (ma :& b'), ErrorOnLateral b, rhs ~ (b, ma :& b' -> SqlExpr (Value Bool))) => ToFrom (RightOuterJoin a rhs) (ma :& b')Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join · orphan
Data type that represents a FULL OUTER JOIN (see LeftOuterJoin for an example).
Constructors
FullOuterJoin a binfixl 2
Instances3IsJoinKind, From, ToFrom
IsJoinKind FullOuterJoinDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (FullOuterJoin a b) => From (FullOuterJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(ToFrom a a', ToFrom b b', ToMaybe a', ToMaybeT a' ~ ma, ToMaybe b', ToMaybeT b' ~ mb, HasOnClause rhs (ma :& mb), ErrorOnLateral b, rhs ~ (b, ma :& mb -> SqlExpr (Value Bool))) => ToFrom (FullOuterJoin a rhs) (ma :& mb)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join · orphan
(Internal) A kind of JOIN.
Constructors
InnerJoinKindINNER JOINCrossJoinKindCROSS JOINLeftOuterJoinKindLEFT OUTER JOINRightOuterJoinKindRIGHT OUTER JOINFullOuterJoinKindFULL OUTER JOIN
Exception thrown whenever on is used to create an ON
clause but no matching JOIN is found.
Constructors
Instances4Eq, Ord, Show, Exception
Eq OnClauseWithoutMatchingJoinExceptionDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalOrd OnClauseWithoutMatchingJoinExceptionDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalShow OnClauseWithoutMatchingJoinExceptionDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalException OnClauseWithoutMatchingJoinExceptionDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal
SQL backend
14 declarationsSQL backend for esqueleto using SqlPersistT.
Instances9Monad, Functor, Applicative, DoInnerJoin, DoLeftJoin, DoCrossJoin, …
Monad SqlQueryDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFunctor SqlQueryDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalApplicative SqlQueryDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(ToFrom a a', SqlSelect b r, ToAlias b, ToAliasReference b, d ~ (a' :& b)) => DoInnerJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) dDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join(ToFrom a a', ToMaybe b, d ~ (a' :& ToMaybeT b), SqlSelect b r, ToAlias b, ToAliasReference b) => DoLeftJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) dDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join(ToFrom a a', SqlSelect b r, ToAlias b, ToAliasReference b) => DoCrossJoin Lateral a (a' -> SqlQuery b) (a' :& b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join(SqlSelect a r, ToAlias a, ToAliasReference a) => ToSqlSetOperation (SqlQuery a) aDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.SqlSetOperation(SqlSelect a r, ToAlias a, ToAliasReference a) => ToFrom (SqlQuery a) aDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.FromValidOnClause (a -> SqlQuery b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join
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.
Instances29Functor, HasField, DoInnerJoin, DoLeftJoin, From, LockableEntity, …
TypeError SqlExprFunctorMessage => Functor SqlExprDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFolks often want the ability to promote a Haskell function into the SqlExpr expression language - and naturally reach for fmap. Unfortunately, this is impossible. We cannot send *functions* to the database, which is what we would need to do in order for this to make sense. Let's consider the type of fmap for SqlExpr:
fmap :: (a -> b) -> SqlExpr a -> SqlExpr bThis type signature is making a pretty strong claim: "Give me a Haskell function from
a -> b. I will then transform a SQL expression representing a Haskell value of typeaand turn it into a SQL expression representing a Haskell value of typeb."Let's suppose we *could* do this -
fmap (+1)would have to somehow inspect the function expression means "add one", and then translate that to the appropriate SQL.This is why
esqueletodefines a bunch of operators:x +. (val 1)can be used instead offmap (+1) x.If you do have a SQL function, then you can provide a safe type and introduce it with unsafeSqlFunction or unsafeSqlBinOp.
(PersistEntity rec, PersistField typ, SymbolToField sym rec typ) => HasField sym (SqlExpr (Entity rec)) (SqlExpr (Value typ))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalThis instance allows you to use
record.fieldnotation with GHC 9.2'sOverloadedRecordDotextension.Example:
-- persistent model: BlogPost authorId PersonId title Text -- query: select $ do bp <- from $table@BlogPost pure $ bp.titleThis is exactly equivalent to the following:
blogPost :: SqlExpr (Entity BlogPost) blogPost ^. BlogPostTitle blogPost ^. #title blogPost.titleThere's another instance defined on
SqlExpr (Entity (Maybe rec)), which allows you to project from aLEFT JOINed entity.(PersistEntity rec, PersistField typ, PersistField typ', SymbolToField sym rec typ, NullableFieldProjection typ typ', HasField sym (SqlExpr (Maybe (Entity rec))) (SqlExpr (Value (Maybe typ')))) => HasField sym (SqlExpr (Maybe (Entity rec))) (SqlExpr (Value (Maybe typ')))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalThis instance allows you to use
record.fieldnotation with GC 9.2'sOverloadedRecordDotextension.Example:
-- persistent model: Person name Text BlogPost title Text authorId PersonId -- query: select $ do (p :& bp) <- from $tablePersonBlogPost on do \(p :& bp) -> just p.id ==. bp.authorId pure (p.name, bp.title)leftJointableThe following forms are all equivalent:
blogPost :: SqlExpr (Maybe (Entity BlogPost)) blogPost ?. BlogPostTitle blogPost ?. #title blogPost.title(ToFrom a a', SqlSelect b r, ToAlias b, ToAliasReference b, d ~ (a' :& b)) => DoInnerJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) dDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.Join(ToFrom a a', ToMaybe b, d ~ (a' :& ToMaybeT b), SqlSelect b r, ToAlias b, ToAliasReference b) => DoLeftJoin Lateral a (a' -> SqlQuery b, d -> SqlExpr (Value Bool)) dDefined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.From.JoinFromPreprocess (SqlExpr (Maybe (Entity val))) => From (SqlExpr (Maybe (Entity val)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (SqlExpr (Entity val)) => From (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity val => LockableEntity (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalToAlias (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasToAlias (SqlExpr (Maybe (Entity a)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasToAlias (SqlExpr (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasToAliasReference (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasReferenceToAliasReference (SqlExpr (Maybe (Entity a)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasReferenceToAliasReference (SqlExpr (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasReferenceToMaybe (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybeToMaybe (SqlExpr (Maybe a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybeToMaybe (SqlExpr (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybe(PersistEntity val, BackendCompatible SqlBackend (PersistEntityBackend val)) => FromPreprocess (SqlExpr (Maybe (Entity val)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(PersistEntity val, BackendCompatible SqlBackend (PersistEntityBackend val)) => FromPreprocess (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalToSomeValues (SqlExpr (Value a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internala ~ Value b => UnsafeSqlFunctionArgument (SqlExpr a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity a => SqlSelect (SqlExpr (Maybe (Entity a))) (Maybe (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity a => SqlSelect (SqlExpr (Entity a)) (Entity a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity e => SqlSelect (SqlExpr (Insertion e)) (Insertion e)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalINSERT INTOhack.PersistField a => SqlSelect (SqlExpr (Value a)) (Value a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalYou may return any single value (i.e. a single column) from a select query.
PersistEntity ent => ToFrom (Table ent) (SqlExpr (Entity ent))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.Fromtype ToMaybeT (SqlExpr (Value a)) = SqlExpr (Value (Maybe (Nullable a)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybetype ToMaybeT (SqlExpr (Maybe a)) = SqlExpr (Maybe a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybetype ToMaybeT (SqlExpr (Entity a)) = SqlExpr (Maybe (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybe
Constraint synonym for persistent entities whose backend
is SqlBackend.
Execute an esqueleto SELECT query inside persistent's
SqlPersistT monad and return a list of rows.
We've seen that from has some magic about which kinds of
things you may bring into scope. This select function also
has some magic for which kinds of things you may bring back to
Haskell-land by using SqlQuery's return:
You may return a
SqlExpr (Entity v)for an entityv(i.e., like the*in SQL), which is then returned to Haskell-land as justEntity v.You may return a
SqlExpr (Maybe (Entity v))for an entityvthat may beNULL, which is then returned to Haskell-land asMaybe (Entity v). Used forOUTER JOINs.You may return a
SqlExpr (Value t)for a valuet(i.e., a single column), wheretis any instance of PersistField, which is then returned to Haskell-land asValue t. You may useValueto return projections of anEntity(see(^.)and(?.)) or to return any other value calculated on the query (e.g., countRows or subSelect).
The SqlSelect a r class has functional dependencies that
allow type information to flow both from a to r and
vice-versa. This means that you'll almost never have to give
any type signatures for esqueleto queries. For example, the
query select $ from $ \p -> return p alone is ambiguous, but
in the context of
do ps <- select $
from $ \p ->
return p
liftIO $ mapM_ (putStrLn . personName . entityVal) ps
we are able to infer from that single personName . entityVal
function composition that the p inside the query is of type
SqlExpr (Entity Person).
Execute an esqueleto SELECT query inside persistent's
SqlPersistT monad and return the first entry wrapped in a Maybe.
@since 3.5.1.0
Example usage
firstPerson :: MonadIO m => SqlPersistT m (Maybe (Entity Person))
firstPerson =
selectOne $ do
person <- from $ table @Person
return person
The above query is equivalent to a select combined with limit but you would still have to transform the results from a list:
firstPerson :: MonadIO m => SqlPersistT m [Entity Person]
firstPerson =
select $ do
person <- from $ table @Person
limit 1
return person
Execute an esqueleto SELECT query inside persistent's
SqlPersistT monad and return a Source of rows.
Execute an esqueleto DELETE query inside persistent's
SqlPersistT monad. Note that currently there are no type
checks for statements that should not appear on a DELETE
query.
Example of usage:
delete $
from $ \appointment ->
where_ (appointment ^. AppointmentDate <. val now)
Unlike select, there is a useful way of using delete that will lead to type ambiguities. If you want to delete all rows (i.e., no where_ clause), you'll have to use a type signature:
delete $
from $ \(appointment :: SqlExpr (Entity Appointment)) ->
return ()
Database.Esqueleto.Experimental:
delete $ do
userFeature <- from $ table @UserFeature
where_ ((userFeature ^. UserFeatureFeature) notIn valList allKnownFeatureFlags)
Same as delete, but returns the number of rows affected.
Execute an esqueleto UPDATE query inside persistent's
SqlPersistT monad. Note that currently there are no type
checks for statements that should not appear on a UPDATE
query.
Example of usage:
update $ \p -> do
set p [ PersonAge =. just (val thisYear) -. p ^. PersonBorn ]
where_ $ isNothing (p ^. PersonAge)
Same as update, but returns the number of rows affected.
Insert a PersistField for every selected value.
Insert a PersistField for every selected value, return the count afterward
Apply a PersistField constructor to SqlExpr Value arguments.
Apply extra SqlExpr Value arguments to a PersistField constructor
Rendering Queries
renderQueryToText :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m)=> Mode-> SqlQuery aThe SQL query you want to render.
-> ReaderT backend m (Text, [PersistValue])
Renders a SqlQuery into a Text value along with the list of
PersistValues that would be supplied to the database for ? placeholders.
You must ensure that the Mode you pass to this function corresponds with
the actual SqlQuery. If you pass a query that uses incompatible features
(like an INSERT statement with a SELECT mode) then you'll get a weird
result.
renderQuerySelect :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m)=> SqlQuery aThe SQL query you want to render.
-> ReaderT backend m (Text, [PersistValue])
Renders a SqlQuery into a Text value along with the list of
PersistValues that would be supplied to the database for ? placeholders.
renderQueryUpdate :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m)=> SqlQuery aThe SQL query you want to render.
-> ReaderT backend m (Text, [PersistValue])
Renders a SqlQuery into a Text value along with the list of
PersistValues that would be supplied to the database for ? placeholders.
renderQueryDelete :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m)=> SqlQuery aThe SQL query you want to render.
-> ReaderT backend m (Text, [PersistValue])
Renders a SqlQuery into a Text value along with the list of
PersistValues that would be supplied to the database for ? placeholders.
renderQueryInsertInto :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m)=> SqlQuery aThe SQL query you want to render.
-> ReaderT backend m (Text, [PersistValue])
Renders a SqlQuery into a Text value along with the list of
PersistValues that would be supplied to the database for ? placeholders.
Internal.Language
1 declarationInstances14From, …
FromPreprocess (SqlExpr (Maybe (Entity val))) => From (SqlExpr (Maybe (Entity val)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (SqlExpr (Entity val)) => From (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (CrossJoin a b) => From (CrossJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (FullOuterJoin a b) => From (FullOuterJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (InnerJoin a b) => From (InnerJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (LeftOuterJoin a b) => From (LeftOuterJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (RightOuterJoin a b) => From (RightOuterJoin a b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b) => From (a, b)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b, From c) => From (a, b, c)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b, From c, From d) => From (a, b, c, d)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b, From c, From d, From e) => From (a, b, c, d, e)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b, From c, From d, From e, From f) => From (a, b, c, d, e, f)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b, From c, From d, From e, From f, From g) => From (a, b, c, d, e, f, g)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(From a, From b, From c, From d, From e, From f, From g, From h) => From (a, b, c, d, e, f, g, h)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal
RDBMS-specific modules
0 declarationsThere are many differences between SQL syntax and functions
supported by different RDBMSs. Since version 2.2.8,
esqueleto includes modules containing functions that are
specific to a given RDBMS.
PostgreSQL: Database.Esqueleto.PostgreSQL.
In order to use these functions, you need to explicitly import their corresponding modules, they're not re-exported here.
Helpers
3 declarationsvalkey i = val . toSqlKey
(https://github.com/prowdsponsor/esqueleto/issues/9).
valJ is like val but for something that is already a Value. The use
case it was written for was, given a Value lift the Key for that Value
into the query expression in a type safe way. However, the implementation is
more generic than that so we call it valJ.
Its important to note that the input entity and the output entity are constrained to be the same by the type signature on the function (https://github.com/prowdsponsor/esqueleto/pull/69).
Avoid N+1 queries and join entities into a map structure.
This function is useful to call on the result of a single JOIN. For
example, suppose you have this query:
getFoosAndNestedBarsFromParent
:: ParentId
-> SqlPersistT IO [(Entity Foo, Maybe (Entity Bar))]
getFoosAndNestedBarsFromParent parentId =
select $ do
(foo :& bar) <- from $
table Foo
`LeftOuterJoin`
table Bar
`on` do
\(foo :& bar) ->
foo ^. FooId ==. bar ?. BarFooId
where_ $
foo ^. FooParentId ==. val parentId
pure (foo, bar)
This is a natural result type for SQL - a list of tuples. However, it's not
what we usually want in Haskell - each Foo in the list will be represented
multiple times, once for each Bar.
We can write fmap associateJoin and it will translate it into a Map
that is keyed on the Key of the left Entity, and the value is a tuple of
the entity's value as well as the list of each coresponding entity.
getFoosAndNestedBarsFromParentHaskellese
:: ParentId
-> SqlPersistT (Map (Key Foo) (Foo, [Maybe (Entity Bar)]))
getFoosAndNestedBarsFromParentHaskellese parentId =
fmap associateJoin $ getFoosdAndNestedBarsFromParent parentId
What if you have multiple joins?
Let's use associateJoin with a *two* join query.
userPostComments
:: SqlQuery (SqlExpr (Entity User, Entity Post, Entity Comment))
userPostsComment = do
(u :& p :& c) <- from $
table User
`InnerJoin`
table Post
on do
\(u :& p) ->
u ^. UserId ==. p ^. PostUserId
`InnerJoin`
table @Comment
`on` do
\(_ :& p :& c) ->
p ^. PostId ==. c ^. CommentPostId
pure (u, p, c)
This query returns a User, with all of the users Posts, and then all of the Comments on that post.
First, we *nest* the tuple.
nest :: (a, b, c) -> (a, (b, c))
nest (a, b, c) = (a, (b, c))
This makes the return of the query conform to the input expected from associateJoin.
nestedUserPostComments
:: SqlPersistT IO [(Entity User, (Entity Post, Entity Comment))]
nestedUserPostComments =
fmap nest $ select userPostsComments
Now, we can call associateJoin on it.
associateUsers
:: [(Entity User, (Entity Post, Entity Comment))]
-> Map UserId (User, [(Entity Post, Entity Comment)])
associateUsers =
associateJoin
Next, we'll use the Functor instances for Map and tuple to call
associateJoin on the [(Entity Post, Entity Comment)].
associatePostsAndComments
:: Map UserId (User, [(Entity Post, Entity Comment)])
-> Map UserId (User, Map PostId (Post, [Entity Comment]))
associatePostsAndComments =
fmap (fmap associateJoin)
For more reading on this topic, see this Foxhound Systems blog post.
Re-exports
237 declarationsWe re-export many symbols from persistent for convenince:
"Store functions" from Database.Persist.
Everything from Database.Persist.Class except for
PersistQueryanddelete(use deleteKey instead).Everything from Database.Persist.Types except for
Update,SelectOpt,BackendSpecificFilterandFilter.Everything from Database.Persist.Sql except for
deleteWhereCountandupdateWhereCount.
Predefined parseJSON. The input JSON looks like
{"id": 1, "name": ...}.
The typical usage is:
instance FromJSON (Entity User) where
parseJSON = entityIdFromJSON
Predefined toJSON. The resulting JSON looks like
{"id": 1, "name": ...}.
The typical usage is:
instance ToJSON (Entity User) where
toJSON = entityIdToJSON
Get list of values corresponding to given entity.
Convenience function for getting a free PersistField instance from a type with JSON instances. The JSON parser used will accept JSON values other that object and arrays. So, if your instance serializes the data to a JSON string, this will still work.
Example usage in combination with toPersistValueJSON:
instance PersistField MyData where
fromPersistValue = fromPersistValueJSON
toPersistValue = toPersistValueJSON
Predefined parseJSON. The input JSON looks like
{"key": 1, "value": {"name": ...}}.
The typical usage is:
instance FromJSON (Entity User) where
parseJSON = keyValueEntityFromJSON
Predefined toJSON. The resulting JSON looks like
{"key": 1, "value": {"name": ...}}.
The typical usage is:
instance ToJSON (Entity User) where
toJSON = keyValueEntityToJSON
Construct an Entity record by providing a value for each of the
record's fields.
These constructions are equivalent:
entityMattConstructor, entityMattTabulate :: Entity User
entityMattConstructor =
Entity
{ entityKey = toSqlKey 123
, entityVal =
User
{ userName = Matt
, userAge = 33
}
}
entityMattTabulate =
tabulateEntity $ \case
UserId ->
toSqlKey 123
UserName ->
Matt
UserAge ->
33
This is a specialization of tabulateEntityA, which allows you to construct an Entity by providing an Applicative action for each field instead of a regular function.
Convenience function for getting a free PersistField instance from a type with JSON instances.
Example usage in combination with fromPersistValueJSON:
instance PersistField MyData where
fromPersistValue = fromPersistValueJSON
toPersistValue = toPersistValueJSON
Get the Keys of all records matching the given criterion.
For an example, see selectList.
Curry this to make a convenience function that loads an associated model.
foreign = belongsTo foreignIdSame as belongsTo, but uses getJust and therefore is similarly unsafe.
Like get, but returns the complete Entity.
Example usage
getSpjEntity :: MonadIO m => ReaderT SqlBackend m (Maybe (Entity User))
getSpjEntity = getEntity spjIdmSpjEnt <- getSpjEntityThe above query when applied on dataset-1, will get this entity:
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | SPJ | 40 |
+----+------+-----+Same as get, but for a non-null (not Maybe) foreign key. Unsafe unless your database is enforcing that the foreign key is valid.
Example usage
getJustSpj :: MonadIO m => ReaderT SqlBackend m User
getJustSpj = getJust spjIdspj <- getJust spjIdThe above query when applied on dataset-1, will get this record:
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | SPJ | 40 |
+----+------+-----+getJustUnknown :: MonadIO m => ReaderT SqlBackend m User
getJustUnknown = getJust unknownIdmrx <- getJustUnknown
This just throws an error.
Same as getJust, but returns an Entity instead of just the record.
Example usage
getJustEntitySpj :: MonadIO m => ReaderT SqlBackend m (Entity User)
getJustEntitySpj = getJustEntity spjIdspjEnt <- getJustEntitySpjThe above query when applied on dataset-1, will get this entity:
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | SPJ | 40 |
+----+------+-----+Like insert, but returns the complete Entity.
Example usage
insertHaskellEntity :: MonadIO m => ReaderT SqlBackend m (Entity User)
insertHaskellEntity = insertEntity $ User "Haskell" 81haskellEnt <- insertHaskellEntityThe above query when applied on dataset-1, will produce this:
+----+---------+-----+
| id | name | age |
+----+---------+-----+
| 1 | SPJ | 40 |
+----+---------+-----+
| 2 | Simon | 41 |
+----+---------+-----+
| 3 | Haskell | 81 |
+----+---------+-----+Like insertEntity but just returns the record instead of Entity.
Example usage
insertDaveRecord :: MonadIO m => ReaderT SqlBackend m User
insertDaveRecord = insertRecord $ User "Dave" 50dave <- insertDaveRecordThe above query when applied on dataset-1, will produce this:
+-----+------+-----+
|id |name |age |
+-----+------+-----+
|1 |SPJ |40 |
+-----+------+-----+
|2 |Simon |41 |
+-----+------+-----+
|3 |Dave |50 |
+-----+------+-----+Run a query against a larger backend by plucking out BaseBackend backend
This is a helper for reusing existing queries when expanding the backend type.
Run a query against a compatible backend, by projecting the backend
This is a helper for using queries which run against a specific backend type that your backend is compatible with.
Check whether there are any conflicts for unique keys with this entity and existing entities in the database.
Returns Nothing if the entity would be unique, and could thus safely be inserted. on a conflict returns the conflicting key
Example usage
We use schema-1 and dataset-1 here.
This would be Nothing:
mAlanConst <- checkUnique $ User "Alan" 70While this would be Just because SPJ already exists:
mSpjConst <- checkUnique $ User "SPJ" 60Check whether there are any conflicts for unique keys with this entity and existing entities in the database.
Returns Nothing if the entity would stay unique, and could thus safely be updated. on a conflict returns the conflicting key
This is similar to checkUnique, except it's useful for updating - when the particular entity already exists, it would normally conflict with itself. This variant ignores those conflicts
Example usage
We use schema-1 and dataset-1 here.
This would be Nothing:
mAlanConst <- checkUnique $ User "Alan" 70While this would be Just because SPJ already exists:
mSpjConst <- checkUnique $ User "SPJ" 60A modification of getBy, which takes the PersistEntity itself instead of a Unique record. Returns a record matching one of the unique keys. This function makes the most sense on entities with a single Unique constructor.
Example usage
getBySpjValue :: MonadIO m => ReaderT SqlBackend m (Maybe (Entity User))
getBySpjValue = getByValue $ User SPJ 999
mSpjEnt <- getBySpjValueThe above query when applied on dataset-1, will get this record:
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | SPJ | 40 |
+----+------+-----+Insert a value, checking for conflicts with any unique constraints. If a duplicate exists in the database, it is returned as Left. Otherwise, the new 'Key is returned as Right.
Example usage
With schema-2 and dataset-1, we have following lines of code:
l1 <- insertBy $ User "SPJ" 20
l2 <- insertBy $ User "XXX" 41
l3 <- insertBy $ User "SPJ" 40
r1 <- insertBy $ User "XXX" 100First three lines return Left because there're duplicates in given record's uniqueness constraints. While the last line returns a new key as Right.
Like insertEntity, but returns Nothing when the record couldn't be inserted because of a uniqueness constraint.
Example usage
We use schema-2 and dataset-1 here.
insertUniqueSpjEntity :: MonadIO m => ReaderT SqlBackend m (Maybe (Entity User))
insertUniqueSpjEntity = insertUniqueEntity $ User "SPJ" 50mSpjEnt <- insertUniqueSpjEntityThe above query results Nothing as SPJ already exists.
insertUniqueAlexaEntity :: MonadIO m => ReaderT SqlBackend m (Maybe (Entity User))
insertUniqueAlexaEntity = insertUniqueEntity $ User "Alexa" 3mAlexaEnt <- insertUniqueSpjEntityBecause there's no such unique keywords of the given record, the above query when applied on dataset-1, will produce this:
+----+-------+-----+
| id | name | age |
+----+-------+-----+
| 1 | SPJ | 40 |
+----+-------+-----+
| 2 | Simon | 41 |
+----+-------+-----+
| 3 | Alexa | 3 |
+----+-------+-----+Given a proxy for a PersistEntity record, this returns the sole UniqueDef for that entity.
Return the single unique key for a record.
Example usage
We use shcema-1 and dataset-1 here.
onlySimonConst :: MonadIO m => ReaderT SqlBackend m (Unique User)
onlySimonConst = onlyUnique $ User "Simon" 999mSimonConst <- onlySimonConstmSimonConst would be Simon's uniqueness constraint. Note that
onlyUnique doesn't work if there're more than two constraints. It will
fail with a type error instead.
Return the database name for the given entity.
Retrieve the list of FieldDef that makes up the fields of the entity.
This does not return the fields for an Id column or an implicit id. It
will return the key columns if you used the Primary syntax for defining the
primary key.
This does not return fields that are marked SafeToRemove or MigrationOnly
- so it only returns fields that are represented in the Haskell type. If you
need those fields, use getEntityFieldsDatabase.
This returns all of the FieldDef defined for the EntityDef, including
those fields that are marked as MigrationOnly (and therefore only present
in the database) or SafeToRemove (and a migration will drop the column if
it exists in the database).
For all the fields that are present on the Haskell-type, see getEntityFields.
Retrieve the Haskell name of the given entity.
Gets the Source of the definition of the entity.
Note that as of this writing the span covers the entire file or quasiquote where the item is defined due to parsing limitations. This may be changed in a future release to be more accurate.
Retrieve the list of UniqueDef from an EntityDef. As of version 2.14, this will also include the primary key on the entity, if one is defined. If you do not want the primary key, see getEntityUniquesNoPrimaryKey.
Perform a mapping function over all of the entity fields, as determined by getEntityFieldsDatabase.
Add an attribute to the list of field attributes.
Check if the field is `Maybe a`
Check if the field definition is nullable
Modify the list of field attributes.
Commit the current transaction and begin a new one. This is used when a transaction commit is required within the context of runSqlConn (which brackets its provided action with a transaction begin/commit pair).
Commit the current transaction and begin a new one with the specified isolation level.
Roll back the current transaction and begin a new one. This rolls back to the state of the last call to transactionSave or the enclosing runSqlConn call.
Roll back the current transaction and begin a new one with the specified isolation level.
A helper function to tell GHC what the EntityWithPrefix prefix should be. This allows you to use a type application to specify the prefix, instead of specifying the etype on the result.
As an example, here's code that uses this:
myQuery :: SqlPersistM [Entity Person]
myQuery = fmap (unPrefix @"p") $ rawSql query []
where
query = "SELECT ?? FROM person AS p"
Creates an empty BackendSpecificOverrides (i.e. use the default behavior; no overrides)
If the override is defined, then this specifies what cascade action should be used if there is none defined for the column.
If the override is defined, then this returns a function that accepts an entity name and field name and provides the ConstraintNameDB for the foreign key constraint.
An abstract accessor for the BackendSpecificOverrides
Create the list of columns for the given entity.
Set the backend's default cascade action.
Set the backend's foreign key generation function to this value.
addMigration Add a migration to the migration plan.
Add a CautiousMigration (aka a [(Bool, Text)]) to the
migration plan.
Given a Migration, this parses it and returns either a list of errors associated with the migration or a list of migrations to do.
Like parseMigration, but instead of returning the value in an Either value, it calls error on the error values.
Prints a migration.
Report a single error in a Migration.
Report multiple errors in a Migration.
Runs a migration. If the migration fails to parse or if any of the migrations are unsafe, then this throws a PersistUnsafeMigrationException.
Same as runMigration, but does not report the individual migrations on stderr. Instead it returns a list of the executed SQL commands.
This is a safer/more robust alternative to runMigrationSilent, but may be less silent for some persistent implementations, most notably persistent-postgresql
Same as runMigration, but returns a list of the SQL commands executed instead of printing them to stderr.
This function silences the migration by remapping stderr. As a result, it is not thread-safe and can clobber output from other parts of the program. This implementation method was chosen to also silence postgresql migration output on stderr, but is not recommended!
Like runMigration, but this will perform the unsafe database migrations instead of erroring out.
Same as runMigrationUnsafe, but returns a list of the SQL commands executed instead of printing them to stderr.
Run an action against the database during a migration. Can be useful for eg creating Postgres extensions:
runSqlCommand $ rawExecute "CREATE EXTENSION IF NOT EXISTS "uuid-ossp";" []
Generates sql for limit and offset for postgres, sqlite and mysql.
filterClause :: PersistEntity val=> Maybe FilterTablePrefixinclude table name or EXCLUDED
-> SqlBackend-> [Filter val]-> Text
filterClauseWithVals :: PersistEntity val=> Maybe FilterTablePrefixinclude table name or EXCLUDED
-> SqlBackend-> [Filter val]-> (Text, [PersistValue])
Render a [Filter record] into a Text value suitable for inclusion
into a SQL query, as well as the [PersistValue] to properly fill in the
? place holders.
orderClause :: PersistEntity val=> Maybe FilterTablePrefixinclude table name or EXCLUDED
-> SqlBackend-> [SelectOpt val]-> Text
useful for a backend to implement fieldName by adding escaping
get the SQL string for the field that an EntityField represents Useful for raw SQL queries
Your backend may provide a more convenient fieldName function which does not operate in a Monad
get the SQL string for the table that a PersistEntity represents Useful for raw SQL queries
Your backend may provide a more convenient tableName function which does not operate in a Monad
useful for a backend to implement tableName by adding escaping
rawExecute :: (MonadIO m, BackendCompatible SqlBackend backend)=> TextSQL statement, possibly with placeholders.
-> [PersistValue]Values to fill the placeholders.
-> ReaderT backend m ()
Execute a raw SQL statement
rawExecuteCount :: (MonadIO m, BackendCompatible SqlBackend backend)=> TextSQL statement, possibly with placeholders.
-> [PersistValue]Values to fill the placeholders.
-> ReaderT backend m Int64
Execute a raw SQL statement and return the number of rows it has modified.
rawSql :: (RawSql a, MonadIO m, BackendCompatible SqlBackend backend)=> TextSQL statement, possibly with placeholders.
-> [PersistValue]Values to fill the placeholders.
-> ReaderT backend m [a]
Execute a raw SQL statement and return its results as a list. If you do not expect a return value, use of rawExecute is recommended.
If you're using Entitys (which is quite likely), then you
must use entity selection placeholders (double question
mark, ??). These ?? placeholders are then replaced for
the names of the columns that we need for your entities.
You'll receive an error if you don't use the placeholders.
Please see the Entitys documentation for more details.
You may put value placeholders (question marks, ?) in your
SQL query. These placeholders are then replaced by the values
you pass on the second parameter, already correctly escaped.
You may want to use toPersistValue to help you constructing
the placeholder values.
Since you're giving a raw SQL statement, you don't get any
guarantees regarding safety. If rawSql is not able to parse
the results of your query back, then an exception is raised.
However, most common problems are mitigated by using the
entity selection placeholder ??, and you shouldn't see any
error at all if you're not using Single.
Some example of rawSql based on this schema:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
deriving Show
BlogPost
title String
authorId PersonId
deriving Show
|]
Examples based on the above schema:
getPerson :: MonadIO m => ReaderT SqlBackend m [Entity Person]
getPerson = rawSql "select ?? from person where name=?" [PersistText "john"]
getAge :: MonadIO m => ReaderT SqlBackend m [Single Int]
getAge = rawSql "select person.age from person where name=?" [PersistText "john"]
getAgeName :: MonadIO m => ReaderT SqlBackend m [(Single Int, Single Text)]
getAgeName = rawSql "select person.age, person.name from person where name=?" [PersistText "john"]
getPersonBlog :: MonadIO m => ReaderT SqlBackend m [(Entity Person, Entity BlogPost)]
getPersonBlog = rawSql "select ??,?? from person,blog_post where person.id = blog_post.author_id" []
Minimal working program for PostgreSQL backend based on the above concepts:
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger (runStderrLoggingT)
import Database.Persist
import Control.Monad.Reader
import Data.Text
import Database.Persist.Sql
import Database.Persist.Postgresql
import Database.Persist.TH
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
deriving Show
|]
conn = "host=localhost dbname=new_db user=postgres password=postgres port=5432"
getPerson :: MonadIO m => ReaderT SqlBackend m [Entity Person]
getPerson = rawSql "select ?? from person where name=?" [PersistText "sibi"]
liftSqlPersistMPool y x = liftIO (runSqlPersistMPool y x)
main :: IO ()
main = runStderrLoggingT $ withPostgresqlPool conn 10 $ liftSqlPersistMPool $ do
runMigration migrateAll
xs <- getPerson
liftIO (print xs)
acquireSqlConn :: (MonadReader backend m, BackendCompatible SqlBackend backend) => m (Acquire backend)Starts a new transaction on the connection. When the acquired connection is released the transaction is committed and the connection returned to the pool.
Upon an exception the transaction is rolled back and the connection destroyed.
This is equivalent to runSqlConn but does not incur the MonadUnliftIO
constraint, meaning it can be used within, for example, a Conduit
pipeline.
Like acquireSqlConn, but lets you specify an explicit isolation level.
createSqlPoolWithConfig :: (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend)=> (LogFunc -> IO backend)Function to create a new connection
-> ConnectionPoolConfig-> m (Pool backend)
Creates a pool of connections to a SQL database.
Like runSqlConn, but supports specifying an isolation level.
Get a connection from the pool, run the given action, and then return the connection to the pool.
This function performs the given action in a transaction. If an exception occurs during the action, then the transaction is rolled back.
Note: This function previously timed out after 2 seconds, but this behavior was buggy and caused more problems than it solved. Since version 2.1.2, it performs no timeout checks.
Like runSqlPool, but does not surround the action in a transaction. This action might leave your database in a weird state.
This function is how runSqlPoolWithHooks is defined.
It's currently the most general function for using a SQL pool.
runSqlPoolWithHooks :: (MonadUnliftIO m, BackendCompatible SqlBackend backend)=> ReaderT backend m a-> Pool backend-> Maybe IsolationLevel-> (backend -> m before)Run this action immediately before the action is performed.
-> (backend -> m after)Run this action immediately after the action is completed.
-> (backend -> SomeException -> m onException)This action is performed when an exception is received. The exception is provided as a convenience - it is rethrown once this cleanup function is complete.
-> m a
This function is how runSqlPool and runSqlPoolNoTransaction are defined. In addition to the action to be performed and the Pool of conections to use, we give you the opportunity to provide three actions - initialize, afterwards, and onException.
Like runSqlPool, but supports specifying an isolation level.
Create a connection and run sql queries within it. This function automatically closes the connection on it's completion.
Example usage
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies#-}
{-# LANGUAGE TemplateHaskell#-}
{-# LANGUAGE QuasiQuotes#-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger
import Conduit
import Database.Persist
import Database.Sqlite
import Database.Persist.Sqlite
import Database.Persist.TH
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
deriving Show
|]
openConnection :: LogFunc -> IO SqlBackend
openConnection logfn = do
conn <- open "/home/sibi/test.db"
wrapConnection conn logfn
main :: IO ()
main = do
runNoLoggingT $ runResourceT $ withSqlConn openConnection (\backend ->
flip runSqlConn backend $ do
runMigration migrateAll
insert_ $ Person "John doe" $ Just 35
insert_ $ Person "Divya" $ Just 36
(pers :: [Entity Person]) <- selectList [] []
liftIO $ print pers
return ()
)On executing it, you get this output:
Migrating: CREATE TABLE "person"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"age" INTEGER NULL)
[Entity {entityKey = PersonKey {unPersonKey = SqlBackendKey {unSqlBackendKey = 1}}, entityVal = Person {personName = "John doe", personAge = Just 35}},Entity {entityKey = PersonKey {unPersonKey = SqlBackendKey {unSqlBackendKey = 2}}, entityVal = Person {personName = "Hema", personAge = Just 36}}]withSqlPool :: (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend)=> (LogFunc -> IO backend)create a new connection
-> Intconnection count
-> (Pool backend -> m a)-> m a
withSqlPoolWithConfig :: (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend)=> (LogFunc -> IO backend)Function to create a new connection
-> ConnectionPoolConfig-> (Pool backend -> m a)-> m a
Creates a pool of connections to a SQL database which can be used by the Pool backend -> m a function.
After the function completes, the connections are destroyed.
Initializes a ConnectionPoolConfig with default values. See the documentation of ConnectionPoolConfig for each field's default value.
Useful for running a read query against a backend with unknown capabilities.
Useful for running a read query against a backend with read and write capabilities.
Useful for running a write query against an untagged backend with unknown capabilities.
Return the [FieldDef] for the entity keys.
Returns a NonEmpty list of FieldDef that correspond with the key
columns for an EntityDef including those fields that are marked as
MigrationOnly (and therefore only present in the database) or
SafeToRemove (and a migration will drop the column if it exists in the
database).
For fields on the Haskell type use keyAndEntityFieldsDatabase
A FieldCascade that does nothing.
Parse raw field attributes into structured form. Any unrecognized attributes will be preserved, identically as they are encountered, as FieldAttrOther values.
Render a CascadeAction to Text such that it can be used in a SQL command.
Renders a FieldCascade value such that it can be used in SQL migrations.
A backwards-compatible alias for those that don't care about distinguishing between read and write queries. It signifies the assumption that, by default, a backend can write as well as read.
A backwards-compatible alias for those that don't care about distinguishing between read and write queries. It signifies the assumption that, by default, a backend can write as well as read.
Represents a value containing all the configuration options for a specific backend. This abstraction makes it easier to write code that can easily swap backends.
Associated types
type family PersistConfigBackend c :: (Type -> Type) -> Type -> Typetype family PersistConfigPool c
Methods
loadConfig :: Value -> Parser cLoad the config settings from a Value, most likely taken from a YAML config file.
applyEnv :: c -> IO cModify the config settings based on environment variables.
createPoolConfig :: c -> IO (PersistConfigPool c)Create a new connection pool based on the given config settings.
runPool :: MonadUnliftIO m => c -> PersistConfigBackend c m a -> PersistConfigPool c -> m aRun a database action by taking a connection from the pool.
Instances1PersistConfig
(PersistConfig c1, PersistConfig c2, PersistConfigPool c1 ~ PersistConfigPool c2, PersistConfigBackend c1 ~ PersistConfigBackend c2) => PersistConfig (Either c1 c2)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistConfig
Instances1PersistConfigBackend
type PersistConfigBackend (Either c1 c2) = PersistConfigBackend c1Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistConfig
Instances1PersistConfigPool
type PersistConfigPool (Either c1 c2) = PersistConfigPool c1Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistConfig
Datatype that represents an entity, with both its Key and its Haskell record representation.
When using a SQL-based backend (such as SQLite or
PostgreSQL), an Entity may take any number of columns
depending on how many fields it has. In order to reconstruct
your entity on the Haskell side, persistent needs all of
your entity columns and in the right order. Note that you
don't need to worry about this when using persistent's API
since everything is handled correctly behind the scenes.
However, if you want to issue a raw SQL command that returns
an Entity, then you have to be careful with the column
order. While you could use SELECT Entity.* WHERE ... and
that would work most of the time, there are times when the
order of the columns on your database is different from the
order that persistent expects (for example, if you add a new
field in the middle of you entity definition and then use the
migration code -- persistent will expect the column to be in
the middle, but your DBMS will put it as the last column).
So, instead of using a query like the one above, you may use
rawSql (from the
Database.Persist.Sql module) with its /entity
selection placeholder/ (a double question mark ??). Using
rawSql the query above must be written as SELECT ?? WHERE
... Then rawSql will replace ?? with the list of all
columns that we need from your entity in the right order. If
your query returns two entities (i.e. (Entity backend a,
Entity backend b)), then you must you use SELECT ??, ??
WHERE ..., and so on.
Instances26HasField, Eq, Ord, Read, Show, Generic, …
(PersistEntity rec, PersistField typ, SymbolToField sym rec typ) => HasField sym (SqlExpr (Entity rec)) (SqlExpr (Value typ))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalThis instance allows you to use
record.fieldnotation with GHC 9.2'sOverloadedRecordDotextension.Example:
-- persistent model: BlogPost authorId PersonId title Text -- query: select $ do bp <- from $table@BlogPost pure $ bp.titleThis is exactly equivalent to the following:
blogPost :: SqlExpr (Entity BlogPost) blogPost ^. BlogPostTitle blogPost ^. #title blogPost.titleThere's another instance defined on
SqlExpr (Entity (Maybe rec)), which allows you to project from aLEFT JOINed entity.(PersistEntity rec, PersistField typ, PersistField typ', SymbolToField sym rec typ, NullableFieldProjection typ typ', HasField sym (SqlExpr (Maybe (Entity rec))) (SqlExpr (Value (Maybe typ')))) => HasField sym (SqlExpr (Maybe (Entity rec))) (SqlExpr (Value (Maybe typ')))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalThis instance allows you to use
record.fieldnotation with GC 9.2'sOverloadedRecordDotextension.Example:
-- persistent model: Person name Text BlogPost title Text authorId PersonId -- query: select $ do (p :& bp) <- from $tablePersonBlogPost on do \(p :& bp) -> just p.id ==. bp.authorId pure (p.name, bp.title)leftJointableThe following forms are all equivalent:
blogPost :: SqlExpr (Maybe (Entity BlogPost)) blogPost ?. BlogPostTitle blogPost ?. #title blogPost.title(Eq (Key record), Eq record) => Eq (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(Ord (Key record), Ord record) => Ord (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(Read (Key record), Read record) => Read (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(Show (Key record), Show record) => Show (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(Generic (Key record), Generic record) => Generic (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntityTypeError (EntityErrorMessage a) => SafeToInsert (Entity a)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(PersistEntity record, PersistField record, PersistField (Key record)) => PersistField (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(PersistField record, PersistEntity record) => PersistFieldSql (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(PersistEntity record, PersistEntityBackend record ~ backend, IsPersistBackend backend) => RawSql (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassFromPreprocess (SqlExpr (Maybe (Entity val))) => From (SqlExpr (Maybe (Entity val)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalFromPreprocess (SqlExpr (Entity val)) => From (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity val => LockableEntity (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalToAlias (SqlExpr (Maybe (Entity a)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasToAlias (SqlExpr (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasToAliasReference (SqlExpr (Maybe (Entity a)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasReferenceToAliasReference (SqlExpr (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToAliasReferenceToMaybe (SqlExpr (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybe(PersistEntity val, BackendCompatible SqlBackend (PersistEntityBackend val)) => FromPreprocess (SqlExpr (Maybe (Entity val)))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal(PersistEntity val, BackendCompatible SqlBackend (PersistEntityBackend val)) => FromPreprocess (SqlExpr (Entity val))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity a => SqlSelect (SqlExpr (Maybe (Entity a))) (Maybe (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity a => SqlSelect (SqlExpr (Entity a)) (Entity a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.InternalPersistEntity ent => ToFrom (Table ent) (SqlExpr (Entity ent))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.Fromtype Rep (Entity record) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity"Entity"
"Database.Persist.Class.PersistEntity"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'False) (C1 ('MetaCons"Entity"
'PrefixI 'True) (S1 ('MetaSel ('Just"entityKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Key record)) :*: S1 ('MetaSel ('Just"entityVal"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 record)))type ToMaybeT (SqlExpr (Entity a)) = SqlExpr (Maybe (Entity a))Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Experimental.ToMaybe
An EntityField is parameterised by the Haskell record it belongs to and the additional type of that field.
As of persistent-2.11.0.0, it's possible to use the OverloadedLabels
language extension to refer to EntityField values polymorphically. See
the documentation on SymbolToField for more information.
Instances1IsLabel
SymbolToField sym rec typ => IsLabel sym (EntityField rec typ)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntityThis instance delegates to SymbolToField to provide
OverloadedLabelssupport to the EntityField type.
Value to filter with. Highly dependant on the type of filter used.
Constructors
FilterValue :: typ -> FilterValue typFilterValues :: [typ] -> FilterValue typUnsafeValue :: PersistField a => a -> FilterValue typ
By default, a backend will automatically generate the key Instead you can specify a Primary key made up of unique values.
Instances1RawSql
(PersistEntity a, PersistEntityBackend a ~ backend, IsPersistBackend backend) => RawSql (Key a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class
class (PersistField (Key record), ToJSON (Key record), FromJSON (Key record), Show (Key record), Read (Key record), Eq (Key record), Ord (Key record)) => PersistEntity record wherePersistent serialized Haskell records to the database. A Database Entity (A row in SQL, a document in MongoDB, etc) corresponds to a Key plus a Haskell record.
For every Haskell record type stored in the database there is a corresponding PersistEntity instance. An instance of PersistEntity contains meta-data for the record. PersistEntity also helps abstract over different record types. That way the same query interface can return a PersistEntity, with each query returning different types of Haskell records.
Some advanced type system capabilities are used to make this process type-safe. Persistent users usually don't need to understand the class associated data and functions.
Associated types
type family PersistEntityBackend recordPersistent allows multiple different backends (databases).
data family Key recordBy default, a backend will automatically generate the key Instead you can specify a Primary key made up of unique values.
data family EntityField record :: Type -> TypeAn EntityField is parameterised by the Haskell record it belongs to and the additional type of that field.
As of
persistent-2.11.0.0, it's possible to use theOverloadedLabelslanguage extension to refer to EntityField values polymorphically. See the documentation on SymbolToField for more information.data family Unique recordUnique keys besides the Key.
Methods
keyToValues :: Key record -> [PersistValue]A lower-level key operation.
keyFromValues :: [PersistValue] -> Either Text (Key record)A lower-level key operation.
persistIdField :: EntityField record (Key record)A meta-operation to retrieve the Key EntityField.
entityDef :: proxy record -> EntityDefRetrieve the EntityDef meta-data for the record.
persistFieldDef :: EntityField record typ -> FieldDefReturn meta-data for a given EntityField.
toPersistFields :: record -> [PersistValue]A meta-operation to get the database fields of a record.
fromPersistValues :: [PersistValue] -> Either Text recordA lower-level operation to convert from database values to a Haskell record.
tabulateEntityA :: Applicative f => (forall a. EntityField record a -> f a) -> f (Entity record)This function allows you to build an
Entity aby specifying an action that returns a value for the field in the callback function. Let's look at an example.parseFromEnvironmentVariables :: IO (Entity User) parseFromEnvironmentVariables = tabulateEntityA $ \userField -> case userField of UserName -> getEnvUSER_NAMEUserAge -> do ageVar <- getEnvUSER_AGEcase readMaybe ageVar of Just age -> pure age Nothing -> error $ "Failed to parse Age from: " <> ageVar UserAddressId -> do addressVar <- getEnvUSER_ADDRESS_IDpure $ AddressKey addressVartabulateEntityApply :: Apply f => (forall a. EntityField record a -> f a) -> f (Entity record)Like tabulateEntityA, but works with any Apply f. This works because all entities have at least one field, and so we can tabulate things into semigroup-like shapes instead.
persistUniqueKeys :: record -> [Unique record]A meta operation to retrieve all the Unique keys.
persistUniqueToFieldNames :: Unique record -> NonEmpty (FieldNameHS, FieldNameDB)A lower level operation.
persistUniqueToValues :: Unique record -> [PersistValue]A lower level operation.
fieldLens :: EntityField record field -> forall (f :: Type -> Type). Functor f => (field -> f field) -> Entity record -> f (Entity record)Use a PersistField as a lens.
keyFromRecordM :: Maybe (record -> Key record)Extract a
Key recordfrom arecordvalue. Currently, this is only defined for entities using thePrimarysyntax for natural/composite keys. In a future version ofpersistentwhich incorporates the ID directly into the entity, this will always be Just.
Persistent allows multiple different backends (databases).
A type class which is used to witness that a type is safe to insert into the database without providing a primary key.
The TemplateHaskell function mkPersist will generate instances of this
class for any entity that it works on. If the entity has a default primary
key, then it provides a regular instance. If the entity has a Primary
natural key, then this works fine. But if the entity has an Id column with
no default=, then this does a TypeError and forces the user to use
insertKey.
Instances2SafeToInsert
TypeError (EntityErrorMessage a) => SafeToInsert (Entity a)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntityTypeError (FunctionErrorMessage a b) => SafeToInsert (a -> b)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity
This type class is used with the OverloadedLabels extension to
provide a more convenient means of using the EntityField type.
EntityField definitions are prefixed with the type name to avoid
ambiguity, but this ambiguity can result in verbose code.
If you have a table User with a name Text field, then the
corresponding EntityField is UserName. With this, we can write
#name :: EntityField User Text.
What's more fun is that the type is more general: it's actually
#name
:: (SymbolToField "name" rec typ)
=> EntityField rec typ
Which means it is *polymorphic* over the actual record. This allows you to write code that can be generic over the tables, provided they have the right fields.
Methods
symbolToField :: EntityField rec typ
Unique keys besides the Key.
Instances1FinalResult
FinalResult (Unique val)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.Internal.Internal
Prior to persistent-2.11.0, we provided an instance of
PersistField for the Natural type. This was in error, because
Natural represents an infinite value, and databases don't have
reasonable types for this.
The instance for Natural used the Int64 underlying type, which will cause underflow and overflow errors. This type has the exact same code in the instances, and will work seamlessly.
A more appropriate type for this is the Word series of types from Data.Word. These have a bounded size, are guaranteed to be non-negative, and are quite efficient for the database to store.
Constructors
Instances6Eq, Num, Ord, Show, PersistField, PersistFieldSql
Eq OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldNum OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldOrd OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldShow OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistFieldSql OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassThis type uses the SqlInt64 version, which will exhibit overflow and underflow behavior. Additionally, it permits negative values in the database, which isn't ideal.
This class teaches Persistent how to take a custom type and marshal it to and from a PersistValue, allowing it to be stored in a database.
Examples
Simple Newtype
You can use newtype to add more type safety/readability to a basis type like ByteString. In these cases, just derive PersistField and PersistFieldSql:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype HashedPassword = HashedPassword ByteString
deriving (Eq, Show, PersistField, PersistFieldSql)
Smart Constructor Newtype
In this example, we create a PersistField instance for a newtype following the "Smart Constructor" pattern.
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import qualified Data.Text as T
import qualified Data.Char as C
-- | An American Social Security Number
newtype SSN = SSN Text
deriving (Eq, Show, PersistFieldSql)
mkSSN :: Text -> Either Text SSN
mkSSN t = if (T.length t == 9) && (T.all C.isDigit t)
then Right $ SSN t
else Left $ "Invalid SSN: " <> t
instance PersistField SSN where
toPersistValue (SSN t) = PersistText t
fromPersistValue (PersistText t) = mkSSN t
-- Handle cases where the database does not give us PersistText
fromPersistValue x = Left $ "File.hs: When trying to deserialize an SSN: expected PersistText, received: " <> T.pack (show x)
Tips:
This file contain dozens of PersistField instances you can look at for examples.
Typically custom PersistField instances will only accept a single PersistValue constructor in fromPersistValue.
Internal PersistField instances accept a wide variety of PersistValues to accomodate e.g. storing booleans as integers, booleans or strings.
If you're making a custom instance and using a SQL database, you'll also need
PersistFieldSqlto specify the type of the database column.
Methods
toPersistValue :: a -> PersistValuefromPersistValue :: PersistValue -> Either Text a
Instances39PersistField, …
TypeError ((((('TextDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistField"The instance of PersistField for the Natural type was removed."
':$$: 'Text"Please see the documentation for OverflowNatural if you want to "
) ':$$: 'Text"continue using the old behavior or want to see documentation on "
) ':$$: 'Text"why the instance was removed."
) ':$$: 'Text""
) ':$$: 'Text"This error instance will be removed in a future release."
) => PersistField NaturalPersistField HtmlDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField ByteStringDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Int16Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Int32Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Int64Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Int8Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField RationalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField BoolDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField DoubleDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField IntDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField WordDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Word16Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Word32Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Word64Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField Word8Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField PersistValueDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField TextDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField TextDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField DayDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField UTCTimeDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField TimeOfDayDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField [Char]Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField a => PersistField (Maybe a)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField a => PersistField (Vector a)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField a => PersistField [a]Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField v => PersistField (IntMap v)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistField(FromJSON a, ToJSON a) => PersistField (JSONB a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.PostgreSQL.JSON.Instances(Ord a, PersistField a) => PersistField (Set a)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistField(PersistEntity record, PersistField record, PersistField (Key record)) => PersistField (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistEntity(BackendCompatible b s, PersistField (BackendKey b)) => PersistField (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesHasResolution a => PersistField (Fixed a)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistField v => PersistField (Map Text v)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistField(PersistField a, PersistField b) => PersistField (a, b)Defined in persistent-2.18.1.0 · Database.Persist.Class.PersistField
Backends supporting conditional read operations.
Methods
selectSourceRes :: (PersistRecordBackend record backend, MonadIO m1, MonadIO m2) => [Filter record] -> [SelectOpt record] -> ReaderT backend m1 (Acquire (ConduitM () (Entity record) m2 ()))Get all records matching the given criterion in the specified order. Returns also the identifiers.
NOTE: This function returns an Acquire and a ConduitM, which implies that it streams from the database. It does not. Please use selectList to simplify the code. If you want streaming behavior, consider
persistent-paginationwhich efficiently chunks a query into ranges, or investigate a backend-specific streaming solution.selectFirst :: (MonadIO m, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m (Maybe (Entity record))Get just the first record for the criterion.
selectKeysRes :: (MonadIO m1, MonadIO m2, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m1 (Acquire (ConduitM () (Key record) m2 ()))Get the Keys of all records matching the given criterion.
Instances4PersistQueryRead
PersistQueryRead SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanPersistQueryRead SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanPersistQueryRead SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphan(HasPersistBackend b, BackendCompatible b s, PersistQueryRead b) => PersistQueryRead (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
class (PersistQueryRead backend, PersistStoreWrite backend) => PersistQueryWrite backend whereBackends supporting conditional write operations
Methods
updateWhere :: (MonadIO m, PersistRecordBackend record backend) => [Filter record] -> [Update record] -> ReaderT backend m ()Update individual fields on any record matching the given criterion.
deleteWhere :: (MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m ()Delete all records matching the given criterion.
Instances3PersistQueryWrite
PersistQueryWrite SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanPersistQueryWrite SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphan(HasPersistBackend b, BackendCompatible b s, PersistQueryWrite b) => PersistQueryWrite (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
This class witnesses that two backend are compatible, and that you can
convert from the sub backend into the sup backend. This is similar
to the HasPersistBackend and IsPersistBackend classes, but where you
don't want to fix the type associated with the PersistEntityBackend of
a record.
Generally speaking, where you might have:
foo ::
( PersistEntity record
, PersistEntityBackend record ~ BaseBackend backend
, IsSqlBackend backend
)
this can be replaced with:
foo ::
( PersistEntity record,
, PersistEntityBackend record ~ backend
, BackendCompatible SqlBackend backend
)
This works for SqlReadBackend because of the instance BackendCompatible , without needing to go through the BaseBackend type family.SqlBackend SqlReadBackend
Likewise, functions that are currently hardcoded to use SqlBackend can be generalized:
-- before:
asdf :: ReaderT SqlBackend m ()
asdf = pure ()
-- after:
asdf' :: BackendCompatible SqlBackend backend => ReaderT backend m ()
asdf' = withCompatibleBackend asdf
Methods
projectBackend :: sub -> sup
Instances3BackendCompatible
BackendCompatible SqlBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBackendCompatible SqlBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBackendCompatible SqlBackend SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan
Instances71Bounded, Enum, Eq, Integral, Num, Ord, …
Bounded (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBounded (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBounded (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Bounded (BackendKey b)) => Bounded (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesEnum (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEnum (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEnum (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Enum (BackendKey b)) => Enum (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesEq (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEq (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEq (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Eq (BackendKey b)) => Eq (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesIntegral (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanIntegral (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanIntegral (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Integral (BackendKey b)) => Integral (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesNum (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanNum (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanNum (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Num (BackendKey b)) => Num (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesOrd (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanOrd (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanOrd (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Ord (BackendKey b)) => Ord (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesRead (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanRead (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanRead (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Read (BackendKey b)) => Read (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesReal (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanReal (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanReal (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Real (BackendKey b)) => Real (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesShow (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanShow (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanShow (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, Show (BackendKey b)) => Show (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesGeneric (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanGeneric (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanGeneric (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromJSON (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromJSON (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromJSON (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, FromJSON (BackendKey b)) => FromJSON (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesToJSON (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToJSON (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToJSON (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, ToJSON (BackendKey b)) => ToJSON (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesFromHttpApiData (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromHttpApiData (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromHttpApiData (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToHttpApiData (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToHttpApiData (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToHttpApiData (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPathPiece (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPathPiece (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPathPiece (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, PersistField (BackendKey b)) => PersistField (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesPersistFieldSql (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, PersistFieldSql (BackendKey b)) => PersistFieldSql (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Typestype Rep (BackendKey SqlReadBackend) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan"BackendKey"
"Database.Persist.Sql.Orphan.PersistStore"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'True) (C1 ('MetaCons"SqlReadBackendKey"
'PrefixI 'True) (S1 ('MetaSel ('Just"unSqlReadBackendKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))type Rep (BackendKey SqlWriteBackend) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan"BackendKey"
"Database.Persist.Sql.Orphan.PersistStore"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'True) (C1 ('MetaCons"SqlWriteBackendKey"
'PrefixI 'True) (S1 ('MetaSel ('Just"unSqlWriteBackendKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))type Rep (BackendKey SqlBackend) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan"BackendKey"
"Database.Persist.Sql.Orphan.PersistStore"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'True) (C1 ('MetaCons"SqlBackendKey"
'PrefixI 'True) (S1 ('MetaSel ('Just"unSqlBackendKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))data BackendKey SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphandata BackendKey SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphandata BackendKey SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphandata BackendKey (Compatible b s)CompatibleKeyunCompatibleKey :: BackendKey b
Fields
Fields
Fields
Instances4BaseBackend
type BaseBackend SqlReadBackend = SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.Internaltype BaseBackend SqlWriteBackend = SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.Internaltype BaseBackend SqlBackend = SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internaltype BaseBackend (Compatible b s) = BaseBackend bDefined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
Class which allows the plucking of a BaseBackend backend from some larger type.
For example,
instance HasPersistBackend (SqlReadBackend, Int) where
type BaseBackend (SqlReadBackend, Int) = SqlBackend
persistBackend = unSqlReadBackend . fst
Associated types
type family BaseBackend backend
Methods
persistBackend :: backend -> BaseBackend backend
Instances4HasPersistBackend
HasPersistBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalHasPersistBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalHasPersistBackend SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal(BackendCompatible b s, HasPersistBackend b) => HasPersistBackend (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
Class which witnesses that backend is essentially the same as BaseBackend backend.
That is, they're isomorphic and backend is just some wrapper over BaseBackend backend.
Instances3IsPersistBackend
IsPersistBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalIsPersistBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalIsPersistBackend SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal
Associated types
data family BackendKey backend
Instances4PersistCore
PersistCore SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistCore SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistCore SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(BackendCompatible b s, PersistCore b) => PersistCore (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
type PersistRecordBackend record backend = (PersistEntity record, PersistEntityBackend record ~ BaseBackend backend)A convenient alias for common type signatures
class (Show (BackendKey backend), Read (BackendKey backend), Eq (BackendKey backend), Ord (BackendKey backend), PersistCore backend, PersistField (BackendKey backend), ToJSON (BackendKey backend), FromJSON (BackendKey backend)) => PersistStoreRead backend whereMethods
get :: (MonadIO m, PersistRecordBackend record backend) => Key record -> ReaderT backend m (Maybe record)Get a record by identifier, if available.
Example usage
getSpj :: MonadIO m => ReaderT SqlBackend m (Maybe User) getSpj = get spjIdmspj <- getSpjThe above query when applied on dataset-1, will get this:
+------+-----+ | name | age | +------+-----+ | SPJ | 40 | +------+-----+getMany :: (MonadIO m, PersistRecordBackend record backend) => [Key record] -> ReaderT backend m (Map (Key record) record)Get many records by their respective identifiers, if available.
Example usage
getUsers :: MonadIO m => ReaderT SqlBackend m (Map (Key User) User) getUsers = getMany allkeysmusers <- getUsersThe above query when applied on dataset-1, will get these records:
+----+-------+-----+ | id | name | age | +----+-------+-----+ | 1 | SPJ | 40 | +----+-------+-----+ | 2 | Simon | 41 | +----+-------+-----+
Instances4PersistStoreRead
PersistStoreRead SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreRead SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreRead SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(HasPersistBackend b, BackendCompatible b s, PersistStoreRead b) => PersistStoreRead (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
class (Show (BackendKey backend), Read (BackendKey backend), Eq (BackendKey backend), Ord (BackendKey backend), PersistStoreRead backend, PersistField (BackendKey backend), ToJSON (BackendKey backend), FromJSON (BackendKey backend)) => PersistStoreWrite backend whereMethods
insert :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Key record)Create a new record in the database, returning an automatically created key (in SQL an auto-increment id).
Example usage
Using schema-1 and dataset-1, let's insert a new user
John.insertJohn :: MonadIO m => ReaderT SqlBackend m (Key User) insertJohn = insert $ User "John" 30johnId <- insertJohnThe above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |John |30 | +-----+------+-----+insert_ :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m ()Same as insert, but doesn't return a
Key.Example usage
insertJohn :: MonadIO m => ReaderT SqlBackend m (Key User) insertJohn = insert_ $ User "John" 30The above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |John |30 | +-----+------+-----+insertMany :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [record] -> ReaderT backend m [Key record]Create multiple records in the database and return their Keys.
If you don't need the inserted Keys, use insertMany_.
The MongoDB and PostgreSQL backends insert all records and retrieve their keys in one database query.
The SQLite and MySQL backends use the slow, default implementation of
mapM insert.Example usage
insertUsers :: MonadIO m => ReaderT SqlBackend m [Key User] insertUsers = insertMany [User "John" 30, User "Nick" 32, User "Jane" 20]userIds <- insertUsersThe above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |John |30 | +-----+------+-----+ |4 |Nick |32 | +-----+------+-----+ |5 |Jane |20 | +-----+------+-----+insertMany_ :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [record] -> ReaderT backend m ()Same as insertMany, but doesn't return any Keys.
The MongoDB, PostgreSQL, SQLite and MySQL backends insert all records in one database query.
Example usage
insertUsers_ :: MonadIO m => ReaderT SqlBackend m () insertUsers_ = insertMany_ [User "John" 30, User "Nick" 32, User "Jane" 20]The above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |John |30 | +-----+------+-----+ |4 |Nick |32 | +-----+------+-----+ |5 |Jane |20 | +-----+------+-----+insertEntityMany :: (MonadIO m, PersistRecordBackend record backend) => [Entity record] -> ReaderT backend m ()Same as insertMany_, but takes an Entity instead of just a record.
Useful when migrating data from one entity to another and want to preserve ids.
The MongoDB, PostgreSQL, SQLite and MySQL backends insert all records in one database query.
Example usage
insertUserEntityMany :: MonadIO m => ReaderT SqlBackend m () insertUserEntityMany = insertEntityMany [SnakeEntity, EvaEntity]The above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |Snake |38 | +-----+------+-----+ |4 |Eva |38 | +-----+------+-----+insertKey :: (MonadIO m, PersistRecordBackend record backend) => Key record -> record -> ReaderT backend m ()Create a new record in the database using the given key.
Example usage
insertAliceKey :: MonadIO m => Key User -> ReaderT SqlBackend m () insertAliceKey key = insertKey key $ User "Alice" 20insertAliceKey $ UserKey {unUserKey = SqlBackendKey {unSqlBackendKey = 3}}The above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |Alice |20 | +-----+------+-----+repsert :: (MonadIO m, PersistRecordBackend record backend) => Key record -> record -> ReaderT backend m ()Put the record in the database with the given key. Unlike replace, if a record with the given key does not exist then a new record will be inserted.
Example usage
We try to explain
upsertByusing schema-1 and dataset-1.First, we insert Philip to dataset-1.
insertPhilip :: MonadIO m => ReaderT SqlBackend m (Key User) insertPhilip = insert $ User "Philip" 42philipId <- insertPhilipThis query will produce:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |Philip|42 | +-----+------+-----+repsertHaskell :: MonadIO m => Key record -> ReaderT SqlBackend m () repsertHaskell id = repsert id $ User "Haskell" 81repsertHaskell philipIdThis query will replace Philip's record with Haskell's one:
+-----+-----------------+--------+ |id |name |age | +-----+-----------------+--------+ |1 |SPJ |40 | +-----+-----------------+--------+ |2 |Simon |41 | +-----+-----------------+--------+ |3 |Philip -> Haskell|42 -> 81| +-----+-----------------+--------+repsert inserts the given record if the key doesn't exist.
repsertXToUnknown :: MonadIO m => ReaderT SqlBackend m () repsertXToUnknown = repsert unknownId $ User "X" 999For example, applying the above query to dataset-1 will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |X |999 | +-----+------+-----+repsertMany :: (MonadIO m, PersistRecordBackend record backend) => [(Key record, record)] -> ReaderT backend m ()Put many entities into the database.
Batch version of repsert for SQL backends.
Useful when migrating data from one entity to another and want to preserve ids.
Example usage
repsertManyUsers :: MonadIO m =>ReaderT SqlBackend m () repsertManyusers = repsertMany [(simonId, User "Philip" 20), (unknownId999, User "Mr. X" 999)]The above query when applied on dataset-1, will produce this:
+-----+----------------+---------+ |id |name |age | +-----+----------------+---------+ |1 |SPJ |40 | +-----+----------------+---------+ |2 |Simon -> Philip |41 -> 20 | +-----+----------------+---------+ |999 |Mr. X |999 | +-----+----------------+---------+replace :: (MonadIO m, PersistRecordBackend record backend) => Key record -> record -> ReaderT backend m ()Replace the record in the database with the given key. Note that the result is undefined if such record does not exist, so you must use insertKey or repsert in these cases.
Example usage
With schema-1 schama-1 and dataset-1,
replaceSpj :: MonadIO m => User -> ReaderT SqlBackend m () replaceSpj record = replace spjId recordThe above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |Mike |45 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+updateGet :: (MonadIO m, PersistRecordBackend record backend) => Key record -> [Update record] -> ReaderT backend m recordUpdate individual fields on a specific record, and retrieve the updated value from the database.
Note that this function will throw an exception if the given key is not found in the database.
Example usage
updateGetSpj :: MonadIO m => [Update User] -> ReaderT SqlBackend m User updateGetSpj updates = updateGet spjId updatesspj <- updateGetSpj [UserAge +=. 100]The above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |140 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+
Instances3PersistStoreWrite
PersistStoreWrite SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreWrite SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan(HasPersistBackend b, BackendCompatible b s, PersistStoreWrite b) => PersistStoreWrite (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
class (PersistEntity record, PersistEntityBackend record ~ backend, PersistCore backend) => ToBackendKey backend record whereToBackendKey converts a PersistEntity Key into a BackendKey
This can be used by each backend to convert between a Key and a plain
Haskell type. For Sql, that is done with toSqlKey and fromSqlKey.
By default, a PersistEntity uses the default BackendKey for its Key and is an instance of ToBackendKey
A Key that instead uses a custom type will not be an instance of ToBackendKey.
Methods
toBackendKey :: Key record -> BackendKey backendfromBackendKey :: BackendKey backend -> Key record
This class is used to ensure that functions requring at least one
unique key are not called with records that have 0 unique keys. The
quasiquoter automatically writes working instances for appropriate
entities, and generates TypeError instances for records that have
0 unique keys.
Methods
requireUniquesP :: record -> NonEmpty (Unique record)
type MultipleUniqueKeysError ty = ((('Text "The entity "
':<>: 'ShowType ty) ':<>: 'Text " has multiple unique keys."
) ':$$: ('Text "The function you are trying to call requires only a single "
':<>: 'Text "unique key."
)) ':$$: (('Text "There is probably a variant of the function with 'By' "
':<>: 'Text "appended that will allow you to select a unique key "
) ':<>: 'Text "for the operation."
)This is an error message. It is used when an entity has multiple unique keys, and the function expects a single unique key.
type NoUniqueKeysError ty = (('Text "The entity "
':<>: 'ShowType ty) ':<>: 'Text " does not have any unique keys."
) ':$$: ('Text "The function you are trying to call requires a unique key "
':<>: 'Text "to be defined on the entity."
)This is an error message. It is used when writing instances of OnlyOneUniqueKey for an entity that has no unique keys.
This class is used to ensure that upsert is only called on records
that have a single Unique key. The quasiquoter automatically generates
working instances for appropriate records, and generates TypeError
instances for records that have 0 or multiple unique keys.
Methods
onlyUniqueP :: record -> Unique record
Queries against Unique keys (other than the id Key).
Please read the general Persistent documentation to learn how to create Unique keys.
Using this with an Entity without a Unique key leads to undefined behavior. A few of these functions require a single Unique, so using an Entity with multiple Uniques is also undefined. In these cases persistent's goal is to throw an exception as soon as possible, but persistent is still transitioning to that.
SQL backends automatically create uniqueness constraints, but for MongoDB you must manually place a unique index on a field to have a uniqueness constraint.
Methods
getBy :: (MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m (Maybe (Entity record))Get a record by unique key, if available. Returns also the identifier.
If your unique key contains a nullable field, then, by default, getBy will not match if any of the fields are NULL.
Example usage
getBySpjName :: MonadIO m => ReaderT SqlBackend m (Maybe (Entity User)) getBySpjName = getBy $ UniqueUserName "SPJ"mSpjEnt <- getBySpjNameThe above query when applied on dataset-1, will get this entity:
+----+------+-----+ | id | name | age | +----+------+-----+ | 1 | SPJ | 40 | +----+------+-----+existsBy :: (MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m BoolReturns True if a record with this unique key exists, otherwise False.
Example usage
existsBySpjName :: MonadIO m => ReaderT SqlBackend m Bool existsBySpjName = existsBy $ UniqueUserName "SPJ"spjEntExists <- existsBySpjNameThe above query when applied on dataset-1, will return the value True.
Instances4PersistUniqueRead
PersistUniqueRead SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanPersistUniqueRead SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanPersistUniqueRead SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphan(HasPersistBackend b, BackendCompatible b s, PersistUniqueRead b) => PersistUniqueRead (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
class (PersistUniqueRead backend, PersistStoreWrite backend) => PersistUniqueWrite backend whereSome functions in this module (insertUnique, insertBy, and replaceUnique) first query the unique indexes to check for conflicts. You could instead optimistically attempt to perform the operation (e.g. replace instead of replaceUnique). However,
there is some fragility to trying to catch the correct exception and determing the column of failure;
an exception will automatically abort the current SQL transaction.
Methods
deleteBy :: (MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m ()Delete a specific record by unique key. Does nothing if no record matches.
Example usage
deleteBySpjName :: MonadIO m => ReaderT SqlBackend m () deleteBySpjName = deleteBy (UniqueUserName "SPJ")The above query when applied on dataset-1, will produce this:
+-----+------+-----+ |id |name |age | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+insertUnique :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Maybe (Key record))Like insert, but returns Nothing when the record couldn't be inserted because of a uniqueness constraint.
Example usage
With schema-1 and dataset-1, we try to insert the following two records:
linusId <- insertUnique $ User "Linus" 48 spjId <- insertUnique $ User "SPJ" 90+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |Linus |48 | +-----+------+-----+Linus's record was inserted to dataset-1, while SPJ wasn't because SPJ already exists in dataset-1.
insertUnique_ :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Maybe ())Same as insertUnique but doesn't return a
Key.Example usage
With schema-1 and dataset-1, we try to insert the following two records:
linusId <- insertUnique_ $ User "Linus" 48 spjId <- insertUnique_ $ User "SPJ" 90+-----+------+-----+ |id |name |age | +-----+------+-----+ |1 |SPJ |40 | +-----+------+-----+ |2 |Simon |41 | +-----+------+-----+ |3 |Linus |48 | +-----+------+-----+Linus's record was inserted to dataset-1, while SPJ wasn't because SPJ already exists in dataset-1.
upsert :: (MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record, SafeToInsert record) => record -> [Update record] -> ReaderT backend m (Entity record)Update based on a uniqueness constraint or insert:
insert the new record if it does not exist;
If the record exists (matched via it's uniqueness constraint), then update the existing record with the parameters which is passed on as list to the function.
Example usage
First, we try to explain upsert using schema-1 and dataset-1.
upsertSpj :: MonadIO m => [Update User] -> ReaderT SqlBackend m (Maybe (Entity User)) upsertSpj updates = upsert (User "SPJ" 999) updatesmSpjEnt <- upsertSpj [UserAge +=. 15]The above query when applied on dataset-1, will produce this:
+-----+-----+--------+ |id |name |age | +-----+-----+--------+ |1 |SPJ |40 -> 55| +-----+-----+--------+ |2 |Simon|41 | +-----+-----+--------+upsertX :: MonadIO m => [Update User] -> ReaderT SqlBackend m (Maybe (Entity User)) upsertX updates = upsert (User "X" 999) updatesmXEnt <- upsertX [UserAge +=. 15]The above query when applied on dataset-1, will produce this:
+-----+-----+--------+ |id |name |age | +-----+-----+--------+ |1 |SPJ |40 | +-----+-----+--------+ |2 |Simon|41 | +-----+-----+--------+ |3 |X |999 | +-----+-----+--------+Next, what if the schema has two uniqueness constraints? Let's check it out using schema-2:
mSpjEnt <- upsertSpj [UserAge +=. 15]This fails with a compile-time type error alerting us to the fact that this record has multiple unique keys, and suggests that we look for upsertBy to select the unique key we want.
upsertBy :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => Unique record -> record -> [Update record] -> ReaderT backend m (Entity record)Update based on a given uniqueness constraint or insert:
insert the new record if it does not exist;
update the existing record that matches the given uniqueness constraint.
Example usage
We try to explain upsertBy using schema-2 and dataset-1.
upsertBySpjName :: MonadIO m => User -> [Update User] -> ReaderT SqlBackend m (Entity User) upsertBySpjName record updates = upsertBy (UniqueUserName "SPJ") record updatesmSpjEnt <- upsertBySpjName (Person "X" 999) [PersonAge += .15]The above query will alter dataset-1 to:
+-----+-----+--------+ |id |name |age | +-----+-----+--------+ |1 |SPJ |40 -> 55| +-----+-----+--------+ |2 |Simon|41 | +-----+-----+--------+upsertBySimonAge :: MonadIO m => User -> [Update User] -> ReaderT SqlBackend m (Entity User) upsertBySimonAge record updates = upsertBy (UniqueUserName "SPJ") record updatesmPhilipEnt <- upsertBySimonAge (User "X" 999) [UserName =. "Philip"]The above query will alter dataset-1 to:
+----+-----------------+-----+ | id | name | age | +----+-----------------+-----+ | 1 | SPJ | 40 | +----+-----------------+-----+ | 2 | Simon -> Philip | 41 | +----+-----------------+-----+upsertByUnknownName :: MonadIO m => User -> [Update User] -> ReaderT SqlBackend m (Entity User) upsertByUnknownName record updates = upsertBy (UniqueUserName "Unknown") record updatesmXEnt <- upsertByUnknownName (User "X" 999) [UserAge +=. 15]This query will alter dataset-1 to:
+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |1 |SPJ |40 | +-----+-----+-----+ |2 |Simon|41 | +-----+-----+-----+ |3 |X |999 | +-----+-----+-----+putMany :: (MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [record] -> ReaderT backend m ()Put many records into db
insert new records that do not exist (or violate any unique constraints)
replace existing records (matching any unique constraint)
Instances3PersistUniqueWrite
PersistUniqueWrite SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanPersistUniqueWrite SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphan(HasPersistBackend b, BackendCompatible b s, PersistUniqueWrite b) => PersistUniqueWrite (Compatible b s)Defined in persistent-2.18.1.0 · Database.Persist.Compatible.Types
A ConstraintNameDB represents the datastore-side name that persistent
will use for a constraint.
Constructors
Instances6Eq, Ord, Read, Show, DatabaseName, Lift
Eq ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesOrd ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesRead ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesShow ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesDatabaseName ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesLift ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.Names
An ConstraintNameHS represents the Haskell-side name that persistent
will use for a constraint.
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq ConstraintNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesOrd ConstraintNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesRead ConstraintNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesShow ConstraintNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesLift ConstraintNameHSDefined in persistent-2.18.1.0 · Database.Persist.Names
Convenience operations for working with '-NameDB' types.
Methods
escapeWith :: (Text -> str) -> a -> str
Instances3DatabaseName
DatabaseName ConstraintNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesDatabaseName EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesDatabaseName FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.Names
An EntityNameDB represents the datastore-side name that persistent
will use for an entity.
Constructors
Instances6Eq, Ord, Read, Show, DatabaseName, Lift
Eq EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesOrd EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesRead EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesShow EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesDatabaseName EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesLift EntityNameDBDefined in persistent-2.18.1.0 · Database.Persist.Names
An EntityNameHS represents the Haskell-side name that persistent
will use for an entity.
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq EntityNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesOrd EntityNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesRead EntityNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesShow EntityNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesLift EntityNameHSDefined in persistent-2.18.1.0 · Database.Persist.Names
A FieldNameDB represents the datastore-side name that persistent
will use for a field.
Constructors
Instances6Eq, Ord, Read, Show, DatabaseName, Lift
Eq FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesOrd FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesRead FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesShow FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesDatabaseName FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.NamesLift FieldNameDBDefined in persistent-2.18.1.0 · Database.Persist.Names
A FieldNameHS represents the Haskell-side name that persistent
will use for a field.
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq FieldNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesOrd FieldNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesRead FieldNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesShow FieldNameHSDefined in persistent-2.18.1.0 · Database.Persist.NamesLift FieldNameHSDefined in persistent-2.18.1.0 · Database.Persist.Names
A type that determines how a backend should handle the literal.
Constructors
EscapedThe accompanying value will be escaped before inserting into the database. This is the correct default choice to use.
UnescapedThe accompanying value will not be escaped when inserting into the database. This is potentially dangerous - use this with care.
DbSpecificThe DbSpecific constructor corresponds to the legacy PersistDbSpecific constructor. We need to keep this around because old databases may have serialized JSON representations that reference this. We don't want to break the ability of a database to load rows.
Instances4Eq, Ord, Read, Show
Eq LiteralTypeDefined in persistent-2.18.1.0 · Database.Persist.PersistValueOrd LiteralTypeDefined in persistent-2.18.1.0 · Database.Persist.PersistValueRead LiteralTypeDefined in persistent-2.18.1.0 · Database.Persist.PersistValueShow LiteralTypeDefined in persistent-2.18.1.0 · Database.Persist.PersistValue
A raw value which can be stored in any backend and can be marshalled to
and from a PersistField.
Constructors
PersistText TextPersistByteString ByteStringPersistInt64 Int64PersistDouble DoublePersistRational RationalPersistBool BoolPersistDay DayPersistTimeOfDay TimeOfDayPersistUTCTime UTCTimePersistNullPersistList [PersistValue]PersistMap [(Text, PersistValue)]PersistObjectId ByteStringIntended especially for MongoDB backend
PersistArray [PersistValue]Intended especially for PostgreSQL backend for text arrays
PersistLiteral_ LiteralType ByteStringThis constructor is used to specify some raw literal value for the backend. The LiteralType value specifies how the value should be escaped. This can be used to make special, custom types avaialable in the back end.
Instances12Eq, Ord, Read, Show, NFData, FromJSON, …
Eq PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueOrd PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueRead PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueShow PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueNFData PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueFromJSON PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueToJSON PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueFromHttpApiData PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValueToHttpApiData PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValuePathPiece PersistValueDefined in persistent-2.18.1.0 · Database.Persist.PersistValuePersistField PersistValueDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistFieldSql PersistValueDefined in persistent-2.18.1.0 · Database.Persist.Sql.Class
Deprecated. Deprecated since 2.11 because of inconsistent escaping behavior across backends. The Postgres backend escapes these values, while the MySQL backend does not. If you are using this, please switch to PersistLiteral_ and provide a relevant LiteralType for your conversion.
This pattern synonym used to be a data constructor for the PersistValue type. It was changed to be a pattern so that JSON-encoded database values could be parsed into their corresponding values. You should not use this, and instead prefer to pattern match on PersistLiteral_ directly.
If you use this, it will overlap a patern match on the 'PersistLiteral_, PersistLiteral, and PersistLiteralEscaped patterns. If you need to disambiguate between these constructors, pattern match on PersistLiteral_ directly.
This pattern synonym used to be a data constructor on PersistValue, but was changed into a catch-all pattern synonym to allow backwards compatiblity with database types. See the documentation on PersistDbSpecific for more details.
This pattern synonym used to be a data constructor on PersistValue, but was changed into a catch-all pattern synonym to allow backwards compatiblity with database types. See the documentation on PersistDbSpecific for more details.
This newtype wrapper is useful when selecting an entity out of the database and you want to provide a prefix to the table being selected.
Consider this raw SQL query:
SELECT ??
FROM my_long_table_name AS mltn
INNER JOIN other_table AS ot
ON mltn.some_col = ot.other_col
WHERE ...We don't want to refer to my_long_table_name every time, so we create
an alias. If we want to select it, we have to tell the raw SQL
quasi-quoter that we expect the entity to be prefixed with some other
name.
We can give the above query a type with this, like:
getStuff :: SqlPersistM [EntityWithPrefix "mltn" MyLongTableName]
getStuff = rawSql queryText []
The EntityWithPrefix bit is a boilerplate newtype wrapper, so you can remove it with unPrefix, like this:
getStuff :: SqlPersistM [Entity MyLongTableName]
getStuff = unPrefix @"mltn" <$> rawSql queryText []
The symbol is a "type application" and requires the TypeApplications@
language extension.
Constructors
EntityWithPrefixunEntityWithPrefix :: Entity record
Instances1RawSql
(PersistEntity record, KnownSymbol prefix, PersistEntityBackend record ~ backend, IsPersistBackend backend) => RawSql (EntityWithPrefix prefix record)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class
Tells Persistent what database column type should be used to store a Haskell type.
Examples
Simple Boolean Alternative
data Switch = On | Off
deriving (Show, Eq)
instance PersistField Switch where
toPersistValue s = case s of
On -> PersistBool True
Off -> PersistBool False
fromPersistValue (PersistBool b) = if b then Right On else Right Off
fromPersistValue x = Left $ "File.hs: When trying to deserialize a Switch: expected PersistBool, received: " <> T.pack (show x)
instance PersistFieldSql Switch where
sqlType _ = SqlBool
Non-Standard Database Types
If your database supports non-standard types, such as Postgres' uuid, you can use SqlOther to use them:
import qualified Data.UUID as UUID
instance PersistField UUID where
toPersistValue = PersistLiteralEncoded . toASCIIBytes
fromPersistValue (PersistLiteralEncoded uuid) =
case fromASCIIBytes uuid of
Nothing -> Left $ "Model/CustomTypes.hs: Failed to deserialize a UUID; received: " <> T.pack (show uuid)
Just uuid' -> Right uuid'
fromPersistValue x = Left $ "File.hs: When trying to deserialize a UUID: expected PersistLiteralEncoded, received: "-- > <> T.pack (show x)
instance PersistFieldSql UUID where
sqlType _ = SqlOther "uuid"
User Created Database Types
Similarly, some databases support creating custom types, e.g. Postgres' DOMAIN and ENUM features. You can use SqlOther to specify a custom type:
CREATE DOMAIN ssn AS text
CHECK ( value ~ '^[0-9]{9}$');instance PersistFieldSQL SSN where
sqlType _ = SqlOther "ssn"
CREATE TYPE rainbow_color AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet');instance PersistFieldSQL RainbowColor where
sqlType _ = SqlOther "rainbow_color"
Instances38PersistFieldSql, …
PersistFieldSql HtmlDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql ByteStringDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Int16Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Int32Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Int64Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Int8Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql RationalDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql BoolDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql DoubleDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql IntDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql WordDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Word16Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Word32Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Word64Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql Word8Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql OverflowNaturalDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassThis type uses the SqlInt64 version, which will exhibit overflow and underflow behavior. Additionally, it permits negative values in the database, which isn't ideal.
PersistFieldSql PersistValueDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql TextDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql TextDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql DayDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql UTCTimeDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql TimeOfDayDefined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql [Char]Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql a => PersistFieldSql (Maybe a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql a => PersistFieldSql (Vector a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql a => PersistFieldSql [a]Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql v => PersistFieldSql (IntMap v)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(FromJSON a, ToJSON a) => PersistFieldSql (JSONB a)Defined in esqueleto-3.6.0.3 · Database.Esqueleto.PostgreSQL.JSON.Instancesjsonb
(Ord a, PersistFieldSql a) => PersistFieldSql (Set a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(PersistField record, PersistEntity record) => PersistFieldSql (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(BackendCompatible b s, PersistFieldSql (BackendKey b)) => PersistFieldSql (BackendKey (Compatible b s))Defined in persistent-2.18.1.0 · Database.Persist.Compatible.TypesHasResolution a => PersistFieldSql (Fixed a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassPersistFieldSql v => PersistFieldSql (Map Text v)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(PersistFieldSql a, PersistFieldSql b) => PersistFieldSql (a, b)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class
Class for data types that may be retrived from a rawSql
query.
Methods
rawSqlCols :: (Text -> Text) -> a -> (Int, [Text])Number of columns that this data type needs and the list of substitutions for
SELECTplaceholders??.rawSqlColCountReason :: a -> StringA string telling the user why the column count is what it is.
rawSqlProcessRow :: [PersistValue] -> Either Text aTransform a row of the result into the data type.
Instances66RawSql, …
PersistField a => RawSql (Single a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.ClassRawSql a => RawSql (Maybe a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(PersistEntity a, PersistEntityBackend a ~ backend, IsPersistBackend backend) => RawSql (Key a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(PersistEntity record, PersistEntityBackend record ~ backend, IsPersistBackend backend) => RawSql (Entity record)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(PersistEntity record, KnownSymbol prefix, PersistEntityBackend record ~ backend, IsPersistBackend backend) => RawSql (EntityWithPrefix prefix record)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b) => RawSql (a, b)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c) => RawSql (a, b, c)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d) => RawSql (a, b, c, d)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e) => RawSql (a, b, c, d, e)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f) => RawSql (a, b, c, d, e, f)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g) => RawSql (a, b, c, d, e, f, g)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h) => RawSql (a, b, c, d, e, f, g, h)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i) => RawSql (a, b, c, d, e, f, g, h, i)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j) => RawSql (a, b, c, d, e, f, g, h, i, j)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k) => RawSql (a, b, c, d, e, f, g, h, i, j, k)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3, RawSql h3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3, h3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3, RawSql h3, RawSql i3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3, h3, i3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class(RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3, RawSql h3, RawSql i3, RawSql j3) => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3, h3, i3, j3)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class
Record of functions to override the default behavior in mkColumns. It is recommended you initialize this with emptyBackendSpecificOverrides and override the default values, so that as new fields are added, your code still compiles.
For added safety, use the getBackendSpecific* and setBackendSpecific*
functions, as a breaking change to the record field labels won't be reflected
in a major version bump of the library.
A Migration is a four level monad stack consisting of:
WriterT [Text]representing a log of errors in the migrations.WriterT CautiousMigrationrepresenting a list of migrations to run, along with whether or not they are safe.ReaderT SqlBackend, aka the SqlPersistT transformer for database interop.IOfor arbitrary IO.
An exception indicating that Persistent refused to run some unsafe migrations. Contains a list of pairs where the Bool tracks whether the migration was unsafe (True means unsafe), and the Sql is the sql statement for the migration.
Constructors
Instances2Show, Exception
Show PersistUnsafeMigrationExceptionDefined in persistent-2.18.1.0 · Database.Persist.Sql.MigrationThis Show instance renders an error message suitable for printing to the console. This is a little dodgy, but since GHC uses Show instances when displaying uncaught exceptions, we have little choice.
Exception PersistUnsafeMigrationExceptionDefined in persistent-2.18.1.0 · Database.Persist.Sql.Migration
Used when determining how to prefix a column name in a WHERE clause.
Constructors
PrefixTableNamePrefix the column with the table name. This is useful if the column name might be ambiguous.
PrefixExcludedPrefix the column name with the
EXCLUDEDkeyword. This is used with the Postgresql backend when doingON CONFLICT DO UPDATEclauses - see the documentation onupsertWhereandupsertManyWhere.
Constructors
ColumncName :: !FieldNameDBcNull :: !BoolcSqlType :: !SqlTypecDefault :: !Maybe TextcGenerated :: !Maybe TextcDefaultConstraintName :: !Maybe ConstraintNameDBcMaxLen :: !Maybe IntegercReference :: !Maybe ColumnReference
This value specifies how a field references another table.
Constructors
ColumnReferencecrTableName :: !EntityNameDBThe table name that the
crConstraintName :: !ConstraintNameDBThe name of the foreign key constraint.
crFieldCascade :: !FieldCascadeWhether or not updates/deletions to the referenced table cascade to this table.
Instances3Eq, Ord, Show
Eq ColumnReferenceDefined in persistent-2.18.1.0 · Database.Persist.Sql.TypesOrd ColumnReferenceDefined in persistent-2.18.1.0 · Database.Persist.Sql.TypesShow ColumnReferenceDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types
Values to configure a pool of database connections. See Data.Pool for details.
Constructors
ConnectionPoolConfigconnectionPoolConfigStripes :: IntHow many stripes to divide the pool into. See Data.Pool for details. Default: 1.
connectionPoolConfigIdleTimeout :: NominalDiffTimeHow long connections can remain idle before being disposed of, in seconds. Default: 600
connectionPoolConfigSize :: IntHow many connections should be held in the connection pool. Default: 10
Instances1Show
Show ConnectionPoolConfigDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types
Instances2Show, Exception
Show PersistentSqlExceptionDefined in persistent-2.18.1.0 · Database.Persist.Sql.TypesException PersistentSqlExceptionDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types
A single column (see rawSql). Any PersistField may be
used here, including PersistValue (which does not do any
processing).
Instances5Eq, Ord, Read, Show, RawSql
Eq a => Eq (Single a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.TypesOrd a => Ord (Single a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.TypesRead a => Read (Single a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.TypesShow a => Show (Single a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.TypesPersistField a => RawSql (Single a)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Class
A backend which is a wrapper around SqlBackend.
type SqlBackendCanRead backend = (BackendCompatible SqlBackend backend, PersistQueryRead backend, PersistStoreRead backend, PersistUniqueRead backend)A constraint synonym which witnesses that a backend is SQL and can run read queries.
type SqlBackendCanWrite backend = (SqlBackendCanRead backend, PersistQueryWrite backend, PersistStoreWrite backend, PersistUniqueWrite backend)A constraint synonym which witnesses that a backend is SQL and can run read and write queries.
An SQL backend which can only handle read queries
The constructor was exposed in 2.10.0.
Constructors
Instances27PersistQueryRead, HasPersistBackend, IsPersistBackend, PersistCore, PersistStoreRead, PersistUniqueRead, …
PersistQueryRead SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanHasPersistBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalIsPersistBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalPersistCore SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreRead SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistUniqueRead SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanBackendCompatible SqlBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBounded (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEnum (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEq (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanIntegral (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanNum (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanOrd (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanRead (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanReal (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanShow (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanGeneric (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromJSON (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToJSON (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromHttpApiData (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToHttpApiData (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPathPiece (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlReadBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphantype Rep (BackendKey SqlReadBackend) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan"BackendKey"
"Database.Persist.Sql.Orphan.PersistStore"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'True) (C1 ('MetaCons"SqlReadBackendKey"
'PrefixI 'True) (S1 ('MetaSel ('Just"unSqlReadBackendKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))data BackendKey SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphantype BaseBackend SqlReadBackend = SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.Internal
type SqlReadT (m :: Type -> Type) a = forall backend. SqlBackendCanRead backend => ReaderT backend m aLike SqlPersistT but compatible with any SQL backend which can handle read queries.
An SQL backend which can handle read or write queries
The constructor was exposed in 2.10.0
Constructors
Instances30PersistQueryRead, PersistQueryWrite, HasPersistBackend, IsPersistBackend, PersistCore, PersistStoreRead, …
PersistQueryRead SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanPersistQueryWrite SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanHasPersistBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalIsPersistBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.InternalPersistCore SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreRead SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreWrite SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistUniqueRead SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanPersistUniqueWrite SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanBackendCompatible SqlBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBounded (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEnum (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEq (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanIntegral (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanNum (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanOrd (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanRead (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanReal (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanShow (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanGeneric (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromJSON (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToJSON (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromHttpApiData (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToHttpApiData (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPathPiece (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlWriteBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphantype Rep (BackendKey SqlWriteBackend) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan"BackendKey"
"Database.Persist.Sql.Orphan.PersistStore"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'True) (C1 ('MetaCons"SqlWriteBackendKey"
'PrefixI 'True) (S1 ('MetaSel ('Just"unSqlWriteBackendKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))data BackendKey SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphantype BaseBackend SqlWriteBackend = SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Types.Internal
type SqlWriteT (m :: Type -> Type) a = forall backend. SqlBackendCanWrite backend => ReaderT backend m aLike SqlPersistT but compatible with any SQL backend which can handle read and write queries.
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 , known as a Pool
SqlBackendConnectionPool, 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.
Instances32PersistQueryRead, PersistQueryWrite, HasPersistBackend, IsPersistBackend, PersistCore, PersistStoreRead, …
PersistQueryRead SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanPersistQueryWrite SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistQuery · orphanHasPersistBackend SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.InternalIsPersistBackend SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.InternalPersistCore SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreRead SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistStoreWrite SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistUniqueRead SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanPersistUniqueWrite SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistUnique · orphanBackendCompatible SqlBackend SqlReadBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBackendCompatible SqlBackend SqlWriteBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBackendCompatible SqlBackend SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanBounded (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEnum (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanEq (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanIntegral (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanNum (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanOrd (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanRead (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanReal (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanShow (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanGeneric (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromJSON (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToJSON (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanFromHttpApiData (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanToHttpApiData (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPathPiece (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistField (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphanPersistFieldSql (BackendKey SqlBackend)Defined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphantype Rep (BackendKey SqlBackend) = D1 ('MetaDataDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphan"BackendKey"
"Database.Persist.Sql.Orphan.PersistStore"
"persistent-2.18.1.0-3nfqmEoifEQWKRFhPRuTO"
'True) (C1 ('MetaCons"SqlBackendKey"
'PrefixI 'True) (S1 ('MetaSel ('Just"unSqlBackendKey"
) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))data BackendKey SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.Sql.Orphan.PersistStore · orphantype BaseBackend SqlBackend = SqlBackendDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal
Constructors
Please refer to the documentation for the database in question for a full overview of the semantics of the varying isolation levels
Instances5Bounded, Enum, Eq, Ord, Show
Bounded IsolationLevelDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal.IsolationLevelEnum IsolationLevelDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal.IsolationLevelEq IsolationLevelDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal.IsolationLevelOrd IsolationLevelDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal.IsolationLevelShow IsolationLevelDefined in persistent-2.18.1.0 · Database.Persist.SqlBackend.Internal.IsolationLevel
A Statement is a representation of a database query that has been prepared and stored on the server side.
Constructors
StatementstmtFinalize :: IO ()stmtReset :: IO ()stmtExecute :: [PersistValue] -> IO Int64stmtQuery :: forall (m :: Type -> Type). MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())
An action that might happen on a deletion or update on a foreign key change.
Instances5Eq, Ord, Read, Show, Lift
Eq CascadeActionDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd CascadeActionDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead CascadeActionDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow CascadeActionDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift CascadeActionDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
A Checkmark should be used as a field type whenever a uniqueness constraint should guarantee that a certain kind of record may appear at most once, but other kinds of records may appear any number of times.
NOTE: You need to mark any Checkmark fields as nullable
(see the following example).
For example, suppose there's a Location entity that
represents where a user has lived:
Location
user UserId
name Text
current Checkmark nullable
UniqueLocation user current
The UniqueLocation constraint allows any number of
Inactive Locations to be current. However, there may be
at most one current Location per user (i.e., either zero
or one per user).
This data type works because of the way that SQL treats
NULLable fields within uniqueness constraints. The SQL
standard says that NULL values should be considered
different, so we represent Inactive as SQL NULL, thus
allowing any number of Inactive records. On the other hand,
we represent Active as TRUE, so the uniqueness constraint
will disallow more than one Active record.
Note: There may be DBMSs that do not respect the SQL
standard's treatment of NULL values on uniqueness
constraints, please check if this data type works before
relying on it.
The SQL BOOLEAN type is used because it's the smallest data
type available. Note that we never use FALSE, just TRUE
and NULL. Provides the same behavior Maybe () would if
() was a valid PersistField.
Instances11Bounded, Enum, Eq, Ord, Read, Show, …
Bounded CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseEnum CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseEq CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseFromHttpApiData CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseToHttpApiData CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BasePathPiece CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Types.BasePersistField CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Class.PersistFieldPersistFieldSql CheckmarkDefined in persistent-2.18.1.0 · Database.Persist.Sql.Class
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq CompositeDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd CompositeDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead CompositeDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow CompositeDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift CompositeDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
An EmbedEntityDef is the same as an EntityDef But it is only used for fieldReference so it only has data needed for embedding
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq EmbedEntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd EmbedEntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead EmbedEntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow EmbedEntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift EmbedEntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
An EmbedFieldDef is the same as a FieldDef But it is only used for embeddedFields so it only has data needed for embedding
Constructors
EmbedFieldDefemFieldDB :: FieldNameDBemFieldEmbed :: Maybe (Either SelfEmbed EntityNameHS)
Instances5Eq, Ord, Read, Show, Lift
Eq EmbedFieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd EmbedFieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead EmbedFieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow EmbedFieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift EmbedFieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
An EntityDef represents the information that persistent knows
about an Entity. It uses this information to generate the Haskell
datatype, the SQL migrations, and other relevant conversions.
Instances5Eq, Ord, Read, Show, Lift
Eq EntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd EntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead EntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow EntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift EntityDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
The definition for the entity's primary key ID.
Constructors
EntityIdField !FieldDefThe entity has a single key column, and it is a surrogate key - that is, you can't go from
rec -> Key rec.EntityIdNaturalKey !CompositeDefThe entity has a natural key. This means you can write
rec -> Key recbecause all the key fields are present on the datatype.A natural key can have one or more columns.
Instances5Eq, Ord, Read, Show, Lift
Eq EntityIdDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd EntityIdDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead EntityIdDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow EntityIdDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift EntityIdDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Attributes that may be attached to fields that can affect migrations and serialization in backend-specific ways.
While we endeavor to, we can't forsee all use cases for all backends, and so FieldAttr is extensible through its constructor FieldAttrOther.
Constructors
FieldAttrMaybeFieldAttrNullableThis indicates that the column is nullable, but should not have a Maybe type. For this to work out, you need to ensure that the
PersistFieldinstance for the type in question can support a PersistNull value.data What = NoWhat | Hello Text instance PersistField What where fromPersistValue PersistNull = pure NoWhat fromPersistValue pv = Hello $ fromPersistValue pv instance PersistFieldSql What where sqlType _ = SqlString User what What nullableFieldAttrMigrationOnlyThis tag means that the column will not be present on the Haskell code, but will not be removed from the database. Useful to deprecate fields in phases.
You should set the column to be nullable in the database. Otherwise, inserts won't have values.
User oldName Text MigrationOnly newName TextFieldAttrSafeToRemoveA
SafeToRemoveattribute is not present on the Haskell datatype, and the backend migrations should attempt to drop the column without triggering any unsafe migration warnings.Useful after you've used
MigrationOnlyto remove a column from the database in phases.User oldName Text SafeToRemove newName TextFieldAttrNoreferenceThis attribute indicates that we should not create a foreign key reference from a column. By default,
persistentwill try and create a foreign key reference for a column if it can determine that the type of the column is aor anKeyentityEntityIdand theEntity's name was present inmkPersist.This is useful if you want to use the explicit foreign key syntax.
Post title Text Comment postId PostId noreference Foreign Post fk_comment_post postIdFieldAttrReference TextThis is set to specify precisely the database table the column refers to.
Post title Text Comment postId PostId references="post"You should not need this -
persistentshould be capable of correctly determining the target table's name. If you do need this, please file an issue describing why.FieldAttrConstraint TextSpecify a name for the constraint on the foreign key reference for this table.
Post title Text Comment postId PostId constraint="my_cool_constraint_name"FieldAttrDefault TextSpecify the default value for a column.
User createdAt UTCTime default="NOW()"Note that a
default=attribute does not mean you can omit the value while inserting.FieldAttrSqltype TextSpecify a custom SQL type for the column. Generally, you should define a custom datatype with a custom
PersistFieldSqlinstance instead of using this.User uuid Text sqltype=UUIDFieldAttrMaxlen IntegerSet a maximum length for a column. Useful for VARCHAR and indexes.
User name Text maxlen=200 UniqueName nameFieldAttrSql TextSpecify the database name of the column.
User blarghle Int sql="b_l_a_r_g_h_l_e"Useful for performing phased migrations, where one column is renamed to another column over time.
FieldAttrOther TextA grab bag of random attributes that were unrecognized by the parser.
Instances5Eq, Ord, Read, Show, Lift
Eq FieldAttrDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd FieldAttrDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead FieldAttrDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow FieldAttrDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift FieldAttrDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
This datatype describes how a foreign reference field cascades deletes or updates.
This type is used in both parsing the model definitions and performing migrations. A Nothing in either of the field values means that the user has not specified a CascadeAction. An unspecified CascadeAction is defaulted to Restrict when doing migrations.
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq FieldCascadeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd FieldCascadeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead FieldCascadeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow FieldCascadeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift FieldCascadeDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
A FieldDef represents the inormation that persistent knows about
a field of a datatype. This includes information used to parse the field
out of the database and what the field corresponds to.
Constructors
FieldDeffieldHaskell :: !FieldNameHSThe name of the field. Note that this does not corresponds to the record labels generated for the particular entity - record labels are generated with the type name prefixed to the field, so a FieldDef that contains a
FieldNameHS "name"for a typeUserwill have a record fielduserName.fieldDB :: !FieldNameDBThe name of the field in the database. For SQL databases, this corresponds to the column name.
fieldType :: !FieldTypeThe type of the field in Haskell.
fieldSqlType :: !SqlTypeThe type of the field in a SQL database.
fieldAttrs :: ![FieldAttr]User annotations for a field. These are provided with the
!operator.fieldStrict :: !BoolfieldReference :: !ReferenceDeffieldCascade :: !FieldCascadeDefines how operations on the field cascade on to the referenced tables. This doesn't have any meaning if the fieldReference is set to NoReference or SelfReference. The cascade option here should be the same as the one obtained in the fieldReference.
fieldComments :: !Maybe TextOptional comments for a
Field.fieldGenerated :: !Maybe TextWhether or not the field is a
GENERATEDcolumn, and additionally the expression to use for generation.fieldIsImplicitIdColumn :: !Bool
Instances5Eq, Ord, Read, Show, Lift
Eq FieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd FieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead FieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow FieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift FieldDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
A FieldType describes a field parsed from the QuasiQuoter and is used to determine the Haskell type in the generated code.
name Text parses into FTTypeCon Nothing Text
name T.Text parses into FTTypeCon (Just T Text)
name (Jsonb User) parses into:
FTApp (FTTypeCon Nothing Jsonb) (FTTypeCon Nothing User)
Instances5Eq, Ord, Read, Show, Lift
Eq FieldTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd FieldTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead FieldTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow FieldTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift FieldTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Constructors
ForeignDefforeignRefTableHaskell :: !EntityNameHSforeignRefTableDBName :: !EntityNameDBforeignConstraintNameHaskell :: !ConstraintNameHSforeignConstraintNameDBName :: !ConstraintNameDBforeignFieldCascade :: !FieldCascadeDetermine how the field will cascade on updates and deletions.
foreignFields :: ![(ForeignFieldDef, ForeignFieldDef)]foreignAttrs :: ![Attr]foreignNullable :: BoolforeignToPrimary :: BoolDetermines if the reference is towards a Primary Key or not.
Instances5Eq, Ord, Read, Show, Lift
Eq ForeignDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd ForeignDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead ForeignDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow ForeignDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift ForeignDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Used instead of FieldDef to generate a smaller amount of code
Constructors
Instances2Eq, Show
Eq IsNullableDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow IsNullableDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Instances2Show, Exception
Show PersistExceptionDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseException PersistExceptionDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Instances3Read, Show, Lift
Read PersistFilterDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow PersistFilterDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift PersistFilterDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Instances3Read, Show, Lift
Read PersistUpdateDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow PersistUpdateDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift PersistUpdateDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
There are 3 kinds of references 1) composite (to fields that exist in the record) 2) single field 3) embedded
Constructors
NoReferenceForeignRef !EntityNameHSA ForeignRef has a late binding to the EntityDef it references via name and has the Haskell type of the foreign key in the form of FieldType
EmbedRef EntityNameHSSelfReferenceA SelfReference stops an immediate cycle which causes non-termination at compile-time (issue #311).
Instances5Eq, Ord, Read, Show, Lift
Eq ReferenceDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd ReferenceDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead ReferenceDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow ReferenceDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift ReferenceDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
A SQL data type. Naming attempts to reflect the underlying Haskell datatypes, eg SqlString instead of SqlVarchar. Different SQL databases may have different translations for these types.
Instances5Eq, Ord, Read, Show, Lift
Eq SqlTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd SqlTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead SqlTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow SqlTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift SqlTypeDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Type for storing the Uniqueness constraint in the Schema. Assume you have the following schema with a uniqueness constraint:
Person
name String
age Int
UniqueAge age
This will be represented as:
UniqueDef
{ uniqueHaskell = ConstraintNameHS (packPTH UniqueAge)
, uniqueDBName = ConstraintNameDB (packPTH "unique_age")
, uniqueFields = [(FieldNameHS (packPTH "age"), FieldNameDB (packPTH "age"))]
, uniqueAttrs = []
}
Constructors
Instances5Eq, Ord, Read, Show, Lift
Eq UniqueDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseOrd UniqueDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseRead UniqueDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow UniqueDefDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseLift UniqueDefDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
Constructors
Instances2Show, Exception
Show UpdateExceptionDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseException UpdateExceptionDefined in persistent-2.18.1.0 · Database.Persist.Types.Base
The reason why a field is nullable is very important. A
field that is nullable because of a Maybe tag will have its
type changed from A to Maybe A. OTOH, a field that is
nullable because of a nullable tag will remain with the same
type.
Instances2Eq, Show
Eq WhyNullableDefined in persistent-2.18.1.0 · Database.Persist.Types.BaseShow WhyNullableDefined in persistent-2.18.1.0 · Database.Persist.Types.Base