-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Type-safe, multi-backend data serialization.
--   
--   Hackage documentation generation is not reliable. For up to date
--   documentation, please see:
--   <a>http://www.stackage.org/package/persistent</a>.
@package persistent
@version 2.10.5.2

module Database.Persist.Types

-- | A <a>Checkmark</a> 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.
--   
--   <i>NOTE:</i> You need to mark any <tt>Checkmark</tt> fields as
--   <tt>nullable</tt> (see the following example).
--   
--   For example, suppose there's a <tt>Location</tt> entity that
--   represents where a user has lived:
--   
--   <pre>
--   Location
--       user    UserId
--       name    Text
--       current Checkmark nullable
--   
--       UniqueLocation user current
--   </pre>
--   
--   The <tt>UniqueLocation</tt> constraint allows any number of
--   <a>Inactive</a> <tt>Location</tt>s to be <tt>current</tt>. However,
--   there may be at most one <tt>current</tt> <tt>Location</tt> per user
--   (i.e., either zero or one per user).
--   
--   This data type works because of the way that SQL treats
--   <tt>NULL</tt>able fields within uniqueness constraints. The SQL
--   standard says that <tt>NULL</tt> values should be considered
--   different, so we represent <a>Inactive</a> as SQL <tt>NULL</tt>, thus
--   allowing any number of <a>Inactive</a> records. On the other hand, we
--   represent <a>Active</a> as <tt>TRUE</tt>, so the uniqueness constraint
--   will disallow more than one <a>Active</a> record.
--   
--   <i>Note:</i> There may be DBMSs that do not respect the SQL standard's
--   treatment of <tt>NULL</tt> values on uniqueness constraints, please
--   check if this data type works before relying on it.
--   
--   The SQL <tt>BOOLEAN</tt> type is used because it's the smallest data
--   type available. Note that we never use <tt>FALSE</tt>, just
--   <tt>TRUE</tt> and <tt>NULL</tt>. Provides the same behavior <tt>Maybe
--   ()</tt> would if <tt>()</tt> was a valid <tt>PersistField</tt>.
data Checkmark

-- | When used on a uniqueness constraint, there may be at most one
--   <a>Active</a> record.
Active :: Checkmark

-- | When used on a uniqueness constraint, there may be any number of
--   <a>Inactive</a> records.
Inactive :: Checkmark
data IsNullable
Nullable :: !WhyNullable -> IsNullable
NotNullable :: IsNullable

-- | The reason why a field is <tt>nullable</tt> is very important. A field
--   that is nullable because of a <tt>Maybe</tt> tag will have its type
--   changed from <tt>A</tt> to <tt>Maybe A</tt>. OTOH, a field that is
--   nullable because of a <tt>nullable</tt> tag will remain with the same
--   type.
data WhyNullable
ByMaybeAttr :: WhyNullable
ByNullableAttr :: WhyNullable

-- | An <a>EntityDef</a> represents the information that
--   <tt>persistent</tt> knows about an Entity. It uses this information to
--   generate the Haskell datatype, the SQL migrations, and other relevant
--   conversions.
data EntityDef
EntityDef :: !HaskellName -> !DBName -> !FieldDef -> ![Attr] -> ![FieldDef] -> ![UniqueDef] -> ![ForeignDef] -> ![Text] -> !Map Text [ExtraLine] -> !Bool -> !Maybe Text -> EntityDef

-- | The name of the entity as Haskell understands it.
[entityHaskell] :: EntityDef -> !HaskellName

-- | The name of the database table corresponding to the entity.
[entityDB] :: EntityDef -> !DBName

-- | The entity's primary key or identifier.
[entityId] :: EntityDef -> !FieldDef

-- | The <tt>persistent</tt> entity syntax allows you to add arbitrary
--   <a>Attr</a>s to an entity using the <tt>!</tt> operator. Those
--   attributes are stored in this list.
[entityAttrs] :: EntityDef -> ![Attr]

-- | The fields for this entity. Note that the ID field will not be present
--   in this list. To get all of the fields for an entity, use
--   <a>keyAndEntityFields</a>.
[entityFields] :: EntityDef -> ![FieldDef]

-- | The Uniqueness constraints for this entity.
[entityUniques] :: EntityDef -> ![UniqueDef]

-- | The foreign key relationships that this entity has to other entities.
[entityForeigns] :: EntityDef -> ![ForeignDef]

-- | A list of type classes that have been derived for this entity.
[entityDerives] :: EntityDef -> ![Text]
[entityExtra] :: EntityDef -> !Map Text [ExtraLine]

-- | Whether or not this entity represents a sum type in the database.
[entitySum] :: EntityDef -> !Bool

-- | Optional comments on the entity.
[entityComments] :: EntityDef -> !Maybe Text
entityPrimary :: EntityDef -> Maybe CompositeDef
entityKeyFields :: EntityDef -> [FieldDef]
keyAndEntityFields :: EntityDef -> [FieldDef]
type ExtraLine = [Text]
newtype HaskellName
HaskellName :: Text -> HaskellName
[unHaskellName] :: HaskellName -> Text
newtype DBName
DBName :: Text -> DBName
[unDBName] :: DBName -> Text
type Attr = Text
data FieldType

-- | Optional module and name.
FTTypeCon :: Maybe Text -> Text -> FieldType
FTApp :: FieldType -> FieldType -> FieldType
FTList :: FieldType -> FieldType

-- | A <a>FieldDef</a> represents the inormation that <tt>persistent</tt>
--   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.
data FieldDef
FieldDef :: !HaskellName -> !DBName -> !FieldType -> !SqlType -> ![Attr] -> !Bool -> !ReferenceDef -> !Maybe Text -> FieldDef

-- | The 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
--   <a>FieldDef</a> that contains a <tt><a>HaskellName</a> "name"</tt> for
--   a type <tt>User</tt> will have a record field <tt>userName</tt>.
[fieldHaskell] :: FieldDef -> !HaskellName

-- | The name of the field in the database. For SQL databases, this
--   corresponds to the column name.
[fieldDB] :: FieldDef -> !DBName

-- | The type of the field in Haskell.
[fieldType] :: FieldDef -> !FieldType

-- | The type of the field in a SQL database.
[fieldSqlType] :: FieldDef -> !SqlType

-- | User annotations for a field. These are provided with the <tt>!</tt>
--   operator.
[fieldAttrs] :: FieldDef -> ![Attr]

-- | If this is <a>True</a>, then the Haskell datatype will have a strict
--   record field. The default value for this is <a>True</a>.
[fieldStrict] :: FieldDef -> !Bool
[fieldReference] :: FieldDef -> !ReferenceDef

-- | Optional comments for a <tt>Field</tt>. There is not currently a way
--   to attach comments to a field in the quasiquoter.
[fieldComments] :: FieldDef -> !Maybe Text

-- | There are 3 kinds of references 1) composite (to fields that exist in
--   the record) 2) single field 3) embedded
data ReferenceDef
NoReference :: ReferenceDef

-- | A ForeignRef has a late binding to the EntityDef it references via
--   HaskellName and has the Haskell type of the foreign key in the form of
--   FieldType
ForeignRef :: !HaskellName -> !FieldType -> ReferenceDef
EmbedRef :: EmbedEntityDef -> ReferenceDef
CompositeRef :: CompositeDef -> ReferenceDef

-- | A SelfReference stops an immediate cycle which causes non-termination
--   at compile-time (issue #311).
SelfReference :: ReferenceDef

-- | An EmbedEntityDef is the same as an EntityDef But it is only used for
--   fieldReference so it only has data needed for embedding
data EmbedEntityDef
EmbedEntityDef :: !HaskellName -> ![EmbedFieldDef] -> EmbedEntityDef
[embeddedHaskell] :: EmbedEntityDef -> !HaskellName
[embeddedFields] :: EmbedEntityDef -> ![EmbedFieldDef]

-- | An EmbedFieldDef is the same as a FieldDef But it is only used for
--   embeddedFields so it only has data needed for embedding
data EmbedFieldDef
EmbedFieldDef :: !DBName -> Maybe EmbedEntityDef -> Maybe HaskellName -> EmbedFieldDef
[emFieldDB] :: EmbedFieldDef -> !DBName
[emFieldEmbed] :: EmbedFieldDef -> Maybe EmbedEntityDef

-- | <a>emFieldEmbed</a> can create a cycle (issue #311) when a cycle is
--   detected, <a>emFieldEmbed</a> will be Nothing and <a>emFieldCycle</a>
--   will be Just
[emFieldCycle] :: EmbedFieldDef -> Maybe HaskellName
toEmbedEntityDef :: EntityDef -> EmbedEntityDef
data UniqueDef
UniqueDef :: !HaskellName -> !DBName -> ![(HaskellName, DBName)] -> ![Attr] -> UniqueDef
[uniqueHaskell] :: UniqueDef -> !HaskellName
[uniqueDBName] :: UniqueDef -> !DBName
[uniqueFields] :: UniqueDef -> ![(HaskellName, DBName)]
[uniqueAttrs] :: UniqueDef -> ![Attr]
data CompositeDef
CompositeDef :: ![FieldDef] -> ![Attr] -> CompositeDef
[compositeFields] :: CompositeDef -> ![FieldDef]
[compositeAttrs] :: CompositeDef -> ![Attr]

-- | Used instead of FieldDef to generate a smaller amount of code
type ForeignFieldDef = (HaskellName, DBName)
data ForeignDef
ForeignDef :: !HaskellName -> !DBName -> !HaskellName -> !DBName -> ![(ForeignFieldDef, ForeignFieldDef)] -> ![Attr] -> Bool -> ForeignDef
[foreignRefTableHaskell] :: ForeignDef -> !HaskellName
[foreignRefTableDBName] :: ForeignDef -> !DBName
[foreignConstraintNameHaskell] :: ForeignDef -> !HaskellName
[foreignConstraintNameDBName] :: ForeignDef -> !DBName
[foreignFields] :: ForeignDef -> ![(ForeignFieldDef, ForeignFieldDef)]
[foreignAttrs] :: ForeignDef -> ![Attr]
[foreignNullable] :: ForeignDef -> Bool
data PersistException

-- | Generic Exception
PersistError :: Text -> PersistException
PersistMarshalError :: Text -> PersistException
PersistInvalidField :: Text -> PersistException
PersistForeignConstraintUnmet :: Text -> PersistException
PersistMongoDBError :: Text -> PersistException
PersistMongoDBUnsupported :: Text -> PersistException

-- | A raw value which can be stored in any backend and can be marshalled
--   to and from a <tt>PersistField</tt>.
data PersistValue
PersistText :: Text -> PersistValue
PersistByteString :: ByteString -> PersistValue
PersistInt64 :: Int64 -> PersistValue
PersistDouble :: Double -> PersistValue
PersistRational :: Rational -> PersistValue
PersistBool :: Bool -> PersistValue
PersistDay :: Day -> PersistValue
PersistTimeOfDay :: TimeOfDay -> PersistValue
PersistUTCTime :: UTCTime -> PersistValue
PersistNull :: PersistValue
PersistList :: [PersistValue] -> PersistValue
PersistMap :: [(Text, PersistValue)] -> PersistValue

-- | Intended especially for MongoDB backend
PersistObjectId :: ByteString -> PersistValue

-- | Intended especially for PostgreSQL backend for text arrays
PersistArray :: [PersistValue] -> PersistValue

-- | Using <a>PersistDbSpecific</a> allows you to use types specific to a
--   particular backend For example, below is a simple example of the
--   PostGIS geography type:
--   
--   <pre>
--   data Geo = Geo ByteString
--   
--   instance PersistField Geo where
--     toPersistValue (Geo t) = PersistDbSpecific t
--   
--     fromPersistValue (PersistDbSpecific t) = Right $ Geo $ Data.ByteString.concat ["'", t, "'"]
--     fromPersistValue _ = Left "Geo values must be converted from PersistDbSpecific"
--   
--   instance PersistFieldSql Geo where
--     sqlType _ = SqlOther "GEOGRAPHY(POINT,4326)"
--   
--   toPoint :: Double -&gt; Double -&gt; Geo
--   toPoint lat lon = Geo $ Data.ByteString.concat ["'POINT(", ps $ lon, " ", ps $ lat, ")'"]
--     where ps = Data.Text.pack . show
--   </pre>
--   
--   If Foo has a geography field, we can then perform insertions like the
--   following:
--   
--   <pre>
--   insert $ Foo (toPoint 44 44)
--   </pre>
PersistDbSpecific :: ByteString -> PersistValue
fromPersistValueText :: PersistValue -> Either Text Text

-- | 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.
data SqlType
SqlString :: SqlType
SqlInt32 :: SqlType
SqlInt64 :: SqlType
SqlReal :: SqlType
SqlNumeric :: Word32 -> Word32 -> SqlType
SqlBool :: SqlType
SqlDay :: SqlType
SqlTime :: SqlType

-- | Always uses UTC timezone
SqlDayTime :: SqlType
SqlBlob :: SqlType

-- | a backend-specific name
SqlOther :: Text -> SqlType
data PersistFilter
Eq :: PersistFilter
Ne :: PersistFilter
Gt :: PersistFilter
Lt :: PersistFilter
Ge :: PersistFilter
Le :: PersistFilter
In :: PersistFilter
NotIn :: PersistFilter
BackendSpecificFilter :: Text -> PersistFilter
data UpdateException
KeyNotFound :: String -> UpdateException
UpsertError :: String -> UpdateException
data OnlyUniqueException
OnlyUniqueException :: String -> OnlyUniqueException
data PersistUpdate
Assign :: PersistUpdate
Add :: PersistUpdate
Subtract :: PersistUpdate
Multiply :: PersistUpdate
Divide :: PersistUpdate
BackendSpecificUpdate :: Text -> PersistUpdate
data SomePersistField
SomePersistField :: a -> SomePersistField

-- | Updating a database entity.
--   
--   Persistent users use combinators to create these.
data Update record
Update :: EntityField record typ -> typ -> PersistUpdate -> Update record
[updateField] :: Update record -> EntityField record typ
[updateValue] :: Update record -> typ
[updateUpdate] :: Update record -> PersistUpdate
BackendUpdate :: BackendSpecificUpdate (PersistEntityBackend record) record -> Update record
type family BackendSpecificUpdate backend record

-- | Query options.
--   
--   Persistent users use these directly.
data SelectOpt record
Asc :: EntityField record typ -> SelectOpt record
Desc :: EntityField record typ -> SelectOpt record
OffsetBy :: Int -> SelectOpt record
LimitTo :: Int -> SelectOpt record

-- | Filters which are available for <tt>select</tt>, <tt>updateWhere</tt>
--   and <tt>deleteWhere</tt>. Each filter constructor specifies the field
--   being filtered on, the type of comparison applied (equals, not equals,
--   etc) and the argument for the comparison.
--   
--   Persistent users use combinators to create these.
--   
--   Note that it's important to be careful about the <a>PersistFilter</a>
--   that you are using, if you use this directly. For example, using the
--   <a>In</a> <a>PersistFilter</a> requires that you have an array- or
--   list-shaped <a>EntityField</a>. It is possible to construct values
--   using this that will create malformed runtime values.
data Filter record
Filter :: EntityField record typ -> FilterValue typ -> PersistFilter -> Filter record
[filterField] :: Filter record -> EntityField record typ
[filterValue] :: Filter record -> FilterValue typ
[filterFilter] :: Filter record -> PersistFilter

-- | convenient for internal use, not needed for the API
FilterAnd :: [Filter record] -> Filter record
FilterOr :: [Filter record] -> Filter record
BackendFilter :: BackendSpecificFilter (PersistEntityBackend record) record -> Filter record

-- | Value to filter with. Highly dependant on the type of filter used.
data FilterValue typ
[FilterValue] :: typ -> FilterValue typ
[FilterValues] :: [typ] -> FilterValue typ
[UnsafeValue] :: forall a typ. PersistField a => a -> FilterValue typ
type family BackendSpecificFilter backend record

-- | By default, a backend will automatically generate the key Instead you
--   can specify a Primary key made up of unique values.
data family Key record

-- | Datatype that represents an entity, with both its <a>Key</a> and its
--   Haskell record representation.
--   
--   When using a SQL-based backend (such as SQLite or PostgreSQL), an
--   <a>Entity</a> may take any number of columns depending on how many
--   fields it has. In order to reconstruct your entity on the Haskell
--   side, <tt>persistent</tt> needs all of your entity columns and in the
--   right order. Note that you don't need to worry about this when using
--   <tt>persistent</tt>'s API since everything is handled correctly behind
--   the scenes.
--   
--   However, if you want to issue a raw SQL command that returns an
--   <a>Entity</a>, then you have to be careful with the column order.
--   While you could use <tt>SELECT Entity.* WHERE ...</tt> 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 <tt>persistent</tt>
--   expects (for example, if you add a new field in the middle of you
--   entity definition and then use the migration code --
--   <tt>persistent</tt> 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 <a>rawSql</a> (from the
--   <a>Database.Persist.GenericSql</a> module) with its /entity selection
--   placeholder/ (a double question mark <tt>??</tt>). Using
--   <tt>rawSql</tt> the query above must be written as <tt>SELECT ?? WHERE
--   ..</tt>. Then <tt>rawSql</tt> will replace <tt>??</tt> with the list
--   of all columns that we need from your entity in the right order. If
--   your query returns two entities (i.e. <tt>(Entity backend a, Entity
--   backend b)</tt>), then you must you use <tt>SELECT ??, ?? WHERE
--   ...</tt>, and so on.
data Entity record
Entity :: Key record -> record -> Entity record
[entityKey] :: Entity record -> Key record
[entityVal] :: Entity record -> record


-- | This module defines the Persistent entity syntax used in the
--   quasiquoter to generate persistent entities.
--   
--   The basic structure of the syntax looks like this:
--   
--   <pre>
--   TableName
--       fieldName      FieldType
--       otherField     String
--       nullableField  Int       Maybe
--   </pre>
--   
--   You start an entity definition with the table name, in this case,
--   <tt>TableName</tt>. It's followed by a list of fields on the entity,
--   which have the basic form <tt>fieldName FieldType</tt>. You can
--   indicate that a field is nullable with <a>Maybe</a> at the end of the
--   type.
--   
--   <tt>persistent</tt> automatically generates an ID column for you, if
--   you don't specify one, so the above table definition corresponds to
--   the following SQL:
--   
--   <pre>
--   CREATE TABLE table_name (
--       id                SERIAL PRIMARY KEY,
--       field_name        field_type NOT NULL,
--       other_field       varchar    NOT NULL,
--       nullable_field    int NULL
--   );
--   </pre>
--   
--   Note that the exact SQL that is generated can be customized using the
--   <a>PersistSettings</a> that are passed to the <a>parse</a> function.
--   
--   It generates a Haskell datatype with the following form:
--   
--   <pre>
--   data TableName = TableName
--       { tableNameFieldName :: FieldType
--       , tableNameOtherField :: String
--       , tableNameNullableField :: Maybe Int
--       }
--   </pre>
--   
--   As with the SQL generated, the specifics of this are customizable. See
--   the <tt>persistent-template</tt> package for details.
--   
--   <h1>Deriving</h1>
--   
--   You can add a deriving clause to a table, and the generated Haskell
--   type will have a deriving clause with that. Unlike normal Haskell
--   syntax, you don't need parentheses or commas to separate the classes,
--   and you can even have multiple deriving clauses.
--   
--   <pre>
--   User
--       name String
--       age  Int
--       deriving Eq Show
--       deriving Ord
--   </pre>
--   
--   <h1>Unique Keys</h1>
--   
--   You can define a uniqueness key on a table with the following format:
--   
--   <pre>
--   User
--      name String
--      age  Int
--   
--      UniqueUserName name
--   </pre>
--   
--   This will put a unique index on the <tt>user</tt> table and the
--   <tt>name</tt> field.
--   
--   <h1>Setting defaults</h1>
--   
--   You can use a <tt>default=${sql expression}</tt> clause to set a
--   default for a field. The thing following the `=` is interpreted as SQL
--   that will be put directly into the table definition.
--   
--   <pre>
--   User
--       name    Text
--       admin   Bool default=false
--   </pre>
--   
--   This creates a SQL definition like this:
--   
--   <pre>
--   CREATE TABLE user (
--     id      SERIAL PRIMARY KEY,
--     name    VARCHAR NOT NULL,
--     admin   BOOL DEFAULT=false
--   );
--   </pre>
--   
--   A restriction here is that you still need to provide a value when
--   performing an <tt>insert</tt>, because the generated Haskell type has
--   the form:
--   
--   <pre>
--   data User = User
--       { userName :: Text
--       , userAdmin :: Bool
--       }
--   </pre>
--   
--   You can work around this by using a 'Maybe Bool' and supplying
--   <a>Nothing</a> by default.
--   
--   <h1>Custom ID column</h1>
--   
--   If you don't want to use the default ID column type of <tt>Int64</tt>,
--   you can set a custom type with an <tt>Id</tt> field. This
--   <tt>User</tt> has a <tt>Text</tt> ID.
--   
--   <pre>
--   User
--       Id   Text
--       name Text
--       age  Int
--   </pre>
--   
--   If you do this, it's a good idea to set a default for the ID.
--   Otherwise, you will need to use <tt>insertKey</tt> instead of
--   <tt>insert</tt> when performing inserts.
--   
--   <pre>
--   <tt>insertKey</tt> (UserKey "Hello world!") (User <a>Bob</a> 32)
--   </pre>
--   
--   If you attempt to do <tt><tt>insert</tt> (User <a>Bob</a> 32)</tt>,
--   then you will receive a runtime error because the SQL database doesn't
--   know how to make an ID for you anymore. So instead just use a default
--   expression, like this:
--   
--   <pre>
--   User
--       Id      Text default=generate_user_id()
--       name    Text
--       age     Int
--   </pre>
--   
--   <h1>Custom Primary Keys</h1>
--   
--   Sometimes you don't want to have an ID column, and you want a
--   different sort of primary key. This is a table that stores unique
--   email addresses, and the email is the primary key. We store the first
--   and second part (eg <tt>first@second</tt>) separately.
--   
--   <pre>
--   Email
--       firstPart   Text
--       secondPart  Text
--   
--       Primary firstPart secondPart
--   </pre>
--   
--   This creates a table with the following form:
--   
--   <pre>
--   CREATE TABLE email (
--       first_part  varchar,
--       second_part varchar,
--   
--       PRIMARY KEY (first_part, second_part)
--   </pre>
--   
--   You can specify 1 or more columns in the primary key.
--   
--   <h1>Overriding SQL</h1>
--   
--   You can use a <tt>sql=custom</tt> annotation to provide some
--   customization on the entity and field. For example, you might prefer
--   to name a table differently than what <tt>persistent</tt> will do by
--   default. You may also prefer to name a field differently.
--   
--   <pre>
--   User sql=big_user_table
--       fullName    String sql=name
--       age         Int
--   </pre>
--   
--   This will alter the generated SQL to be:
--   
--   <pre>
--   CREATE TABEL big_user_table (
--       id      SERIAL PRIMARY KEY,
--       name    VARCHAR,
--       age     INT
--   );
--   </pre>
--   
--   <h1>Attributes</h1>
--   
--   The QuasiQuoter allows you to provide arbitrary attributes to an
--   entity or field. This can be used to extend the code in ways that the
--   library hasn't anticipated. If you use this feature, we'd definitely
--   appreciate hearing about it and potentially supporting your use case
--   directly!
--   
--   <pre>
--   User !funny
--       field   String  !sad
--       good    Dog     !sogood
--   </pre>
--   
--   We can see the attributes using the <a>entityAttrs</a> field and the
--   <a>fieldAttrs</a> field.
--   
--   <pre>
--   userAttrs = do
--       let userDefinition = <tt>entityDef</tt> (<tt>Proxy</tt> :: <tt>Proxy</tt> User)
--       let userAttributes = <a>entityAttrs</a> userDefinition
--       let fieldAttributes = <a>map</a> <a>fieldAttrs</a> (<a>entityFields</a> userDefinition)
--       print userAttributes
--   -- ["funny"]
--       print fieldAttributes
--   -- [["sad"],["sogood"]]
--   </pre>
--   
--   <h1>Documentation Comments</h1>
--   
--   The quasiquoter supports ordinary comments with <tt>--</tt> and
--   <tt>#</tt>. Since <tt>persistent-2.10.5.1</tt>, it also supports
--   documentation comments. The grammar for documentation comments is
--   similar to Haskell's Haddock syntax, with a few restrictions:
--   
--   <ol>
--   <li>Only the <tt>-- | </tt> form is allowed.</li>
--   <li>You must put a space before and after the <tt>|</tt> pipe
--   character.</li>
--   <li>The comment must be indented at the same level as the entity or
--   field it documents.</li>
--   </ol>
--   
--   An example of the field documentation is:
--   
--   <pre>
--   -- | I am a doc comment for a User. Users are important
--   -- | to the application, and should be treasured.
--   User
--       -- | Users have names. Call them by names.
--       name String
--       -- | A user can be old, or young, and we care about
--       -- | this for some reason.
--       age Int
--   </pre>
--   
--   The documentation is present on the <a>entityComments</a> field on the
--   <a>EntityDef</a> for the entity:
--   
--   <pre>
--   &gt;&gt;&gt; let userDefinition = entityDef (Proxy :: Proxy User)
--   &gt;&gt;&gt; entityComments userDefinition
--   "I am a doc comment for a User. Users are importantnto the application, and should be treasured.n"
--   </pre>
--   
--   Likewise, the field documentation is present in the
--   <a>fieldComments</a> field on the <a>FieldDef</a> present in the
--   <a>EntityDef</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let userFields = entityFields userDefinition
--   &gt;&gt;&gt; let comments = map fieldComments userFields
--   &gt;&gt;&gt; mapM_ putStrLn comments
--   "Users have names. Call them by names."
--   "A user can be old, or young, and we care aboutnthis for some reason."
--   </pre>
--   
--   Unfortunately, we can't use this to create Haddocks for you, because
--   <a>Template Haskell does not support Haddock yet</a>.
--   <tt>persistent</tt> backends *can* use this to generate SQL
--   <tt>COMMENT</tt>s, which are useful for a database perspective, and
--   you can use the <a>@persistent-documentation@</a> library to render a
--   Markdown document of the entity definitions.
module Database.Persist.Quasi

-- | Parses a quasi-quoted syntax into a list of entity definitions.
parse :: PersistSettings -> Text -> [EntityDef]
data PersistSettings
PersistSettings :: !Text -> Text -> !Bool -> !Text -> PersistSettings
[psToDBName] :: PersistSettings -> !Text -> Text

-- | Whether fields are by default strict. Default value: <tt>True</tt>.
[psStrictFields] :: PersistSettings -> !Bool

-- | The name of the id column. Default value: <tt>id</tt> The name of the
--   id column can also be changed on a per-model basis
--   <a>https://github.com/yesodweb/persistent/wiki/Persistent-entity-syntax</a>
[psIdName] :: PersistSettings -> !Text
upperCaseSettings :: PersistSettings
lowerCaseSettings :: PersistSettings
nullable :: [Text] -> IsNullable
instance GHC.Show.Show Database.Persist.Quasi.LinesWithComments
instance GHC.Classes.Eq Database.Persist.Quasi.LinesWithComments
instance GHC.Classes.Eq Database.Persist.Quasi.Token
instance GHC.Show.Show Database.Persist.Quasi.Token
instance GHC.Show.Show a => GHC.Show.Show (Database.Persist.Quasi.ParseState a)
instance GHC.Show.Show (f Data.Text.Internal.Text) => GHC.Show.Show (Database.Persist.Quasi.Line' f)
instance GHC.Classes.Eq (f Data.Text.Internal.Text) => GHC.Classes.Eq (Database.Persist.Quasi.Line' f)

module Database.Persist.Class

-- | <a>ToBackendKey</a> converts a <a>PersistEntity</a> <a>Key</a> into a
--   <a>BackendKey</a> This can be used by each backend to convert between
--   a <a>Key</a> and a plain Haskell type. For Sql, that is done with
--   <tt>toSqlKey</tt> and <tt>fromSqlKey</tt>.
--   
--   By default, a <a>PersistEntity</a> uses the default <a>BackendKey</a>
--   for its Key and is an instance of ToBackendKey
--   
--   A <a>Key</a> that instead uses a custom type will not be an instance
--   of <a>ToBackendKey</a>.
class (PersistEntity record, PersistEntityBackend record ~ backend, PersistCore backend) => ToBackendKey backend record
toBackendKey :: ToBackendKey backend record => Key record -> BackendKey backend
fromBackendKey :: ToBackendKey backend record => BackendKey backend -> Key record
class PersistCore backend where {
    data family BackendKey backend;
}

-- | 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.
type PersistStore a = PersistStoreWrite a
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

-- | Get a record by identifier, if available.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   getSpj :: MonadIO m =&gt; ReaderT SqlBackend m (Maybe User)
--   getSpj = get spjId
--   </pre>
--   
--   <pre>
--   mspj &lt;- getSpj
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get this:
--   
--   <pre>
--   +------+-----+
--   | name | age |
--   +------+-----+
--   | SPJ  |  40 |
--   +------+-----+
--   </pre>
get :: (PersistStoreRead backend, MonadIO m, PersistRecordBackend record backend) => Key record -> ReaderT backend m (Maybe record)

-- | Get many records by their respective identifiers, if available.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>:
--   
--   <pre>
--   getUsers :: MonadIO m =&gt; ReaderT SqlBackend m (Map (Key User) User)
--   getUsers = getMany allkeys
--   </pre>
--   
--   <pre>
--   musers &lt;- getUsers
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get these
--   records:
--   
--   <pre>
--   +----+-------+-----+
--   | id | name  | age |
--   +----+-------+-----+
--   |  1 | SPJ   |  40 |
--   +----+-------+-----+
--   |  2 | Simon |  41 |
--   +----+-------+-----+
--   </pre>
getMany :: (PersistStoreRead backend, MonadIO m, PersistRecordBackend record backend) => [Key record] -> ReaderT backend m (Map (Key record) record)
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

-- | Create a new record in the database, returning an automatically
--   created key (in SQL an auto-increment id).
--   
--   <h3><b>Example usage</b></h3>
--   
--   Using <a>schema-1</a> and <a>dataset-1</a>, let's insert a new user
--   <tt>John</tt>.
--   
--   <pre>
--   insertJohn :: MonadIO m =&gt; ReaderT SqlBackend m (Key User)
--   insertJohn = insert $ User "John" 30
--   </pre>
--   
--   <pre>
--   johnId &lt;- insertJohn
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |John  |30   |
--   +-----+------+-----+
--   </pre>
insert :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => record -> ReaderT backend m (Key record)

-- | Same as <a>insert</a>, but doesn't return a <tt>Key</tt>.
--   
--   <h3><b>Example usage</b></h3>
--   
--   with <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertJohn :: MonadIO m =&gt; ReaderT SqlBackend m (Key User)
--   insertJohn = insert_ $ User "John" 30
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |John  |30   |
--   +-----+------+-----+
--   </pre>
insert_ :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => record -> ReaderT backend m ()

-- | Create multiple records in the database and return their <a>Key</a>s.
--   
--   If you don't need the inserted <a>Key</a>s, use <a>insertMany_</a>.
--   
--   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
--   <tt>mapM insert</tt>.
--   
--   <h3><b>Example usage</b></h3>
--   
--   with <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertUsers :: MonadIO m =&gt; ReaderT SqlBackend m [Key User]
--   insertUsers = insertMany [User "John" 30, User "Nick" 32, User "Jane" 20]
--   </pre>
--   
--   <pre>
--   userIds &lt;- insertUsers
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |John  |30   |
--   +-----+------+-----+
--   |4    |Nick  |32   |
--   +-----+------+-----+
--   |5    |Jane  |20   |
--   +-----+------+-----+
--   </pre>
insertMany :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => [record] -> ReaderT backend m [Key record]

-- | Same as <a>insertMany</a>, but doesn't return any <a>Key</a>s.
--   
--   The MongoDB, PostgreSQL, SQLite and MySQL backends insert all records
--   in one database query.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertUsers_ :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   insertUsers_ = insertMany_ [User "John" 30, User "Nick" 32, User "Jane" 20]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |John  |30   |
--   +-----+------+-----+
--   |4    |Nick  |32   |
--   +-----+------+-----+
--   |5    |Jane  |20   |
--   +-----+------+-----+
--   </pre>
insertMany_ :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => [record] -> ReaderT backend m ()

-- | Same as <a>insertMany_</a>, but takes an <a>Entity</a> 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.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertUserEntityMany :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   insertUserEntityMany = insertEntityMany [SnakeEntity, EvaEntity]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |Snake |38   |
--   +-----+------+-----+
--   |4    |Eva   |38   |
--   +-----+------+-----+
--   </pre>
insertEntityMany :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => [Entity record] -> ReaderT backend m ()

-- | Create a new record in the database using the given key.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertAliceKey :: MonadIO m =&gt; Key User -&gt; ReaderT SqlBackend m ()
--   insertAliceKey key = insertKey key $ User "Alice" 20
--   </pre>
--   
--   <pre>
--   insertAliceKey $ UserKey {unUserKey = SqlBackendKey {unSqlBackendKey = 3}}
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |Alice |20   |
--   +-----+------+-----+
--   </pre>
insertKey :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> record -> ReaderT backend m ()

-- | Put the record in the database with the given key. Unlike
--   <a>replace</a>, if a record with the given key does not exist then a
--   new record will be inserted.
--   
--   <h3><b>Example usage</b></h3>
--   
--   We try to explain <tt>upsertBy</tt> using <a>schema-1</a> and
--   <a>dataset-1</a>.
--   
--   First, we insert Philip to <a>dataset-1</a>.
--   
--   <pre>
--   insertPhilip :: MonadIO m =&gt; ReaderT SqlBackend m (Key User)
--   insertPhilip = insert $ User "Philip" 42
--   </pre>
--   
--   <pre>
--   philipId &lt;- insertPhilip
--   </pre>
--   
--   This query will produce:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |Philip|42   |
--   +-----+------+-----+
--   </pre>
--   
--   <pre>
--   repsertHaskell :: MonadIO m =&gt; Key record -&gt; ReaderT SqlBackend m ()
--   repsertHaskell id = repsert id $ User "Haskell" 81
--   </pre>
--   
--   <pre>
--   repsertHaskell philipId
--   </pre>
--   
--   This query will replace Philip's record with Haskell's one:
--   
--   <pre>
--   +-----+-----------------+--------+
--   |id   |name             |age     |
--   +-----+-----------------+--------+
--   |1    |SPJ              |40      |
--   +-----+-----------------+--------+
--   |2    |Simon            |41      |
--   +-----+-----------------+--------+
--   |3    |Philip -&gt; Haskell|42 -&gt; 81|
--   +-----+-----------------+--------+
--   </pre>
--   
--   <a>repsert</a> inserts the given record if the key doesn't exist.
--   
--   <pre>
--   repsertXToUnknown :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   repsertXToUnknown = repsert unknownId $ User "X" 999
--   </pre>
--   
--   For example, applying the above query to <a>dataset-1</a> will produce
--   this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |X     |999  |
--   +-----+------+-----+
--   </pre>
repsert :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> record -> ReaderT backend m ()

-- | Put many entities into the database.
--   
--   Batch version of <a>repsert</a> for SQL backends.
--   
--   Useful when migrating data from one entity to another and want to
--   preserve ids.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   repsertManyUsers :: MonadIO m =&gt;ReaderT SqlBackend m ()
--   repsertManyusers = repsertMany [(simonId, User "Philip" 20), (unknownId999, User "Mr. X" 999)]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+----------------+---------+
--   |id   |name            |age      |
--   +-----+----------------+---------+
--   |1    |SPJ             |40       |
--   +-----+----------------+---------+
--   |2    |Simon -&gt; Philip |41 -&gt; 20 |
--   +-----+----------------+---------+
--   |999  |Mr. X           |999      |
--   +-----+----------------+---------+
--   </pre>
repsertMany :: (PersistStoreWrite backend, 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
--   <a>insertKey</a> or <a>repsert</a> in these cases.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1 schama-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   replaceSpj :: MonadIO m =&gt; User -&gt; ReaderT SqlBackend m ()
--   replaceSpj record = replace spjId record
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |Mike  |45   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   </pre>
replace :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> record -> ReaderT backend m ()

-- | Delete a specific record by identifier. Does nothing if record does
--   not exist.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   deleteSpj :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   deleteSpj = delete spjId
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   </pre>
delete :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> ReaderT backend m ()

-- | Update individual fields on a specific record.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   updateSpj :: MonadIO m =&gt; [Update User] -&gt; ReaderT SqlBackend m ()
--   updateSpj updates = update spjId updates
--   </pre>
--   
--   <pre>
--   updateSpj [UserAge +=. 100]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |140  |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   </pre>
update :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> [Update record] -> ReaderT backend m ()

-- | Update 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.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   updateGetSpj :: MonadIO m =&gt; [Update User] -&gt; ReaderT SqlBackend m User
--   updateGetSpj updates = updateGet spjId updates
--   </pre>
--   
--   <pre>
--   spj &lt;- updateGetSpj [UserAge +=. 100]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |140  |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   </pre>
updateGet :: (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> [Update record] -> ReaderT backend m record

-- | A convenient alias for common type signatures
type PersistRecordBackend record backend = (PersistEntity record, PersistEntityBackend record ~ BaseBackend backend)

-- | Same as <a>get</a>, but for a non-null (not Maybe) foreign key. Unsafe
--   unless your database is enforcing that the foreign key is valid.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   getJustSpj :: MonadIO m =&gt; ReaderT SqlBackend m User
--   getJustSpj = getJust spjId
--   </pre>
--   
--   <pre>
--   spj &lt;- getJust spjId
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get this
--   record:
--   
--   <pre>
--   +----+------+-----+
--   | id | name | age |
--   +----+------+-----+
--   |  1 | SPJ  |  40 |
--   +----+------+-----+
--   </pre>
--   
--   <pre>
--   getJustUnknown :: MonadIO m =&gt; ReaderT SqlBackend m User
--   getJustUnknown = getJust unknownId
--   </pre>
--   
--   mrx &lt;- getJustUnknown
--   
--   This just throws an error.
getJust :: (PersistStoreRead backend, PersistRecordBackend record backend, MonadIO m) => Key record -> ReaderT backend m record

-- | Same as <a>getJust</a>, but returns an <a>Entity</a> instead of just
--   the record.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   getJustEntitySpj :: MonadIO m =&gt; ReaderT SqlBackend m (Entity User)
--   getJustEntitySpj = getJustEntity spjId
--   </pre>
--   
--   <pre>
--   spjEnt &lt;- getJustEntitySpj
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get this
--   entity:
--   
--   <pre>
--   +----+------+-----+
--   | id | name | age |
--   +----+------+-----+
--   |  1 | SPJ  |  40 |
--   +----+------+-----+
--   </pre>
getJustEntity :: (PersistEntityBackend record ~ BaseBackend backend, MonadIO m, PersistEntity record, PersistStoreRead backend) => Key record -> ReaderT backend m (Entity record)

-- | Like <tt>get</tt>, but returns the complete <tt>Entity</tt>.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   getSpjEntity :: MonadIO m =&gt; ReaderT SqlBackend m (Maybe (Entity User))
--   getSpjEntity = getEntity spjId
--   </pre>
--   
--   <pre>
--   mSpjEnt &lt;- getSpjEntity
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get this
--   entity:
--   
--   <pre>
--   +----+------+-----+
--   | id | name | age |
--   +----+------+-----+
--   |  1 | SPJ  |  40 |
--   +----+------+-----+
--   </pre>
getEntity :: (PersistStoreRead backend, PersistRecordBackend e backend, MonadIO m) => Key e -> ReaderT backend m (Maybe (Entity e))

-- | Curry this to make a convenience function that loads an associated
--   model.
--   
--   <pre>
--   foreign = belongsTo foreignId
--   </pre>
belongsTo :: (PersistStoreRead backend, PersistEntity ent1, PersistRecordBackend ent2 backend, MonadIO m) => (ent1 -> Maybe (Key ent2)) -> ent1 -> ReaderT backend m (Maybe ent2)

-- | Same as <a>belongsTo</a>, but uses <tt>getJust</tt> and therefore is
--   similarly unsafe.
belongsToJust :: (PersistStoreRead backend, PersistEntity ent1, PersistRecordBackend ent2 backend, MonadIO m) => (ent1 -> Key ent2) -> ent1 -> ReaderT backend m ent2

-- | Like <tt>insert</tt>, but returns the complete <tt>Entity</tt>.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertHaskellEntity :: MonadIO m =&gt; ReaderT SqlBackend m (Entity User)
--   insertHaskellEntity = insertEntity $ User "Haskell" 81
--   </pre>
--   
--   <pre>
--   haskellEnt &lt;- insertHaskellEntity
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +----+---------+-----+
--   | id |  name   | age |
--   +----+---------+-----+
--   |  1 | SPJ     |  40 |
--   +----+---------+-----+
--   |  2 | Simon   |  41 |
--   +----+---------+-----+
--   |  3 | Haskell |  81 |
--   +----+---------+-----+
--   </pre>
insertEntity :: (PersistStoreWrite backend, PersistRecordBackend e backend, MonadIO m) => e -> ReaderT backend m (Entity e)

-- | Like <a>insertEntity</a> but just returns the record instead of
--   <a>Entity</a>.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   insertDaveRecord :: MonadIO m =&gt; ReaderT SqlBackend m User
--   insertDaveRecord = insertRecord $ User "Dave" 50
--   </pre>
--   
--   <pre>
--   dave &lt;- insertDaveRecord
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |Dave  |50   |
--   +-----+------+-----+
--   </pre>
insertRecord :: (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, MonadIO m, PersistStoreWrite backend) => record -> ReaderT backend m record

-- | 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.
type PersistUnique a = PersistUniqueWrite a

-- | Queries against <a>Unique</a> keys (other than the id <a>Key</a>).
--   
--   Please read the general Persistent documentation to learn how to
--   create <a>Unique</a> keys.
--   
--   Using this with an Entity without a Unique key leads to undefined
--   behavior. A few of these functions require a <i>single</i>
--   <a>Unique</a>, so using an Entity with multiple <a>Unique</a>s 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.
class (PersistCore backend, PersistStoreRead backend) => PersistUniqueRead backend

-- | Get a record by unique key, if available. Returns also the identifier.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>:
--   
--   <pre>
--   getBySpjName :: MonadIO m  =&gt; ReaderT SqlBackend m (Maybe (Entity User))
--   getBySpjName = getBy $ UniqueUserName "SPJ"
--   </pre>
--   
--   <pre>
--   mSpjEnt &lt;- getBySpjName
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get this
--   entity:
--   
--   <pre>
--   +----+------+-----+
--   | id | name | age |
--   +----+------+-----+
--   |  1 | SPJ  |  40 |
--   +----+------+-----+
--   </pre>
getBy :: (PersistUniqueRead backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m (Maybe (Entity record))

-- | Some functions in this module (<a>insertUnique</a>, <a>insertBy</a>,
--   and <a>replaceUnique</a>) first query the unique indexes to check for
--   conflicts. You could instead optimistically attempt to perform the
--   operation (e.g. <a>replace</a> instead of <a>replaceUnique</a>).
--   However,
--   
--   <ul>
--   <li>there is some fragility to trying to catch the correct exception
--   and determing the column of failure;</li>
--   <li>an exception will automatically abort the current SQL
--   transaction.</li>
--   </ul>
class (PersistUniqueRead backend, PersistStoreWrite backend) => PersistUniqueWrite backend

-- | Delete a specific record by unique key. Does nothing if no record
--   matches.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   <pre>
--   deleteBySpjName :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   deleteBySpjName = deleteBy UniqueUserName "SPJ"
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   </pre>
deleteBy :: (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m ()

-- | Like <a>insert</a>, but returns <a>Nothing</a> when the record
--   couldn't be inserted because of a uniqueness constraint.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>, we try to insert the
--   following two records:
--   
--   <pre>
--   linusId &lt;- insertUnique $ User "Linus" 48
--   spjId   &lt;- insertUnique $ User "SPJ" 90
--   </pre>
--   
--   <pre>
--   +-----+------+-----+
--   |id   |name  |age  |
--   +-----+------+-----+
--   |1    |SPJ   |40   |
--   +-----+------+-----+
--   |2    |Simon |41   |
--   +-----+------+-----+
--   |3    |Linus |48   |
--   +-----+------+-----+
--   </pre>
--   
--   Linus's record was inserted to <a>dataset-1</a>, while SPJ wasn't
--   because SPJ already exists in <a>dataset-1</a>.
insertUnique :: (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend) => record -> ReaderT backend m (Maybe (Key record))

-- | Update based on a uniqueness constraint or insert:
--   
--   <ul>
--   <li>insert the new record if it does not exist;</li>
--   <li>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.</li>
--   </ul>
--   
--   <h3><b>Example usage</b></h3>
--   
--   First, we try to explain <a>upsert</a> using <a>schema-1</a> and
--   <a>dataset-1</a>.
--   
--   <pre>
--   upsertSpj :: MonadIO m =&gt; [Update User] -&gt; ReaderT SqlBackend m (Maybe (Entity User))
--   upsertSpj updates = upsert (User "SPJ" 999) upadtes
--   </pre>
--   
--   <pre>
--   mSpjEnt &lt;- upsertSpj [UserAge +=. 15]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+--------+
--   |id   |name |age     |
--   +-----+-----+--------+
--   |1    |SPJ  |40 -&gt; 55|
--   +-----+-----+--------+
--   |2    |Simon|41      |
--   +-----+-----+--------+
--   </pre>
--   
--   <pre>
--   upsertX :: MonadIO m =&gt; [Update User] -&gt; ReaderT SqlBackend m (Maybe (Entity User))
--   upsertX updates = upsert (User "X" 999) updates
--   </pre>
--   
--   <pre>
--   mXEnt &lt;- upsertX [UserAge +=. 15]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+--------+
--   |id   |name |age     |
--   +-----+-----+--------+
--   |1    |SPJ  |40      |
--   +-----+-----+--------+
--   |2    |Simon|41      |
--   +-----+-----+--------+
--   |3    |X    |999     |
--   +-----+-----+--------+
--   </pre>
--   
--   Next, what if the schema has two uniqueness constraints? Let's check
--   it out using <a>schema-2</a>:
--   
--   <pre>
--   mSpjEnt &lt;- upsertSpj [UserAge +=. 15]
--   </pre>
--   
--   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
--   <a>upsertBy</a> to select the unique key we want.
upsert :: (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record) => record -> [Update record] -> ReaderT backend m (Entity record)

-- | Update based on a given uniqueness constraint or insert:
--   
--   <ul>
--   <li>insert the new record if it does not exist;</li>
--   <li>update the existing record that matches the given uniqueness
--   constraint.</li>
--   </ul>
--   
--   <h3><b>Example usage</b></h3>
--   
--   We try to explain <a>upsertBy</a> using <a>schema-2</a> and
--   <a>dataset-1</a>.
--   
--   <pre>
--   upsertBySpjName :: MonadIO m =&gt; User -&gt; [Update User] -&gt; ReaderT SqlBackend m (Entity User)
--   upsertBySpjName record updates = upsertBy (UniqueUserName "SPJ") record updates
--   </pre>
--   
--   <pre>
--   mSpjEnt &lt;- upsertBySpjName (Person "X" 999) [PersonAge += .15]
--   </pre>
--   
--   The above query will alter <a>dataset-1</a> to:
--   
--   <pre>
--   +-----+-----+--------+
--   |id   |name |age     |
--   +-----+-----+--------+
--   |1    |SPJ  |40 -&gt; 55|
--   +-----+-----+--------+
--   |2    |Simon|41      |
--   +-----+-----+--------+
--   </pre>
--   
--   <pre>
--   upsertBySimonAge :: MonadIO m =&gt; User -&gt; [Update User] -&gt; ReaderT SqlBackend m (Entity User)
--   upsertBySimonAge record updates = upsertBy (UniqueUserName "SPJ") record updates
--   </pre>
--   
--   <pre>
--   mPhilipEnt &lt;- upsertBySimonAge (User "X" 999) [UserName =. "Philip"]
--   </pre>
--   
--   The above query will alter <a>dataset-1</a> to:
--   
--   <pre>
--   +----+-----------------+-----+
--   | id |      name       | age |
--   +----+-----------------+-----+
--   |  1 | SPJ             |  40 |
--   +----+-----------------+-----+
--   |  2 | Simon -&gt; Philip |  41 |
--   +----+-----------------+-----+
--   </pre>
--   
--   <pre>
--   upsertByUnknownName :: MonadIO m =&gt; User -&gt; [Update User] -&gt; ReaderT SqlBackend m (Entity User)
--   upsertByUnknownName record updates = upsertBy (UniqueUserName "Unknown") record updates
--   </pre>
--   
--   <pre>
--   mXEnt &lt;- upsertByUnknownName (User "X" 999) [UserAge +=. 15]
--   </pre>
--   
--   This query will alter <a>dataset-1</a> to:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   |3    |X    |999  |
--   +-----+-----+-----+
--   </pre>
upsertBy :: (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> record -> [Update record] -> ReaderT backend m (Entity record)

-- | Put many records into db
--   
--   <ul>
--   <li>insert new records that do not exist (or violate any unique
--   constraints)</li>
--   <li>replace existing records (matching any unique constraint)</li>
--   </ul>
putMany :: (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend) => [record] -> ReaderT backend m ()

-- | This class is used to ensure that <a>upsert</a> is only called on
--   records that have a single <a>Unique</a> key. The quasiquoter
--   automatically generates working instances for appropriate records, and
--   generates <tt>TypeError</tt> instances for records that have 0 or
--   multiple unique keys.
class PersistEntity record => OnlyOneUniqueKey record
onlyUniqueP :: OnlyOneUniqueKey record => record -> Unique 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 <tt>TypeError</tt> instances for records that
--   have 0 unique keys.
class PersistEntity record => AtLeastOneUniqueKey record
requireUniquesP :: AtLeastOneUniqueKey record => record -> NonEmpty (Unique record)

-- | This is an error message. It is used when writing instances of
--   <a>OnlyOneUniqueKey</a> for an entity that has no unique keys.
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 an entity has multiple
--   unique keys, and the function expects a single unique key.
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."

-- | A modification of <a>getBy</a>, which takes the <a>PersistEntity</a>
--   itself instead of a <a>Unique</a> record. Returns a record matching
--   <i>one</i> of the unique keys. This function makes the most sense on
--   entities with a single <a>Unique</a> constructor.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>,
--   
--   getBySpjValue :: MonadIO m =&gt; ReaderT SqlBackend m (Maybe (Entity
--   User)) getBySpjValue = getByValue $ User <a>SPJ</a> 999
--   
--   <pre>
--   mSpjEnt &lt;- getBySpjValue
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will get this
--   record:
--   
--   <pre>
--   +----+------+-----+
--   | id | name | age |
--   +----+------+-----+
--   |  1 | SPJ  |  40 |
--   +----+------+-----+
--   </pre>
getByValue :: forall record m backend. (MonadIO m, PersistUniqueRead backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record) => record -> ReaderT backend m (Maybe (Entity record))

-- | Insert a value, checking for conflicts with any unique constraints. If
--   a duplicate exists in the database, it is returned as <a>Left</a>.
--   Otherwise, the new 'Key is returned as <a>Right</a>.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-2</a> and <a>dataset-1</a>, we have following lines of
--   code:
--   
--   <pre>
--   l1 &lt;- insertBy $ User "SPJ" 20
--   l2 &lt;- insertBy $ User "XXX" 41
--   l3 &lt;- insertBy $ User "SPJ" 40
--   r1 &lt;- insertBy $ User "XXX" 100
--   </pre>
--   
--   First three lines return <a>Left</a> because there're duplicates in
--   given record's uniqueness constraints. While the last line returns a
--   new key as <a>Right</a>.
insertBy :: (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record) => record -> ReaderT backend m (Either (Entity record) (Key record))

-- | Like <a>insertEntity</a>, but returns <a>Nothing</a> when the record
--   couldn't be inserted because of a uniqueness constraint.
--   
--   <h3><b>Example usage</b></h3>
--   
--   We use <a>schema-2</a> and <a>dataset-1</a> here.
--   
--   <pre>
--   insertUniqueSpjEntity :: MonadIO m =&gt; ReaderT SqlBackend m (Maybe (Entity User))
--   insertUniqueSpjEntity = insertUniqueEntity $ User "SPJ" 50
--   </pre>
--   
--   <pre>
--   mSpjEnt &lt;- insertUniqueSpjEntity
--   </pre>
--   
--   The above query results <a>Nothing</a> as SPJ already exists.
--   
--   <pre>
--   insertUniqueAlexaEntity :: MonadIO m =&gt; ReaderT SqlBackend m (Maybe (Entity User))
--   insertUniqueAlexaEntity = insertUniqueEntity $ User "Alexa" 3
--   </pre>
--   
--   <pre>
--   mAlexaEnt &lt;- insertUniqueSpjEntity
--   </pre>
--   
--   Because there's no such unique keywords of the given record, the above
--   query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +----+-------+-----+
--   | id | name  | age |
--   +----+-------+-----+
--   |  1 | SPJ   |  40 |
--   +----+-------+-----+
--   |  2 | Simon |  41 |
--   +----+-------+-----+
--   |  3 | Alexa |   3 |
--   +----+-------+-----+
--   </pre>
insertUniqueEntity :: (MonadIO m, PersistRecordBackend record backend, PersistUniqueWrite backend) => record -> ReaderT backend m (Maybe (Entity record))

-- | Attempt to replace the record of the given key with the given new
--   record. First query the unique fields to make sure the replacement
--   maintains uniqueness constraints.
--   
--   Return <a>Nothing</a> if the replacement was made. If uniqueness is
--   violated, return a <a>Just</a> with the <a>Unique</a> violation
replaceUnique :: (MonadIO m, Eq (Unique record), PersistRecordBackend record backend, PersistUniqueWrite backend) => Key record -> record -> ReaderT backend m (Maybe (Unique record))

-- | Check whether there are any conflicts for unique keys with this entity
--   and existing entities in the database.
--   
--   Returns <a>Nothing</a> if the entity would be unique, and could thus
--   safely be inserted. on a conflict returns the conflicting key
--   
--   <h3><b>Example usage</b></h3>
--   
--   We use <a>schema-1</a> and <a>dataset-1</a> here.
--   
--   This would be <a>Nothing</a>:
--   
--   <pre>
--   mAlanConst &lt;- checkUnique $ User "Alan" 70
--   </pre>
--   
--   While this would be <a>Just</a> because SPJ already exists:
--   
--   <pre>
--   mSpjConst &lt;- checkUnique $ User "SPJ" 60
--   </pre>
checkUnique :: (MonadIO m, PersistRecordBackend record backend, PersistUniqueRead backend) => record -> ReaderT backend m (Maybe (Unique record))

-- | Return the single unique key for a record.
--   
--   <h3><b>Example usage</b></h3>
--   
--   We use shcema-1 and <a>dataset-1</a> here.
--   
--   <pre>
--   onlySimonConst :: MonadIO m =&gt; ReaderT SqlBackend m (Unique User)
--   onlySimonConst = onlyUnique $ User "Simon" 999
--   </pre>
--   
--   <pre>
--   mSimonConst &lt;- onlySimonConst
--   </pre>
--   
--   <tt>mSimonConst</tt> would be Simon's uniqueness constraint. Note that
--   <tt>onlyUnique</tt> doesn't work if there're more than two
--   constraints. It will fail with a type error instead.
onlyUnique :: (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend, OnlyOneUniqueKey record) => record -> ReaderT backend m (Unique record)

-- | 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.
type PersistQuery a = PersistQueryWrite a

-- | Backends supporting conditional read operations.
class (PersistCore backend, PersistStoreRead backend) => PersistQueryRead backend

-- | Get all records matching the given criterion in the specified order.
--   Returns also the identifiers.
selectSourceRes :: (PersistQueryRead backend, PersistRecordBackend record backend, MonadIO m1, MonadIO m2) => [Filter record] -> [SelectOpt record] -> ReaderT backend m1 (Acquire (ConduitM () (Entity record) m2 ()))

-- | Get just the first record for the criterion.
selectFirst :: (PersistQueryRead backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m (Maybe (Entity record))

-- | Get the <a>Key</a>s of all records matching the given criterion.
selectKeysRes :: (PersistQueryRead backend, MonadIO m1, MonadIO m2, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m1 (Acquire (ConduitM () (Key record) m2 ()))

-- | The total number of records fulfilling the given criterion.
count :: (PersistQueryRead backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m Int

-- | Backends supporting conditional write operations
class (PersistQueryRead backend, PersistStoreWrite backend) => PersistQueryWrite backend

-- | Update individual fields on any record matching the given criterion.
updateWhere :: (PersistQueryWrite backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> [Update record] -> ReaderT backend m ()

-- | Delete all records matching the given criterion.
deleteWhere :: (PersistQueryWrite backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m ()

-- | Get all records matching the given criterion in the specified order.
--   Returns also the identifiers.
selectSource :: (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m) => [Filter record] -> [SelectOpt record] -> ConduitM () (Entity record) m ()

-- | Get the <a>Key</a>s of all records matching the given criterion.
selectKeys :: (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m) => [Filter record] -> [SelectOpt record] -> ConduitM () (Key record) m ()

-- | Call <a>selectSource</a> but return the result as a list.
selectList :: (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m [Entity record]

-- | Call <a>selectKeys</a> but return the result as a list.
selectKeysList :: (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m [Key record]

-- | For combinations of backends and entities that support
--   cascade-deletion. “Cascade-deletion” means that entries that depend on
--   other entries to be deleted will be deleted as well.
class (PersistStoreWrite backend, PersistEntity record, BaseBackend backend ~ PersistEntityBackend record) => DeleteCascade record backend

-- | Perform cascade-deletion of single database entry.
deleteCascade :: (DeleteCascade record backend, MonadIO m) => Key record -> ReaderT backend m ()

-- | Cascade-deletion of entries satisfying given filters.
deleteCascadeWhere :: (MonadIO m, DeleteCascade record backend, PersistQueryWrite backend) => [Filter record] -> ReaderT backend m ()

-- | Persistent serialized Haskell records to the database. A Database
--   <a>Entity</a> (A row in SQL, a document in MongoDB, etc) corresponds
--   to a <a>Key</a> plus a Haskell record.
--   
--   For every Haskell record type stored in the database there is a
--   corresponding <a>PersistEntity</a> 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 <a>PersistEntity</a>, 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.
class (PersistField (Key record), ToJSON (Key record), FromJSON (Key record), Show (Key record), Read (Key record), Eq (Key record), Ord (Key record)) => PersistEntity record where {
    
    -- | Persistent allows multiple different backends (databases).
    type family PersistEntityBackend record;
    
    -- | By default, a backend will automatically generate the key Instead you
    --   can specify a Primary key made up of unique values.
    data family Key record;
    
    -- | An <a>EntityField</a> is parameterised by the Haskell record it
    --   belongs to and the additional type of that field.
    data family EntityField record :: * -> *;
    
    -- | Unique keys besides the <a>Key</a>.
    data family Unique record;
}

-- | A lower-level key operation.
keyToValues :: PersistEntity record => Key record -> [PersistValue]

-- | A lower-level key operation.
keyFromValues :: PersistEntity record => [PersistValue] -> Either Text (Key record)

-- | A meta-operation to retrieve the <a>Key</a> <a>EntityField</a>.
persistIdField :: PersistEntity record => EntityField record (Key record)

-- | Retrieve the <a>EntityDef</a> meta-data for the record.
entityDef :: (PersistEntity record, Monad m) => m record -> EntityDef

-- | Return meta-data for a given <a>EntityField</a>.
persistFieldDef :: PersistEntity record => EntityField record typ -> FieldDef

-- | A meta-operation to get the database fields of a record.
toPersistFields :: PersistEntity record => record -> [SomePersistField]

-- | A lower-level operation to convert from database values to a Haskell
--   record.
fromPersistValues :: PersistEntity record => [PersistValue] -> Either Text record

-- | A meta operation to retrieve all the <a>Unique</a> keys.
persistUniqueKeys :: PersistEntity record => record -> [Unique record]

-- | A lower level operation.
persistUniqueToFieldNames :: PersistEntity record => Unique record -> [(HaskellName, DBName)]

-- | A lower level operation.
persistUniqueToValues :: PersistEntity record => Unique record -> [PersistValue]

-- | Use a <a>PersistField</a> as a lens.
fieldLens :: PersistEntity record => EntityField record field -> forall f. Functor f => (field -> f field) -> Entity record -> f (Entity record)

-- | This class teaches Persistent how to take a custom type and marshal it
--   to and from a <a>PersistValue</a>, allowing it to be stored in a
--   database.
--   
--   <h4><b>Examples</b></h4>
--   
--   <h5>Simple Newtype</h5>
--   
--   You can use <tt>newtype</tt> to add more type safety/readability to a
--   basis type like <a>ByteString</a>. In these cases, just derive
--   <a>PersistField</a> and <tt>PersistFieldSql</tt>:
--   
--   <pre>
--   {-# LANGUAGE GeneralizedNewtypeDeriving #-}
--   
--   newtype HashedPassword = HashedPassword <a>ByteString</a>
--     deriving (Eq, Show, <a>PersistField</a>, PersistFieldSql)
--   </pre>
--   
--   <h5>Smart Constructor Newtype</h5>
--   
--   In this example, we create a <a>PersistField</a> instance for a
--   newtype following the "Smart Constructor" pattern.
--   
--   <pre>
--   {-# LANGUAGE GeneralizedNewtypeDeriving #-}
--   import qualified <a>Data.Text</a> as T
--   import qualified <a>Data.Char</a> as C
--   
--   -- | An American Social Security Number
--   newtype SSN = SSN <a>Text</a>
--    deriving (Eq, Show, PersistFieldSql)
--   
--   mkSSN :: <a>Text</a> -&gt; <a>Either</a> <a>Text</a> SSN
--   mkSSN t = if (T.length t == 9) &amp;&amp; (T.all C.isDigit t)
--    then <a>Right</a> $ SSN t
--    else <a>Left</a> $ "Invalid SSN: " &lt;&gt; t
--   
--   instance <a>PersistField</a> SSN where
--     <a>toPersistValue</a> (SSN t) = <a>PersistText</a> t
--     <a>fromPersistValue</a> (<a>PersistText</a> t) = mkSSN t
--     -- Handle cases where the database does not give us PersistText
--     <a>fromPersistValue</a> x = <a>Left</a> $ "File.hs: When trying to deserialize an SSN: expected PersistText, received: " &lt;&gt; T.pack (show x)
--   </pre>
--   
--   Tips:
--   
--   <ul>
--   <li>This file contain dozens of <a>PersistField</a> instances you can
--   look at for examples.</li>
--   <li>Typically custom <a>PersistField</a> instances will only accept a
--   single <a>PersistValue</a> constructor in
--   <a>fromPersistValue</a>.</li>
--   <li>Internal <a>PersistField</a> instances accept a wide variety of
--   <a>PersistValue</a>s to accomodate e.g. storing booleans as integers,
--   booleans or strings.</li>
--   <li>If you're making a custom instance and using a SQL database,
--   you'll also need <tt>PersistFieldSql</tt> to specify the type of the
--   database column.</li>
--   </ul>
class PersistField a
toPersistValue :: PersistField a => a -> PersistValue
fromPersistValue :: PersistField a => PersistValue -> Either Text a

-- | 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.
class PersistConfig c where {
    type family PersistConfigBackend c :: (* -> *) -> * -> *;
    type family PersistConfigPool c;
}

-- | Load the config settings from a <a>Value</a>, most likely taken from a
--   YAML config file.
loadConfig :: PersistConfig c => Value -> Parser c

-- | Modify the config settings based on environment variables.
applyEnv :: PersistConfig c => c -> IO c

-- | Create a new connection pool based on the given config settings.
createPoolConfig :: PersistConfig c => c -> IO (PersistConfigPool c)

-- | Run a database action by taking a connection from the pool.
runPool :: (PersistConfig c, MonadUnliftIO m) => c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a

-- | Get list of values corresponding to given entity.
entityValues :: PersistEntity record => Entity record -> [PersistValue]

-- | Class which allows the plucking of a <tt>BaseBackend backend</tt> from
--   some larger type. For example, <tt> instance HasPersistBackend
--   (SqlReadBackend, Int) where type BaseBackend (SqlReadBackend, Int) =
--   SqlBackend persistBackend = unSqlReadBackend . fst </tt>
class HasPersistBackend backend where {
    type family BaseBackend backend;
}
persistBackend :: HasPersistBackend backend => backend -> BaseBackend backend

-- | Class which witnesses that <tt>backend</tt> is essentially the same as
--   <tt>BaseBackend backend</tt>. That is, they're isomorphic and
--   <tt>backend</tt> is just some wrapper over <tt>BaseBackend
--   backend</tt>.
class (HasPersistBackend backend) => IsPersistBackend backend
liftPersist :: (MonadIO m, MonadReader backend m) => ReaderT backend IO b -> m b

-- | This class witnesses that two backend are compatible, and that you can
--   convert from the <tt>sub</tt> backend into the <tt>sup</tt> backend.
--   This is similar to the <a>HasPersistBackend</a> and
--   <a>IsPersistBackend</a> classes, but where you don't want to fix the
--   type associated with the <a>PersistEntityBackend</a> of a record.
--   
--   Generally speaking, where you might have:
--   
--   <pre>
--   foo ::
--     ( <a>PersistEntity</a> record
--     , <tt>PeristEntityBackend</tt> record ~ <a>BaseBackend</a> backend
--     , <tt>IsSqlBackend</tt> backend
--     )
--   </pre>
--   
--   this can be replaced with:
--   
--   <pre>
--   foo ::
--     ( <a>PersistEntity</a> record,
--     , <a>PersistEntityBackend</a> record ~ backend
--     , <a>BackendCompatible</a> <tt>SqlBackend</tt> backend
--     )
--   </pre>
--   
--   This works for <tt>SqlReadBackend</tt> because of the <tt>instance
--   <a>BackendCompatible</a> <tt>SqlBackend</tt>
--   <tt>SqlReadBackend</tt></tt>, without needing to go through the
--   <a>BaseBackend</a> type family.
--   
--   Likewise, functions that are currently hardcoded to use
--   <tt>SqlBackend</tt> can be generalized:
--   
--   <pre>
--   -- before:
--   asdf :: <a>ReaderT</a> <tt>SqlBackend</tt> m ()
--   asdf = pure ()
--   
--   -- after:
--   asdf' :: <a>BackendCompatible</a> SqlBackend backend =&gt; ReaderT backend m ()
--   asdf' = withReaderT <a>projectBackend</a> asdf
--   </pre>
class BackendCompatible sup sub
projectBackend :: BackendCompatible sup sub => sub -> sup

-- | Predefined <tt>toJSON</tt>. The resulting JSON looks like <tt>{"key":
--   1, "value": {"name": ...}}</tt>.
--   
--   The typical usage is:
--   
--   <pre>
--   instance ToJSON (Entity User) where
--       toJSON = keyValueEntityToJSON
--   </pre>
keyValueEntityToJSON :: (PersistEntity record, ToJSON record) => Entity record -> Value

-- | Predefined <tt>parseJSON</tt>. The input JSON looks like <tt>{"key":
--   1, "value": {"name": ...}}</tt>.
--   
--   The typical usage is:
--   
--   <pre>
--   instance FromJSON (Entity User) where
--       parseJSON = keyValueEntityFromJSON
--   </pre>
keyValueEntityFromJSON :: (PersistEntity record, FromJSON record) => Value -> Parser (Entity record)

-- | Predefined <tt>toJSON</tt>. The resulting JSON looks like <tt>{"id":
--   1, "name": ...}</tt>.
--   
--   The typical usage is:
--   
--   <pre>
--   instance ToJSON (Entity User) where
--       toJSON = entityIdToJSON
--   </pre>
entityIdToJSON :: (PersistEntity record, ToJSON record) => Entity record -> Value

-- | Predefined <tt>parseJSON</tt>. The input JSON looks like <tt>{"id": 1,
--   "name": ...}</tt>.
--   
--   The typical usage is:
--   
--   <pre>
--   instance FromJSON (Entity User) where
--       parseJSON = entityIdFromJSON
--   </pre>
entityIdFromJSON :: (PersistEntity record, FromJSON record) => Value -> Parser (Entity record)

-- | Convenience function for getting a free <a>PersistField</a> instance
--   from a type with JSON instances.
--   
--   Example usage in combination with <a>fromPersistValueJSON</a>:
--   
--   <pre>
--   instance PersistField MyData where
--     fromPersistValue = fromPersistValueJSON
--     toPersistValue = toPersistValueJSON
--   </pre>
toPersistValueJSON :: ToJSON a => a -> PersistValue

-- | Convenience function for getting a free <a>PersistField</a> 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 <a>toPersistValueJSON</a>:
--   
--   <pre>
--   instance PersistField MyData where
--     fromPersistValue = fromPersistValueJSON
--     toPersistValue = toPersistValueJSON
--   </pre>
fromPersistValueJSON :: FromJSON a => PersistValue -> Either Text a

module Database.Persist.Sql.Types.Internal

-- | Class which allows the plucking of a <tt>BaseBackend backend</tt> from
--   some larger type. For example, <tt> instance HasPersistBackend
--   (SqlReadBackend, Int) where type BaseBackend (SqlReadBackend, Int) =
--   SqlBackend persistBackend = unSqlReadBackend . fst </tt>
class HasPersistBackend backend where {
    type family BaseBackend backend;
}
persistBackend :: HasPersistBackend backend => backend -> BaseBackend backend

-- | Class which witnesses that <tt>backend</tt> is essentially the same as
--   <tt>BaseBackend backend</tt>. That is, they're isomorphic and
--   <tt>backend</tt> is just some wrapper over <tt>BaseBackend
--   backend</tt>.
class (HasPersistBackend backend) => IsPersistBackend backend

-- | This function is how we actually construct and tag a backend as having
--   read or write capabilities. It should be used carefully and only when
--   actually constructing a <tt>backend</tt>. Careless use allows us to
--   accidentally run a write query against a read-only database.
mkPersistBackend :: IsPersistBackend backend => BaseBackend backend -> backend

-- | An SQL backend which can only handle read queries
--   
--   The constructor was exposed in 2.10.0.
newtype SqlReadBackend
SqlReadBackend :: SqlBackend -> SqlReadBackend
[unSqlReadBackend] :: SqlReadBackend -> SqlBackend

-- | An SQL backend which can handle read or write queries
--   
--   The constructor was exposed in 2.10.0
newtype SqlWriteBackend
SqlWriteBackend :: SqlBackend -> SqlWriteBackend
[unSqlWriteBackend] :: SqlWriteBackend -> SqlBackend

-- | Useful for running a read query against a backend with unknown
--   capabilities.
readToUnknown :: Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlBackend m a

-- | Useful for running a read query against a backend with read and write
--   capabilities.
readToWrite :: Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlWriteBackend m a

-- | Useful for running a write query against an untagged backend with
--   unknown capabilities.
writeToUnknown :: Monad m => ReaderT SqlWriteBackend m a -> ReaderT SqlBackend m a
type LogFunc = Loc -> LogSource -> LogLevel -> LogStr -> IO ()
data InsertSqlResult
ISRSingle :: Text -> InsertSqlResult
ISRInsertGet :: Text -> Text -> InsertSqlResult
ISRManyKeys :: Text -> [PersistValue] -> InsertSqlResult
data Statement
Statement :: IO () -> IO () -> ([PersistValue] -> IO Int64) -> (forall m. MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())) -> Statement
[stmtFinalize] :: Statement -> IO ()
[stmtReset] :: Statement -> IO ()
[stmtExecute] :: Statement -> [PersistValue] -> IO Int64
[stmtQuery] :: Statement -> forall m. MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())

-- | Please refer to the documentation for the database in question for a
--   full overview of the semantics of the varying isloation levels
data IsolationLevel
ReadUncommitted :: IsolationLevel
ReadCommitted :: IsolationLevel
RepeatableRead :: IsolationLevel
Serializable :: IsolationLevel
makeIsolationLevelStatement :: (Monoid s, IsString s) => IsolationLevel -> s
data SqlBackend
SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> IORef (Map Text Statement) -> IO () -> ([EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])) -> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> (DBName -> Text) -> Text -> Text -> ((Int, Int) -> Bool -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> SqlBackend
[connPrepare] :: SqlBackend -> Text -> IO Statement

-- | table name, column names, id name, either 1 or 2 statements to run
[connInsertSql] :: SqlBackend -> EntityDef -> [PersistValue] -> InsertSqlResult

-- | SQL for inserting many rows and returning their primary keys, for
--   backends that support this functioanlity. If <a>Nothing</a>, rows will
--   be inserted one-at-a-time using <a>connInsertSql</a>.
[connInsertManySql] :: SqlBackend -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult)

-- | Some databases support performing UPSERT _and_ RETURN entity in a
--   single call.
--   
--   This field when set will be used to generate the UPSERT+RETURN sql
--   given * an entity definition * updates to be run on unique key(s)
--   collision
--   
--   When left as <a>Nothing</a>, we find the unique key from entity def
--   before * trying to fetch an entity by said key * perform an update
--   when result found, else issue an insert * return new entity from db
[connUpsertSql] :: SqlBackend -> Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text)

-- | Some databases support performing bulk UPSERT, specifically "insert or
--   replace many records" in a single call.
--   
--   This field when set, given * an entity definition * number of records
--   to be inserted should produce a PUT MANY sql with placeholders for
--   records
--   
--   When left as <a>Nothing</a>, we default to using
--   <tt>defaultPutMany</tt>.
[connPutManySql] :: SqlBackend -> Maybe (EntityDef -> Int -> Text)
[connStmtMap] :: SqlBackend -> IORef (Map Text Statement)
[connClose] :: SqlBackend -> IO ()
[connMigrateSql] :: SqlBackend -> [EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])
[connBegin] :: SqlBackend -> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()
[connCommit] :: SqlBackend -> (Text -> IO Statement) -> IO ()
[connRollback] :: SqlBackend -> (Text -> IO Statement) -> IO ()
[connEscapeName] :: SqlBackend -> DBName -> Text
[connNoLimit] :: SqlBackend -> Text
[connRDBMS] :: SqlBackend -> Text
[connLimitOffset] :: SqlBackend -> (Int, Int) -> Bool -> Text -> Text
[connLogFunc] :: SqlBackend -> LogFunc

-- | Some databases (probably only Sqlite) have a limit on how many
--   question-mark parameters may be used in a statement
[connMaxParams] :: SqlBackend -> Maybe Int

-- | Some databases support performing bulk an atomic+bulk INSERT where
--   constraint conflicting entities can replace existing entities.
--   
--   This field when set, given * an entity definition * number of records
--   to be inserted should produce a INSERT sql with placeholders for
--   primary+record fields
--   
--   When left as <a>Nothing</a>, we default to using
--   <tt>defaultRepsertMany</tt>.
[connRepsertManySql] :: SqlBackend -> Maybe (EntityDef -> Int -> Text)

-- | A constraint synonym which witnesses that a backend is SQL and can run
--   read queries.
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 and write queries.
type SqlBackendCanWrite backend = (SqlBackendCanRead backend, PersistQueryWrite backend, PersistStoreWrite backend, PersistUniqueWrite backend)

-- | Like <tt>SqlPersistT</tt> but compatible with any SQL backend which
--   can handle read queries.
type SqlReadT m a = forall backend. (SqlBackendCanRead backend) => ReaderT backend m a

-- | Like <tt>SqlPersistT</tt> but compatible with any SQL backend which
--   can handle read and write queries.
type SqlWriteT m a = forall backend. (SqlBackendCanWrite backend) => ReaderT backend m a

-- | A backend which is a wrapper around <tt>SqlBackend</tt>.
type IsSqlBackend backend = (IsPersistBackend backend, BaseBackend backend ~ SqlBackend)
instance GHC.Enum.Bounded Database.Persist.Sql.Types.Internal.IsolationLevel
instance GHC.Classes.Ord Database.Persist.Sql.Types.Internal.IsolationLevel
instance GHC.Enum.Enum Database.Persist.Sql.Types.Internal.IsolationLevel
instance GHC.Classes.Eq Database.Persist.Sql.Types.Internal.IsolationLevel
instance GHC.Show.Show Database.Persist.Sql.Types.Internal.IsolationLevel
instance Database.Persist.Class.PersistStore.HasPersistBackend Database.Persist.Sql.Types.Internal.SqlWriteBackend
instance Database.Persist.Class.PersistStore.IsPersistBackend Database.Persist.Sql.Types.Internal.SqlWriteBackend
instance Database.Persist.Class.PersistStore.HasPersistBackend Database.Persist.Sql.Types.Internal.SqlReadBackend
instance Database.Persist.Class.PersistStore.IsPersistBackend Database.Persist.Sql.Types.Internal.SqlReadBackend
instance Database.Persist.Class.PersistStore.HasPersistBackend Database.Persist.Sql.Types.Internal.SqlBackend
instance Database.Persist.Class.PersistStore.IsPersistBackend Database.Persist.Sql.Types.Internal.SqlBackend

module Database.Persist

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

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

-- | Assign a field by subtraction (<tt>-=</tt>).
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   subtractAge :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   subtractAge = updateWhere [UserName ==. "SPJ" ] [UserAge -=. 1]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+---------+
--   |id   |name |age      |
--   +-----+-----+---------+
--   |1    |SPJ  |40 -&gt; 39 |
--   +-----+-----+---------+
--   |2    |Simon|41       |
--   +-----+-----+---------+
--   </pre>
(-=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v
infixr 3 -=.

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

-- | Assign a field by division (<tt>/=</tt>).
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   divideAge :: MonadIO m =&gt; ReaderT SqlBackend m ()
--   divideAge = updateWhere [UserName ==. "SPJ" ] [UserAge /=. 2]
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+---------+
--   |id   |name |age      |
--   +-----+-----+---------+
--   |1    |SPJ  |40 -&gt; 20 |
--   +-----+-----+---------+
--   |2    |Simon|41       |
--   +-----+-----+---------+
--   </pre>
(/=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Update v
infixr 3 /=.

-- | Check for equality.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectSPJ :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectSPJ = selectList [UserName ==. "SPJ" ] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   </pre>
(==.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v
infix 4 ==.

-- | Non-equality check.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectSimon :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectSimon = selectList [UserName !=. "SPJ" ] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   </pre>
(!=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v
infix 4 !=.

-- | Less-than check.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectLessAge :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectLessAge = selectList [UserAge &lt;. 41 ] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   </pre>
(<.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v
infix 4 <.

-- | Greater-than check.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectGreaterAge :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectGreaterAge = selectList [UserAge &gt;. 40 ] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   </pre>
(>.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v
infix 4 >.

-- | Less-than or equal check.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectLessEqualAge :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectLessEqualAge = selectList [UserAge &lt;=. 40 ] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |1    |SPJ  |40   |
--   +-----+-----+-----+
--   </pre>
(<=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v
infix 4 <=.

-- | Greater-than or equal check.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectGreaterEqualAge :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectGreaterEqualAge = selectList [UserAge &gt;=. 41 ] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   </pre>
(>=.) :: forall v typ. PersistField typ => EntityField v typ -> typ -> Filter v
infix 4 >=.

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

-- | Check if value is not in given list.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   selectSimon :: MonadIO m =&gt; ReaderT SqlBackend m [Entity User]
--   selectSimon = selectList [UserAge /&lt;-. [40]] []
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will produce this:
--   
--   <pre>
--   +-----+-----+-----+
--   |id   |name |age  |
--   +-----+-----+-----+
--   |2    |Simon|41   |
--   +-----+-----+-----+
--   </pre>
(/<-.) :: forall v typ. PersistField typ => EntityField v typ -> [typ] -> Filter v
infix 4 /<-.

-- | The OR of two lists of filters. For example:
--   
--   <pre>
--   selectList
--       ([ PersonAge &gt;. 25
--        , PersonAge &lt;. 30 ] ||.
--        [ PersonIncome &gt;. 15000
--        , PersonIncome &lt;. 25000 ])
--       []
--   </pre>
--   
--   will filter records where a person's age is between 25 and 30
--   <i>or</i> a person's income is between (15000 and 25000).
--   
--   If you are looking for an <tt>(&amp;&amp;.)</tt> operator to do <tt>(A
--   AND B AND (C OR D))</tt> you can use the <tt>(++)</tt> operator
--   instead as there is no <tt>(&amp;&amp;.)</tt>. For example:
--   
--   <pre>
--   selectList
--       ([ PersonAge &gt;. 25
--        , PersonAge &lt;. 30 ] ++
--       ([PersonCategory ==. 1] ||.
--        [PersonCategory ==. 5]))
--       []
--   </pre>
--   
--   will filter records where a person's age is between 25 and 30
--   <i>and</i> (person's category is either 1 or 5).
(||.) :: forall v. [Filter v] -> [Filter v] -> [Filter v]
infixl 3 ||.

-- | Convert list of <a>PersistValue</a>s into textual representation of
--   JSON object. This is a type-constrained synonym for <a>toJsonText</a>.
listToJSON :: [PersistValue] -> Text

-- | Convert map (list of tuples) into textual representation of JSON
--   object. This is a type-constrained synonym for <a>toJsonText</a>.
mapToJSON :: [(Text, PersistValue)] -> Text

-- | A more general way to convert instances of <a>ToJSON</a> type class to
--   strict text <a>Text</a>.
toJsonText :: ToJSON j => j -> Text

-- | FIXME Add documentation to that.
getPersistMap :: PersistValue -> Either Text [(Text, PersistValue)]

-- | FIXME What's this exactly?
limitOffsetOrder :: PersistEntity val => [SelectOpt val] -> (Int, Int, [SelectOpt val])

module Database.Persist.Sql.Util
parseEntityValues :: PersistEntity record => EntityDef -> [PersistValue] -> Either Text (Entity record)
entityColumnNames :: EntityDef -> SqlBackend -> [Sql]
keyAndEntityColumnNames :: EntityDef -> SqlBackend -> [Sql]
entityColumnCount :: EntityDef -> Int
isIdField :: PersistEntity record => EntityField record typ -> Bool
hasCompositeKey :: EntityDef -> Bool
dbIdColumns :: SqlBackend -> EntityDef -> [Text]
dbIdColumnsEsc :: (DBName -> Text) -> EntityDef -> [Text]
dbColumns :: SqlBackend -> EntityDef -> [Text]

-- | Gets the <a>FieldDef</a> for an <a>Update</a>.
updateFieldDef :: PersistEntity v => Update v -> FieldDef
updatePersistValue :: Update v -> PersistValue
mkUpdateText :: PersistEntity record => SqlBackend -> Update record -> Text
mkUpdateText' :: PersistEntity record => (DBName -> Text) -> (Text -> Text) -> Update record -> Text
commaSeparated :: [Text] -> Text
parenWrapped :: Text -> Text

module Database.Persist.Sql

-- | A single column (see <tt>rawSql</tt>). Any <tt>PersistField</tt> may
--   be used here, including <a>PersistValue</a> (which does not do any
--   processing).
newtype Single a
Single :: a -> Single a
[unSingle] :: Single a -> a
type ConnectionPool = Pool SqlBackend

-- | A <a>Migration</a> is a four level monad stack consisting of:
--   
--   <ul>
--   <li><tt><a>WriterT</a> [<a>Text</a>]</tt> representing a log of errors
--   in the migrations.</li>
--   <li><tt><a>WriterT</a> <a>CautiousMigration</a></tt> representing a
--   list of migrations to run, along with whether or not they are
--   safe.</li>
--   <li><tt><a>ReaderT</a> <a>SqlBackend</a></tt>, aka the
--   <a>SqlPersistT</a> transformer for database interop.</li>
--   <li><tt><a>IO</a></tt> for arbitrary IO.</li>
--   </ul>
type Migration = WriterT [Text] (WriterT CautiousMigration (ReaderT SqlBackend IO)) ()
type CautiousMigration = [(Bool, Sql)]
type Sql = Text
type SqlPersistM = SqlPersistT (NoLoggingT (ResourceT IO))
type SqlPersistT = ReaderT SqlBackend
data PersistentSqlException
StatementAlreadyFinalized :: Text -> PersistentSqlException
Couldn'tGetSQLConnection :: PersistentSqlException
data Column
Column :: !DBName -> !Bool -> !SqlType -> !Maybe Text -> !Maybe DBName -> !Maybe Integer -> !Maybe (DBName, DBName) -> Column
[cName] :: Column -> !DBName
[cNull] :: Column -> !Bool
[cSqlType] :: Column -> !SqlType
[cDefault] :: Column -> !Maybe Text
[cDefaultConstraintName] :: Column -> !Maybe DBName
[cMaxLen] :: Column -> !Maybe Integer
[cReference] :: Column -> !Maybe (DBName, DBName)
data SqlBackend
SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> IORef (Map Text Statement) -> IO () -> ([EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])) -> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> (DBName -> Text) -> Text -> Text -> ((Int, Int) -> Bool -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> SqlBackend
[connPrepare] :: SqlBackend -> Text -> IO Statement

-- | table name, column names, id name, either 1 or 2 statements to run
[connInsertSql] :: SqlBackend -> EntityDef -> [PersistValue] -> InsertSqlResult

-- | SQL for inserting many rows and returning their primary keys, for
--   backends that support this functioanlity. If <a>Nothing</a>, rows will
--   be inserted one-at-a-time using <a>connInsertSql</a>.
[connInsertManySql] :: SqlBackend -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult)

-- | Some databases support performing UPSERT _and_ RETURN entity in a
--   single call.
--   
--   This field when set will be used to generate the UPSERT+RETURN sql
--   given * an entity definition * updates to be run on unique key(s)
--   collision
--   
--   When left as <a>Nothing</a>, we find the unique key from entity def
--   before * trying to fetch an entity by said key * perform an update
--   when result found, else issue an insert * return new entity from db
[connUpsertSql] :: SqlBackend -> Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text)

-- | Some databases support performing bulk UPSERT, specifically "insert or
--   replace many records" in a single call.
--   
--   This field when set, given * an entity definition * number of records
--   to be inserted should produce a PUT MANY sql with placeholders for
--   records
--   
--   When left as <a>Nothing</a>, we default to using
--   <tt>defaultPutMany</tt>.
[connPutManySql] :: SqlBackend -> Maybe (EntityDef -> Int -> Text)
[connStmtMap] :: SqlBackend -> IORef (Map Text Statement)
[connClose] :: SqlBackend -> IO ()
[connMigrateSql] :: SqlBackend -> [EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])
[connBegin] :: SqlBackend -> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()
[connCommit] :: SqlBackend -> (Text -> IO Statement) -> IO ()
[connRollback] :: SqlBackend -> (Text -> IO Statement) -> IO ()
[connEscapeName] :: SqlBackend -> DBName -> Text
[connNoLimit] :: SqlBackend -> Text
[connRDBMS] :: SqlBackend -> Text
[connLimitOffset] :: SqlBackend -> (Int, Int) -> Bool -> Text -> Text
[connLogFunc] :: SqlBackend -> LogFunc

-- | Some databases (probably only Sqlite) have a limit on how many
--   question-mark parameters may be used in a statement
[connMaxParams] :: SqlBackend -> Maybe Int

-- | Some databases support performing bulk an atomic+bulk INSERT where
--   constraint conflicting entities can replace existing entities.
--   
--   This field when set, given * an entity definition * number of records
--   to be inserted should produce a INSERT sql with placeholders for
--   primary+record fields
--   
--   When left as <a>Nothing</a>, we default to using
--   <tt>defaultRepsertMany</tt>.
[connRepsertManySql] :: SqlBackend -> Maybe (EntityDef -> Int -> Text)

-- | An SQL backend which can only handle read queries
--   
--   The constructor was exposed in 2.10.0.
newtype SqlReadBackend
SqlReadBackend :: SqlBackend -> SqlReadBackend
[unSqlReadBackend] :: SqlReadBackend -> SqlBackend

-- | An SQL backend which can handle read or write queries
--   
--   The constructor was exposed in 2.10.0
newtype SqlWriteBackend
SqlWriteBackend :: SqlBackend -> SqlWriteBackend
[unSqlWriteBackend] :: SqlWriteBackend -> SqlBackend
data Statement
Statement :: IO () -> IO () -> ([PersistValue] -> IO Int64) -> (forall m. MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())) -> Statement
[stmtFinalize] :: Statement -> IO ()
[stmtReset] :: Statement -> IO ()
[stmtExecute] :: Statement -> [PersistValue] -> IO Int64
[stmtQuery] :: Statement -> forall m. MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())
type LogFunc = Loc -> LogSource -> LogLevel -> LogStr -> IO ()
data InsertSqlResult
ISRSingle :: Text -> InsertSqlResult
ISRInsertGet :: Text -> Text -> InsertSqlResult
ISRManyKeys :: Text -> [PersistValue] -> InsertSqlResult

-- | Useful for running a read query against a backend with unknown
--   capabilities.
readToUnknown :: Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlBackend m a

-- | Useful for running a read query against a backend with read and write
--   capabilities.
readToWrite :: Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlWriteBackend m a

-- | Useful for running a write query against an untagged backend with
--   unknown capabilities.
writeToUnknown :: Monad m => ReaderT SqlWriteBackend m a -> ReaderT SqlBackend m a

-- | A constraint synonym which witnesses that a backend is SQL and can run
--   read queries.
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 and write queries.
type SqlBackendCanWrite backend = (SqlBackendCanRead backend, PersistQueryWrite backend, PersistStoreWrite backend, PersistUniqueWrite backend)

-- | Like <tt>SqlPersistT</tt> but compatible with any SQL backend which
--   can handle read queries.
type SqlReadT m a = forall backend. (SqlBackendCanRead backend) => ReaderT backend m a

-- | Like <tt>SqlPersistT</tt> but compatible with any SQL backend which
--   can handle read and write queries.
type SqlWriteT m a = forall backend. (SqlBackendCanWrite backend) => ReaderT backend m a

-- | A backend which is a wrapper around <tt>SqlBackend</tt>.
type IsSqlBackend backend = (IsPersistBackend backend, BaseBackend backend ~ SqlBackend)

-- | Class for data types that may be retrived from a <tt>rawSql</tt>
--   query.
class RawSql a

-- | Number of columns that this data type needs and the list of
--   substitutions for <tt>SELECT</tt> placeholders <tt>??</tt>.
rawSqlCols :: RawSql a => (DBName -> Text) -> a -> (Int, [Text])

-- | A string telling the user why the column count is what it is.
rawSqlColCountReason :: RawSql a => a -> String

-- | Transform a row of the result into the data type.
rawSqlProcessRow :: RawSql a => [PersistValue] -> Either Text a

-- | Tells Persistent what database column type should be used to store a
--   Haskell type.
--   
--   <h4><b>Examples</b></h4>
--   
--   <h5>Simple Boolean Alternative</h5>
--   
--   <pre>
--   data Switch = On | Off
--     deriving (Show, Eq)
--   
--   instance <a>PersistField</a> Switch where
--     <a>toPersistValue</a> s = case s of
--       On -&gt; <a>PersistBool</a> True
--       Off -&gt; <a>PersistBool</a> False
--     <a>fromPersistValue</a> (<a>PersistBool</a> b) = if b then <a>Right</a> On else <a>Right</a> Off
--     <a>fromPersistValue</a> x = Left $ "File.hs: When trying to deserialize a Switch: expected PersistBool, received: " &lt;&gt; T.pack (show x)
--   
--   instance <a>PersistFieldSql</a> Switch where
--     <a>sqlType</a> _ = <a>SqlBool</a>
--   </pre>
--   
--   <h5>Non-Standard Database Types</h5>
--   
--   If your database supports non-standard types, such as Postgres'
--   <tt>uuid</tt>, you can use <a>SqlOther</a> to use them:
--   
--   <pre>
--   import qualified Data.UUID as UUID
--   instance <a>PersistField</a> UUID where
--     <a>toPersistValue</a> = <a>PersistDbSpecific</a> . toASCIIBytes
--     <a>fromPersistValue</a> (<a>PersistDbSpecific</a> uuid) =
--       case fromASCIIBytes uuid of
--         <a>Nothing</a> -&gt; <a>Left</a> $ "Model/CustomTypes.hs: Failed to deserialize a UUID; received: " &lt;&gt; T.pack (show uuid)
--         <a>Just</a> uuid' -&gt; <a>Right</a> uuid'
--     <a>fromPersistValue</a> x = Left $ "File.hs: When trying to deserialize a UUID: expected PersistDbSpecific, received: "-- &gt;  &lt;&gt; T.pack (show x)
--   
--   instance <a>PersistFieldSql</a> UUID where
--     <a>sqlType</a> _ = <a>SqlOther</a> "uuid"
--   </pre>
--   
--   <h5>User Created Database Types</h5>
--   
--   Similarly, some databases support creating custom types, e.g.
--   Postgres' <a>DOMAIN</a> and <a>ENUM</a> features. You can use
--   <a>SqlOther</a> to specify a custom type:
--   
--   <pre>
--   CREATE DOMAIN ssn AS text
--         CHECK ( value ~ '^[0-9]{9}$');
--   </pre>
--   
--   <pre>
--   instance <tt>PersistFieldSQL</tt> SSN where
--     <a>sqlType</a> _ = <a>SqlOther</a> "ssn"
--   </pre>
--   
--   <pre>
--   CREATE TYPE rainbow_color AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet');
--   </pre>
--   
--   <pre>
--   instance <tt>PersistFieldSQL</tt> RainbowColor where
--     <a>sqlType</a> _ = <a>SqlOther</a> "rainbow_color"
--   </pre>
class PersistField a => PersistFieldSql a
sqlType :: PersistFieldSql a => Proxy a -> SqlType

-- | 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:
--   
--   <pre>
--   SELECT ??
--   FROM my_long_table_name AS mltn
--   INNER JOIN other_table AS ot
--      ON mltn.some_col = ot.other_col
--   WHERE ...
--   </pre>
--   
--   We don't want to refer to <tt>my_long_table_name</tt> 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:
--   
--   <pre>
--   getStuff :: <a>SqlPersistM</a> [<a>EntityWithPrefix</a> "mltn" MyLongTableName]
--   getStuff = rawSql queryText []
--   </pre>
--   
--   The <a>EntityWithPrefix</a> bit is a boilerplate newtype wrapper, so
--   you can remove it with <a>unPrefix</a>, like this:
--   
--   <pre>
--   getStuff :: <a>SqlPersistM</a> [<a>Entity</a> MyLongTableName]
--   getStuff = <a>unPrefix</a> @"mltn" <a>&lt;$&gt;</a> <tt>rawSql</tt> queryText []
--   </pre>
--   
--   The <tt> symbol is a "type application" and requires the
--   </tt>TypeApplications@ language extension.
newtype EntityWithPrefix (prefix :: Symbol) record
EntityWithPrefix :: Entity record -> EntityWithPrefix (prefix :: Symbol) record
[unEntityWithPrefix] :: EntityWithPrefix (prefix :: Symbol) record -> Entity record

-- | A helper function to tell GHC what the <a>EntityWithPrefix</a> 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:
--   
--   <pre>
--   myQuery :: <a>SqlPersistM</a> [<a>Entity</a> Person]
--   myQuery = map (unPrefix @"p") <a>$</a> rawSql query []
--     where
--       query = "SELECT ?? FROM person AS p"
--   </pre>
unPrefix :: forall prefix record. EntityWithPrefix prefix record -> Entity record

-- | The returned <a>Acquire</a> gets a connection from the pool, but does
--   <b>NOT</b> start a new transaction. Used to implement
--   <a>acquireSqlConnFromPool</a> and
--   <a>acquireSqlConnFromPoolWithIsolation</a>, this is useful for
--   performing actions on a connection that cannot be done within a
--   transaction, such as VACUUM in Sqlite.
unsafeAcquireSqlConnFromPool :: forall backend m. (MonadReader (Pool backend) m, BackendCompatible SqlBackend backend) => m (Acquire backend)

-- | The returned <a>Acquire</a> gets a connection from the pool, starts a
--   new transaction and gives access to the prepared 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 <a>runSqlPool</a> but does not incur the
--   <a>MonadUnliftIO</a> constraint, meaning it can be used within, for
--   example, a <tt>Conduit</tt> pipeline.
acquireSqlConnFromPool :: (MonadReader (Pool backend) m, BackendCompatible SqlBackend backend) => m (Acquire backend)

-- | Like <a>acquireSqlConnFromPool</a>, but lets you specify an explicit
--   isolation level.
acquireSqlConnFromPoolWithIsolation :: (MonadReader (Pool backend) m, BackendCompatible SqlBackend backend) => IsolationLevel -> m (Acquire backend)

-- | Get a connection from the pool, run the given action, and then return
--   the connection to the pool.
--   
--   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.
runSqlPool :: (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> Pool backend -> m a

-- | Like <a>runSqlPool</a>, but supports specifying an isolation level.
runSqlPoolWithIsolation :: (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> Pool backend -> IsolationLevel -> m a

-- | 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
--   <a>MonadUnliftIO</a> constraint, meaning it can be used within, for
--   example, a <tt>Conduit</tt> pipeline.
acquireSqlConn :: (MonadReader backend m, BackendCompatible SqlBackend backend) => m (Acquire backend)

-- | Like <a>acquireSqlConn</a>, but lets you specify an explicit isolation
--   level.
acquireSqlConnWithIsolation :: (MonadReader backend m, BackendCompatible SqlBackend backend) => IsolationLevel -> m (Acquire backend)
runSqlConn :: (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> m a

-- | Like <a>runSqlConn</a>, but supports specifying an isolation level.
runSqlConnWithIsolation :: (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> IsolationLevel -> m a
runSqlPersistM :: BackendCompatible SqlBackend backend => ReaderT backend (NoLoggingT (ResourceT IO)) a -> backend -> IO a
runSqlPersistMPool :: BackendCompatible SqlBackend backend => ReaderT backend (NoLoggingT (ResourceT IO)) a -> Pool backend -> IO a
liftSqlPersistMPool :: (MonadIO m, BackendCompatible SqlBackend backend) => ReaderT backend (NoLoggingT (ResourceT IO)) a -> Pool backend -> m a
withSqlPool :: (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> (Pool backend -> m a) -> m a
createSqlPool :: forall m backend. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> m (Pool backend)
askLogFunc :: forall m. (MonadUnliftIO m, MonadLogger m) => m LogFunc

-- | Create a connection and run sql queries within it. This function
--   automatically closes the connection on it's completion.
--   
--   <h3><b>Example usage</b></h3>
--   
--   <pre>
--   {-# 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 -&gt; IO SqlBackend
--   openConnection logfn = do
--    conn &lt;- open "/home/sibi/test.db"
--    wrapConnection conn logfn
--   
--   main :: IO ()
--   main = do
--     runNoLoggingT $ runResourceT $ withSqlConn openConnection (\backend -&gt;
--                                         flip runSqlConn backend $ do
--                                           runMigration migrateAll
--                                           insert_ $ Person "John doe" $ Just 35
--                                           insert_ $ Person "Divya" $ Just 36
--                                           (pers :: [Entity Person]) &lt;- selectList [] []
--                                           liftIO $ print pers
--                                           return ()
--                                        )
--   </pre>
--   
--   On executing it, you get this output:
--   
--   <pre>
--   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}}]
--   </pre>
withSqlConn :: (MonadUnliftIO m, MonadLogger m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> (backend -> m a) -> m a
close' :: BackendCompatible SqlBackend backend => backend -> IO ()

-- | Given a <a>Migration</a>, this parses it and returns either a list of
--   errors associated with the migration or a list of migrations to do.
parseMigration :: MonadIO m => Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration)

-- | Like <a>parseMigration</a>, but instead of returning the value in an
--   <a>Either</a> value, it calls <a>error</a> on the error values.
parseMigration' :: MonadIO m => Migration -> ReaderT SqlBackend m CautiousMigration

-- | Prints a migration.
printMigration :: MonadIO m => Migration -> ReaderT SqlBackend m ()

-- | Convert a <a>Migration</a> to a list of <a>Text</a> values
--   corresponding to their <a>Sql</a> statements.
showMigration :: MonadIO m => Migration -> ReaderT SqlBackend m [Text]

-- | Return all of the <a>Sql</a> values associated with the given
--   migration. Calls <a>error</a> if there's a parse error on any
--   migration.
getMigration :: MonadIO m => Migration -> ReaderT SqlBackend m [Sql]

-- | Runs a migration. If the migration fails to parse or if any of the
--   migrations are unsafe, then this calls <a>error</a> to halt the
--   program.
runMigration :: MonadIO m => Migration -> ReaderT SqlBackend m ()

-- | Same as <a>runMigration</a>, 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 <a>runMigrationSilent</a>,
--   but may be less silent for some persistent implementations, most
--   notably persistent-postgresql
runMigrationQuiet :: MonadIO m => Migration -> ReaderT SqlBackend m [Text]

-- | Same as <a>runMigration</a>, but returns a list of the SQL commands
--   executed instead of printing them to stderr.
--   
--   This function silences the migration by remapping <a>stderr</a>. 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!
runMigrationSilent :: MonadUnliftIO m => Migration -> ReaderT SqlBackend m [Text]

-- | Like <a>runMigration</a>, but this will perform the unsafe database
--   migrations instead of erroring out.
runMigrationUnsafe :: MonadIO m => Migration -> ReaderT SqlBackend m ()

-- | Same as <a>runMigrationUnsafe</a>, but returns a list of the SQL
--   commands executed instead of printing them to stderr.
runMigrationUnsafeQuiet :: MonadIO m => Migration -> ReaderT SqlBackend m [Text]

-- | Given a list of old entity definitions and a new <a>EntityDef</a> in
--   <tt>val</tt>, this creates a <a>Migration</a> to update the old list
--   of definitions with the new one.
migrate :: [EntityDef] -> EntityDef -> Migration

-- | Report multiple errors in a <a>Migration</a>.
reportErrors :: [Text] -> Migration

-- | Report a single error in a <a>Migration</a>.
reportError :: Text -> Migration

-- | Add a <a>CautiousMigration</a> (aka a <tt>[(<a>Bool</a>,
--   <a>Text</a>)]</tt>) to the migration plan.
addMigrations :: CautiousMigration -> Migration

-- | Add a migration to the migration plan.
addMigration :: Bool -> Sql -> Migration
withRawQuery :: MonadIO m => Text -> [PersistValue] -> ConduitM [PersistValue] Void IO a -> ReaderT SqlBackend m a
data family BackendKey backend
toSqlKey :: ToBackendKey SqlBackend record => Int64 -> Key record
fromSqlKey :: ToBackendKey SqlBackend record => Key record -> Int64

-- | 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
getFieldName :: forall record typ m backend. (PersistEntity record, PersistEntityBackend record ~ SqlBackend, BackendCompatible SqlBackend backend, Monad m) => EntityField record typ -> ReaderT backend m Text

-- | get the SQL string for the table that a PeristEntity represents Useful
--   for raw SQL queries
--   
--   Your backend may provide a more convenient tableName function which
--   does not operate in a Monad
getTableName :: forall record m backend. (PersistEntity record, BackendCompatible SqlBackend backend, Monad m) => record -> ReaderT backend m Text

-- | useful for a backend to implement tableName by adding escaping
tableDBName :: PersistEntity record => record -> DBName

-- | useful for a backend to implement fieldName by adding escaping
fieldDBName :: forall record typ. PersistEntity record => EntityField record typ -> DBName
rawQuery :: (MonadResource m, MonadReader env m, BackendCompatible SqlBackend env) => Text -> [PersistValue] -> ConduitM () [PersistValue] m ()
rawQueryRes :: (MonadIO m1, MonadIO m2, BackendCompatible SqlBackend env) => Text -> [PersistValue] -> ReaderT env m1 (Acquire (ConduitM () [PersistValue] m2 ()))

-- | Execute a raw SQL statement
rawExecute :: (MonadIO m, BackendCompatible SqlBackend backend) => Text -> [PersistValue] -> ReaderT backend m ()

-- | Execute a raw SQL statement and return the number of rows it has
--   modified.
rawExecuteCount :: (MonadIO m, BackendCompatible SqlBackend backend) => Text -> [PersistValue] -> ReaderT backend m Int64

-- | Execute a raw SQL statement and return its results as a list. If you
--   do not expect a return value, use of <a>rawExecute</a> is recommended.
--   
--   If you're using <a>Entity</a><tt>s</tt> (which is quite likely), then
--   you <i>must</i> use entity selection placeholders (double question
--   mark, <tt>??</tt>). These <tt>??</tt> 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
--   <a>Entity</a><tt>s</tt> documentation for more details.
--   
--   You may put value placeholders (question marks, <tt>?</tt>) 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 <a>toPersistValue</a> to help you constructing the placeholder
--   values.
--   
--   Since you're giving a raw SQL statement, you don't get any guarantees
--   regarding safety. If <a>rawSql</a> 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
--   <tt>??</tt>, and you shouldn't see any error at all if you're not
--   using <a>Single</a>.
--   
--   Some example of <a>rawSql</a> based on this schema:
--   
--   <pre>
--   share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
--   Person
--       name String
--       age Int Maybe
--       deriving Show
--   BlogPost
--       title String
--       authorId PersonId
--       deriving Show
--   |]
--   </pre>
--   
--   Examples based on the above schema:
--   
--   <pre>
--   getPerson :: MonadIO m =&gt; ReaderT SqlBackend m [Entity Person]
--   getPerson = rawSql "select ?? from person where name=?" [PersistText "john"]
--   
--   getAge :: MonadIO m =&gt; ReaderT SqlBackend m [Single Int]
--   getAge = rawSql "select person.age from person where name=?" [PersistText "john"]
--   
--   getAgeName :: MonadIO m =&gt; ReaderT SqlBackend m [(Single Int, Single Text)]
--   getAgeName = rawSql "select person.age, person.name from person where name=?" [PersistText "john"]
--   
--   getPersonBlog :: MonadIO m =&gt; ReaderT SqlBackend m [(Entity Person, Entity BlogPost)]
--   getPersonBlog = rawSql "select ??,?? from person,blog_post where person.id = blog_post.author_id" []
--   </pre>
--   
--   Minimal working program for PostgreSQL backend based on the above
--   concepts:
--   
--   <pre>
--   {-# 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 =&gt; 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 &lt;- getPerson
--            liftIO (print xs)
--   </pre>
rawSql :: (RawSql a, MonadIO m, BackendCompatible SqlBackend backend) => Text -> [PersistValue] -> ReaderT backend m [a]

-- | Same as <a>deleteWhere</a>, but returns the number of rows affected.
deleteWhereCount :: (PersistEntity val, MonadIO m, PersistEntityBackend val ~ SqlBackend, BackendCompatible SqlBackend backend) => [Filter val] -> ReaderT backend m Int64

-- | Same as <a>updateWhere</a>, but returns the number of rows affected.
updateWhereCount :: (PersistEntity val, MonadIO m, SqlBackend ~ PersistEntityBackend val, BackendCompatible SqlBackend backend) => [Filter val] -> [Update val] -> ReaderT backend m Int64

-- | Commit the current transaction and begin a new one. This is used when
--   a transaction commit is required within the context of
--   <a>runSqlConn</a> (which brackets its provided action with a
--   transaction begin/commit pair).
transactionSave :: MonadIO m => ReaderT SqlBackend m ()

-- | Commit the current transaction and begin a new one with the specified
--   isolation level.
transactionSaveWithIsolation :: MonadIO m => IsolationLevel -> ReaderT SqlBackend m ()

-- | Roll back the current transaction and begin a new one. This rolls back
--   to the state of the last call to <a>transactionSave</a> or the
--   enclosing <a>runSqlConn</a> call.
transactionUndo :: MonadIO m => ReaderT SqlBackend m ()

-- | Roll back the current transaction and begin a new one with the
--   specified isolation level.
transactionUndoWithIsolation :: MonadIO m => IsolationLevel -> ReaderT SqlBackend m ()

-- | Please refer to the documentation for the database in question for a
--   full overview of the semantics of the varying isloation levels
data IsolationLevel
ReadUncommitted :: IsolationLevel
ReadCommitted :: IsolationLevel
RepeatableRead :: IsolationLevel
Serializable :: IsolationLevel
getStmtConn :: SqlBackend -> Text -> IO Statement

-- | Create the list of columns for the given entity.
mkColumns :: [EntityDef] -> EntityDef -> ([Column], [UniqueDef], [ForeignDef])
defaultAttribute :: [Attr] -> Maybe Text

-- | Generates sql for limit and offset for postgres, sqlite and mysql.
decorateSQLWithLimitOffset :: Text -> (Int, Int) -> Bool -> Text -> Text
