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


-- | 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.17.1.0

module Database.Persist.Class.PersistConfig

-- | 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 PersistConfigBackend c :: Type -> Type -> Type -> Type;
    type 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
instance (Database.Persist.Class.PersistConfig.PersistConfig c1, Database.Persist.Class.PersistConfig.PersistConfig c2, Database.Persist.Class.PersistConfig.PersistConfigPool c1 GHC.Types.~ Database.Persist.Class.PersistConfig.PersistConfigPool c2, Database.Persist.Class.PersistConfig.PersistConfigBackend c1 GHC.Types.~ Database.Persist.Class.PersistConfig.PersistConfigBackend c2) => Database.Persist.Class.PersistConfig.PersistConfig (GHC.Internal.Data.Either.Either c1 c2)


-- | This module contains types and functions for working with and
--   disambiguating database and Haskell names.
module Database.Persist.Names

-- | Convenience operations for working with '-NameDB' types.
class DatabaseName a
escapeWith :: DatabaseName a => (Text -> str) -> a -> str

-- | A <a>FieldNameDB</a> represents the datastore-side name that
--   <tt>persistent</tt> will use for a field.
newtype FieldNameDB
FieldNameDB :: Text -> FieldNameDB
[unFieldNameDB] :: FieldNameDB -> Text

-- | A <a>FieldNameHS</a> represents the Haskell-side name that
--   <tt>persistent</tt> will use for a field.
newtype FieldNameHS
FieldNameHS :: Text -> FieldNameHS
[unFieldNameHS] :: FieldNameHS -> Text

-- | An <a>EntityNameHS</a> represents the Haskell-side name that
--   <tt>persistent</tt> will use for an entity.
newtype EntityNameHS
EntityNameHS :: Text -> EntityNameHS
[unEntityNameHS] :: EntityNameHS -> Text

-- | An <a>EntityNameDB</a> represents the datastore-side name that
--   <tt>persistent</tt> will use for an entity.
newtype EntityNameDB
EntityNameDB :: Text -> EntityNameDB
[unEntityNameDB] :: EntityNameDB -> Text

-- | A <a>ConstraintNameDB</a> represents the datastore-side name that
--   <tt>persistent</tt> will use for a constraint.
newtype ConstraintNameDB
ConstraintNameDB :: Text -> ConstraintNameDB
[unConstraintNameDB] :: ConstraintNameDB -> Text

-- | An <a>ConstraintNameHS</a> represents the Haskell-side name that
--   <tt>persistent</tt> will use for a constraint.
newtype ConstraintNameHS
ConstraintNameHS :: Text -> ConstraintNameHS
[unConstraintNameHS] :: ConstraintNameHS -> Text
instance Database.Persist.Names.DatabaseName Database.Persist.Names.ConstraintNameDB
instance Database.Persist.Names.DatabaseName Database.Persist.Names.EntityNameDB
instance Database.Persist.Names.DatabaseName Database.Persist.Names.FieldNameDB
instance GHC.Classes.Eq Database.Persist.Names.ConstraintNameDB
instance GHC.Classes.Eq Database.Persist.Names.ConstraintNameHS
instance GHC.Classes.Eq Database.Persist.Names.EntityNameDB
instance GHC.Classes.Eq Database.Persist.Names.EntityNameHS
instance GHC.Classes.Eq Database.Persist.Names.FieldNameDB
instance GHC.Classes.Eq Database.Persist.Names.FieldNameHS
instance GHC.Internal.TH.Lift.Lift Database.Persist.Names.ConstraintNameDB
instance GHC.Internal.TH.Lift.Lift Database.Persist.Names.ConstraintNameHS
instance GHC.Internal.TH.Lift.Lift Database.Persist.Names.EntityNameDB
instance GHC.Internal.TH.Lift.Lift Database.Persist.Names.EntityNameHS
instance GHC.Internal.TH.Lift.Lift Database.Persist.Names.FieldNameDB
instance GHC.Internal.TH.Lift.Lift Database.Persist.Names.FieldNameHS
instance GHC.Classes.Ord Database.Persist.Names.ConstraintNameDB
instance GHC.Classes.Ord Database.Persist.Names.ConstraintNameHS
instance GHC.Classes.Ord Database.Persist.Names.EntityNameDB
instance GHC.Classes.Ord Database.Persist.Names.EntityNameHS
instance GHC.Classes.Ord Database.Persist.Names.FieldNameDB
instance GHC.Classes.Ord Database.Persist.Names.FieldNameHS
instance GHC.Internal.Read.Read Database.Persist.Names.ConstraintNameDB
instance GHC.Internal.Read.Read Database.Persist.Names.ConstraintNameHS
instance GHC.Internal.Read.Read Database.Persist.Names.EntityNameDB
instance GHC.Internal.Read.Read Database.Persist.Names.EntityNameHS
instance GHC.Internal.Read.Read Database.Persist.Names.FieldNameDB
instance GHC.Internal.Read.Read Database.Persist.Names.FieldNameHS
instance GHC.Internal.Show.Show Database.Persist.Names.ConstraintNameDB
instance GHC.Internal.Show.Show Database.Persist.Names.ConstraintNameHS
instance GHC.Internal.Show.Show Database.Persist.Names.EntityNameDB
instance GHC.Internal.Show.Show Database.Persist.Names.EntityNameHS
instance GHC.Internal.Show.Show Database.Persist.Names.FieldNameDB
instance GHC.Internal.Show.Show Database.Persist.Names.FieldNameHS


-- | This module contains an intermediate representation of values before
--   the backends serialize them into explicit database types.
module Database.Persist.PersistValue

-- | 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

-- | This constructor is used to specify some raw literal value for the
--   backend. The <a>LiteralType</a> value specifies how the value should
--   be escaped. This can be used to make special, custom types avaialable
--   in the back end.
PersistLiteral_ :: LiteralType -> ByteString -> PersistValue

-- | This pattern synonym used to be a data constructor on
--   <a>PersistValue</a>, but was changed into a catch-all pattern synonym
--   to allow backwards compatiblity with database types. See the
--   documentation on <a>PersistDbSpecific</a> for more details.
pattern PersistLiteral :: ByteString -> PersistValue

-- | This pattern synonym used to be a data constructor on
--   <a>PersistValue</a>, but was changed into a catch-all pattern synonym
--   to allow backwards compatiblity with database types. See the
--   documentation on <a>PersistDbSpecific</a> for more details.
pattern PersistLiteralEscaped :: ByteString -> PersistValue

-- | This pattern synonym used to be a data constructor for the
--   <a>PersistValue</a> type. It was changed to be a pattern so that
--   JSON-encoded database values could be parsed into their corresponding
--   values. You should not use this, and instead prefer to pattern match
--   on <a>PersistLiteral_</a> directly.
--   
--   If you use this, it will overlap a patern match on the
--   'PersistLiteral_, <a>PersistLiteral</a>, and
--   <a>PersistLiteralEscaped</a> patterns. If you need to disambiguate
--   between these constructors, pattern match on <a>PersistLiteral_</a>
--   directly.

-- | <i>Deprecated: Deprecated since 2.11 because of inconsistent escaping
--   behavior across backends. The Postgres backend escapes these values,
--   while the MySQL backend does not. If you are using this, please switch
--   to <a>PersistLiteral_</a> and provide a relevant <a>LiteralType</a>
--   for your conversion.</i>
pattern PersistDbSpecific :: ByteString -> PersistValue
fromPersistValueText :: PersistValue -> Either Text Text

-- | A type that determines how a backend should handle the literal.
data LiteralType

-- | The accompanying value will be escaped before inserting into the
--   database. This is the correct default choice to use.
Escaped :: LiteralType

-- | The accompanying value will not be escaped when inserting into the
--   database. This is potentially dangerous - use this with care.
Unescaped :: LiteralType

-- | The <a>DbSpecific</a> constructor corresponds to the legacy
--   <a>PersistDbSpecific</a> constructor. We need to keep this around
--   because old databases may have serialized JSON representations that
--   reference this. We don't want to break the ability of a database to
--   load rows.
DbSpecific :: LiteralType
instance GHC.Classes.Eq Database.Persist.PersistValue.LiteralType
instance GHC.Classes.Eq Database.Persist.PersistValue.PersistValue
instance Web.Internal.HttpApiData.FromHttpApiData Database.Persist.PersistValue.PersistValue
instance Data.Aeson.Types.FromJSON.FromJSON Database.Persist.PersistValue.PersistValue
instance Control.DeepSeq.NFData Database.Persist.PersistValue.PersistValue
instance GHC.Classes.Ord Database.Persist.PersistValue.LiteralType
instance GHC.Classes.Ord Database.Persist.PersistValue.PersistValue
instance Web.PathPieces.PathPiece Database.Persist.PersistValue.PersistValue
instance GHC.Internal.Read.Read Database.Persist.PersistValue.LiteralType
instance GHC.Internal.Read.Read Database.Persist.PersistValue.PersistValue
instance GHC.Internal.Show.Show Database.Persist.PersistValue.LiteralType
instance GHC.Internal.Show.Show Database.Persist.PersistValue.PersistValue
instance Web.Internal.HttpApiData.ToHttpApiData Database.Persist.PersistValue.PersistValue
instance Data.Aeson.Types.ToJSON.ToJSON Database.Persist.PersistValue.PersistValue

module Database.Persist.Quasi.Internal.TypeParser

-- | A parsed type expression.
data TypeExpr
TypeApplication :: TypeExpr -> [TypeExpr] -> TypeExpr
TypeConstructorExpr :: TypeConstructor -> TypeExpr
TypeLitString :: String -> TypeExpr
TypeLitInt :: String -> TypeExpr
TypeLitPromotedConstructor :: TypeConstructor -> TypeExpr

-- | A parsed type constructor.
data TypeConstructor
ListConstructor :: TypeConstructor
TypeConstructor :: String -> TypeConstructor

-- | Parses a Persistent-style type expression. Persistent's type
--   expressions are largely similar to Haskell's, but with a few
--   differences:
--   
--   <ol>
--   <li>Syntactic sugar is not currently supported for constructing types
--   other than List.</li>
--   <li>Only certain typelevel literals are supported: Strings, Ints, and
--   promoted type constructors.</li>
--   <li>Because they must be parsed as part of an entity field definition,
--   top-level applications of non-nullary type constructors (except for
--   the sugary List constructor) must be parenthesized.</li>
--   </ol>
--   
--   VALID: Int VALID: [Maybe Int] VALID: (Maybe Int) INVALID: Maybe Int
typeExpr :: MonadParsec e String m => m TypeExpr

-- | Parses a type expression in non-top-level contexts, where an
--   unparenthesized type constructor application is acceptable.
innerTypeExpr :: MonadParsec e String m => m TypeExpr

-- | Given a TypeExpr, renders it back to a String in a canonical form that
--   looks normal to humans and is re-parseable when making an
--   UnboundEntityDef that uses it.
typeExprContent :: TypeExpr -> Text
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.TypeParser.TypeConstructor
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.TypeParser.TypeExpr
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.TypeParser.TypeConstructor
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.TypeParser.TypeExpr

module Database.Persist.SqlBackend.Internal.IsolationLevel

-- | Please refer to the documentation for the database in question for a
--   full overview of the semantics of the varying isolation levels
data IsolationLevel
ReadUncommitted :: IsolationLevel
ReadCommitted :: IsolationLevel
RepeatableRead :: IsolationLevel
Serializable :: IsolationLevel
makeIsolationLevelStatement :: (Monoid s, IsString s) => IsolationLevel -> s
instance GHC.Internal.Enum.Bounded Database.Persist.SqlBackend.Internal.IsolationLevel.IsolationLevel
instance GHC.Internal.Enum.Enum Database.Persist.SqlBackend.Internal.IsolationLevel.IsolationLevel
instance GHC.Classes.Eq Database.Persist.SqlBackend.Internal.IsolationLevel.IsolationLevel
instance GHC.Classes.Ord Database.Persist.SqlBackend.Internal.IsolationLevel.IsolationLevel
instance GHC.Internal.Show.Show Database.Persist.SqlBackend.Internal.IsolationLevel.IsolationLevel

module Database.Persist.SqlBackend.Internal.SqlPoolHooks

-- | A set of hooks that may be used to alter the behaviour of
--   <tt>runSqlPoolWithExtensibleHooks</tt> in a backwards-compatible
--   fashion.
data SqlPoolHooks (m :: Type -> Type) backend
SqlPoolHooks :: (backend -> m backend) -> (backend -> Maybe IsolationLevel -> m ()) -> (backend -> Maybe IsolationLevel -> m ()) -> (backend -> Maybe IsolationLevel -> SomeException -> m ()) -> SqlPoolHooks (m :: Type -> Type) backend

-- | Alter the backend prior to executing any actions with it.
[alterBackend] :: SqlPoolHooks (m :: Type -> Type) backend -> backend -> m backend

-- | Run this action immediately before the action is performed.
[runBefore] :: SqlPoolHooks (m :: Type -> Type) backend -> backend -> Maybe IsolationLevel -> m ()

-- | Run this action immediately after the action is completed.
[runAfter] :: SqlPoolHooks (m :: Type -> Type) backend -> backend -> Maybe IsolationLevel -> m ()

-- | This action is performed when an exception is received. The exception
--   is provided as a convenience - it is rethrown once this cleanup
--   function is complete.
[runOnException] :: SqlPoolHooks (m :: Type -> Type) backend -> backend -> Maybe IsolationLevel -> SomeException -> m ()

module Database.Persist.Types.SourceSpan

-- | A pair of (start line<i>col, end line</i>col) coordinates. The end
--   column will be one past the final character (i.e. the span
--   (1,1)-&gt;(1,1) is zero characters long).
--   
--   SourceSpans are 1-indexed in both lines and columns.
--   
--   Conceptually identical to GHC's <tt>RealSourceSpan</tt>.
data SourceSpan
SourceSpan :: !Text -> !Int -> !Int -> !Int -> !Int -> SourceSpan
[spanFile] :: SourceSpan -> !Text
[spanStartLine] :: SourceSpan -> !Int
[spanStartCol] :: SourceSpan -> !Int
[spanEndLine] :: SourceSpan -> !Int
[spanEndCol] :: SourceSpan -> !Int
instance GHC.Classes.Eq Database.Persist.Types.SourceSpan.SourceSpan
instance GHC.Internal.TH.Lift.Lift Database.Persist.Types.SourceSpan.SourceSpan
instance GHC.Classes.Ord Database.Persist.Types.SourceSpan.SourceSpan
instance GHC.Internal.Read.Read Database.Persist.Types.SourceSpan.SourceSpan
instance GHC.Internal.Show.Show Database.Persist.Types.SourceSpan.SourceSpan

module Database.Persist.SqlBackend.Internal.Statement

-- | A <a>Statement</a> is a representation of a database query that has
--   been prepared and stored on the server side.
data Statement
Statement :: IO () -> IO () -> ([PersistValue] -> IO Int64) -> (forall (m :: Type -> Type). MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())) -> Statement
[stmtFinalize] :: Statement -> IO ()
[stmtReset] :: Statement -> IO ()
[stmtExecute] :: Statement -> [PersistValue] -> IO Int64
[stmtQuery] :: Statement -> forall (m :: Type -> Type). MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())

module Database.Persist.SqlBackend.Internal.StatementCache

-- | A statement cache used to lookup statements that have already been
--   prepared for a given query.
data StatementCache
StatementCache :: (StatementCacheKey -> IO (Maybe Statement)) -> (StatementCacheKey -> Statement -> IO ()) -> IO () -> IO Int -> StatementCache
[statementCacheLookup] :: StatementCache -> StatementCacheKey -> IO (Maybe Statement)
[statementCacheInsert] :: StatementCache -> StatementCacheKey -> Statement -> IO ()
[statementCacheClear] :: StatementCache -> IO ()
[statementCacheSize] :: StatementCache -> IO Int
newtype StatementCacheKey
StatementCacheKey :: Text -> StatementCacheKey
[cacheKey] :: StatementCacheKey -> Text

-- | Construct a <a>StatementCacheKey</a> from a raw SQL query.
mkCacheKeyFromQuery :: Text -> StatementCacheKey

module Database.Persist.SqlBackend.StatementCache

-- | A statement cache used to lookup statements that have already been
--   prepared for a given query.
data StatementCache
data StatementCacheKey

-- | Construct a <a>StatementCacheKey</a> from a raw SQL query.
mkCacheKeyFromQuery :: Text -> StatementCacheKey

-- | Configuration parameters for creating a custom statement cache
data MkStatementCache
MkStatementCache :: (StatementCacheKey -> IO (Maybe Statement)) -> (StatementCacheKey -> Statement -> IO ()) -> IO () -> IO Int -> MkStatementCache

-- | Retrieve a statement from the cache, or return nothing if it is not
--   found.
[statementCacheLookup] :: MkStatementCache -> StatementCacheKey -> IO (Maybe Statement)

-- | Put a new statement into the cache. An immediate lookup of the
--   statement MUST return the inserted statement for the given cache key.
--   Depending on the implementation, the statement cache MAY choose to
--   evict other statements from the cache within this function.
[statementCacheInsert] :: MkStatementCache -> StatementCacheKey -> Statement -> IO ()

-- | Remove all statements from the cache. Implementations of this should
--   be sure to call <a>stmtFinalize</a> on all statements removed from the
--   cache.
[statementCacheClear] :: MkStatementCache -> IO ()

-- | Get the current size of the cache.
[statementCacheSize] :: MkStatementCache -> IO Int

-- | Make a simple statement cache that will cache statements if they are
--   not currently cached.
mkSimpleStatementCache :: IORef (Map Text Statement) -> MkStatementCache

-- | Create a statement cache.
mkStatementCache :: MkStatementCache -> StatementCache

module Database.Persist.SqlBackend.Internal.InsertSqlResult
data InsertSqlResult
ISRSingle :: Text -> InsertSqlResult
ISRInsertGet :: Text -> Text -> InsertSqlResult
ISRManyKeys :: Text -> [PersistValue] -> InsertSqlResult

module Database.Persist.SqlBackend.Internal.MkSqlBackend

-- | This type shares many of the same field names as the
--   <tt>SqlBackend</tt> type. It's useful for library authors to use this
--   when migrating from using the <tt>SqlBackend</tt> constructor directly
--   to the <tt>mkSqlBackend</tt> function.
--   
--   This type will only contain required fields for constructing a
--   <tt>SqlBackend</tt>. For fields that aren't present on this record,
--   you'll want to use the various <tt>set</tt> functions or
data MkSqlBackendArgs
MkSqlBackendArgs :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> 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 ()) -> (FieldNameDB -> Text) -> (EntityDef -> Text) -> (Text -> Text) -> Text -> Text -> ((Int, Int) -> Text -> Text) -> LogFunc -> MkSqlBackendArgs

-- | This function should prepare a <a>Statement</a> in the target
--   database, which should allow for efficient query reuse.
[connPrepare] :: MkSqlBackendArgs -> Text -> IO Statement

-- | This function generates the SQL and values necessary for performing an
--   insert against the database.
[connInsertSql] :: MkSqlBackendArgs -> EntityDef -> [PersistValue] -> InsertSqlResult

-- | A reference to the cache of statements. <a>Statement</a>s are keyed by
--   the <a>Text</a> queries that generated them.
[connStmtMap] :: MkSqlBackendArgs -> IORef (Map Text Statement)

-- | Close the underlying connection.
[connClose] :: MkSqlBackendArgs -> IO ()

-- | This function returns the migrations required to include the
--   <a>EntityDef</a> parameter in the <tt>[<a>EntityDef</a>]</tt>
--   database. This might include creating a new table if the entity is not
--   present, or altering an existing table if it is.
[connMigrateSql] :: MkSqlBackendArgs -> [EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])

-- | A function to begin a transaction for the underlying database.
[connBegin] :: MkSqlBackendArgs -> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()

-- | A function to commit a transaction to the underlying database.
[connCommit] :: MkSqlBackendArgs -> (Text -> IO Statement) -> IO ()

-- | A function to roll back a transaction on the underlying database.
[connRollback] :: MkSqlBackendArgs -> (Text -> IO Statement) -> IO ()

-- | A function to extract and escape the name of the column corresponding
--   to the provided field.
[connEscapeFieldName] :: MkSqlBackendArgs -> FieldNameDB -> Text

-- | A function to extract and escape the name of the table corresponding
--   to the provided entity. PostgreSQL uses this to support schemas.
[connEscapeTableName] :: MkSqlBackendArgs -> EntityDef -> Text

-- | A function to escape raw DB identifiers. MySQL uses backticks, while
--   PostgreSQL uses quotes, and so on.
[connEscapeRawName] :: MkSqlBackendArgs -> Text -> Text
[connNoLimit] :: MkSqlBackendArgs -> Text

-- | A tag displaying what database the <tt>SqlBackend</tt> is for. Can be
--   used to differentiate features in downstream libraries for different
--   database backends.
[connRDBMS] :: MkSqlBackendArgs -> Text

-- | Attach a 'LIMIT/OFFSET' clause to a SQL query. Note that LIMIT/OFFSET
--   is problematic for performance, and indexed range queries are the
--   superior way to offer pagination.
[connLimitOffset] :: MkSqlBackendArgs -> (Int, Int) -> Text -> Text

-- | A log function for the <tt>SqlBackend</tt> to use.
[connLogFunc] :: MkSqlBackendArgs -> LogFunc
type LogFunc = Loc -> LogSource -> LogLevel -> LogStr -> IO ()


module Database.Persist.FieldDef.Internal

-- | 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 :: !FieldNameHS -> !FieldNameDB -> !FieldType -> !SqlType -> ![FieldAttr] -> !Bool -> !ReferenceDef -> !FieldCascade -> !Maybe Text -> !Maybe Text -> !Bool -> 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>FieldNameHS</a> "name"</tt> for
--   a type <tt>User</tt> will have a record field <tt>userName</tt>.
[fieldHaskell] :: FieldDef -> !FieldNameHS

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

-- | 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 -> ![FieldAttr]

-- | 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

-- | Defines how operations on the field cascade on to the referenced
--   tables. This doesn't have any meaning if the <a>fieldReference</a> is
--   set to <a>NoReference</a> or <a>SelfReference</a>. The cascade option
--   here should be the same as the one obtained in the
--   <a>fieldReference</a>.
[fieldCascade] :: FieldDef -> !FieldCascade

-- | Optional comments for a <tt>Field</tt>.
[fieldComments] :: FieldDef -> !Maybe Text

-- | Whether or not the field is a <tt>GENERATED</tt> column, and
--   additionally the expression to use for generation.
[fieldGenerated] :: FieldDef -> !Maybe Text

-- | <a>True</a> if the field is an implicit ID column. <a>False</a>
--   otherwise.
[fieldIsImplicitIdColumn] :: FieldDef -> !Bool
isFieldNotGenerated :: FieldDef -> Bool

-- | This datatype describes how a foreign reference field cascades deletes
--   or updates.
--   
--   This type is used in both parsing the model definitions and performing
--   migrations. A <a>Nothing</a> in either of the field values means that
--   the user has not specified a <a>CascadeAction</a>. An unspecified
--   <a>CascadeAction</a> is defaulted to <a>Restrict</a> when doing
--   migrations.
data FieldCascade
FieldCascade :: !Maybe CascadeAction -> !Maybe CascadeAction -> FieldCascade
[fcOnUpdate] :: FieldCascade -> !Maybe CascadeAction
[fcOnDelete] :: FieldCascade -> !Maybe CascadeAction

-- | Renders a <a>FieldCascade</a> value such that it can be used in SQL
--   migrations.
renderFieldCascade :: FieldCascade -> Text

-- | Render a <a>CascadeAction</a> to <a>Text</a> such that it can be used
--   in a SQL command.
renderCascadeAction :: CascadeAction -> Text

-- | A <a>FieldCascade</a> that does nothing.
noCascade :: FieldCascade

-- | An action that might happen on a deletion or update on a foreign key
--   change.
data CascadeAction
Cascade :: CascadeAction
Restrict :: CascadeAction
SetNull :: CascadeAction
SetDefault :: CascadeAction


module Database.Persist.FieldDef

-- | 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

-- | Replace the <a>FieldDef</a> <a>FieldAttr</a> with the new list.
setFieldAttrs :: [FieldAttr] -> FieldDef -> FieldDef

-- | Modify the list of field attributes.
overFieldAttrs :: ([FieldAttr] -> [FieldAttr]) -> FieldDef -> FieldDef

-- | Add an attribute to the list of field attributes.
addFieldAttr :: FieldAttr -> FieldDef -> FieldDef

-- | Check if the field definition is nullable
isFieldNullable :: FieldDef -> IsNullable

-- | Check if the field is `Maybe a`
isFieldMaybe :: FieldDef -> Bool
isFieldNotGenerated :: FieldDef -> Bool

-- | Returns <a>True</a> if the <a>FieldDef</a> does not have a
--   <tt>MigrationOnly</tt> or <tt>SafeToRemove</tt> flag from the
--   QuasiQuoter.
isHaskellField :: FieldDef -> Bool

-- | This datatype describes how a foreign reference field cascades deletes
--   or updates.
--   
--   This type is used in both parsing the model definitions and performing
--   migrations. A <a>Nothing</a> in either of the field values means that
--   the user has not specified a <a>CascadeAction</a>. An unspecified
--   <a>CascadeAction</a> is defaulted to <a>Restrict</a> when doing
--   migrations.
data FieldCascade
FieldCascade :: !Maybe CascadeAction -> !Maybe CascadeAction -> FieldCascade
[fcOnUpdate] :: FieldCascade -> !Maybe CascadeAction
[fcOnDelete] :: FieldCascade -> !Maybe CascadeAction

-- | Renders a <a>FieldCascade</a> value such that it can be used in SQL
--   migrations.
renderFieldCascade :: FieldCascade -> Text

-- | Render a <a>CascadeAction</a> to <a>Text</a> such that it can be used
--   in a SQL command.
renderCascadeAction :: CascadeAction -> Text

-- | A <a>FieldCascade</a> that does nothing.
noCascade :: FieldCascade

-- | An action that might happen on a deletion or update on a foreign key
--   change.
data CascadeAction
Cascade :: CascadeAction
Restrict :: CascadeAction
SetNull :: CascadeAction
SetDefault :: CascadeAction


-- | The <a>EntityDef</a> type, fields, and constructor are exported from
--   this module. Breaking changes to the <a>EntityDef</a> type are not
--   reflected in the major version of the API. Please import from
--   <a>Database.Persist.EntityDef</a> instead.
--   
--   If you need this module, please file a GitHub issue why.
module Database.Persist.EntityDef.Internal

-- | 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 :: !EntityNameHS -> !EntityNameDB -> !EntityIdDef -> ![Attr] -> ![FieldDef] -> ![UniqueDef] -> ![ForeignDef] -> ![Text] -> !Map Text [ExtraLine] -> !Bool -> !Maybe Text -> !Maybe SourceSpan -> EntityDef

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

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

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

-- | 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

-- | Source code span occupied by this entity. May be absent if it is not
--   known.
--   
--   Note that until a refactor is completed, these cover the entire
--   persistent parser input rather than the particular entity in question.
[entitySpan] :: EntityDef -> !Maybe SourceSpan
entityPrimary :: EntityDef -> Maybe CompositeDef

-- | Return the <tt>[<a>FieldDef</a>]</tt> for the entity keys.
entitiesPrimary :: EntityDef -> NonEmpty FieldDef

-- | Returns a <a>NonEmpty</a> list of <a>FieldDef</a> that correspond with
--   the key columns for an <a>EntityDef</a>.
keyAndEntityFields :: EntityDef -> NonEmpty FieldDef

-- | Returns a <a>NonEmpty</a> list of <a>FieldDef</a> that correspond with
--   the key columns for an <a>EntityDef</a> including those fields that
--   are marked as <tt>MigrationOnly</tt> (and therefore only present in
--   the database) or <tt>SafeToRemove</tt> (and a migration will drop the
--   column if it exists in the database).
--   
--   For fields on the Haskell type use <a>keyAndEntityFieldsDatabase</a>
keyAndEntityFieldsDatabase :: EntityDef -> NonEmpty FieldDef
toEmbedEntityDef :: EntityDef -> EmbedEntityDef

-- | The definition for the entity's primary key ID.
data EntityIdDef

-- | The entity has a single key column, and it is a surrogate key - that
--   is, you can't go from <tt>rec -&gt; Key rec</tt>.
EntityIdField :: !FieldDef -> EntityIdDef

-- | The entity has a natural key. This means you can write <tt>rec -&gt;
--   Key rec</tt> because all the key fields are present on the datatype.
--   
--   A natural key can have one or more columns.
EntityIdNaturalKey :: !CompositeDef -> EntityIdDef


-- | An <a>EntityDef</a> represents metadata about a type that
--   <tt>persistent</tt> uses to store the type in the database, as well as
--   generate Haskell code from it.
module Database.Persist.EntityDef

-- | 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

-- | Retrieve the Haskell name of the given entity.
getEntityHaskellName :: EntityDef -> EntityNameHS

-- | Return the database name for the given entity.
getEntityDBName :: EntityDef -> EntityNameDB

-- | Retrieve the list of <a>FieldDef</a> that makes up the fields of the
--   entity.
--   
--   This does not return the fields for an <tt>Id</tt> column or an
--   implicit <tt>id</tt>. It will return the key columns if you used the
--   <tt>Primary</tt> syntax for defining the primary key.
--   
--   This does not return fields that are marked <tt>SafeToRemove</tt> or
--   <tt>MigrationOnly</tt> - so it only returns fields that are
--   represented in the Haskell type. If you need those fields, use
--   <a>getEntityFieldsDatabase</a>.
getEntityFields :: EntityDef -> [FieldDef]

-- | This returns all of the <a>FieldDef</a> defined for the
--   <a>EntityDef</a>, including those fields that are marked as
--   <tt>MigrationOnly</tt> (and therefore only present in the database) or
--   <tt>SafeToRemove</tt> (and a migration will drop the column if it
--   exists in the database).
--   
--   For all the fields that are present on the Haskell-type, see
--   <a>getEntityFields</a>.
getEntityFieldsDatabase :: EntityDef -> [FieldDef]

getEntityForeignDefs :: EntityDef -> [ForeignDef]

-- | Retrieve the list of <a>UniqueDef</a> from an <a>EntityDef</a>. As of
--   version 2.14, this will also include the primary key on the entity, if
--   one is defined. If you do not want the primary key, see
--   <a>getEntityUniquesNoPrimaryKey</a>.
getEntityUniques :: EntityDef -> [UniqueDef]

-- | Retrieve the list of <a>UniqueDef</a> from an <a>EntityDef</a>. This
--   does not include a <tt>Primary</tt> key, if one is defined. A future
--   version of <tt>persistent</tt> will include a <tt>Primary</tt> key
--   among the <tt>Unique</tt> constructors for the <tt>Entity</tt>.
getEntityUniquesNoPrimaryKey :: EntityDef -> [UniqueDef]

getEntityId :: EntityDef -> EntityIdDef

getEntityIdField :: EntityDef -> Maybe FieldDef

getEntityKeyFields :: EntityDef -> NonEmpty FieldDef
getEntityComments :: EntityDef -> Maybe Text
getEntityExtra :: EntityDef -> Map Text [[Text]]

-- | Gets the <tt>Source</tt> of the definition of the entity.
--   
--   Note that as of this writing the span covers the entire file or
--   quasiquote where the item is defined due to parsing limitations. This
--   may be changed in a future release to be more accurate.
getEntitySpan :: EntityDef -> Maybe SourceSpan

isEntitySum :: EntityDef -> Bool
entityPrimary :: EntityDef -> Maybe CompositeDef

-- | Return the <tt>[<a>FieldDef</a>]</tt> for the entity keys.
entitiesPrimary :: EntityDef -> NonEmpty FieldDef

-- | Returns a <a>NonEmpty</a> list of <a>FieldDef</a> that correspond with
--   the key columns for an <a>EntityDef</a>.
keyAndEntityFields :: EntityDef -> NonEmpty FieldDef

-- | Returns a <a>NonEmpty</a> list of <a>FieldDef</a> that correspond with
--   the key columns for an <a>EntityDef</a> including those fields that
--   are marked as <tt>MigrationOnly</tt> (and therefore only present in
--   the database) or <tt>SafeToRemove</tt> (and a migration will drop the
--   column if it exists in the database).
--   
--   For fields on the Haskell type use <a>keyAndEntityFieldsDatabase</a>
keyAndEntityFieldsDatabase :: EntityDef -> NonEmpty FieldDef

-- | Set an <a>entityId</a> to be the given <a>FieldDef</a>.
setEntityId :: FieldDef -> EntityDef -> EntityDef

setEntityIdDef :: EntityIdDef -> EntityDef -> EntityDef

setEntityDBName :: EntityNameDB -> EntityDef -> EntityDef

-- | Perform a mapping function over all of the entity fields, as
--   determined by <a>getEntityFieldsDatabase</a>.
overEntityFields :: ([FieldDef] -> [FieldDef]) -> EntityDef -> EntityDef

-- | The definition for the entity's primary key ID.
data EntityIdDef

-- | The entity has a single key column, and it is a surrogate key - that
--   is, you can't go from <tt>rec -&gt; Key rec</tt>.
EntityIdField :: !FieldDef -> EntityIdDef

-- | The entity has a natural key. This means you can write <tt>rec -&gt;
--   Key rec</tt> because all the key fields are present on the datatype.
--   
--   A natural key can have one or more columns.
EntityIdNaturalKey :: !CompositeDef -> EntityIdDef

module Database.Persist.Class.PersistField

-- | 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

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

-- | Prior to <tt>persistent-2.11.0</tt>, we provided an instance of
--   <a>PersistField</a> for the <a>Natural</a> type. This was in error,
--   because <a>Natural</a> represents an infinite value, and databases
--   don't have reasonable types for this.
--   
--   The instance for <a>Natural</a> used the <a>Int64</a> underlying type,
--   which will cause underflow and overflow errors. This type has the
--   exact same code in the instances, and will work seamlessly.
--   
--   A more appropriate type for this is the <a>Word</a> series of types
--   from <a>Data.Word</a>. These have a bounded size, are guaranteed to be
--   non-negative, and are quite efficient for the database to store.
newtype OverflowNatural
OverflowNatural :: Natural -> OverflowNatural
[unOverflowNatural] :: OverflowNatural -> Natural
instance GHC.Classes.Eq Database.Persist.Class.PersistField.OverflowNatural
instance GHC.Internal.Num.Num Database.Persist.Class.PersistField.OverflowNatural
instance GHC.Classes.Ord Database.Persist.Class.PersistField.OverflowNatural
instance Database.Persist.Class.PersistField.PersistField GHC.Types.Bool
instance Database.Persist.Class.PersistField.PersistField Data.ByteString.Internal.Type.ByteString
instance Database.Persist.Class.PersistField.PersistField Database.Persist.Types.Base.Checkmark
instance Database.Persist.Class.PersistField.PersistField Data.Time.Calendar.Days.Day
instance Database.Persist.Class.PersistField.PersistField GHC.Types.Double
instance Data.Fixed.HasResolution a => Database.Persist.Class.PersistField.PersistField (Data.Fixed.Fixed a)
instance Database.Persist.Class.PersistField.PersistField GHC.Types.Int
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Int.Int16
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Int.Int32
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Int.Int64
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Int.Int8
instance Database.Persist.Class.PersistField.PersistField v => Database.Persist.Class.PersistField.PersistField (Data.IntMap.Internal.IntMap v)
instance Database.Persist.Class.PersistField.PersistField [GHC.Types.Char]
instance Database.Persist.Class.PersistField.PersistField a => Database.Persist.Class.PersistField.PersistField [a]
instance Database.Persist.Class.PersistField.PersistField v => Database.Persist.Class.PersistField.PersistField (Data.Map.Internal.Map Data.Text.Internal.Text v)
instance Database.Persist.Class.PersistField.PersistField Text.Blaze.Html.Html
instance Database.Persist.Class.PersistField.PersistField a => Database.Persist.Class.PersistField.PersistField (GHC.Internal.Maybe.Maybe a)
instance (TypeError ...) => Database.Persist.Class.PersistField.PersistField GHC.Num.Natural.Natural
instance Database.Persist.Class.PersistField.PersistField Database.Persist.Class.PersistField.OverflowNatural
instance Database.Persist.Class.PersistField.PersistField Database.Persist.PersistValue.PersistValue
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Real.Rational
instance (GHC.Classes.Ord a, Database.Persist.Class.PersistField.PersistField a) => Database.Persist.Class.PersistField.PersistField (Data.Set.Internal.Set a)
instance Database.Persist.Class.PersistField.PersistField Data.Text.Internal.Lazy.Text
instance Database.Persist.Class.PersistField.PersistField Data.Text.Internal.Text
instance Database.Persist.Class.PersistField.PersistField Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
instance (Database.Persist.Class.PersistField.PersistField a, Database.Persist.Class.PersistField.PersistField b) => Database.Persist.Class.PersistField.PersistField (a, b)
instance Database.Persist.Class.PersistField.PersistField Data.Time.Clock.Internal.UTCTime.UTCTime
instance Database.Persist.Class.PersistField.PersistField a => Database.Persist.Class.PersistField.PersistField (Data.Vector.Vector a)
instance Database.Persist.Class.PersistField.PersistField GHC.Types.Word
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Word.Word16
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Word.Word32
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Word.Word64
instance Database.Persist.Class.PersistField.PersistField GHC.Internal.Word.Word8
instance GHC.Internal.Show.Show Database.Persist.Class.PersistField.OverflowNatural

module Database.Persist.Class.PersistEntity

-- | 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 PersistEntityBackend record;
    
    -- | By default, a backend will automatically generate the key Instead you
    --   can specify a Primary key made up of unique values.
    data Key record;
    
    -- | An <a>EntityField</a> is parameterised by the Haskell record it
    --   belongs to and the additional type of that field.
    --   
    --   As of <tt>persistent-2.11.0.0</tt>, it's possible to use the
    --   <tt>OverloadedLabels</tt> language extension to refer to
    --   <a>EntityField</a> values polymorphically. See the documentation on
    --   <a>SymbolToField</a> for more information.
    data EntityField record :: Type -> Type;
    
    -- | Unique keys besides the <a>Key</a>.
    data 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 => proxy 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 -> [PersistValue]

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

-- | This function allows you to build an <tt><a>Entity</a> a</tt> by
--   specifying an action that returns a value for the field in the
--   callback function. Let's look at an example.
--   
--   <pre>
--   parseFromEnvironmentVariables :: IO (Entity User)
--   parseFromEnvironmentVariables =
--       tabulateEntityA $ \userField -&gt;
--           case userField of
--               UserName -&gt;
--                   getEnv <a>USER_NAME</a>
--               UserAge -&gt; do
--                   ageVar &lt;- getEnv <a>USER_AGE</a>
--                   case readMaybe ageVar of
--                       Just age -&gt;
--                           pure age
--                       Nothing -&gt;
--                           error $ "Failed to parse Age from: " &lt;&gt; ageVar
--               UserAddressId -&gt; do
--                   addressVar &lt;- getEnv <a>USER_ADDRESS_ID</a>
--                   pure $ AddressKey addressVar
--   </pre>
tabulateEntityA :: (PersistEntity record, Applicative f) => (forall a. () => EntityField record a -> f a) -> f (Entity record)

-- | Like <a>tabulateEntityA</a>, but works with any <a>Apply</a> f. This
--   works because all entities have at least one field, and so we can
--   tabulate things into semigroup-like shapes instead.
tabulateEntityApply :: (PersistEntity record, Apply f) => (forall a. () => EntityField record a -> f a) -> f (Entity 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 -> NonEmpty (FieldNameHS, FieldNameDB)

-- | 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 :: Type -> Type). Functor f => (field -> f field) -> Entity record -> f (Entity record)

-- | Extract a <tt><a>Key</a> record</tt> from a <tt>record</tt> value.
--   Currently, this is only defined for entities using the
--   <tt>Primary</tt> syntax for natural/composite keys. In a future
--   version of <tt>persistent</tt> which incorporates the ID directly into
--   the entity, this will always be Just.
keyFromRecordM :: PersistEntity record => Maybe (record -> Key record)

-- | Construct an <tt><a>Entity</a> record</tt> by providing a value for
--   each of the record's fields.
--   
--   These constructions are equivalent:
--   
--   <pre>
--   entityMattConstructor, entityMattTabulate :: Entity User
--   entityMattConstructor =
--       Entity
--           { entityKey = toSqlKey 123
--           , entityVal =
--               User
--                   { userName = <a>Matt</a>
--                   , userAge = 33
--                   }
--           }
--   
--   entityMattTabulate =
--       tabulateEntity $ \case
--           UserId -&gt;
--               toSqlKey 123
--           UserName -&gt;
--               <a>Matt</a>
--           UserAge -&gt;
--               33
--   </pre>
--   
--   This is a specialization of <a>tabulateEntityA</a>, which allows you
--   to construct an <a>Entity</a> by providing an <a>Applicative</a>
--   action for each field instead of a regular function.
tabulateEntity :: PersistEntity record => (forall a. () => EntityField record a -> a) -> Entity record

-- | 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] :: forall typ. typ -> FilterValue typ
[FilterValues] :: forall typ. [typ] -> FilterValue typ
[UnsafeValue] :: forall a typ. PersistField a => a -> FilterValue typ
type family BackendSpecificFilter backend 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.Sql</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

-- | Newtype wrapper for optionally deriving typeclass instances on
--   <a>PersistEntity</a> keys.
newtype ViaPersistEntity record
ViaPersistEntity :: Key record -> ViaPersistEntity record

-- | Textual representation of the record
recordName :: PersistEntity record => record -> Text

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

-- | 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

-- | Convenience function for getting a free <a>PersistField</a> instance
--   from a type with an <a>Enum</a> instance. The function
--   <tt>derivePersistField</tt> from the persistent-template package
--   should generally be preferred. However, if you want to ensure that an
--   <tt>ORDER BY</tt> clause that uses your field will order rows by the
--   data constructor order, this is a better choice.
--   
--   Example usage in combination with <a>fromPersistValueEnum</a>:
--   
--   <pre>
--   data SeverityLevel = Low | Medium | Critical | High
--     deriving (Enum, Bounded)
--   instance PersistField SeverityLevel where
--     fromPersistValue = fromPersistValueEnum
--     toPersistValue = toPersistValueEnum
--   </pre>
toPersistValueEnum :: Enum a => a -> PersistValue

-- | Convenience function for getting a free <a>PersistField</a> instance
--   from a type with an <a>Enum</a> instance. This function also requires
--   a <a>Bounded</a> instance to improve the reporting of errors.
--   
--   Example usage in combination with <a>toPersistValueEnum</a>:
--   
--   <pre>
--   data SeverityLevel = Low | Medium | Critical | High
--     deriving (Enum, Bounded)
--   instance PersistField SeverityLevel where
--     fromPersistValue = fromPersistValueEnum
--     toPersistValue = toPersistValueEnum
--   </pre>
fromPersistValueEnum :: (Enum a, Bounded a) => PersistValue -> Either Text a

-- | This type class is used with the <tt>OverloadedLabels</tt> extension
--   to provide a more convenient means of using the <a>EntityField</a>
--   type. <a>EntityField</a> definitions are prefixed with the type name
--   to avoid ambiguity, but this ambiguity can result in verbose code.
--   
--   If you have a table <tt>User</tt> with a <tt>name Text</tt> field,
--   then the corresponding <a>EntityField</a> is <tt>UserName</tt>. With
--   this, we can write <tt>#name :: <a>EntityField</a> User Text</tt>.
--   
--   What's more fun is that the type is more general: it's actually <tt>
--   #name :: (<a>SymbolToField</a> "name" rec typ) =&gt; EntityField rec
--   typ </tt>
--   
--   Which means it is *polymorphic* over the actual record. This allows
--   you to write code that can be generic over the tables, provided they
--   have the right fields.
class SymbolToField (sym :: Symbol) rec typ | sym rec -> typ
symbolToField :: SymbolToField sym rec typ => EntityField rec typ

-- | A type class which is used to witness that a type is safe to insert
--   into the database without providing a primary key.
--   
--   The <tt>TemplateHaskell</tt> function <tt>mkPersist</tt> will generate
--   instances of this class for any entity that it works on. If the entity
--   has a default primary key, then it provides a regular instance. If the
--   entity has a <tt>Primary</tt> natural key, then this works fine. But
--   if the entity has an <tt>Id</tt> column with no <tt>default=</tt>,
--   then this does a <a>TypeError</a> and forces the user to use
--   <tt>insertKey</tt>.
class SafeToInsert a
type SafeToInsertErrorMessage a = 'Text "The PersistEntity " ':<>: 'ShowType a ':<>: 'Text " does not have a default primary key." ':$$: 'Text "This means that 'insert' will fail with a database error." ':$$: 'Text "Please  provide a default= clause inthe entity definition," ':$$: 'Text "or use 'insertKey' instead to provide one."
instance (GHC.Classes.Eq (Database.Persist.Class.PersistEntity.Key record), GHC.Classes.Eq record) => GHC.Classes.Eq (Database.Persist.Class.PersistEntity.Entity record)
instance (GHC.Internal.Generics.Generic (Database.Persist.Class.PersistEntity.Key record), GHC.Internal.Generics.Generic record) => GHC.Internal.Generics.Generic (Database.Persist.Class.PersistEntity.Entity record)
instance Database.Persist.Class.PersistEntity.SymbolToField sym rec typ => GHC.Internal.OverloadedLabels.IsLabel sym (Database.Persist.Class.PersistEntity.EntityField rec typ)
instance (GHC.Classes.Ord (Database.Persist.Class.PersistEntity.Key record), GHC.Classes.Ord record) => GHC.Classes.Ord (Database.Persist.Class.PersistEntity.Entity record)
instance Database.Persist.Class.PersistEntity.PersistEntity record => Web.PathPieces.PathMultiPiece (Database.Persist.Class.PersistEntity.ViaPersistEntity record)
instance (Database.Persist.Class.PersistEntity.PersistEntity record, Database.Persist.Class.PersistField.PersistField record, Database.Persist.Class.PersistField.PersistField (Database.Persist.Class.PersistEntity.Key record)) => Database.Persist.Class.PersistField.PersistField (Database.Persist.Class.PersistEntity.Entity record)
instance (GHC.Internal.Read.Read (Database.Persist.Class.PersistEntity.Key record), GHC.Internal.Read.Read record) => GHC.Internal.Read.Read (Database.Persist.Class.PersistEntity.Entity record)
instance (TypeError ...) => Database.Persist.Class.PersistEntity.SafeToInsert (Database.Persist.Class.PersistEntity.Entity a)
instance (TypeError ...) => Database.Persist.Class.PersistEntity.SafeToInsert (a -> b)
instance (GHC.Internal.Show.Show (Database.Persist.Class.PersistEntity.Key record), GHC.Internal.Show.Show record) => GHC.Internal.Show.Show (Database.Persist.Class.PersistEntity.Entity record)


-- | This module exports many types and functions for operating on
--   <tt>persistent</tt>'s database representation. It's a bit of a kitchen
--   sink. In the future, this module will be reorganized, and many of the
--   dependent modules will be viewable on their own for easier
--   documentation and organization.
module Database.Persist.Types

-- | 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] :: forall typ. typ -> FilterValue typ
[FilterValues] :: forall typ. [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.Sql</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

-- | Prior to <tt>persistent-2.11.0</tt>, we provided an instance of
--   <a>PersistField</a> for the <a>Natural</a> type. This was in error,
--   because <a>Natural</a> represents an infinite value, and databases
--   don't have reasonable types for this.
--   
--   The instance for <a>Natural</a> used the <a>Int64</a> underlying type,
--   which will cause underflow and overflow errors. This type has the
--   exact same code in the instances, and will work seamlessly.
--   
--   A more appropriate type for this is the <a>Word</a> series of types
--   from <a>Data.Word</a>. These have a bounded size, are guaranteed to be
--   non-negative, and are quite efficient for the database to store.
newtype OverflowNatural
OverflowNatural :: Natural -> OverflowNatural
[unOverflowNatural] :: OverflowNatural -> Natural
fieldAttrsContainsNullable :: [FieldAttr] -> IsNullable

-- | Returns a <a>NonEmpty</a> list of <a>FieldDef</a> that correspond with
--   the key columns for an <a>EntityDef</a>.
keyAndEntityFields :: EntityDef -> NonEmpty FieldDef

-- | Returns a <a>NonEmpty</a> list of <a>FieldDef</a> that correspond with
--   the key columns for an <a>EntityDef</a> including those fields that
--   are marked as <tt>MigrationOnly</tt> (and therefore only present in
--   the database) or <tt>SafeToRemove</tt> (and a migration will drop the
--   column if it exists in the database).
--   
--   For fields on the Haskell type use <a>keyAndEntityFieldsDatabase</a>
keyAndEntityFieldsDatabase :: EntityDef -> NonEmpty FieldDef

-- | A <a>FieldCascade</a> that does nothing.
noCascade :: FieldCascade

-- | Parse raw field attributes into structured form. Any unrecognized
--   attributes will be preserved, identically as they are encountered, as
--   <a>FieldAttrOther</a> values.
parseFieldAttrs :: [Text] -> [FieldAttr]

-- | A type that determines how a backend should handle the literal.
data LiteralType

-- | The accompanying value will be escaped before inserting into the
--   database. This is the correct default choice to use.
Escaped :: LiteralType

-- | The accompanying value will not be escaped when inserting into the
--   database. This is potentially dangerous - use this with care.
Unescaped :: LiteralType

-- | The <a>DbSpecific</a> constructor corresponds to the legacy
--   <a>PersistDbSpecific</a> constructor. We need to keep this around
--   because old databases may have serialized JSON representations that
--   reference this. We don't want to break the ability of a database to
--   load rows.
DbSpecific :: LiteralType

-- | 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

-- | This constructor is used to specify some raw literal value for the
--   backend. The <a>LiteralType</a> value specifies how the value should
--   be escaped. This can be used to make special, custom types avaialable
--   in the back end.
PersistLiteral_ :: LiteralType -> ByteString -> PersistValue

-- | This pattern synonym used to be a data constructor for the
--   <a>PersistValue</a> type. It was changed to be a pattern so that
--   JSON-encoded database values could be parsed into their corresponding
--   values. You should not use this, and instead prefer to pattern match
--   on <a>PersistLiteral_</a> directly.
--   
--   If you use this, it will overlap a patern match on the
--   'PersistLiteral_, <a>PersistLiteral</a>, and
--   <a>PersistLiteralEscaped</a> patterns. If you need to disambiguate
--   between these constructors, pattern match on <a>PersistLiteral_</a>
--   directly.

-- | <i>Deprecated: Deprecated since 2.11 because of inconsistent escaping
--   behavior across backends. The Postgres backend escapes these values,
--   while the MySQL backend does not. If you are using this, please switch
--   to <a>PersistLiteral_</a> and provide a relevant <a>LiteralType</a>
--   for your conversion.</i>
pattern PersistDbSpecific :: ByteString -> PersistValue

-- | This pattern synonym used to be a data constructor on
--   <a>PersistValue</a>, but was changed into a catch-all pattern synonym
--   to allow backwards compatiblity with database types. See the
--   documentation on <a>PersistDbSpecific</a> for more details.
pattern PersistLiteral :: ByteString -> PersistValue

-- | This pattern synonym used to be a data constructor on
--   <a>PersistValue</a>, but was changed into a catch-all pattern synonym
--   to allow backwards compatiblity with database types. See the
--   documentation on <a>PersistDbSpecific</a> for more details.
pattern PersistLiteralEscaped :: ByteString -> PersistValue
type Attr = Text

-- | An action that might happen on a deletion or update on a foreign key
--   change.
data CascadeAction
Cascade :: CascadeAction
Restrict :: CascadeAction
SetNull :: CascadeAction
SetDefault :: CascadeAction

-- | 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 CompositeDef
CompositeDef :: !NonEmpty FieldDef -> ![Attr] -> CompositeDef
[compositeFields] :: CompositeDef -> !NonEmpty FieldDef
[compositeAttrs] :: CompositeDef -> ![Attr]

-- | 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 :: EntityNameHS -> [EmbedFieldDef] -> EmbedEntityDef
[embeddedHaskell] :: EmbedEntityDef -> EntityNameHS
[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 :: FieldNameDB -> Maybe (Either SelfEmbed EntityNameHS) -> EmbedFieldDef
[emFieldDB] :: EmbedFieldDef -> FieldNameDB
[emFieldEmbed] :: EmbedFieldDef -> Maybe (Either SelfEmbed EntityNameHS)
type ExtraLine = [Text]

-- | Attributes that may be attached to fields that can affect migrations
--   and serialization in backend-specific ways.
--   
--   While we endeavor to, we can't forsee all use cases for all backends,
--   and so <a>FieldAttr</a> is extensible through its constructor
--   <a>FieldAttrOther</a>.
data FieldAttr

-- | The <a>Maybe</a> keyword goes after the type. This indicates that the
--   column is nullable, and the generated Haskell code will have a
--   <tt><a>Maybe</a></tt> type for it.
--   
--   Example:
--   
--   <pre>
--   User
--       name Text Maybe
--   </pre>
FieldAttrMaybe :: FieldAttr

-- | This indicates that the column is nullable, but should not have a
--   <a>Maybe</a> type. For this to work out, you need to ensure that the
--   <tt>PersistField</tt> instance for the type in question can support a
--   <a>PersistNull</a> value.
--   
--   <pre>
--   data What = NoWhat | Hello Text
--   
--   instance PersistField What where
--       fromPersistValue PersistNull =
--           pure NoWhat
--       fromPersistValue pv =
--           Hello <a>$</a> fromPersistValue pv
--   
--   instance PersistFieldSql What where
--       sqlType _ = SqlString
--   
--   User
--       what What nullable
--   </pre>
FieldAttrNullable :: FieldAttr

-- | This tag means that the column will not be present on the Haskell
--   code, but will not be removed from the database. Useful to deprecate
--   fields in phases.
--   
--   You should set the column to be nullable in the database. Otherwise,
--   inserts won't have values.
--   
--   <pre>
--   User
--       oldName Text MigrationOnly
--       newName Text
--   </pre>
FieldAttrMigrationOnly :: FieldAttr

-- | A <tt>SafeToRemove</tt> attribute is not present on the Haskell
--   datatype, and the backend migrations should attempt to drop the column
--   without triggering any unsafe migration warnings.
--   
--   Useful after you've used <tt>MigrationOnly</tt> to remove a column
--   from the database in phases.
--   
--   <pre>
--   User
--       oldName Text SafeToRemove
--       newName Text
--   </pre>
FieldAttrSafeToRemove :: FieldAttr

-- | This attribute indicates that we should not create a foreign key
--   reference from a column. By default, <tt>persistent</tt> will try and
--   create a foreign key reference for a column if it can determine that
--   the type of the column is a <tt><tt>Key</tt> entity</tt> or an
--   <tt>EntityId</tt> and the <tt>Entity</tt>'s name was present in
--   <tt>mkPersist</tt>.
--   
--   This is useful if you want to use the explicit foreign key syntax.
--   
--   <pre>
--   Post
--       title    Text
--   
--   Comment
--       postId   PostId      noreference
--       Foreign Post fk_comment_post postId
--   </pre>
FieldAttrNoreference :: FieldAttr

-- | This is set to specify precisely the database table the column refers
--   to.
--   
--   <pre>
--   Post
--       title    Text
--   
--   Comment
--       postId   PostId references="post"
--   </pre>
--   
--   You should not need this - <tt>persistent</tt> should be capable of
--   correctly determining the target table's name. If you do need this,
--   please file an issue describing why.
FieldAttrReference :: Text -> FieldAttr

-- | Specify a name for the constraint on the foreign key reference for
--   this table.
--   
--   <pre>
--   Post
--       title    Text
--   
--   Comment
--       postId   PostId constraint="my_cool_constraint_name"
--   </pre>
FieldAttrConstraint :: Text -> FieldAttr

-- | Specify the default value for a column.
--   
--   <pre>
--   User
--       createdAt    UTCTime     default="NOW()"
--   </pre>
--   
--   Note that a <tt>default=</tt> attribute does not mean you can omit the
--   value while inserting.
FieldAttrDefault :: Text -> FieldAttr

-- | Specify a custom SQL type for the column. Generally, you should define
--   a custom datatype with a custom <tt>PersistFieldSql</tt> instance
--   instead of using this.
--   
--   <pre>
--   User
--       uuid     Text    sqltype=<a>UUID</a>
--   </pre>
FieldAttrSqltype :: Text -> FieldAttr

-- | Set a maximum length for a column. Useful for VARCHAR and indexes.
--   
--   <pre>
--   User
--       name     Text    maxlen=200
--   
--       UniqueName name
--   </pre>
FieldAttrMaxlen :: Integer -> FieldAttr

-- | Specify the database name of the column.
--   
--   <pre>
--   User
--       blarghle     Int     sql="b_l_a_r_g_h_l_e"
--   </pre>
--   
--   Useful for performing phased migrations, where one column is renamed
--   to another column over time.
FieldAttrSql :: Text -> FieldAttr

-- | A grab bag of random attributes that were unrecognized by the parser.
FieldAttrOther :: Text -> FieldAttr

-- | This datatype describes how a foreign reference field cascades deletes
--   or updates.
--   
--   This type is used in both parsing the model definitions and performing
--   migrations. A <a>Nothing</a> in either of the field values means that
--   the user has not specified a <a>CascadeAction</a>. An unspecified
--   <a>CascadeAction</a> is defaulted to <a>Restrict</a> when doing
--   migrations.
data FieldCascade
FieldCascade :: !Maybe CascadeAction -> !Maybe CascadeAction -> FieldCascade
[fcOnUpdate] :: FieldCascade -> !Maybe CascadeAction
[fcOnDelete] :: FieldCascade -> !Maybe CascadeAction

-- | 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 :: !FieldNameHS -> !FieldNameDB -> !FieldType -> !SqlType -> ![FieldAttr] -> !Bool -> !ReferenceDef -> !FieldCascade -> !Maybe Text -> !Maybe Text -> !Bool -> 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>FieldNameHS</a> "name"</tt> for
--   a type <tt>User</tt> will have a record field <tt>userName</tt>.
[fieldHaskell] :: FieldDef -> !FieldNameHS

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

-- | 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 -> ![FieldAttr]

-- | 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

-- | Defines how operations on the field cascade on to the referenced
--   tables. This doesn't have any meaning if the <a>fieldReference</a> is
--   set to <a>NoReference</a> or <a>SelfReference</a>. The cascade option
--   here should be the same as the one obtained in the
--   <a>fieldReference</a>.
[fieldCascade] :: FieldDef -> !FieldCascade

-- | Optional comments for a <tt>Field</tt>.
[fieldComments] :: FieldDef -> !Maybe Text

-- | Whether or not the field is a <tt>GENERATED</tt> column, and
--   additionally the expression to use for generation.
[fieldGenerated] :: FieldDef -> !Maybe Text

-- | <a>True</a> if the field is an implicit ID column. <a>False</a>
--   otherwise.
[fieldIsImplicitIdColumn] :: FieldDef -> !Bool

-- | A <a>FieldType</a> describes a field parsed from the QuasiQuoter and
--   is used to determine the Haskell type in the generated code.
--   
--   <tt>name Text</tt> parses into <tt>FTTypeCon Nothing <a>Text</a></tt>
--   
--   <tt>name T.Text</tt> parses into <tt>FTTypeCon (Just <a>T</a>
--   <a>Text</a>)</tt>
--   
--   <tt>name (Jsonb User)</tt> parses into:
--   
--   <pre>
--   FTApp (FTTypeCon Nothing <a>Jsonb</a>) (FTTypeCon Nothing <a>User</a>)
--   </pre>
data FieldType

-- | Optional module and name.
FTTypeCon :: Maybe Text -> Text -> FieldType
FTLit :: FieldTypeLit -> FieldType
FTTypePromoted :: Text -> FieldType
FTApp :: FieldType -> FieldType -> FieldType
FTList :: FieldType -> FieldType
data ForeignDef
ForeignDef :: !EntityNameHS -> !EntityNameDB -> !ConstraintNameHS -> !ConstraintNameDB -> !FieldCascade -> ![(ForeignFieldDef, ForeignFieldDef)] -> ![Attr] -> Bool -> Bool -> ForeignDef
[foreignRefTableHaskell] :: ForeignDef -> !EntityNameHS
[foreignRefTableDBName] :: ForeignDef -> !EntityNameDB
[foreignConstraintNameHaskell] :: ForeignDef -> !ConstraintNameHS
[foreignConstraintNameDBName] :: ForeignDef -> !ConstraintNameDB

-- | Determine how the field will cascade on updates and deletions.
[foreignFieldCascade] :: ForeignDef -> !FieldCascade
[foreignFields] :: ForeignDef -> ![(ForeignFieldDef, ForeignFieldDef)]
[foreignAttrs] :: ForeignDef -> ![Attr]
[foreignNullable] :: ForeignDef -> Bool

-- | Determines if the reference is towards a Primary Key or not.
[foreignToPrimary] :: ForeignDef -> Bool

-- | Used instead of FieldDef to generate a smaller amount of code
type ForeignFieldDef = (FieldNameHS, FieldNameDB)
data IsNullable
Nullable :: !WhyNullable -> IsNullable
NotNullable :: IsNullable
data PersistException

-- | Generic Exception
PersistError :: Text -> PersistException
PersistMarshalError :: Text -> PersistException
PersistInvalidField :: Text -> PersistException
PersistForeignConstraintUnmet :: Text -> PersistException
PersistMongoDBError :: Text -> PersistException
PersistMongoDBUnsupported :: Text -> PersistException
data PersistFilter
Eq :: PersistFilter
Ne :: PersistFilter
Gt :: PersistFilter
Lt :: PersistFilter
Ge :: PersistFilter
Le :: PersistFilter
In :: PersistFilter
NotIn :: PersistFilter
BackendSpecificFilter :: Text -> PersistFilter
data PersistUpdate
Assign :: PersistUpdate
Add :: PersistUpdate
Subtract :: PersistUpdate
Multiply :: PersistUpdate
Divide :: PersistUpdate
BackendSpecificUpdate :: Text -> PersistUpdate

-- | 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
--   name and has the Haskell type of the foreign key in the form of
--   FieldType
ForeignRef :: !EntityNameHS -> ReferenceDef
EmbedRef :: EntityNameHS -> ReferenceDef

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

-- | 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

-- | Type for storing the Uniqueness constraint in the Schema. Assume you
--   have the following schema with a uniqueness constraint:
--   
--   <pre>
--   Person
--     name String
--     age Int
--     UniqueAge age
--   </pre>
--   
--   This will be represented as:
--   
--   <pre>
--   UniqueDef
--       { uniqueHaskell = ConstraintNameHS (packPTH <a>UniqueAge</a>)
--       , uniqueDBName = ConstraintNameDB (packPTH "unique_age")
--       , uniqueFields = [(FieldNameHS (packPTH "age"), FieldNameDB (packPTH "age"))]
--       , uniqueAttrs = []
--       }
--   </pre>
data UniqueDef
UniqueDef :: !ConstraintNameHS -> !ConstraintNameDB -> !NonEmpty (FieldNameHS, FieldNameDB) -> ![Attr] -> UniqueDef
[uniqueHaskell] :: UniqueDef -> !ConstraintNameHS
[uniqueDBName] :: UniqueDef -> !ConstraintNameDB
[uniqueFields] :: UniqueDef -> !NonEmpty (FieldNameHS, FieldNameDB)
[uniqueAttrs] :: UniqueDef -> ![Attr]
data UpdateException
KeyNotFound :: String -> UpdateException
UpsertError :: String -> UpdateException

-- | 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

module Database.Persist.Quasi.PersistSettings.Internal
data PersistSettings
PersistSettings :: !Text -> Text -> !EntityNameHS -> ConstraintNameHS -> Text -> !Bool -> !Text -> Maybe ParserErrorLevel -> Maybe ParserErrorLevel -> PersistSettings

-- | Modify the Haskell-style name into a database-style name.
[psToDBName] :: PersistSettings -> !Text -> Text

-- | A function for generating the constraint name, with access to the
--   entity and constraint names. Default value: <tt>mappend</tt>
[psToFKName] :: PersistSettings -> !EntityNameHS -> ConstraintNameHS -> 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

-- | Whether and with what severity to disallow tabs in entity source text.
[psTabErrorLevel] :: PersistSettings -> Maybe ParserErrorLevel

-- | Whether and with what severity to disallow quoted entity field
--   attributes and quoted directive arguments.
[psQuotedArgumentErrorLevel] :: PersistSettings -> Maybe ParserErrorLevel
defaultPersistSettings :: PersistSettings
upperCaseSettings :: PersistSettings
lowerCaseSettings :: PersistSettings

data ParserErrorLevel
LevelError :: ParserErrorLevel
LevelWarning :: ParserErrorLevel

data ParserWarning
ParserWarning :: String -> ParseError String Void -> PosState String -> ParserWarning
[parserWarningExtraMessage] :: ParserWarning -> String
[parserWarningUnderlyingError] :: ParserWarning -> ParseError String Void
[parserWarningPosState] :: ParserWarning -> PosState String
warningPos :: ParserWarning -> SourcePos

-- | Uses <tt>errorBundlePretty</tt> to render a parser warning.
parserWarningMessage :: ParserWarning -> String
toFKNameInfixed :: Text -> EntityNameHS -> ConstraintNameHS -> Text

-- | Retrieve the function in the <a>PersistSettings</a> that modifies the
--   names into database names.
getPsToDBName :: PersistSettings -> Text -> Text

-- | Set the name modification function that translates the QuasiQuoted
--   names for use in the database.
setPsToDBName :: (Text -> Text) -> PersistSettings -> PersistSettings

-- | Set a custom function used to create the constraint name for a foreign
--   key.
setPsToFKName :: (EntityNameHS -> ConstraintNameHS -> Text) -> PersistSettings -> PersistSettings

-- | A preset configuration function that puts an underscore between the
--   entity name and the constraint name when creating a foreign key
--   constraint name
setPsUseSnakeCaseForeignKeys :: PersistSettings -> PersistSettings

-- | Equivalent to <a>setPsUseSnakeCaseForeignKeys</a>, but misspelled.

-- | <i>Deprecated: use the correctly spelled, equivalent,
--   setPsUseSnakeCaseForeignKeys instead</i>
setPsUseSnakeCaseForiegnKeys :: PersistSettings -> PersistSettings

-- | Retrieve whether or not the <a>PersistSettings</a> will generate code
--   with strict fields.
getPsStrictFields :: PersistSettings -> Bool

-- | Set whether or not the <a>PersistSettings</a> will make fields strict.
setPsStrictFields :: Bool -> PersistSettings -> PersistSettings

-- | Retrieve the default name of the <tt>id</tt> column.
getPsIdName :: PersistSettings -> Text

-- | Set the default name of the <tt>id</tt> column.
setPsIdName :: Text -> PersistSettings -> PersistSettings

-- | Retrieve the severity of the error generated when the parser
--   encounters a tab. If it is <tt>Nothing</tt>, tabs are permitted in
--   entity definitions.
getPsTabErrorLevel :: PersistSettings -> Maybe ParserErrorLevel

-- | Set the severity of the error generated when the parser encounters a
--   tab. If set to <tt>Nothing</tt>, tabs are permitted in entity
--   definitions.
setPsTabErrorLevel :: Maybe ParserErrorLevel -> PersistSettings -> PersistSettings

-- | Retrieve the severity of the error generated when the parser
--   encounters a quoted entity field attribute or quoted directive
--   argument. If it is <tt>Nothing</tt>, quoted arguments are permitted in
--   both entity field definitions and directives.
getPsQuotedArgumentErrorLevel :: PersistSettings -> Maybe ParserErrorLevel

-- | Set the severity of the error generated when the parser encounters a
--   quoted entity field attribute. If set to <tt>Nothing</tt>, quoted
--   arguments are permitted in both entity field definitions and
--   directives.
setPsQuotedArgumentErrorLevel :: Maybe ParserErrorLevel -> PersistSettings -> PersistSettings
instance GHC.Classes.Eq Database.Persist.Quasi.PersistSettings.Internal.ParserErrorLevel
instance GHC.Classes.Eq Database.Persist.Quasi.PersistSettings.Internal.ParserWarning
instance GHC.Classes.Ord Database.Persist.Quasi.PersistSettings.Internal.ParserWarning
instance GHC.Internal.Show.Show Database.Persist.Quasi.PersistSettings.Internal.ParserErrorLevel
instance GHC.Internal.Show.Show Database.Persist.Quasi.PersistSettings.Internal.ParserWarning

module Database.Persist.Quasi.PersistSettings
data PersistSettings
defaultPersistSettings :: PersistSettings
upperCaseSettings :: PersistSettings
lowerCaseSettings :: PersistSettings

data ParserErrorLevel
LevelError :: ParserErrorLevel
LevelWarning :: ParserErrorLevel

data ParserWarning
warningPos :: ParserWarning -> SourcePos

-- | Uses <tt>errorBundlePretty</tt> to render a parser warning.
parserWarningMessage :: ParserWarning -> String

-- | Retrieve the function in the <a>PersistSettings</a> that modifies the
--   names into database names.
getPsToDBName :: PersistSettings -> Text -> Text

-- | Set the name modification function that translates the QuasiQuoted
--   names for use in the database.
setPsToDBName :: (Text -> Text) -> PersistSettings -> PersistSettings

-- | Set a custom function used to create the constraint name for a foreign
--   key.
setPsToFKName :: (EntityNameHS -> ConstraintNameHS -> Text) -> PersistSettings -> PersistSettings

-- | A preset configuration function that puts an underscore between the
--   entity name and the constraint name when creating a foreign key
--   constraint name
setPsUseSnakeCaseForeignKeys :: PersistSettings -> PersistSettings

-- | Equivalent to <a>setPsUseSnakeCaseForeignKeys</a>, but misspelled.

-- | <i>Deprecated: use the correctly spelled, equivalent,
--   setPsUseSnakeCaseForeignKeys instead</i>
setPsUseSnakeCaseForiegnKeys :: PersistSettings -> PersistSettings

-- | Retrieve whether or not the <a>PersistSettings</a> will generate code
--   with strict fields.
getPsStrictFields :: PersistSettings -> Bool

-- | Set whether or not the <a>PersistSettings</a> will make fields strict.
setPsStrictFields :: Bool -> PersistSettings -> PersistSettings

-- | Retrieve the default name of the <tt>id</tt> column.
getPsIdName :: PersistSettings -> Text

-- | Set the default name of the <tt>id</tt> column.
setPsIdName :: Text -> PersistSettings -> PersistSettings

-- | Retrieve the severity of the error generated when the parser
--   encounters a tab. If it is <tt>Nothing</tt>, tabs are permitted in
--   entity definitions.
getPsTabErrorLevel :: PersistSettings -> Maybe ParserErrorLevel

-- | Set the severity of the error generated when the parser encounters a
--   tab. If set to <tt>Nothing</tt>, tabs are permitted in entity
--   definitions.
setPsTabErrorLevel :: Maybe ParserErrorLevel -> PersistSettings -> PersistSettings

-- | Retrieve the severity of the error generated when the parser
--   encounters a quoted entity field attribute or quoted directive
--   argument. If it is <tt>Nothing</tt>, quoted arguments are permitted in
--   both entity field definitions and directives.
getPsQuotedArgumentErrorLevel :: PersistSettings -> Maybe ParserErrorLevel

-- | Set the severity of the error generated when the parser encounters a
--   quoted entity field attribute. If set to <tt>Nothing</tt>, quoted
--   arguments are permitted in both entity field definitions and
--   directives.
setPsQuotedArgumentErrorLevel :: Maybe ParserErrorLevel -> PersistSettings -> PersistSettings

module Database.Persist.Class.PersistStore

-- | 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 BaseBackend backend;
}
persistBackend :: HasPersistBackend backend => backend -> BaseBackend backend

-- | Run a query against a larger backend by plucking out <tt>BaseBackend
--   backend</tt>
--   
--   This is a helper for reusing existing queries when expanding the
--   backend type.
withBaseBackend :: forall backend (m :: Type -> Type) a. HasPersistBackend backend => ReaderT (BaseBackend backend) m a -> ReaderT backend m a

-- | 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

-- | A convenient alias for common type signatures
type PersistRecordBackend record backend = (PersistEntity record, PersistEntityBackend record ~ BaseBackend backend)
liftPersist :: (MonadIO m, MonadReader backend m) => ReaderT backend IO b -> m b
class PersistCore backend where {
    data BackendKey backend;
}
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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => 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_ :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => 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 :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [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_ :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend) => Key record -> [Update record] -> ReaderT backend m 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 :: forall e backend (m :: Type -> Type). (PersistStoreRead backend, PersistRecordBackend e backend, MonadIO m) => Key e -> ReaderT backend m (Maybe (Entity e))

-- | 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 :: forall record backend (m :: Type -> Type). (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 :: forall record backend (m :: Type -> Type). (PersistEntityBackend record ~ BaseBackend backend, MonadIO m, PersistEntity record, PersistStoreRead backend) => Key record -> ReaderT backend m (Entity record)

-- | Curry this to make a convenience function that loads an associated
--   model.
--   
--   <pre>
--   foreign = belongsTo foreignId
--   </pre>
belongsTo :: forall ent1 ent2 backend (m :: Type -> Type). (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 :: forall ent1 ent2 backend (m :: Type -> Type). (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 :: forall e backend (m :: Type -> Type). (PersistStoreWrite backend, PersistRecordBackend e backend, SafeToInsert e, MonadIO m, HasCallStack) => 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 :: forall record backend (m :: Type -> Type). (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, MonadIO m, PersistStoreWrite backend, SafeToInsert record, HasCallStack) => record -> ReaderT backend m record

-- | <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

-- | 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
--     , <a>PersistEntityBackend</a> 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' = <a>withCompatibleBackend</a> asdf
--   </pre>
class BackendCompatible sup sub
projectBackend :: BackendCompatible sup sub => sub -> sup

-- | Run a query against a compatible backend, by projecting the backend
--   
--   This is a helper for using queries which run against a specific
--   backend type that your backend is compatible with.
withCompatibleBackend :: forall sup sub (m :: Type -> Type) a. BackendCompatible sup sub => ReaderT sup m a -> ReaderT sub m a

module Database.Persist.SqlBackend.Internal

-- | A <a>SqlBackend</a> represents a handle or connection to a database.
--   It contains functions and values that allow databases to have more
--   optimized implementations, as well as references that benefit
--   performance and sharing.
--   
--   Instead of using the <a>SqlBackend</a> constructor directly, use the
--   <a>mkSqlBackend</a> function.
--   
--   A <a>SqlBackend</a> is *not* thread-safe. You should not assume that a
--   <a>SqlBackend</a> can be shared among threads and run concurrent
--   queries. This *will* result in problems. Instead, you should create a
--   <tt><tt>Pool</tt> <a>SqlBackend</a></tt>, known as a
--   <tt>ConnectionPool</tt>, and pass that around in multi-threaded
--   applications.
--   
--   To run actions in the <tt>persistent</tt> library, you should use the
--   <tt>runSqlConn</tt> function. If you're using a multithreaded
--   application, use the <tt>runSqlPool</tt> function.
data SqlBackend
SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> StatementCache -> 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 ()) -> (FieldNameDB -> Text) -> (EntityDef -> Text) -> (Text -> Text) -> Text -> Text -> ((Int, Int) -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> Vault -> SqlBackendHooks -> SqlBackend

-- | This function should prepare a <a>Statement</a> in the target
--   database, which should allow for efficient query reuse.
[connPrepare] :: SqlBackend -> Text -> IO Statement

-- | This function generates the SQL and values necessary for performing an
--   insert against the database.
[connInsertSql] :: SqlBackend -> EntityDef -> [PersistValue] -> InsertSqlResult

-- | SQL for inserting many rows and returning their primary keys, for
--   backends that support this functionality. 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 (FieldNameHS, FieldNameDB) -> 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)

-- | A reference to the cache of statements. <a>Statement</a>s are keyed by
--   the <a>Text</a> queries that generated them.
[connStmtMap] :: SqlBackend -> StatementCache

-- | Close the underlying connection.
[connClose] :: SqlBackend -> IO ()

-- | This function returns the migrations required to include the
--   <a>EntityDef</a> parameter in the <tt>[<a>EntityDef</a>]</tt>
--   database. This might include creating a new table if the entity is not
--   present, or altering an existing table if it is.
[connMigrateSql] :: SqlBackend -> [EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])

-- | A function to begin a transaction for the underlying database.
[connBegin] :: SqlBackend -> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()

-- | A function to commit a transaction to the underlying database.
[connCommit] :: SqlBackend -> (Text -> IO Statement) -> IO ()

-- | A function to roll back a transaction on the underlying database.
[connRollback] :: SqlBackend -> (Text -> IO Statement) -> IO ()

-- | A function to extract and escape the name of the column corresponding
--   to the provided field.
[connEscapeFieldName] :: SqlBackend -> FieldNameDB -> Text

-- | A function to extract and escape the name of the table corresponding
--   to the provided entity. PostgreSQL uses this to support schemas.
[connEscapeTableName] :: SqlBackend -> EntityDef -> Text

-- | A function to escape raw DB identifiers. MySQL uses backticks, while
--   PostgreSQL uses quotes, and so on.
[connEscapeRawName] :: SqlBackend -> Text -> Text
[connNoLimit] :: SqlBackend -> Text

-- | A tag displaying what database the <a>SqlBackend</a> is for. Can be
--   used to differentiate features in downstream libraries for different
--   database backends.
[connRDBMS] :: SqlBackend -> Text

-- | Attach a 'LIMIT/OFFSET' clause to a SQL query. Note that LIMIT/OFFSET
--   is problematic for performance, and indexed range queries are the
--   superior way to offer pagination.
[connLimitOffset] :: SqlBackend -> (Int, Int) -> Text -> Text

-- | A log function for the <a>SqlBackend</a> to use.
[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)

-- | Carry arbitrary payloads for the connection that may be used to
--   propagate information into hooks.
[connVault] :: SqlBackend -> Vault

-- | Instrumentation hooks that may be used to track the behaviour of a
--   backend.
[connHooks] :: SqlBackend -> SqlBackendHooks
newtype SqlBackendHooks
SqlBackendHooks :: (SqlBackend -> Text -> Statement -> IO Statement) -> SqlBackendHooks
[hookGetStatement] :: SqlBackendHooks -> SqlBackend -> Text -> Statement -> IO Statement
emptySqlBackendHooks :: SqlBackendHooks

-- | A function for creating a value of the <a>SqlBackend</a> type. You
--   should prefer to use this instead of the constructor for
--   <a>SqlBackend</a>, because default values for this will be provided
--   for new fields on the record when new functionality is added.
mkSqlBackend :: MkSqlBackendArgs -> SqlBackend
instance Database.Persist.Class.PersistStore.HasPersistBackend Database.Persist.SqlBackend.Internal.SqlBackend
instance Database.Persist.Class.PersistStore.IsPersistBackend Database.Persist.SqlBackend.Internal.SqlBackend


-- | This module contains types and information necessary for a SQL
--   database. Database support libraries, like
--   <tt>persistent-postgresql</tt>, will be responsible for constructing
--   these values.
module Database.Persist.SqlBackend

-- | A <a>SqlBackend</a> represents a handle or connection to a database.
--   It contains functions and values that allow databases to have more
--   optimized implementations, as well as references that benefit
--   performance and sharing.
--   
--   Instead of using the <a>SqlBackend</a> constructor directly, use the
--   <a>mkSqlBackend</a> function.
--   
--   A <a>SqlBackend</a> is *not* thread-safe. You should not assume that a
--   <a>SqlBackend</a> can be shared among threads and run concurrent
--   queries. This *will* result in problems. Instead, you should create a
--   <tt><tt>Pool</tt> <a>SqlBackend</a></tt>, known as a
--   <tt>ConnectionPool</tt>, and pass that around in multi-threaded
--   applications.
--   
--   To run actions in the <tt>persistent</tt> library, you should use the
--   <tt>runSqlConn</tt> function. If you're using a multithreaded
--   application, use the <tt>runSqlPool</tt> function.
data SqlBackend

-- | A function for creating a value of the <a>SqlBackend</a> type. You
--   should prefer to use this instead of the constructor for
--   <a>SqlBackend</a>, because default values for this will be provided
--   for new fields on the record when new functionality is added.
mkSqlBackend :: MkSqlBackendArgs -> SqlBackend

-- | This type shares many of the same field names as the
--   <tt>SqlBackend</tt> type. It's useful for library authors to use this
--   when migrating from using the <tt>SqlBackend</tt> constructor directly
--   to the <tt>mkSqlBackend</tt> function.
--   
--   This type will only contain required fields for constructing a
--   <tt>SqlBackend</tt>. For fields that aren't present on this record,
--   you'll want to use the various <tt>set</tt> functions or
data MkSqlBackendArgs
MkSqlBackendArgs :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> 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 ()) -> (FieldNameDB -> Text) -> (EntityDef -> Text) -> (Text -> Text) -> Text -> Text -> ((Int, Int) -> Text -> Text) -> LogFunc -> MkSqlBackendArgs

-- | This function should prepare a <a>Statement</a> in the target
--   database, which should allow for efficient query reuse.
[connPrepare] :: MkSqlBackendArgs -> Text -> IO Statement

-- | This function generates the SQL and values necessary for performing an
--   insert against the database.
[connInsertSql] :: MkSqlBackendArgs -> EntityDef -> [PersistValue] -> InsertSqlResult

-- | A reference to the cache of statements. <a>Statement</a>s are keyed by
--   the <a>Text</a> queries that generated them.
[connStmtMap] :: MkSqlBackendArgs -> IORef (Map Text Statement)

-- | Close the underlying connection.
[connClose] :: MkSqlBackendArgs -> IO ()

-- | This function returns the migrations required to include the
--   <a>EntityDef</a> parameter in the <tt>[<a>EntityDef</a>]</tt>
--   database. This might include creating a new table if the entity is not
--   present, or altering an existing table if it is.
[connMigrateSql] :: MkSqlBackendArgs -> [EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])

-- | A function to begin a transaction for the underlying database.
[connBegin] :: MkSqlBackendArgs -> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()

-- | A function to commit a transaction to the underlying database.
[connCommit] :: MkSqlBackendArgs -> (Text -> IO Statement) -> IO ()

-- | A function to roll back a transaction on the underlying database.
[connRollback] :: MkSqlBackendArgs -> (Text -> IO Statement) -> IO ()

-- | A function to extract and escape the name of the column corresponding
--   to the provided field.
[connEscapeFieldName] :: MkSqlBackendArgs -> FieldNameDB -> Text

-- | A function to extract and escape the name of the table corresponding
--   to the provided entity. PostgreSQL uses this to support schemas.
[connEscapeTableName] :: MkSqlBackendArgs -> EntityDef -> Text

-- | A function to escape raw DB identifiers. MySQL uses backticks, while
--   PostgreSQL uses quotes, and so on.
[connEscapeRawName] :: MkSqlBackendArgs -> Text -> Text
[connNoLimit] :: MkSqlBackendArgs -> Text

-- | A tag displaying what database the <tt>SqlBackend</tt> is for. Can be
--   used to differentiate features in downstream libraries for different
--   database backends.
[connRDBMS] :: MkSqlBackendArgs -> Text

-- | Attach a 'LIMIT/OFFSET' clause to a SQL query. Note that LIMIT/OFFSET
--   is problematic for performance, and indexed range queries are the
--   superior way to offer pagination.
[connLimitOffset] :: MkSqlBackendArgs -> (Int, Int) -> Text -> Text

-- | A log function for the <tt>SqlBackend</tt> to use.
[connLogFunc] :: MkSqlBackendArgs -> LogFunc
data SqlBackendHooks
emptySqlBackendHooks :: SqlBackendHooks

-- | Get a tag displaying what database the <a>SqlBackend</a> is for. Can
--   be used to differentiate features in downstream libraries for
--   different database backends. @since 2.13.3.0
getRDBMS :: (BackendCompatible SqlBackend backend, MonadReader backend m) => m Text

-- | This function can be used directly with a <a>SqlBackend</a> to escape
--   a <a>FieldNameDB</a>.
--   
--   <pre>
--   let conn :: SqlBackend
--   getEscapedFieldName (FieldNameDB "asdf") conn
--   </pre>
--   
--   Alternatively, you can use it in a <tt><a>ReaderT</a>
--   <a>SqlBackend</a></tt> context, like <tt>SqlPersistT</tt>:
--   
--   <pre>
--   query :: SqlPersistM Text
--   query = do
--       field &lt;- getEscapedFieldName (FieldNameDB "asdf")
--       pure field
--   </pre>
getEscapedFieldName :: (BackendCompatible SqlBackend backend, MonadReader backend m) => FieldNameDB -> m Text

-- | This function can be used directly with a <a>SqlBackend</a> to escape
--   a raw <a>Text</a>.
--   
--   <pre>
--   let conn :: SqlBackend
--   getEscapedRawName (FieldNameDB "asdf") conn
--   </pre>
--   
--   Alternatively, you can use it in a <tt><a>ReaderT</a>
--   <a>SqlBackend</a></tt> context, like <tt>SqlPersistT</tt>:
--   
--   <pre>
--   query :: SqlPersistM Text
--   query = do
--       field &lt;- getEscapedRawName (FieldNameDB "asdf")
--       pure field
--   </pre>
getEscapedRawName :: (BackendCompatible SqlBackend backend, MonadReader backend m) => Text -> m Text

-- | Return the function for escaping a raw name.
getEscapeRawNameFunction :: (BackendCompatible SqlBackend backend, MonadReader backend m) => m (Text -> Text)

-- | Decorate the given SQL query with the <tt>(LIMIT, OFFSET)</tt>
--   specified.
getConnLimitOffset :: (BackendCompatible SqlBackend backend, MonadReader backend m) => (Int, Int) -> Text -> m Text

-- | Retrieve the function for generating an upsert statement, if the
--   backend supports it.
getConnUpsertSql :: (BackendCompatible SqlBackend backend, MonadReader backend m) => m (Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text))

-- | Retrieve the vault from the provided database backend.
getConnVault :: (BackendCompatible SqlBackend backend, MonadReader backend m) => m Vault

-- | Retrieve instrumentation hooks from the provided database backend.
getConnHooks :: (BackendCompatible SqlBackend backend, MonadReader backend m) => m SqlBackendHooks

-- | Set the maximum parameters that may be issued in a given SQL query.
--   This should be used only if the database backend have this limitation.
setConnMaxParams :: Int -> SqlBackend -> SqlBackend

-- | Set the <a>connRepsertManySql</a> field on the <a>SqlBackend</a>. This
--   should only be set by the database backend library. If this is not
--   set, a slow default will be used.
setConnRepsertManySql :: (EntityDef -> Int -> Text) -> SqlBackend -> SqlBackend

-- | Set the <a>connInsertManySql</a> field on the <a>SqlBackend</a>. This
--   should only be used by the database backend library to provide an
--   efficient implementation of a bulk insert function. If this is not
--   set, a slow default will be used.
setConnInsertManySql :: (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> SqlBackend -> SqlBackend

-- | Set the <a>connUpsertSql</a> field on the <a>SqlBackend</a>. This
--   should only be used by the database backend library to provide an
--   efficient implementation of a bulk insert function. If this is not
--   set, a slow default will be used.
setConnUpsertSql :: (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text) -> SqlBackend -> SqlBackend

-- | Set the 'connPutManySql field on the <a>SqlBackend</a>. This should
--   only be used by the database backend library to provide an efficient
--   implementation of a bulk insert function. If this is not set, a slow
--   default will be used.
setConnPutManySql :: (EntityDef -> Int -> Text) -> SqlBackend -> SqlBackend

-- | Set the vault on the provided database backend.
setConnVault :: Vault -> SqlBackend -> SqlBackend

-- | Modify the vault on the provided database backend.
modifyConnVault :: (Vault -> Vault) -> SqlBackend -> SqlBackend

-- | Set hooks on the provided database backend.
setConnHooks :: SqlBackendHooks -> SqlBackend -> SqlBackend

module Database.Persist.Class.PersistUnique

-- | 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 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 :: forall record (m :: Type -> Type). (PersistUniqueRead backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m (Maybe (Entity record))

-- | Returns True if a record with this unique key exists, otherwise False.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>:
--   
--   <pre>
--   existsBySpjName :: MonadIO m  =&gt; ReaderT SqlBackend m Bool
--   existsBySpjName = existsBy $ UniqueUserName "SPJ"
--   </pre>
--   
--   <pre>
--   spjEntExists &lt;- existsBySpjName
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will return the
--   value True.
existsBy :: forall record (m :: Type -> Type). (PersistUniqueRead backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m Bool

-- | 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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Maybe (Key record))

-- | Same as <a>insertUnique</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>, 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_ :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Maybe ())

-- | 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) updates
--   </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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record, SafeToInsert 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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => 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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [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

-- | Given a proxy for a <a>PersistEntity</a> record, this returns the sole
--   <a>UniqueDef</a> for that entity.
onlyOneUniqueDef :: (OnlyOneUniqueKey record, Monad proxy) => proxy record -> UniqueDef

-- | 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)

-- | Given a proxy for a record that has an instance of
--   <a>AtLeastOneUniqueKey</a>, this returns a <a>NonEmpty</a> list of the
--   <a>UniqueDef</a>s for that entity.
atLeastOneUniqueDef :: (AtLeastOneUniqueKey record, Monad proxy) => proxy record -> NonEmpty UniqueDef

-- | 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 :: Type -> Type) backend. (MonadIO m, PersistUniqueRead backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record) => record -> ReaderT backend m (Maybe (Entity record))

-- | Retrieve a record from the database using the given unique keys. It
--   will attempt to find a matching record for each <a>Unique</a> in the
--   list, and returns the first one that has a match.
--   
--   Returns <a>Nothing</a> if you provide an empty list ('[]') or if no
--   value matches in the database.
getByValueUniques :: forall record backend (m :: Type -> Type). (MonadIO m, PersistUniqueRead backend, PersistRecordBackend record backend) => [Unique 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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record, SafeToInsert 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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistRecordBackend record backend, PersistUniqueWrite backend, SafeToInsert record) => 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 :: forall record backend (m :: Type -> Type). (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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistRecordBackend record backend, PersistUniqueRead backend) => 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 stay unique, and could thus
--   safely be updated. on a conflict returns the conflicting key
--   
--   This is similar to <a>checkUnique</a>, except it's useful for updating
--   - when the particular entity already exists, it would normally
--   conflict with itself. This variant ignores those conflicts
--   
--   <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>
checkUniqueUpdateable :: forall record backend (m :: Type -> Type). (MonadIO m, PersistRecordBackend record backend, PersistUniqueRead backend) => Entity 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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend, OnlyOneUniqueKey record) => record -> ReaderT backend m (Unique record)

-- | The slow but generic <a>upsertBy</a> implementation for any
--   <a>PersistUniqueRead</a>. * Lookup corresponding entities (if any)
--   <a>getBy</a>. * If the record exists, update using <a>updateGet</a>. *
--   If it does not exist, insert using <a>insertEntity</a>. @since 2.11
defaultUpsertBy :: forall record backend (m :: Type -> Type). (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, MonadIO m, PersistStoreWrite backend, PersistUniqueRead backend, SafeToInsert record) => Unique record -> record -> [Update record] -> ReaderT backend m (Entity record)

-- | The slow but generic <a>putMany</a> implementation for any
--   <a>PersistUniqueRead</a>. * Lookup corresponding entities (if any) for
--   each record using <a>getByValue</a> * For pre-existing records, issue
--   a <a>replace</a> for each old key and new record * For new records,
--   issue a bulk <a>insertMany_</a>
defaultPutMany :: forall record backend (m :: Type -> Type). (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, MonadIO m, PersistStoreWrite backend, PersistUniqueRead backend, SafeToInsert record) => [record] -> ReaderT backend m ()

-- | This function returns a list of <a>PersistValue</a> that correspond to
--   the <a>Unique</a> keys on that record. This is useful for comparing
--   two <tt>record</tt>s for equality only on the basis of their
--   <a>Unique</a> keys.
persistUniqueKeyValues :: PersistEntity record => record -> [PersistValue]

module Database.Persist.Class.PersistQuery

-- | Returns a <tt>[<a>Entity</a> record]</tt> corresponding to the filters
--   and options provided.
--   
--   Filters are constructed using the operators defined in
--   <a>Database.Persist</a> (and re-exported from
--   <a>Database.Persist.Sql</a>). Let's look at some examples:
--   
--   <pre>
--   usersWithAgeOver40 :: <tt>SqlPersistT</tt> <a>IO</a> [<a>Entity</a> User]
--   usersWithAgeOver40 =
--       <a>selectList</a> [UserAge <a>&gt;=.</a> 40] []
--   </pre>
--   
--   If you provide multiple values in the list, the conditions are
--   <tt>AND</tt>ed together.
--   
--   <pre>
--   usersWithAgeBetween30And50 :: <tt>SqlPersistT</tt> <a>IO</a> [<a>Entity</a> User]
--   usersWithAgeBetween30And50 =
--        <a>selectList</a>
--            [ UserAge <a>&gt;=.</a> 30
--            , UserAge <a>&lt;=.</a> 50
--            ]
--            []
--   </pre>
--   
--   The second list contains the <a>SelectOpt</a> for a record. We can
--   select the first ten records with <a>LimitTo</a>
--   
--   <pre>
--   firstTenUsers =
--       <a>selectList</a> [] [<a>LimitTo</a> 10]
--   </pre>
--   
--   And we can select the second ten users with <a>OffsetBy</a>.
--   
--   <pre>
--   secondTenUsers =
--       <a>selectList</a> [] [<a>LimitTo</a> 10, <a>OffsetBy</a> 10]
--   </pre>
--   
--   <a>Warning that LIMIT/OFFSET is bad for pagination!</a>
--   
--   The type of record can usually be infered from the types of the
--   provided filters and select options. In the previous two examples,
--   though, you'll notice that the select options are polymorphic,
--   applying to any record type. In order to help type inference in such
--   situations, or simply as an enhancement to readability, you might find
--   type application useful, illustrated below.
--   
--   <pre>
--   {-# LANGUAGE TypeApplications #-}
--   ...
--   
--   firstTenUsers =
--       <a>selectList</a> <tt>User [] [<a>LimitTo</a> 10]
--   
--   secondTenUsers =
--       <a>selectList</a> </tt>User [] [<a>LimitTo</a> 10, <a>OffsetBy</a> 10]
--   </pre>
--   
--   With <a>Asc</a> and <a>Desc</a>, we can provide the field we want to
--   sort on. We can provide multiple sort orders - later ones are used to
--   sort records that are equal on the first field.
--   
--   <pre>
--   newestUsers =
--       selectList [] [<a>Desc</a> UserCreatedAt, <a>LimitTo</a> 10]
--   
--   oldestUsers =
--       selectList [] [<a>Asc</a> UserCreatedAt, <a>LimitTo</a> 10]
--   </pre>
selectList :: forall record backend (m :: Type -> Type). (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m [Entity record]

-- | 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.
--   
--   NOTE: This function returns an <a>Acquire</a> and a <a>ConduitM</a>,
--   which implies that it streams from the database. It does not. Please
--   use <a>selectList</a> to simplify the code. If you want streaming
--   behavior, consider <tt>persistent-pagination</tt> which efficiently
--   chunks a query into ranges, or investigate a backend-specific
--   streaming solution.
selectSourceRes :: forall record (m1 :: Type -> Type) (m2 :: Type -> Type). (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 :: forall (m :: Type -> Type) record. (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 :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) record. (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 :: forall (m :: Type -> Type) record. (PersistQueryRead backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m Int

-- | Check if there is at least one record fulfilling the given criterion.
exists :: forall (m :: Type -> Type) record. (PersistQueryRead backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m Bool

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

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

-- | Delete all records matching the given criterion.
deleteWhere :: forall (m :: Type -> Type) record. (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.
--   
--   WARNING: This function returns a <a>ConduitM</a>, which suggests that
--   it streams the results. It does not stream results on most backends.
--   If you need streaming, see <tt>persistent-pagination</tt> for a means
--   of chunking results based on indexed ranges.
selectSource :: forall record backend (m :: Type -> Type). (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.
--   
--   For an example, see <a>selectList</a>.
selectKeys :: forall record backend (m :: Type -> Type). (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m) => [Filter record] -> [SelectOpt record] -> ConduitM () (Key record) m ()

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


-- | This module exports all of the type classes in <tt>persistent</tt> for
--   operating on the database backends.
--   
--   <tt>persistent</tt> offers methods that are abstract in the specific
--   <tt>backend</tt> type. For SQL databases, this wil be
--   <a>SqlBackend</a>. Other database backends will define their own
--   types.
--   
--   Methods and functions in this module have examples documented under an
--   "Example Usage" thing, that you need to click on to expand.
module Database.Persist.Class

-- | 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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => 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_ :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => 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 :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [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_ :: forall record (m :: Type -> Type). (PersistStoreWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (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 :: forall record backend (m :: Type -> Type). (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 :: forall record backend (m :: Type -> Type). (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 :: forall e backend (m :: Type -> Type). (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 :: forall ent1 ent2 backend (m :: Type -> Type). (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 :: forall ent1 ent2 backend (m :: Type -> Type). (PersistStoreRead backend, PersistEntity ent1, PersistRecordBackend ent2 backend, MonadIO m) => (ent1 -> Key ent2) -> ent1 -> ReaderT backend m ent2

-- | A type class which is used to witness that a type is safe to insert
--   into the database without providing a primary key.
--   
--   The <tt>TemplateHaskell</tt> function <tt>mkPersist</tt> will generate
--   instances of this class for any entity that it works on. If the entity
--   has a default primary key, then it provides a regular instance. If the
--   entity has a <tt>Primary</tt> natural key, then this works fine. But
--   if the entity has an <tt>Id</tt> column with no <tt>default=</tt>,
--   then this does a <a>TypeError</a> and forces the user to use
--   <tt>insertKey</tt>.
class SafeToInsert a

-- | 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 :: forall e backend (m :: Type -> Type). (PersistStoreWrite backend, PersistRecordBackend e backend, SafeToInsert e, MonadIO m, HasCallStack) => 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 :: forall record backend (m :: Type -> Type). (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, MonadIO m, PersistStoreWrite backend, SafeToInsert record, HasCallStack) => 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 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 :: forall record (m :: Type -> Type). (PersistUniqueRead backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m (Maybe (Entity record))

-- | Returns True if a record with this unique key exists, otherwise False.
--   
--   <h3><b>Example usage</b></h3>
--   
--   With <a>schema-1</a> and <a>dataset-1</a>:
--   
--   <pre>
--   existsBySpjName :: MonadIO m  =&gt; ReaderT SqlBackend m Bool
--   existsBySpjName = existsBy $ UniqueUserName "SPJ"
--   </pre>
--   
--   <pre>
--   spjEntExists &lt;- existsBySpjName
--   </pre>
--   
--   The above query when applied on <a>dataset-1</a>, will return the
--   value True.
existsBy :: forall record (m :: Type -> Type). (PersistUniqueRead backend, MonadIO m, PersistRecordBackend record backend) => Unique record -> ReaderT backend m Bool

-- | 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 :: forall record (m :: Type -> Type). (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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Maybe (Key record))

-- | Same as <a>insertUnique</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>, 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_ :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => record -> ReaderT backend m (Maybe ())

-- | 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) updates
--   </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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record, SafeToInsert 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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => 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 :: forall record (m :: Type -> Type). (PersistUniqueWrite backend, MonadIO m, PersistRecordBackend record backend, SafeToInsert record) => [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)

-- | Given a proxy for a <a>PersistEntity</a> record, this returns the sole
--   <a>UniqueDef</a> for that entity.
onlyOneUniqueDef :: (OnlyOneUniqueKey record, Monad proxy) => proxy record -> UniqueDef

-- | 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 :: Type -> Type) 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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record, SafeToInsert 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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistRecordBackend record backend, PersistUniqueWrite backend, SafeToInsert record) => 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 :: forall record backend (m :: Type -> Type). (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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistRecordBackend record backend, PersistUniqueRead backend) => 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 stay unique, and could thus
--   safely be updated. on a conflict returns the conflicting key
--   
--   This is similar to <a>checkUnique</a>, except it's useful for updating
--   - when the particular entity already exists, it would normally
--   conflict with itself. This variant ignores those conflicts
--   
--   <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>
checkUniqueUpdateable :: forall record backend (m :: Type -> Type). (MonadIO m, PersistRecordBackend record backend, PersistUniqueRead backend) => Entity 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 :: forall record backend (m :: Type -> Type). (MonadIO m, PersistUniqueWrite backend, PersistRecordBackend record backend, OnlyOneUniqueKey record) => record -> ReaderT backend m (Unique record)

-- | Returns a <tt>[<a>Entity</a> record]</tt> corresponding to the filters
--   and options provided.
--   
--   Filters are constructed using the operators defined in
--   <a>Database.Persist</a> (and re-exported from
--   <a>Database.Persist.Sql</a>). Let's look at some examples:
--   
--   <pre>
--   usersWithAgeOver40 :: <tt>SqlPersistT</tt> <a>IO</a> [<a>Entity</a> User]
--   usersWithAgeOver40 =
--       <a>selectList</a> [UserAge <a>&gt;=.</a> 40] []
--   </pre>
--   
--   If you provide multiple values in the list, the conditions are
--   <tt>AND</tt>ed together.
--   
--   <pre>
--   usersWithAgeBetween30And50 :: <tt>SqlPersistT</tt> <a>IO</a> [<a>Entity</a> User]
--   usersWithAgeBetween30And50 =
--        <a>selectList</a>
--            [ UserAge <a>&gt;=.</a> 30
--            , UserAge <a>&lt;=.</a> 50
--            ]
--            []
--   </pre>
--   
--   The second list contains the <a>SelectOpt</a> for a record. We can
--   select the first ten records with <a>LimitTo</a>
--   
--   <pre>
--   firstTenUsers =
--       <a>selectList</a> [] [<a>LimitTo</a> 10]
--   </pre>
--   
--   And we can select the second ten users with <a>OffsetBy</a>.
--   
--   <pre>
--   secondTenUsers =
--       <a>selectList</a> [] [<a>LimitTo</a> 10, <a>OffsetBy</a> 10]
--   </pre>
--   
--   <a>Warning that LIMIT/OFFSET is bad for pagination!</a>
--   
--   The type of record can usually be infered from the types of the
--   provided filters and select options. In the previous two examples,
--   though, you'll notice that the select options are polymorphic,
--   applying to any record type. In order to help type inference in such
--   situations, or simply as an enhancement to readability, you might find
--   type application useful, illustrated below.
--   
--   <pre>
--   {-# LANGUAGE TypeApplications #-}
--   ...
--   
--   firstTenUsers =
--       <a>selectList</a> <tt>User [] [<a>LimitTo</a> 10]
--   
--   secondTenUsers =
--       <a>selectList</a> </tt>User [] [<a>LimitTo</a> 10, <a>OffsetBy</a> 10]
--   </pre>
--   
--   With <a>Asc</a> and <a>Desc</a>, we can provide the field we want to
--   sort on. We can provide multiple sort orders - later ones are used to
--   sort records that are equal on the first field.
--   
--   <pre>
--   newestUsers =
--       selectList [] [<a>Desc</a> UserCreatedAt, <a>LimitTo</a> 10]
--   
--   oldestUsers =
--       selectList [] [<a>Asc</a> UserCreatedAt, <a>LimitTo</a> 10]
--   </pre>
selectList :: forall record backend (m :: Type -> Type). (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend) => [Filter record] -> [SelectOpt record] -> ReaderT backend m [Entity record]

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

-- | 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.
--   
--   NOTE: This function returns an <a>Acquire</a> and a <a>ConduitM</a>,
--   which implies that it streams from the database. It does not. Please
--   use <a>selectList</a> to simplify the code. If you want streaming
--   behavior, consider <tt>persistent-pagination</tt> which efficiently
--   chunks a query into ranges, or investigate a backend-specific
--   streaming solution.
selectSourceRes :: forall record (m1 :: Type -> Type) (m2 :: Type -> Type). (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 :: forall (m :: Type -> Type) record. (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 :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) record. (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 :: forall (m :: Type -> Type) record. (PersistQueryRead backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m Int

-- | Check if there is at least one record fulfilling the given criterion.
exists :: forall (m :: Type -> Type) record. (PersistQueryRead backend, MonadIO m, PersistRecordBackend record backend) => [Filter record] -> ReaderT backend m Bool

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

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

-- | Delete all records matching the given criterion.
deleteWhere :: forall (m :: Type -> Type) record. (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.
--   
--   WARNING: This function returns a <a>ConduitM</a>, which suggests that
--   it streams the results. It does not stream results on most backends.
--   If you need streaming, see <tt>persistent-pagination</tt> for a means
--   of chunking results based on indexed ranges.
selectSource :: forall record backend (m :: Type -> Type). (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m) => [Filter record] -> [SelectOpt record] -> ConduitM () (Entity record) m ()

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

-- | 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 PersistEntityBackend record;
    
    -- | By default, a backend will automatically generate the key Instead you
    --   can specify a Primary key made up of unique values.
    data Key record;
    
    -- | An <a>EntityField</a> is parameterised by the Haskell record it
    --   belongs to and the additional type of that field.
    --   
    --   As of <tt>persistent-2.11.0.0</tt>, it's possible to use the
    --   <tt>OverloadedLabels</tt> language extension to refer to
    --   <a>EntityField</a> values polymorphically. See the documentation on
    --   <a>SymbolToField</a> for more information.
    data EntityField record :: Type -> Type;
    
    -- | Unique keys besides the <a>Key</a>.
    data 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 => proxy 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 -> [PersistValue]

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

-- | This function allows you to build an <tt><a>Entity</a> a</tt> by
--   specifying an action that returns a value for the field in the
--   callback function. Let's look at an example.
--   
--   <pre>
--   parseFromEnvironmentVariables :: IO (Entity User)
--   parseFromEnvironmentVariables =
--       tabulateEntityA $ \userField -&gt;
--           case userField of
--               UserName -&gt;
--                   getEnv <a>USER_NAME</a>
--               UserAge -&gt; do
--                   ageVar &lt;- getEnv <a>USER_AGE</a>
--                   case readMaybe ageVar of
--                       Just age -&gt;
--                           pure age
--                       Nothing -&gt;
--                           error $ "Failed to parse Age from: " &lt;&gt; ageVar
--               UserAddressId -&gt; do
--                   addressVar &lt;- getEnv <a>USER_ADDRESS_ID</a>
--                   pure $ AddressKey addressVar
--   </pre>
tabulateEntityA :: (PersistEntity record, Applicative f) => (forall a. () => EntityField record a -> f a) -> f (Entity record)

-- | Like <a>tabulateEntityA</a>, but works with any <a>Apply</a> f. This
--   works because all entities have at least one field, and so we can
--   tabulate things into semigroup-like shapes instead.
tabulateEntityApply :: (PersistEntity record, Apply f) => (forall a. () => EntityField record a -> f a) -> f (Entity 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 -> NonEmpty (FieldNameHS, FieldNameDB)

-- | 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 :: Type -> Type). Functor f => (field -> f field) -> Entity record -> f (Entity record)

-- | Extract a <tt><a>Key</a> record</tt> from a <tt>record</tt> value.
--   Currently, this is only defined for entities using the
--   <tt>Primary</tt> syntax for natural/composite keys. In a future
--   version of <tt>persistent</tt> which incorporates the ID directly into
--   the entity, this will always be Just.
keyFromRecordM :: PersistEntity record => Maybe (record -> Key record)

-- | Construct an <tt><a>Entity</a> record</tt> by providing a value for
--   each of the record's fields.
--   
--   These constructions are equivalent:
--   
--   <pre>
--   entityMattConstructor, entityMattTabulate :: Entity User
--   entityMattConstructor =
--       Entity
--           { entityKey = toSqlKey 123
--           , entityVal =
--               User
--                   { userName = <a>Matt</a>
--                   , userAge = 33
--                   }
--           }
--   
--   entityMattTabulate =
--       tabulateEntity $ \case
--           UserId -&gt;
--               toSqlKey 123
--           UserName -&gt;
--               <a>Matt</a>
--           UserAge -&gt;
--               33
--   </pre>
--   
--   This is a specialization of <a>tabulateEntityA</a>, which allows you
--   to construct an <a>Entity</a> by providing an <a>Applicative</a>
--   action for each field instead of a regular function.
tabulateEntity :: PersistEntity record => (forall a. () => EntityField record a -> a) -> Entity record

-- | This type class is used with the <tt>OverloadedLabels</tt> extension
--   to provide a more convenient means of using the <a>EntityField</a>
--   type. <a>EntityField</a> definitions are prefixed with the type name
--   to avoid ambiguity, but this ambiguity can result in verbose code.
--   
--   If you have a table <tt>User</tt> with a <tt>name Text</tt> field,
--   then the corresponding <a>EntityField</a> is <tt>UserName</tt>. With
--   this, we can write <tt>#name :: <a>EntityField</a> User Text</tt>.
--   
--   What's more fun is that the type is more general: it's actually <tt>
--   #name :: (<a>SymbolToField</a> "name" rec typ) =&gt; EntityField rec
--   typ </tt>
--   
--   Which means it is *polymorphic* over the actual record. This allows
--   you to write code that can be generic over the tables, provided they
--   have the right fields.
class SymbolToField (sym :: Symbol) rec typ | sym rec -> typ
symbolToField :: SymbolToField sym rec typ => EntityField rec typ

-- | 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 PersistConfigBackend c :: Type -> Type -> Type -> Type;
    type 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 BaseBackend backend;
}
persistBackend :: HasPersistBackend backend => backend -> BaseBackend backend

-- | Run a query against a larger backend by plucking out <tt>BaseBackend
--   backend</tt>
--   
--   This is a helper for reusing existing queries when expanding the
--   backend type.
withBaseBackend :: forall backend (m :: Type -> Type) a. HasPersistBackend backend => ReaderT (BaseBackend backend) m a -> ReaderT backend m a

-- | 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
--     , <a>PersistEntityBackend</a> 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' = <a>withCompatibleBackend</a> asdf
--   </pre>
class BackendCompatible sup sub
projectBackend :: BackendCompatible sup sub => sub -> sup

-- | Run a query against a compatible backend, by projecting the backend
--   
--   This is a helper for using queries which run against a specific
--   backend type that your backend is compatible with.
withCompatibleBackend :: forall sup sub (m :: Type -> Type) a. BackendCompatible sup sub => ReaderT sup m a -> ReaderT sub m a
class PersistCore backend where {
    data BackendKey backend;
}

-- | <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

-- | 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


-- | Breaking changes to this module are not reflected in the major version
--   number. Prefer to import from <a>Database.Persist.Sql</a> instead. If
--   you neeed something from this module, please file an issue on GitHub.
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 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 :: forall (m :: Type -> Type) a. 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 :: forall (m :: Type -> Type) a. Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlWriteBackend m a

-- | Useful for running a write query against an untagged backend with
--   unknown capabilities.
writeToUnknown :: forall (m :: Type -> Type) a. 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

-- | A <a>Statement</a> is a representation of a database query that has
--   been prepared and stored on the server side.
data Statement
Statement :: IO () -> IO () -> ([PersistValue] -> IO Int64) -> (forall (m :: Type -> Type). MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())) -> Statement
[stmtFinalize] :: Statement -> IO ()
[stmtReset] :: Statement -> IO ()
[stmtExecute] :: Statement -> [PersistValue] -> IO Int64
[stmtQuery] :: Statement -> forall (m :: Type -> Type). 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 isolation levels
data IsolationLevel
ReadUncommitted :: IsolationLevel
ReadCommitted :: IsolationLevel
RepeatableRead :: IsolationLevel
Serializable :: IsolationLevel
makeIsolationLevelStatement :: (Monoid s, IsString s) => IsolationLevel -> s

-- | A <a>SqlBackend</a> represents a handle or connection to a database.
--   It contains functions and values that allow databases to have more
--   optimized implementations, as well as references that benefit
--   performance and sharing.
--   
--   Instead of using the <a>SqlBackend</a> constructor directly, use the
--   <a>mkSqlBackend</a> function.
--   
--   A <a>SqlBackend</a> is *not* thread-safe. You should not assume that a
--   <a>SqlBackend</a> can be shared among threads and run concurrent
--   queries. This *will* result in problems. Instead, you should create a
--   <tt><tt>Pool</tt> <a>SqlBackend</a></tt>, known as a
--   <tt>ConnectionPool</tt>, and pass that around in multi-threaded
--   applications.
--   
--   To run actions in the <tt>persistent</tt> library, you should use the
--   <tt>runSqlConn</tt> function. If you're using a multithreaded
--   application, use the <tt>runSqlPool</tt> function.
data SqlBackend
SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> StatementCache -> 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 ()) -> (FieldNameDB -> Text) -> (EntityDef -> Text) -> (Text -> Text) -> Text -> Text -> ((Int, Int) -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> Vault -> SqlBackendHooks -> SqlBackend

-- | This function should prepare a <a>Statement</a> in the target
--   database, which should allow for efficient query reuse.
[connPrepare] :: SqlBackend -> Text -> IO Statement

-- | This function generates the SQL and values necessary for performing an
--   insert against the database.
[connInsertSql] :: SqlBackend -> EntityDef -> [PersistValue] -> InsertSqlResult

-- | SQL for inserting many rows and returning their primary keys, for
--   backends that support this functionality. 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 (FieldNameHS, FieldNameDB) -> 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)

-- | A reference to the cache of statements. <a>Statement</a>s are keyed by
--   the <a>Text</a> queries that generated them.
[connStmtMap] :: SqlBackend -> StatementCache

-- | Close the underlying connection.
[connClose] :: SqlBackend -> IO ()

-- | This function returns the migrations required to include the
--   <a>EntityDef</a> parameter in the <tt>[<a>EntityDef</a>]</tt>
--   database. This might include creating a new table if the entity is not
--   present, or altering an existing table if it is.
[connMigrateSql] :: SqlBackend -> [EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])

-- | A function to begin a transaction for the underlying database.
[connBegin] :: SqlBackend -> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()

-- | A function to commit a transaction to the underlying database.
[connCommit] :: SqlBackend -> (Text -> IO Statement) -> IO ()

-- | A function to roll back a transaction on the underlying database.
[connRollback] :: SqlBackend -> (Text -> IO Statement) -> IO ()

-- | A function to extract and escape the name of the column corresponding
--   to the provided field.
[connEscapeFieldName] :: SqlBackend -> FieldNameDB -> Text

-- | A function to extract and escape the name of the table corresponding
--   to the provided entity. PostgreSQL uses this to support schemas.
[connEscapeTableName] :: SqlBackend -> EntityDef -> Text

-- | A function to escape raw DB identifiers. MySQL uses backticks, while
--   PostgreSQL uses quotes, and so on.
[connEscapeRawName] :: SqlBackend -> Text -> Text
[connNoLimit] :: SqlBackend -> Text

-- | A tag displaying what database the <a>SqlBackend</a> is for. Can be
--   used to differentiate features in downstream libraries for different
--   database backends.
[connRDBMS] :: SqlBackend -> Text

-- | Attach a 'LIMIT/OFFSET' clause to a SQL query. Note that LIMIT/OFFSET
--   is problematic for performance, and indexed range queries are the
--   superior way to offer pagination.
[connLimitOffset] :: SqlBackend -> (Int, Int) -> Text -> Text

-- | A log function for the <a>SqlBackend</a> to use.
[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)

-- | Carry arbitrary payloads for the connection that may be used to
--   propagate information into hooks.
[connVault] :: SqlBackend -> Vault

-- | Instrumentation hooks that may be used to track the behaviour of a
--   backend.
[connHooks] :: SqlBackend -> SqlBackendHooks

-- | 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 :: Type -> Type) 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 :: Type -> Type) 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)
newtype SqlBackendHooks
SqlBackendHooks :: (SqlBackend -> Text -> Statement -> IO Statement) -> SqlBackendHooks
[hookGetStatement] :: SqlBackendHooks -> SqlBackend -> Text -> Statement -> IO Statement
instance Database.Persist.Class.PersistStore.HasPersistBackend Database.Persist.Sql.Types.Internal.SqlReadBackend
instance Database.Persist.Class.PersistStore.HasPersistBackend Database.Persist.Sql.Types.Internal.SqlWriteBackend
instance Database.Persist.Class.PersistStore.IsPersistBackend Database.Persist.Sql.Types.Internal.SqlReadBackend
instance Database.Persist.Class.PersistStore.IsPersistBackend Database.Persist.Sql.Types.Internal.SqlWriteBackend


-- | Welcome to <tt>persistent</tt>!
--   
--   This library intends to provide an easy, flexible, and convenient
--   interface to various data storage backends. Backends include SQL
--   databases, like <tt>mysql</tt>, <tt>postgresql</tt>, and
--   <tt>sqlite</tt>, as well as NoSQL databases, like <tt>mongodb</tt> and
--   <tt>redis</tt>.
--   
--   If you intend on using a SQL database, then check out
--   <a>Database.Persist.Sql</a>.
module Database.Persist

-- | Assign a field a value.
--   
--   <h3>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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>Examples</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).
(||.) :: [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)
keyAndEntityColumnNames :: EntityDef -> SqlBackend -> NonEmpty Text
entityColumnCount :: EntityDef -> Int
isIdField :: PersistEntity record => EntityField record typ -> Bool

-- | Returns <a>True</a> if the entity has a natural key defined with the
--   Primary keyword.
--   
--   A natural key is a key that is inherent to the record, and is part of
--   the actual Haskell record. The opposite of a natural key is a
--   "surrogate key", which is not part of the normal domain object.
--   Automatically generated ID columns are the most common surrogate ID,
--   while an email address is a common natural key.
--   
--   <pre>
--   User
--       email String
--       name String
--       Primary email
--   
--   Person
--       Id   UUID
--       name String
--   
--   Follower
--       name String
--   </pre>
--   
--   Given these entity definitions, <tt>User</tt> would return
--   <a>True</a>, because the <tt>Primary</tt> keyword sets the
--   <tt>email</tt> column to be the primary key. The generated Haskell
--   type would look like this:
--   
--   <pre>
--   data User = User
--       { userEmail :: String
--       , userName :: String
--       }
--   </pre>
--   
--   <tt>Person</tt> would be false. While the <tt>Id</tt> syntax allows
--   you to define a custom ID type for an entity, the <tt>Id</tt> column
--   is a surrogate key.
--   
--   The same is true for <tt>Follower</tt>. The automatically generated
--   autoincremented integer primary key is a surrogate key.
--   
--   There's nothing preventing you from defining a <tt>Primary</tt>
--   definition that refers to a surrogate key. This is totally fine.
hasNaturalKey :: EntityDef -> Bool

-- | Returns <a>True</a> if the provided entity has a custom composite
--   primary key. Composite keys have multiple fields in them.
--   
--   <pre>
--   User
--       email String
--       name String
--       Primary userId
--   
--   Profile
--       personId PersonId
--       email    String
--       Primary personId email
--   
--   Person
--       Id   UUID
--       name String
--   
--   Follower
--       name String
--   </pre>
--   
--   Given these entity definitions, only <tt>Profile</tt> would return
--   <a>True</a>, because it is the only entity with multiple columns in
--   the primary key. <tt>User</tt> has a single column natural key.
--   <tt>Person</tt> has a custom single column surrogate key defined with
--   <tt>Id</tt>. And <tt>Follower</tt> has a default single column
--   surrogate key.
hasCompositePrimaryKey :: EntityDef -> Bool
dbIdColumns :: SqlBackend -> EntityDef -> NonEmpty Text
dbIdColumnsEsc :: (FieldNameDB -> Text) -> EntityDef -> NonEmpty Text
dbColumns :: SqlBackend -> EntityDef -> NonEmpty 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 => (FieldNameDB -> Text) -> (Text -> Text) -> Update record -> Text
commaSeparated :: [Text] -> Text
parenWrapped :: Text -> Text

-- | Make a list <a>PersistValue</a> suitable for database inserts. Pairs
--   nicely with the function <a>mkInsertPlaceholders</a>.
--   
--   Does not include generated columns.
mkInsertValues :: PersistEntity rec => rec -> [PersistValue]

-- | Returns a list of escaped field names and <tt>"?"</tt> placeholder
--   values for performing inserts. This does not include generated
--   columns.
--   
--   Does not include generated columns.
mkInsertPlaceholders :: EntityDef -> (FieldNameDB -> Text) -> [(Text, Text)]
parseExistsResult :: Maybe [PersistValue] -> Text -> String -> Bool

module Database.Persist.SqlBackend.SqlPoolHooks

-- | A set of hooks that may be used to alter the behaviour of
--   <tt>runSqlPoolWithExtensibleHooks</tt> in a backwards-compatible
--   fashion.
data SqlPoolHooks (m :: Type -> Type) backend

-- | Lifecycle hooks that may be altered to extend SQL pool behavior in a
--   backwards compatible fashion.
--   
--   By default, the hooks have the following semantics:
--   
--   <ul>
--   <li><a>alterBackend</a> has no effect</li>
--   <li><a>runBefore</a> begins a transaction</li>
--   <li><a>runAfter</a> commits the current transaction</li>
--   <li><a>runOnException</a> rolls back the current transaction</li>
--   </ul>
defaultSqlPoolHooks :: forall (m :: Type -> Type) backend. (MonadIO m, BackendCompatible SqlBackend backend) => SqlPoolHooks m backend
getAlterBackend :: SqlPoolHooks m backend -> backend -> m backend
modifyAlterBackend :: SqlPoolHooks m backend -> ((backend -> m backend) -> backend -> m backend) -> SqlPoolHooks m backend
setAlterBackend :: SqlPoolHooks m backend -> (backend -> m backend) -> SqlPoolHooks m backend
getRunBefore :: SqlPoolHooks m backend -> backend -> Maybe IsolationLevel -> m ()
modifyRunBefore :: SqlPoolHooks m backend -> ((backend -> Maybe IsolationLevel -> m ()) -> backend -> Maybe IsolationLevel -> m ()) -> SqlPoolHooks m backend
setRunBefore :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> m ()) -> SqlPoolHooks m backend
getRunAfter :: SqlPoolHooks m backend -> backend -> Maybe IsolationLevel -> m ()
modifyRunAfter :: SqlPoolHooks m backend -> ((backend -> Maybe IsolationLevel -> m ()) -> backend -> Maybe IsolationLevel -> m ()) -> SqlPoolHooks m backend
setRunAfter :: SqlPoolHooks m backend -> (backend -> Maybe IsolationLevel -> m ()) -> SqlPoolHooks m backend
getRunOnException :: SqlPoolHooks m backend -> backend -> Maybe IsolationLevel -> SomeException -> m ()


-- | This module documents tools and utilities for running SQL migrations.
--   
--   A <a>Migration</a> is (currently) an alias for a <a>WriterT</a> of
module Database.Persist.Sql.Migration

-- | 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 ()

-- | A list of SQL operations, marked with a safety flag. If the
--   <a>Bool</a> is <a>True</a>, then the operation is *unsafe* - it might
--   be destructive, or otherwise not idempotent. If the <a>Bool</a> is
--   <a>False</a>, then the operation is *safe*, and can be run repeatedly
--   without issues.
type CautiousMigration = [(Bool, Sql)]
type Sql = Text

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

-- | 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 :: forall (m :: Type -> Type). (HasCallStack, 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' :: forall (m :: Type -> Type). (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m CautiousMigration

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

-- | 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 :: forall (m :: Type -> Type). (MonadIO m, HasCallStack) => Migration -> ReaderT SqlBackend m [Sql]

-- | Runs a migration. If the migration fails to parse or if any of the
--   migrations are unsafe, then this throws a
--   <a>PersistUnsafeMigrationException</a>.
runMigration :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). MonadUnliftIO m => Migration -> ReaderT SqlBackend m [Text]

-- | Like <a>runMigration</a>, but this will perform the unsafe database
--   migrations instead of erroring out.
runMigrationUnsafe :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). (HasCallStack, 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

-- | Run an action against the database during a migration. Can be useful
--   for eg creating Postgres extensions:
--   
--   <pre>
--   runSqlCommand $ <a>rawExecute</a> "CREATE EXTENSION IF NOT EXISTS "uuid-ossp";" []
--   </pre>
runSqlCommand :: SqlPersistT IO () -> Migration

-- | An exception indicating that Persistent refused to run some unsafe
--   migrations. Contains a list of pairs where the Bool tracks whether the
--   migration was unsafe (True means unsafe), and the Sql is the sql
--   statement for the migration.
newtype PersistUnsafeMigrationException
PersistUnsafeMigrationException :: [(Bool, Sql)] -> PersistUnsafeMigrationException
instance GHC.Internal.Exception.Type.Exception Database.Persist.Sql.Migration.PersistUnsafeMigrationException
instance GHC.Internal.Show.Show Database.Persist.Sql.Migration.PersistUnsafeMigrationException


-- | of this module will not have a corresponding major version bump.
--   
--   Please depend on <a>Database.Persist.ImplicitIdDef</a> instead. If you
--   can't use that module, please file an issue on GitHub with your
--   desired use case.
module Database.Persist.ImplicitIdDef.Internal

-- | A specification for how the implied ID columns are created.
--   
--   By default, <tt>persistent</tt> will give each table a default column
--   named <tt>id</tt> (customizable by <tt>PersistSettings</tt>), and the
--   column type will be whatever you'd expect from <tt><tt>BackendKey</tt>
--   yourBackendType</tt>. For The <tt>SqlBackend</tt> type, this is an
--   auto incrementing integer primary key.
--   
--   You might want to give a different example. A common use case in
--   postgresql is to use the UUID type, and automatically generate them
--   using a SQL function.
--   
--   Previously, you'd need to add a custom <tt>Id</tt> annotation for each
--   model.
--   
--   <pre>
--   User
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--   
--   Dog
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--       user UserId
--   </pre>
--   
--   Now, you can simply create an <a>ImplicitIdDef</a> that corresponds to
--   this declaration.
--   
--   <pre>
--   newtype UUID = UUID <tt>ByteString</tt>
--   
--   instance <a>PersistField</a> UUID where
--       <tt>toPersistValue</tt> (UUID bs) =
--           <a>PersistLiteral_</a> <a>Escaped</a> bs
--       <tt>fromPersistValue</tt> pv =
--           case pv of
--               PersistLiteral_ Escaped bs -&gt;
--                   Right (UUID bs)
--               _ -&gt;
--                   Left "nope"
--   
--   instance <a>PersistFieldSql</a> UUID where
--       <a>sqlType</a> _ = <a>SqlOther</a> <a>UUID</a>
--   </pre>
--   
--   With this instance at the ready, we can now create our implicit
--   definition:
--   
--   <pre>
--   uuidDef :: ImplicitIdDef
--   uuidDef = mkImplicitIdDef @UUID "uuid_generate_v1mc()"
--   </pre>
--   
--   And we can use <tt>setImplicitIdDef</tt> to use this with the
--   <tt>MkPersistSettings</tt> for our block.
--   
--   <pre>
--   mkPersist (setImplicitIdDef uuidDef sqlSettings) [persistLowerCase| ... |]
--   </pre>
--   
--   TODO: either explain interaction with mkMigrate or fix it. see issue
--   #1249 for more details.
data ImplicitIdDef
ImplicitIdDef :: (EntityNameHS -> FieldType) -> SqlType -> (Bool -> Type -> Type) -> Maybe Text -> Maybe Integer -> ImplicitIdDef

-- | The field type. Accepts the <a>EntityNameHS</a> if you want to refer
--   to it. By default, <tt>Id</tt> is appended to the end of the Haskell
--   name.
[iidFieldType] :: ImplicitIdDef -> EntityNameHS -> FieldType

-- | The <a>SqlType</a> for the default column. By default, this is
--   <a>SqlInt64</a> to correspond with an autoincrementing integer primary
--   key.
[iidFieldSqlType] :: ImplicitIdDef -> SqlType

-- | The Bool argument is whether or not the <tt>MkPersistBackend</tt> type
--   has the <tt>mpsGeneric</tt> field set.
--   
--   The <a>Type</a> is the <tt>mpsBackend</tt> value.
--   
--   The default uses <tt><tt>BackendKey</tt> <tt>SqlBackend</tt></tt> (or
--   a generic equivalent).
[iidType] :: ImplicitIdDef -> Bool -> Type -> Type

-- | The default expression for the field. Note that setting this to
--   <a>Nothing</a> is unsafe. see
--   <a>https://github.com/yesodweb/persistent/issues/1247</a> for more
--   information.
--   
--   With some cases - like the Postgresql <tt>SERIAL</tt> type - this is
--   safe, since there's an implied default.
[iidDefault] :: ImplicitIdDef -> Maybe Text

-- | Specify the maximum length for a key column. This is necessary for
--   <tt>VARCHAR</tt> columns, like <tt>UUID</tt> in MySQL. MySQL will
--   throw a runtime error if a text or binary column is used in an index
--   without a length specification.
[iidMaxLen] :: ImplicitIdDef -> Maybe Integer

-- | Create an <a>ImplicitIdDef</a> based on the <a>Typeable</a> and
--   <a>PersistFieldSql</a> constraints in scope.
--   
--   This function uses the <tt>TypeApplications</tt> syntax. Let's look at
--   an example that works with Postgres UUIDs.
--   
--   <pre>
--   newtype UUID = UUID Text
--       deriving newtype PersistField
--   
--   instance PersistFieldSql UUID where
--       sqlType _ = SqlOther "UUID"
--   
--   idDef :: ImplicitIdDef
--   idDef = mkImplicitIdDefTypeable @UUID "uuid_generate_v1mc()"
--   </pre>
--   
--   This <a>ImplicitIdDef</a> will generate default UUID columns, and the
--   database will call the <tt>uuid_generate_v1mc()</tt> function to
--   generate the value for new rows being inserted.
--   
--   If the type <tt>t</tt> is <a>Text</a> or <a>String</a> then a
--   <tt>max_len</tt> attribute of 200 is set. To customize this, use
--   <a>setImplicitIdDefMaxLen</a>.
mkImplicitIdDef :: (Typeable t, PersistFieldSql t) => Text -> ImplicitIdDef

-- | Set the maximum length of the implied ID column. This is required for
--   any type where the associated <a>SqlType</a> is a <tt>TEXT</tt> or
--   <tt>VARCHAR</tt> sort of thing.
setImplicitIdDefMaxLen :: Integer -> ImplicitIdDef -> ImplicitIdDef

-- | This function converts a <a>Typeable</a> type into a
--   <tt>persistent</tt> representation of the type of a field -
--   <tt>FieldTyp</tt>.
fieldTypeFromTypeable :: (PersistField t, Typeable t) => FieldType

-- | Remove the default attribute of the <a>ImplicitIdDef</a> column. This
--   will require you to provide an ID for the model with every insert,
--   using <tt>insertKey</tt> instead of <tt>insert</tt>, unless the type
--   has some means of getting around that in the migrations.
--   
--   As an example, the Postgresql <tt>SERIAL</tt> type expands to an
--   autoincrementing integer. Postgres will implicitly create the relevant
--   series and set the default to be
--   <tt>NEXTVAL(<tt>series_name</tt>)</tt>. A default is therefore
--   unnecessary to use for this type.
--   
--   However, for a <tt>UUID</tt>, postgres *does not* have an implicit
--   default. You must either specify a default UUID generation function,
--   or insert them yourself (again, using <tt>insertKey</tt>).
--   
--   This function will be deprecated in the future when omiting the
--   default implicit ID column is more fully supported.
unsafeClearDefaultImplicitId :: ImplicitIdDef -> ImplicitIdDef


-- | This module contains types and functions for creating an
--   <a>ImplicitIdDef</a>, which allows you to customize the implied ID
--   column that <tt>persistent</tt> generates.
--   
--   If this module doesn't suit your needs, you may want to import
--   <a>Database.Persist.ImplicitIdDef.Internal</a> instead. If you do so,
--   please file an issue on GitHub so we can support your needs. Breaking
--   changes to that module will *not* be accompanied with a major version
--   bump.
module Database.Persist.ImplicitIdDef

-- | A specification for how the implied ID columns are created.
--   
--   By default, <tt>persistent</tt> will give each table a default column
--   named <tt>id</tt> (customizable by <tt>PersistSettings</tt>), and the
--   column type will be whatever you'd expect from <tt><tt>BackendKey</tt>
--   yourBackendType</tt>. For The <tt>SqlBackend</tt> type, this is an
--   auto incrementing integer primary key.
--   
--   You might want to give a different example. A common use case in
--   postgresql is to use the UUID type, and automatically generate them
--   using a SQL function.
--   
--   Previously, you'd need to add a custom <tt>Id</tt> annotation for each
--   model.
--   
--   <pre>
--   User
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--   
--   Dog
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--       user UserId
--   </pre>
--   
--   Now, you can simply create an <a>ImplicitIdDef</a> that corresponds to
--   this declaration.
--   
--   <pre>
--   newtype UUID = UUID <tt>ByteString</tt>
--   
--   instance <a>PersistField</a> UUID where
--       <tt>toPersistValue</tt> (UUID bs) =
--           <a>PersistLiteral_</a> <a>Escaped</a> bs
--       <tt>fromPersistValue</tt> pv =
--           case pv of
--               PersistLiteral_ Escaped bs -&gt;
--                   Right (UUID bs)
--               _ -&gt;
--                   Left "nope"
--   
--   instance <a>PersistFieldSql</a> UUID where
--       <a>sqlType</a> _ = <a>SqlOther</a> <a>UUID</a>
--   </pre>
--   
--   With this instance at the ready, we can now create our implicit
--   definition:
--   
--   <pre>
--   uuidDef :: ImplicitIdDef
--   uuidDef = mkImplicitIdDef @UUID "uuid_generate_v1mc()"
--   </pre>
--   
--   And we can use <tt>setImplicitIdDef</tt> to use this with the
--   <tt>MkPersistSettings</tt> for our block.
--   
--   <pre>
--   mkPersist (setImplicitIdDef uuidDef sqlSettings) [persistLowerCase| ... |]
--   </pre>
--   
--   TODO: either explain interaction with mkMigrate or fix it. see issue
--   #1249 for more details.
data ImplicitIdDef

-- | Create an <a>ImplicitIdDef</a> based on the <a>Typeable</a> and
--   <a>PersistFieldSql</a> constraints in scope.
--   
--   This function uses the <tt>TypeApplications</tt> syntax. Let's look at
--   an example that works with Postgres UUIDs.
--   
--   <pre>
--   newtype UUID = UUID Text
--       deriving newtype PersistField
--   
--   instance PersistFieldSql UUID where
--       sqlType _ = SqlOther "UUID"
--   
--   idDef :: ImplicitIdDef
--   idDef = mkImplicitIdDefTypeable @UUID "uuid_generate_v1mc()"
--   </pre>
--   
--   This <a>ImplicitIdDef</a> will generate default UUID columns, and the
--   database will call the <tt>uuid_generate_v1mc()</tt> function to
--   generate the value for new rows being inserted.
--   
--   If the type <tt>t</tt> is <a>Text</a> or <a>String</a> then a
--   <tt>max_len</tt> attribute of 200 is set. To customize this, use
--   <a>setImplicitIdDefMaxLen</a>.
mkImplicitIdDef :: (Typeable t, PersistFieldSql t) => Text -> ImplicitIdDef

-- | This is the default variant. Setting the implicit ID definition to
--   this value should not have any change at all on how entities are
--   defined by default.
autoIncrementingInteger :: ImplicitIdDef

-- | Set the maximum length of the implied ID column. This is required for
--   any type where the associated <a>SqlType</a> is a <tt>TEXT</tt> or
--   <tt>VARCHAR</tt> sort of thing.
setImplicitIdDefMaxLen :: Integer -> ImplicitIdDef -> ImplicitIdDef

-- | Remove the default attribute of the <a>ImplicitIdDef</a> column. This
--   will require you to provide an ID for the model with every insert,
--   using <tt>insertKey</tt> instead of <tt>insert</tt>, unless the type
--   has some means of getting around that in the migrations.
--   
--   As an example, the Postgresql <tt>SERIAL</tt> type expands to an
--   autoincrementing integer. Postgres will implicitly create the relevant
--   series and set the default to be
--   <tt>NEXTVAL(<tt>series_name</tt>)</tt>. A default is therefore
--   unnecessary to use for this type.
--   
--   However, for a <tt>UUID</tt>, postgres *does not* have an implicit
--   default. You must either specify a default UUID generation function,
--   or insert them yourself (again, using <tt>insertKey</tt>).
--   
--   This function will be deprecated in the future when omiting the
--   default implicit ID column is more fully supported.
unsafeClearDefaultImplicitId :: ImplicitIdDef -> ImplicitIdDef

module Database.Persist.Compatible

-- | A newtype wrapper for compatible backends, mainly useful for
--   <tt>DerivingVia</tt>.
--   
--   When writing a new backend that is <a>BackendCompatible</a> with an
--   existing backend, instances for the new backend can be naturally
--   defined in terms of the instances for the existing backend.
--   
--   For example, if you decide to augment the <tt>SqlBackend</tt> with
--   some additional features:
--   
--   <pre>
--   data BetterSqlBackend = BetterSqlBackend { sqlBackend :: SqlBackend, ... }
--   
--   instance BackendCompatible SqlBackend BetterSqlBackend where
--     projectBackend = sqlBackend
--   </pre>
--   
--   Then you can use <tt>DerivingVia</tt> to automatically get instances
--   like:
--   
--   <pre>
--   deriving via (Compatible SqlBackend BetterSqlBackend) instance PersistStoreRead BetterSqlBackend
--   deriving via (Compatible SqlBackend BetterSqlBackend) instance PersistStoreWrite BetterSqlBackend
--   ...
--   </pre>
--   
--   These instances will go through the compatible backend (in this case,
--   <tt>SqlBackend</tt>) for all their queries.
--   
--   These instances require that both backends have the same
--   <a>BaseBackend</a>, but deriving <a>HasPersistBackend</a> will enforce
--   that for you.
--   
--   <pre>
--   deriving via (Compatible SqlBackend BetterSqlBackend) instance HasPersistBackend BetterSqlBackend
--   </pre>
newtype Compatible b s
Compatible :: s -> Compatible b s
[unCompatible] :: Compatible b s -> s

-- | Gives a bunch of useful instance declarations for a backend based on
--   its compatibility with another backend, using <a>Compatible</a>.
--   
--   The argument should be a type of the form <tt> forall v1 ... vn.
--   Compatible b s </tt> (Quantification is optional, but supported
--   because TH won't let you have unbound type variables in a type
--   splice). The instance is produced for <tt>s</tt> based on the instance
--   defined for <tt>b</tt>, which is constrained in the instance head to
--   exist.
--   
--   <tt>v1 ... vn</tt> are implicitly quantified in the instance, which is
--   derived via <tt><a>Compatible</a> b s</tt>.
makeCompatibleInstances :: Q Type -> Q [Dec]

-- | Gives a bunch of useful instance declarations for a backend key based
--   on its compatibility with another backend &amp; key, using
--   <a>Compatible</a>.
--   
--   The argument should be a type of the form <tt> forall v1 ... vn.
--   Compatible b s </tt> (Quantification is optional, but supported
--   because TH won't let you have unbound type variables in a type
--   splice). The instance is produced for <tt><a>BackendKey</a> s</tt>
--   based on the instance defined for <tt><a>BackendKey</a> b</tt>, which
--   is constrained in the instance head to exist.
--   
--   <tt>v1 ... vn</tt> are implicitly quantified in the instance, which is
--   derived via <tt><a>BackendKey</a> (<a>Compatible</a> b s)</tt>.
makeCompatibleKeyInstances :: Q Type -> Q [Dec]


-- | This module is the primary entry point if you're working with
--   <tt>persistent</tt> on a SQL database.
--   
--   <h1>Getting Started</h1>
--   
--   First, you'll want to define your database entities. You can do that
--   with "Database.Persist.Quasi."
--   
--   Then, you'll use the operations
module Database.Persist.Sql

-- | 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 = fmap (unPrefix @"p") <a>$</a> rawSql query []
--     where
--       query = "SELECT ?? FROM person AS p"
--   </pre>
unPrefix :: forall (prefix :: Symbol) record. EntityWithPrefix prefix record -> Entity record

-- | 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

-- | 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> = <tt>PersistLiteralEncoded</tt> . toASCIIBytes
--     <a>fromPersistValue</a> (<tt>PersistLiteralEncoded</tt> 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 PersistLiteralEncoded, 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

-- | 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 => (Text -> 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

-- | 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 <a>runSqlConn</a> 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)
close' :: BackendCompatible SqlBackend backend => backend -> IO ()
createSqlPool :: forall backend m. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> m (Pool backend)

-- | Creates a pool of connections to a SQL database.
createSqlPoolWithConfig :: (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> ConnectionPoolConfig -> m (Pool backend)
liftSqlPersistMPool :: forall backend m a. (MonadIO m, BackendCompatible SqlBackend backend) => ReaderT backend (NoLoggingT (ResourceT IO)) a -> Pool backend -> m a
runSqlConn :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> m a

-- | Like <a>runSqlConn</a>, but supports specifying an isolation level.
runSqlConnWithIsolation :: forall backend m a. (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

-- | Get a connection from the pool, run the given action, and then return
--   the connection to the pool.
--   
--   This function performs the given action in a transaction. If an
--   exception occurs during the action, then the transaction is rolled
--   back.
--   
--   Note: This function previously timed out after 2 seconds, but this
--   behavior was buggy and caused more problems than it solved. Since
--   version 2.1.2, it performs no timeout checks.
runSqlPool :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> Pool backend -> m a

-- | Like <a>runSqlPool</a>, but does not surround the action in a
--   transaction. This action might leave your database in a weird state.
runSqlPoolNoTransaction :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> Pool backend -> Maybe IsolationLevel -> m a

-- | This function is how <a>runSqlPoolWithHooks</a> is defined.
--   
--   It's currently the most general function for using a SQL pool.
runSqlPoolWithExtensibleHooks :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> Pool backend -> Maybe IsolationLevel -> SqlPoolHooks m backend -> m a

-- | This function is how <a>runSqlPool</a> and
--   <a>runSqlPoolNoTransaction</a> are defined. In addition to the action
--   to be performed and the <a>Pool</a> of conections to use, we give you
--   the opportunity to provide three actions - initialize, afterwards, and
--   onException.
runSqlPoolWithHooks :: forall backend m a before after onException. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> Pool backend -> Maybe IsolationLevel -> (backend -> m before) -> (backend -> m after) -> (backend -> SomeException -> m onException) -> m a

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

-- | 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 :: forall backend m a. (MonadUnliftIO m, MonadLoggerIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> (backend -> m a) -> m a
withSqlPool :: forall backend m a. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> (Pool backend -> m a) -> m a

-- | Creates a pool of connections to a SQL database which can be used by
--   the <tt>Pool backend -&gt; m a</tt> function. After the function
--   completes, the connections are destroyed.
withSqlPoolWithConfig :: forall backend m a. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> ConnectionPoolConfig -> (Pool backend -> m a) -> m a

-- | useful for a backend to implement fieldName by adding escaping
fieldDBName :: PersistEntity record => EntityField record typ -> FieldNameDB
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 :: Type -> Type) 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 PersistEntity 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 :: Type -> Type) 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 -> EntityNameDB
toSqlKey :: ToBackendKey SqlBackend record => Int64 -> Key record
withRawQuery :: forall (m :: Type -> Type) a. MonadIO m => Text -> [PersistValue] -> ConduitM [PersistValue] Void IO a -> ReaderT SqlBackend m a
data family BackendKey backend
data family BackendKey backend
rawQuery :: forall (m :: Type -> Type) env. (MonadResource m, MonadReader env m, BackendCompatible SqlBackend env) => Text -> [PersistValue] -> ConduitM () [PersistValue] m ()
rawQueryRes :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) env. (MonadIO m1, MonadIO m2, BackendCompatible SqlBackend env) => Text -> [PersistValue] -> ReaderT env m1 (Acquire (ConduitM () [PersistValue] m2 ()))

-- | Execute a raw SQL statement
rawExecute :: forall (m :: Type -> Type) backend. (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 :: forall (m :: Type -> Type) backend. (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 :: forall a (m :: Type -> Type) backend. (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 :: forall val (m :: Type -> Type) backend. (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 :: forall val (m :: Type -> Type) backend. (PersistEntity val, MonadIO m, SqlBackend ~ PersistEntityBackend val, BackendCompatible SqlBackend backend) => [Filter val] -> [Update val] -> ReaderT backend m Int64

-- | Render a <tt>[<a>Filter</a> record]</tt> into a <a>Text</a> value
--   suitable for inclusion into a SQL query.
filterClause :: PersistEntity val => Maybe FilterTablePrefix -> SqlBackend -> [Filter val] -> Text

-- | Render a <tt>[<a>Filter</a> record]</tt> into a <a>Text</a> value
--   suitable for inclusion into a SQL query, as well as the
--   <tt>[<a>PersistValue</a>]</tt> to properly fill in the <tt>?</tt>
--   place holders.
filterClauseWithVals :: PersistEntity val => Maybe FilterTablePrefix -> SqlBackend -> [Filter val] -> (Text, [PersistValue])

-- | Render a <tt>[<a>SelectOpt</a> record]</tt> made up *only* of
--   <a>Asc</a> and <a>Desc</a> constructors into a <a>Text</a> value
--   suitable for inclusion into a SQL query.
orderClause :: PersistEntity val => Maybe FilterTablePrefix -> SqlBackend -> [SelectOpt val] -> Text

-- | Used when determining how to prefix a column name in a <tt>WHERE</tt>
--   clause.
data FilterTablePrefix

-- | Prefix the column with the table name. This is useful if the column
--   name might be ambiguous.
PrefixTableName :: FilterTablePrefix

-- | Prefix the column name with the <tt>EXCLUDED</tt> keyword. This is
--   used with the Postgresql backend when doing <tt>ON CONFLICT DO
--   UPDATE</tt> clauses - see the documentation on <tt>upsertWhere</tt>
--   and <tt>upsertManyWhere</tt>.
PrefixExcluded :: FilterTablePrefix

-- | 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 :: forall (m :: Type -> Type). MonadIO m => ReaderT SqlBackend m ()

-- | Commit the current transaction and begin a new one with the specified
--   isolation level.
transactionSaveWithIsolation :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). MonadIO m => ReaderT SqlBackend m ()

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

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

-- | Record of functions to override the default behavior in
--   <a>mkColumns</a>. It is recommended you initialize this with
--   <a>emptyBackendSpecificOverrides</a> and override the default values,
--   so that as new fields are added, your code still compiles.
--   
--   For added safety, use the <tt>getBackendSpecific*</tt> and
--   <tt>setBackendSpecific*</tt> functions, as a breaking change to the
--   record field labels won't be reflected in a major version bump of the
--   library.
data BackendSpecificOverrides

-- | Creates an empty <a>BackendSpecificOverrides</a> (i.e. use the default
--   behavior; no overrides)
emptyBackendSpecificOverrides :: BackendSpecificOverrides

-- | If the override is defined, then this returns a function that accepts
--   an entity name and field name and provides the <a>ConstraintNameDB</a>
--   for the foreign key constraint.
--   
--   An abstract accessor for the <a>BackendSpecificOverrides</a>
getBackendSpecificForeignKeyName :: BackendSpecificOverrides -> Maybe (EntityNameDB -> FieldNameDB -> ConstraintNameDB)

-- | Set the backend's foreign key generation function to this value.
setBackendSpecificForeignKeyName :: (EntityNameDB -> FieldNameDB -> ConstraintNameDB) -> BackendSpecificOverrides -> BackendSpecificOverrides
defaultAttribute :: [FieldAttr] -> Maybe Text

-- | Please refer to the documentation for the database in question for a
--   full overview of the semantics of the varying isolation levels
data IsolationLevel
ReadUncommitted :: IsolationLevel
ReadCommitted :: IsolationLevel
RepeatableRead :: IsolationLevel
Serializable :: IsolationLevel

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

-- | Initializes a ConnectionPoolConfig with default values. See the
--   documentation of <a>ConnectionPoolConfig</a> for each field's default
--   value.
defaultConnectionPoolConfig :: ConnectionPoolConfig

-- | Useful for running a read query against a backend with unknown
--   capabilities.
readToUnknown :: forall (m :: Type -> Type) a. 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 :: forall (m :: Type -> Type) a. Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlWriteBackend m a

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

-- | Prior to <tt>persistent-2.11.0</tt>, we provided an instance of
--   <a>PersistField</a> for the <a>Natural</a> type. This was in error,
--   because <a>Natural</a> represents an infinite value, and databases
--   don't have reasonable types for this.
--   
--   The instance for <a>Natural</a> used the <a>Int64</a> underlying type,
--   which will cause underflow and overflow errors. This type has the
--   exact same code in the instances, and will work seamlessly.
--   
--   A more appropriate type for this is the <a>Word</a> series of types
--   from <a>Data.Word</a>. These have a bounded size, are guaranteed to be
--   non-negative, and are quite efficient for the database to store.
newtype OverflowNatural
OverflowNatural :: Natural -> OverflowNatural
[unOverflowNatural] :: OverflowNatural -> Natural
data Column
Column :: !FieldNameDB -> !Bool -> !SqlType -> !Maybe Text -> !Maybe Text -> !Maybe ConstraintNameDB -> !Maybe Integer -> !Maybe ColumnReference -> Column
[cName] :: Column -> !FieldNameDB
[cNull] :: Column -> !Bool
[cSqlType] :: Column -> !SqlType
[cDefault] :: Column -> !Maybe Text
[cGenerated] :: Column -> !Maybe Text
[cDefaultConstraintName] :: Column -> !Maybe ConstraintNameDB
[cMaxLen] :: Column -> !Maybe Integer
[cReference] :: Column -> !Maybe ColumnReference

-- | This value specifies how a field references another table.
data ColumnReference
ColumnReference :: !EntityNameDB -> !ConstraintNameDB -> !FieldCascade -> ColumnReference

-- | The table name that the
[crTableName] :: ColumnReference -> !EntityNameDB

-- | The name of the foreign key constraint.
[crConstraintName] :: ColumnReference -> !ConstraintNameDB

-- | Whether or not updates/deletions to the referenced table cascade to
--   this table.
[crFieldCascade] :: ColumnReference -> !FieldCascade
type ConnectionPool = Pool SqlBackend

-- | Values to configure a pool of database connections. See
--   <a>Data.Pool</a> for details.
data ConnectionPoolConfig
ConnectionPoolConfig :: Int -> NominalDiffTime -> Int -> ConnectionPoolConfig

-- | How many stripes to divide the pool into. See <a>Data.Pool</a> for
--   details. Default: 1.
[connectionPoolConfigStripes] :: ConnectionPoolConfig -> Int

-- | How long connections can remain idle before being disposed of, in
--   seconds. Default: 600
[connectionPoolConfigIdleTimeout] :: ConnectionPoolConfig -> NominalDiffTime

-- | How many connections should be held in the connection pool. Default:
--   10
[connectionPoolConfigSize] :: ConnectionPoolConfig -> Int
data PersistentSqlException
StatementAlreadyFinalized :: Text -> PersistentSqlException
Couldn'tGetSQLConnection :: PersistentSqlException

-- | 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 SqlPersistM = SqlPersistT NoLoggingT ResourceT IO
type SqlPersistT = ReaderT SqlBackend

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

-- | 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)

-- | 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

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

-- | 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

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

-- | A <a>SqlBackend</a> represents a handle or connection to a database.
--   It contains functions and values that allow databases to have more
--   optimized implementations, as well as references that benefit
--   performance and sharing.
--   
--   Instead of using the <a>SqlBackend</a> constructor directly, use the
--   <a>mkSqlBackend</a> function.
--   
--   A <a>SqlBackend</a> is *not* thread-safe. You should not assume that a
--   <a>SqlBackend</a> can be shared among threads and run concurrent
--   queries. This *will* result in problems. Instead, you should create a
--   <tt><tt>Pool</tt> <a>SqlBackend</a></tt>, known as a
--   <tt>ConnectionPool</tt>, and pass that around in multi-threaded
--   applications.
--   
--   To run actions in the <tt>persistent</tt> library, you should use the
--   <tt>runSqlConn</tt> function. If you're using a multithreaded
--   application, use the <tt>runSqlPool</tt> function.
data SqlBackend
data InsertSqlResult
ISRSingle :: Text -> InsertSqlResult
ISRInsertGet :: Text -> Text -> InsertSqlResult
ISRManyKeys :: Text -> [PersistValue] -> InsertSqlResult
type LogFunc = Loc -> LogSource -> LogLevel -> LogStr -> IO ()

-- | A <a>Statement</a> is a representation of a database query that has
--   been prepared and stored on the server side.
data Statement
Statement :: IO () -> IO () -> ([PersistValue] -> IO Int64) -> (forall (m :: Type -> Type). MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())) -> Statement
[stmtFinalize] :: Statement -> IO ()
[stmtReset] :: Statement -> IO ()
[stmtExecute] :: Statement -> [PersistValue] -> IO Int64
[stmtQuery] :: Statement -> forall (m :: Type -> Type). MonadIO m => [PersistValue] -> Acquire (ConduitM () [PersistValue] m ())

module Database.Persist.Quasi.Internal.ModelParser

-- | Source location: file and line/col information. This is half of a
--   <a>SourceSpan</a>.
data SourceLoc
SourceLoc :: Text -> Int -> Int -> SourceLoc
[locFile] :: SourceLoc -> Text
[locStartLine] :: SourceLoc -> Int
[locStartCol] :: SourceLoc -> Int

-- | An attribute of an entity field definition or a directive.
data Attribute
Assignment :: Text -> Text -> Attribute
Parenthetical :: Text -> Attribute
PText :: Text -> Attribute

-- | Quoted field attributes are deprecated since 2.17.1.0.
Quotation :: Text -> Attribute
attribute :: Parser Attribute

-- | Converts an attribute into a Text representation for second-stage
--   parsing or presentation to the user
attributeContent :: Attribute -> Text
data Directive
Directive :: Maybe DocCommentBlock -> DirectiveName -> [Attribute] -> SourcePos -> Directive
[directiveDocCommentBlock] :: Directive -> Maybe DocCommentBlock
[directiveName] :: Directive -> DirectiveName
[directiveAttributes] :: Directive -> [Attribute]
[directivePos] :: Directive -> SourcePos

-- | Converts a directive into a Text representation for second-stage
--   parsing or presentation to the user
directiveContent :: Directive -> [Text]
data EntityField
EntityField :: Maybe DocCommentBlock -> Maybe FieldStrictness -> FieldName -> TypeExpr -> [Attribute] -> SourcePos -> EntityField
[entityFieldDocCommentBlock] :: EntityField -> Maybe DocCommentBlock
[entityFieldStrictness] :: EntityField -> Maybe FieldStrictness
[entityFieldName] :: EntityField -> FieldName
[entityFieldType] :: EntityField -> TypeExpr
[entityFieldAttributes] :: EntityField -> [Attribute]
[entityFieldPos] :: EntityField -> SourcePos
entityField :: Parser Member
entityFieldContent :: EntityField -> [Text]
newtype FieldName
FieldName :: Text -> FieldName
fieldName :: Parser FieldName
data ParsedEntityDef
ParsedEntityDef :: [Text] -> EntityNameHS -> Bool -> [Attribute] -> [(EntityField, Maybe Text)] -> [(Directive, Maybe Text)] -> Map Text [ExtraLine] -> Maybe SourceSpan -> ParsedEntityDef
[parsedEntityDefComments] :: ParsedEntityDef -> [Text]
[parsedEntityDefEntityName] :: ParsedEntityDef -> EntityNameHS
[parsedEntityDefIsSum] :: ParsedEntityDef -> Bool
[parsedEntityDefEntityAttributes] :: ParsedEntityDef -> [Attribute]
[parsedEntityDefFields] :: ParsedEntityDef -> [(EntityField, Maybe Text)]
[parsedEntityDefDirectives] :: ParsedEntityDef -> [(Directive, Maybe Text)]
[parsedEntityDefExtras] :: ParsedEntityDef -> Map Text [ExtraLine]
[parsedEntityDefSpan] :: ParsedEntityDef -> Maybe SourceSpan
parseSource :: PersistSettings -> Maybe SourceLoc -> Text -> ParseResult [ParsedEntityDef]

-- | Represents an entity member as a list of EntityFields
memberEntityFields :: Member -> [EntityField]

data ParserWarning

-- | Uses <tt>errorBundlePretty</tt> to render a parser warning.
parserWarningMessage :: ParserWarning -> String

-- | Result of parsing a single source text.
type ParseResult a = (Set ParserWarning, Either ParseErrorBundle String Void a)

-- | Cumulative result of parsing multiple source texts.
type CumulativeParseResult a = (Set ParserWarning, Either [EntityParseError] a)
toCumulativeParseResult :: Monoid a => [ParseResult a] -> CumulativeParseResult a

-- | Renders a list of EntityParseErrors as a String using
--   <a>errorBundlePretty</a>, separated by line breaks. @since 2.16.0.0
renderErrors :: [EntityParseError] -> String

-- | Run a parser using provided PersistSettings and ExtraState @since
--   2.16.0.0
runConfiguredParser :: PersistSettings -> ExtraState -> Parser a -> String -> String -> InternalParseResult a

data ParserErrorLevel
LevelError :: ParserErrorLevel
LevelWarning :: ParserErrorLevel
initialExtraState :: ExtraState
instance GHC.Internal.Base.Alternative Database.Persist.Quasi.Internal.ModelParser.Parser
instance GHC.Internal.Base.Applicative Database.Persist.Quasi.Internal.ModelParser.Parser
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.ModelParser.Attribute
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.ModelParser.CommentToken
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.ModelParser.DirectiveName
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.ModelParser.FieldName
instance GHC.Internal.Base.Functor Database.Persist.Quasi.Internal.ModelParser.Parser
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.ModelParser.SourceLoc
instance GHC.Internal.Control.Monad.Fail.MonadFail Database.Persist.Quasi.Internal.ModelParser.Parser
instance Text.Megaparsec.Class.MonadParsec GHC.Internal.Base.Void GHC.Internal.Base.String Database.Persist.Quasi.Internal.ModelParser.Parser
instance GHC.Internal.Base.Monad Database.Persist.Quasi.Internal.ModelParser.Parser
instance GHC.Internal.Base.MonadPlus Database.Persist.Quasi.Internal.ModelParser.Parser
instance Control.Monad.Reader.Class.MonadReader Database.Persist.Quasi.PersistSettings.Internal.PersistSettings Database.Persist.Quasi.Internal.ModelParser.Parser
instance Control.Monad.State.Class.MonadState Database.Persist.Quasi.Internal.ModelParser.ExtraState Database.Persist.Quasi.Internal.ModelParser.Parser
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.ModelParser.Attribute
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.ModelParser.CommentToken
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.Attribute
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.BlockKey
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.CommentToken
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.Directive
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.DirectiveName
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.DocCommentBlock
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.EntityBlock
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.EntityField
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.EntityHeader
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.ExtraBlock
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.ExtraBlockHeader
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.ExtraBlockLine
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.FieldName
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.FieldStrictness
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.Member
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.ParsedEntityDef
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ModelParser.SourceLoc


-- | This <tt>Internal</tt> module may have breaking changes that will not
--   be reflected in major version bumps. Please use
--   <a>Database.Persist.Quasi</a> instead. If you need something in this
--   module, please file an issue on GitHub.
module Database.Persist.Quasi.Internal

-- | Parses a quasi-quoted syntax into a list of entity definitions.
parse :: PersistSettings -> [(Maybe SourceLoc, Text)] -> CumulativeParseResult [UnboundEntityDef]
data PersistSettings
upperCaseSettings :: PersistSettings
lowerCaseSettings :: PersistSettings

-- | An attribute of an entity field definition or a directive.
data Attribute
Assignment :: Text -> Text -> Attribute
Parenthetical :: Text -> Attribute
PText :: Text -> Attribute

-- | Quoted field attributes are deprecated since 2.17.1.0.
Quotation :: Text -> Attribute

-- | Source location: file and line/col information. This is half of a
--   <a>SourceSpan</a>.
data SourceLoc
SourceLoc :: Text -> Int -> Int -> SourceLoc
[locFile] :: SourceLoc -> Text
[locStartLine] :: SourceLoc -> Int
[locStartCol] :: SourceLoc -> Int
sourceLocFromTHLoc :: Loc -> SourceLoc
parseFieldType :: Text -> Either String FieldType
takeColsEx :: PersistSettings -> [Text] -> Maybe UnboundFieldDef

-- | Cumulative result of parsing multiple source texts.
type CumulativeParseResult a = (Set ParserWarning, Either [EntityParseError] a)

-- | Renders a list of EntityParseErrors as a String using
--   <a>errorBundlePretty</a>, separated by line breaks. @since 2.16.0.0
renderErrors :: [EntityParseError] -> String

-- | Uses <tt>errorBundlePretty</tt> to render a parser warning.
parserWarningMessage :: ParserWarning -> String

-- | An <a>EntityDef</a> produced by the QuasiQuoter. It contains
--   information that the QuasiQuoter is capable of knowing about the
--   entities. It is inherently unfinished, though - there are many other
--   <tt>Unbound</tt> datatypes that also contain partial information.
--   
--   The <a>unboundEntityDef</a> is not complete or reliable - to know
--   which fields are safe to use, consult the parsing code.
--   
--   This type was completely internal until 2.13.0.0, when it was exposed
--   as part of the <a>Database.Persist.Quasi.Internal</a> module.
--   
--   TODO: refactor this so we can expose it for consumers.
data UnboundEntityDef
UnboundEntityDef :: [UnboundForeignDef] -> PrimarySpec -> EntityDef -> [UnboundFieldDef] -> Maybe SourceSpan -> UnboundEntityDef

-- | A list of foreign definitions on the parsed entity.
[unboundForeignDefs] :: UnboundEntityDef -> [UnboundForeignDef]

-- | The specification for the primary key of the unbound entity.
[unboundPrimarySpec] :: UnboundEntityDef -> PrimarySpec

-- | The incomplete and partial <a>EntityDef</a> that we're defining. We
--   re-use the type here to prevent duplication, but several of the fields
--   are unset and left to defaults.
[unboundEntityDef] :: UnboundEntityDef -> EntityDef

-- | The list of fields for the entity. We're not capable of knowing
--   information like "is this a reference?" or "what's the underlying type
--   of the field?" yet, so we defer those to the Template Haskell
--   execution.
[unboundEntityFields] :: UnboundEntityDef -> [UnboundFieldDef]

-- | The source code span of this entity in the models file.
[unboundEntityDefSpan] :: UnboundEntityDef -> Maybe SourceSpan

-- | Return the <a>EntityNameHS</a> for an <a>UnboundEntityDef</a>.
getUnboundEntityNameHS :: UnboundEntityDef -> EntityNameHS

-- | Convert an <a>EntityDef</a> into an <a>UnboundEntityDef</a>. This
--   "forgets" information about the <a>EntityDef</a>, but it is all kept
--   present on the <a>unboundEntityDef</a> field if necessary.
unbindEntityDef :: EntityDef -> UnboundEntityDef

-- | Returns the <tt>[<a>UnboundFieldDef</a>]</tt> for an
--   <a>UnboundEntityDef</a>. This returns all fields defined on the
--   entity.
getUnboundFieldDefs :: UnboundEntityDef -> [UnboundFieldDef]

-- | Define an explicit foreign key reference.
--   
--   <pre>
--   User
--       name Text
--       email Text
--   
--       Primary name email
--   
--   Dog
--       ownerName Text
--       ownerEmail Text
--   
--       Foreign User fk_dog_user ownerName ownerEmail
--   </pre>
data UnboundForeignDef
UnboundForeignDef :: UnboundForeignFieldList -> ForeignDef -> UnboundForeignDef

-- | Fields in the source entity.
[unboundForeignFields] :: UnboundForeignDef -> UnboundForeignFieldList

-- | The <a>ForeignDef</a> which needs information filled in.
--   
--   This value is unreliable. See the parsing code to see what data is
--   filled in here.
[unboundForeignDef] :: UnboundForeignDef -> ForeignDef
getSqlNameOr :: FieldNameDB -> [FieldAttr] -> FieldNameDB

-- | A representation of a database column, with everything that can be
--   known at parse time.
data UnboundFieldDef
UnboundFieldDef :: FieldNameHS -> FieldNameDB -> [FieldAttr] -> Bool -> FieldType -> FieldCascade -> Maybe Text -> Maybe Text -> UnboundFieldDef

-- | The Haskell name of the field. This is parsed directly from the
--   definition, and is used to generate the Haskell record field and the
--   <a>EntityField</a> definition.
[unboundFieldNameHS] :: UnboundFieldDef -> FieldNameHS

-- | The database name of the field. By default, this is determined by the
--   <a>PersistSettings</a> record at parse time. You can customize this
--   with a <tt>sql=</tt> attribute:
--   
--   <pre>
--   name Text  sql=foo_name
--   </pre>
[unboundFieldNameDB] :: UnboundFieldDef -> FieldNameDB

-- | The attributes present on the field. For rules on parsing and utility,
--   see the comments on the datatype.
[unboundFieldAttrs] :: UnboundFieldDef -> [FieldAttr]

-- | Whether or not the field should be strict in the generated Haskell
--   code.
[unboundFieldStrict] :: UnboundFieldDef -> Bool

-- | The type of the field, as far as is known at parse time.
--   
--   The TemplateHaskell code will reconstruct a <tt>Type</tt> out of this,
--   but the names will be imported as-is.
[unboundFieldType] :: UnboundFieldDef -> FieldType

-- | We parse if there's a <a>FieldCascade</a> on the field. If the field
--   is not a reference, this information is ignored.
--   
--   <pre>
--   Post
--      user UserId OnDeleteCascade
--   </pre>
[unboundFieldCascade] :: UnboundFieldDef -> FieldCascade

-- | Contains an expression to generate the column. If this is present,
--   then the column will not be written to the database, but generated by
--   the expression every time.
--   
--   <pre>
--   Item
--       subtotal Int
--       taxRate  Rational
--       total    Int      generated="subtotal * tax_rate"
--   </pre>
[unboundFieldGenerated] :: UnboundFieldDef -> Maybe Text

-- | Any comments present on the field. Documentation comments use a
--   Haskell-like syntax, and must be present before the field in question.
--   
--   <pre>
--   Post
--       -- | This is the blog post title.
--       title Text
--       -- | You can have multi-line comments.
--       -- | But each line must have the pipe character.
--       author UserId
--   </pre>
[unboundFieldComments] :: UnboundFieldDef -> Maybe Text

-- | A definition for a composite primary key.
--   
--   @since.2.13.0.0
data UnboundCompositeDef
UnboundCompositeDef :: NonEmpty FieldNameHS -> [Attr] -> UnboundCompositeDef

-- | The field names for the primary key.
[unboundCompositeCols] :: UnboundCompositeDef -> NonEmpty FieldNameHS

-- | A list of attributes defined on the primary key. This is anything that
--   occurs after a <tt>!</tt> character.
[unboundCompositeAttrs] :: UnboundCompositeDef -> [Attr]

-- | This type represents an <tt>Id</tt> declaration in the QuasiQuoted
--   syntax.
--   
--   <pre>
--   Id
--   </pre>
--   
--   This uses the implied settings, and is equivalent to omitting the
--   <tt>Id</tt> statement entirely.
--   
--   <pre>
--   Id Text
--   </pre>
--   
--   This will set the field type of the ID to be <a>Text</a>.
--   
--   <pre>
--   Id Text sql=foo_id
--   </pre>
--   
--   This will set the field type of the Id to be <a>Text</a> and the SQL
--   DB name to be <tt>foo_id</tt>.
--   
--   <pre>
--   Id FooId
--   </pre>
--   
--   This results in a shared primary key - the <tt>FooId</tt> refers to a
--   <tt>Foo</tt> table.
--   
--   <pre>
--   Id FooId OnDelete Cascade
--   </pre>
--   
--   You can set a cascade behavior on an ID column.
data UnboundIdDef
UnboundIdDef :: EntityNameHS -> !FieldNameDB -> [FieldAttr] -> FieldCascade -> Maybe FieldType -> UnboundIdDef
[unboundIdEntityName] :: UnboundIdDef -> EntityNameHS
[unboundIdDBName] :: UnboundIdDef -> !FieldNameDB
[unboundIdAttrs] :: UnboundIdDef -> [FieldAttr]
[unboundIdCascade] :: UnboundIdDef -> FieldCascade
[unboundIdType] :: UnboundIdDef -> Maybe FieldType

-- | Forget innformation about a <a>FieldDef</a> so it can beused as an
--   <a>UnboundFieldDef</a>.
unbindFieldDef :: FieldDef -> UnboundFieldDef
isUnboundFieldNullable :: UnboundFieldDef -> IsNullable

-- | Convert an <a>UnboundIdDef</a> into a <a>FieldDef</a> suitable for use
--   in the <a>EntityIdField</a> constructor.
unboundIdDefToFieldDef :: FieldNameDB -> EntityNameHS -> UnboundIdDef -> FieldDef

-- | The specification for how an entity's primary key should be formed.
--   
--   Persistent requires that every table have a primary key. By default,
--   an implied ID is assigned, based on the <tt>mpsImplicitIdDef</tt>
--   field on <tt>MkPersistSettings</tt>. Because we can't access that type
--   at parse-time, we defer that decision until later.
data PrimarySpec

-- | A <a>NaturalKey</a> contains columns that are defined on the datatype
--   itself. This is defined using the <tt>Primary</tt> keyword and given a
--   non-empty list of columns.
--   
--   <pre>
--   User
--       name    Text
--       email   Text
--   
--       Primary name email
--   </pre>
--   
--   A natural key may also contain only a single column. A natural key
--   with multiple columns is called a 'composite key'.
NaturalKey :: UnboundCompositeDef -> PrimarySpec

-- | A surrogate key is not part of the domain model for a database table.
--   You can specify a custom surro
--   
--   You can specify a custom surrogate key using the <tt>Id</tt> syntax.
--   
--   <pre>
--   User
--       Id    Text
--       name  Text
--   </pre>
--   
--   Note that you must provide a <tt>default=</tt> expression when using
--   this in order to use <tt>insert</tt> or related functions. The
--   <tt>insertKey</tt> function can be used instead, as it allows you to
--   specify a key directly. Fixing this issue is tracked in #1247 on
--   GitHub.
SurrogateKey :: UnboundIdDef -> PrimarySpec

-- | The default key for the entity using the settings in
--   <tt>MkPersistSettings</tt>.
--   
--   This is implicit - a table without an <tt>Id</tt> or <tt>Primary</tt>
--   declaration will have a <a>DefaultKey</a>.
DefaultKey :: FieldNameDB -> PrimarySpec
mkAutoIdField' :: FieldNameDB -> EntityNameHS -> SqlType -> FieldDef

-- | A list of fields present on the foreign reference.
data UnboundForeignFieldList

-- | If no <tt>References</tt> keyword is supplied, then it is assumed that
--   you are referring to the <tt>Primary</tt> key or <tt>Id</tt> of the
--   target entity.
FieldListImpliedId :: NonEmpty FieldNameHS -> UnboundForeignFieldList

-- | You can specify the exact columns you're referring to here, if they
--   aren't part of a primary key. Most databases expect a unique index on
--   the columns you refer to, but Persistent doesnt' check that.
--   
--   <pre>
--   User
--       Id           UUID default="uuid_generate_v1mc()"
--       name         Text
--   
--       UniqueName name
--   
--   Dog
--       ownerName    Text
--   
--       Foreign User fk_dog_user ownerName References name
--   </pre>
FieldListHasReferences :: NonEmpty ForeignFieldReference -> UnboundForeignFieldList

-- | A pairing of the <a>FieldNameHS</a> for the source table to the
--   <a>FieldNameHS</a> for the target table.
data ForeignFieldReference
ForeignFieldReference :: FieldNameHS -> FieldNameHS -> ForeignFieldReference

-- | The column on the source table.
[ffrSourceField] :: ForeignFieldReference -> FieldNameHS

-- | The column on the target table.
[ffrTargetField] :: ForeignFieldReference -> FieldNameHS

-- | Convert an <a>EntityNameHS</a> into <a>FieldType</a> that will get
--   parsed into the ID type for the entity.
--   
--   <pre>
--   &gt;&gt;&gt; mkKeyConType (EntityNameHS "Hello)
--   FTTypeCon Nothing <a>HelloId</a>
--   </pre>
mkKeyConType :: EntityNameHS -> FieldType

-- | Returns <a>True</a> if the <a>UnboundFieldDef</a> does not have a
--   <tt>MigrationOnly</tt> or <tt>SafeToRemove</tt> flag from the
--   QuasiQuoter.
isHaskellUnboundField :: UnboundFieldDef -> Bool
data FieldTypeLit
IntTypeLit :: Integer -> FieldTypeLit
TextTypeLit :: Text -> FieldTypeLit
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.ForeignFieldReference
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.PrimarySpec
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.UnboundCompositeDef
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.UnboundEntityDef
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.UnboundFieldDef
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.UnboundForeignDef
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.UnboundForeignFieldList
instance GHC.Classes.Eq Database.Persist.Quasi.Internal.UnboundIdDef
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.ForeignFieldReference
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.PrimarySpec
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.UnboundCompositeDef
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.UnboundEntityDef
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.UnboundFieldDef
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.UnboundForeignDef
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.UnboundForeignFieldList
instance GHC.Internal.TH.Lift.Lift Database.Persist.Quasi.Internal.UnboundIdDef
instance GHC.Internal.Base.Monoid Database.Persist.Quasi.Internal.EntityConstraintDefs
instance GHC.Internal.Base.Monoid (Database.Persist.Quasi.Internal.SetOnceAtMost a)
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.ForeignFieldReference
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.PrimarySpec
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.UnboundCompositeDef
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.UnboundEntityDef
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.UnboundFieldDef
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.UnboundForeignDef
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.UnboundForeignFieldList
instance GHC.Classes.Ord Database.Persist.Quasi.Internal.UnboundIdDef
instance GHC.Internal.Base.Semigroup Database.Persist.Quasi.Internal.EntityConstraintDefs
instance GHC.Internal.Base.Semigroup (Database.Persist.Quasi.Internal.SetOnceAtMost a)
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.ForeignFieldReference
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Database.Persist.Quasi.Internal.ParseState a)
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.PrimarySpec
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.UnboundCompositeDef
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.UnboundEntityDef
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.UnboundFieldDef
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.UnboundForeignDef
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.UnboundForeignFieldList
instance GHC.Internal.Show.Show Database.Persist.Quasi.Internal.UnboundIdDef


-- | 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 <a>Database.Persist.TH</a> module 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 <tt>=</tt> 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.
--   
--   <b>Note</b>: Persistent determines whether or not to migrate a
--   column's default value by comparing the exact string found in your
--   <tt>models</tt> file with the one returned by the database. If a
--   database canonicalizes the SQL <tt>FALSE</tt> from your
--   <tt>models</tt> file to <tt>false</tt> in the database, Persistent
--   will think the default value needs to be migrated and <a>attempt a
--   migration each time you start your app</a>.
--   
--   To workaround this, find the exact SQL your DBMS uses for the default
--   value. For example, using postgres:
--   
--   <pre>
--   psql database_name # Open postgres
--   
--   \d+ table_name -- describe the table schema
--   </pre>
--   
--   <pre>
--   ...
--   created       | timestamp without time zone | not null default now()
--   </pre>
--   
--   Then use the listed default value SQL inside your <tt>models</tt>
--   file.
--   
--   <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>
--   
--   Since the primary key for this table is part of the record, it's
--   called a "natural key" in the SQL lingo. As a key with multiple
--   fields, it is also a "composite key."
--   
--   You can specify a <tt>Primary</tt> key with a single field, too.
--   
--   <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 TABLE big_user_table (
--       id      SERIAL PRIMARY KEY,
--       name    VARCHAR,
--       age     INT
--   );
--   </pre>
--   
--   <h1>Customizing Types/Tables</h1>
--   
--   <h2>JSON instances</h2>
--   
--   You can automatically get ToJSON and FromJSON instances for any entity
--   by adding <tt>json</tt> to the entity line:
--   
--   <pre>
--   Person json
--       name Text
--   </pre>
--   
--   Requires <tt>{-# LANGUAGE FlexibleInstances #-}</tt>
--   
--   Customizable by using mpsEntityJSON *
--   <a>http://hackage.haskell.org/package/persistent-template/docs/Database-Persist-TH.html#v:EntityJSON</a>
--   *
--   <a>http://hackage.haskell.org/package/persistent/docs/Database-Persist-Class.html#v:keyValueEntityToJSON</a>
--   
--   <h2>Changing table/collection name</h2>
--   
--   <pre>
--   Person sql=peoples
--       name Text
--   </pre>
--   
--   <h2>Change table/collection key definition (field name and/or type,
--   persistent &gt;= 2.1)</h2>
--   
--   <tt>Id</tt> defines the column to use to define the key of the entity.
--   Without type, the default backend key type will be used. You can
--   change its database name using the <tt>sql</tt> attributes :
--   
--   <pre>
--   Person
--      Id         sql=my_id_name
--      phone Text
--   </pre>
--   
--   With a Haskell type, the corresponding type is used. Note that you'll
--   need to use <tt>default=</tt> to tell it what to do on insertion.
--   
--   <pre>
--   Person
--      Id    Day default=CURRENT_DATE
--      phone Text
--   </pre>
--   
--   <tt>default=</tt> works for SQL databases, and is backend specific.
--   For MongoDB currently one always needs to create the key on the
--   application side and use <tt>insertKey</tt>. <tt>insert</tt> will not
--   work correctly. Sql backends can also do this if default does not
--   work.
--   
--   <tt>sqltype</tt> can also be used to specify a different database type
--   
--   <pre>
--   Currency
--       Id String sqltype=varchar(3) sql=code
--   </pre>
--   
--   Composite key (using multiple columns) can also be defined using
--   <tt>Primary</tt>.
--   
--   <tt>sql=</tt> also works for setting the names of unique indexes.
--   
--   <pre>
--   Person
--     name Text
--     phone Text
--     UniquePersonPhone phone sql=UniqPerPhone
--   </pre>
--   
--   This makes a unique index requiring <tt>phone</tt> to be unique across
--   <tt>Person</tt> rows. Ordinarily Persistent will generate a snake-case
--   index name from the capitalized name provided such that
--   <tt>UniquePersonPhone</tt> becomes <tt>unique_person_phone</tt>.
--   However, we provided a <tt>sql=</tt> so the index name in the database
--   will instead be <tt>UniqPerPhone</tt>. Keep in mind <tt>sql=</tt> and
--   <tt>!</tt> attrs must come after the list of fields in front of the
--   index name in the quasi-quoter.
--   
--   <h1>Customizing Fields</h1>
--   
--   <h2>Nullable Fields</h2>
--   
--   As illustrated in the example at the beginning of this page, we are
--   able to represent nullable fields by including <a>Maybe</a> at the end
--   of the type declaration:
--   
--   <pre>
--   TableName
--       fieldName      FieldType
--       otherField     String
--       nullableField  Int       Maybe
--   </pre>
--   
--   Alternatively we can specify the keyword nullable:
--   
--   <pre>
--   TableName
--       fieldName      FieldType
--       otherField     String
--       nullableField  Int       nullable
--   </pre>
--   
--   However the difference here is in the first instance the Haskell type
--   will be 'Maybe Int', but in the second it will be <a>Int</a>. Be aware
--   that this will cause runtime errors if the database returns
--   <tt>NULL</tt> and the <tt>PersistField</tt> instance does not handle
--   <tt>PersistNull</tt>.
--   
--   If you wish to define your Maybe types in a way that is similar to the
--   actual Haskell definition, you can define 'Maybe Int' like so:
--   
--   <pre>
--   TableName
--       fieldName      FieldType
--       otherField     String
--       nullableField  (Maybe Int)
--   </pre>
--   
--   However, note, the field _must_ be enclosed in parenthesis.
--   
--   <h2><tt>sqltype=</tt></h2>
--   
--   By default, Persistent maps the Haskell types you specify in the
--   Models DSL to an appropriate SQL type in the database (refer to the
--   section "Conversion table (migrations)" for the default mappings).
--   Using the <tt>sqltype=</tt> option, you can customize the SQL type
--   Persistent uses for your column. Use cases include:
--   
--   <ul>
--   <li>Interacting with an existing database whose column types don't
--   match Persistent's defaults.</li>
--   <li>Taking advantage of a specific SQL type's features</li>
--   <li>e.g. Using an equivalent type that has better space or performance
--   characteristics</li>
--   </ul>
--   
--   To use this setting, add the <tt>sqltype=</tt> option after declaring
--   your field name and type:
--   
--   <pre>
--   User
--       username Text sqltype=varchar(255)
--   </pre>
--   
--   <h2>Laziness</h2>
--   
--   By default the records created by persistent have strict fields. You
--   can prefix a field name with <tt>~</tt> to make it lazy (or <tt>!</tt>
--   to make it strict).
--   
--   <h2>Attributes</h2>
--   
--   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 <tt>entityAttrs</tt> field and the
--   <tt>fieldAttrs</tt> field.
--   
--   <pre>
--   userAttrs = do
--       let userDefinition = <tt>entityDef</tt> (<tt>Proxy</tt> :: <tt>Proxy</tt> User)
--       let userAttributes = <tt>entityAttrs</tt> userDefinition
--       let fieldAttributes = <a>map</a> <tt>fieldAttrs</tt> (<tt>entityFields</tt> userDefinition)
--       print userAttributes
--   -- ["funny"]
--       print fieldAttributes
--   -- [["sad"],["sogood"]]
--   </pre>
--   
--   <h2><tt>!no-migrate</tt></h2>
--   
--   To prevent <tt>migrateModels</tt> from generating _any_ migrations for
--   an entity, add the <tt>!no-migrate</tt> attribute to it's definition:
--   
--   <pre>
--   User !no-migrate
--       field   String
--       good    Dog
--   </pre>
--   
--   <h2><tt>MigrationOnly</tt></h2>
--   
--   Introduced with <tt>persistent-template</tt> 1.2.0. The purpose of
--   this attribute is to mark a field which will be entirely ignored by
--   the normal processing, but retained in the database definition for
--   purposes of migration. This means, in SQL, a column will not be
--   flagged for removal by the migration scripts, even though it is not
--   used in your code. This is useful for phasing out usage of a column
--   before entirely removing it, or having columns which are needed by
--   other tools but not by Persistent.
--   
--   <pre>
--   Person
--       name Text
--       age Int
--       unusedField ByteString Maybe MigrationOnly
--   </pre>
--   
--   Note that you almost certainly want to either mark the field as
--   <tt>Maybe</tt> or provide a default value, otherwise insertions will
--   fail.
--   
--   <h2><tt>SafeToRemove</tt></h2>
--   
--   This is intended to be used as part of a deprecation of a field, after
--   <tt>MigrationOnly</tt> has been used usually. This works somewhat as a
--   superset of the functionality of <tt>MigrationOnly</tt>. In addition,
--   the field will be removed from the database if it is present. Note
--   that this is a destructive change which you are marking as safe.
--   
--   <h2>Constraints</h2>
--   
--   Migration will remove any manual constraints from your tables.
--   Exception: constraints whose names begin with the string
--   <tt>__manual_</tt> (which starts with two underscores) will be
--   preserved.
--   
--   <h1>Foreign Keys</h1>
--   
--   If you define an entity and want to refer to it in another table, you
--   can use the entity's Id type in a column directly.
--   
--   <pre>
--   Person
--       name    Text
--   
--   Dog
--       name    Text
--       owner   PersonId
--   </pre>
--   
--   This automatically creates a foreign key reference from <tt>Dog</tt>
--   to <tt>Person</tt>. The foreign key constraint means that, if you have
--   a <tt>PersonId</tt> on the <tt>Dog</tt>, the database guarantees that
--   the corresponding <tt>Person</tt> exists in the database. If you try
--   to delete a <tt>Person</tt> out of the database that has a
--   <tt>Dog</tt>, you'll receive an exception that a foreign key violation
--   has occurred.
--   
--   <h2><tt>constraint=</tt></h2>
--   
--   You can use the <tt>constraint=</tt> attribute to override the
--   constraint name used in migrations. This is useful particularly when
--   the automatically generated constraint names exceed database limits
--   (e.g. MySQL does not allow constraint names longer than 64
--   characters).
--   
--   <pre>
--   VeryLongTableName
--     name Text
--   
--   AnotherVeryLongTableName
--     veryLongTableNameId VeryLongTableNameId constraint=short_foreign_key
--   </pre>
--   
--   <h2>OnUpdate and OnDelete</h2>
--   
--   These options affects how a referring record behaves when the target
--   record is changed. There are several options:
--   
--   <ul>
--   <li><tt>Restrict</tt> - This is the default. It prevents the action
--   from occurring.</li>
--   <li><tt>Cascade</tt> - this copies the change to the child record. If
--   a parent record is deleted, then the child record will be deleted
--   too.</li>
--   <li><tt>SetNull</tt> - If the parent record is modified, then this
--   sets the reference to <tt>NULL</tt>. This only works on <tt>Maybe</tt>
--   foreign keys.</li>
--   <li><tt>SetDefault</tt> - This will set the column's value to the
--   <tt>default</tt> for the column, if specified.</li>
--   </ul>
--   
--   To specify the behavior for a reference, write <tt>OnUpdate</tt> or
--   <tt>OnDelete</tt> followed by the action.
--   
--   <pre>
--   Record
--       -- If the referred Foo is deleted or updated, then this record will
--       -- also be deleted or updated.
--       fooId   FooId   OnDeleteCascade OnUpdateCascade
--   
--       -- If the referred Bar is deleted, then we'll set the reference to
--       -- <a>Nothing</a>. If the referred Bar is updated, then we'll cascade the
--       -- update.
--       barId   BarId Maybe     OnDeleteSetNull OnUpdateCascade
--   
--       -- If the referred Baz is deleted, then we set to the default ID.
--       bazId   BazId   OnDeleteSetDefault  default=1
--   </pre>
--   
--   Let's demonstrate this with a shopping cart example.
--   
--   <pre>
--   User
--       name    Text
--   
--   Cart
--       user    UserId Maybe
--   
--   CartItem
--       cartId  CartId
--       itemId  ItemId
--   
--   Item
--       name    Text
--       price   Int
--   </pre>
--   
--   Let's consider how we want to handle deletions and updates. If a
--   <tt>User</tt> is deleted or update, then we want to cascade the action
--   to the associated <tt>Cart</tt>.
--   
--   <pre>
--   Cart
--       user    UserId Maybe OnDeleteCascade OnUpdateCascade
--   </pre>
--   
--   If an <tt>Item</tt> is deleted, then we want to set the
--   <tt>CartItem</tt> to refer to a special "deleted item" in the
--   database. If a <tt>Cart</tt> is deleted, though, then we just want to
--   delete the <tt>CartItem</tt>.
--   
--   <pre>
--   CartItem
--       cartId CartId   OnDeleteCascade
--       itemId ItemId   OnDeleteSetDefault default=1
--   </pre>
--   
--   <h2><tt>Foreign</tt> keyword</h2>
--   
--   The above example is a "simple" foreign key. It refers directly to the
--   Id column, and it only works with a non-composite primary key. We can
--   define more complicated foreign keys using the <tt>Foreign</tt>
--   keyword.
--   
--   A pseudo formal syntax for <tt>Foreign</tt> is:
--   
--   <pre>
--   Foreign $(TargetEntity) [$(cascade-actions)] $(constraint-name) $(columns) [ $(references) ]
--   
--   columns := column0 [column1 column2 .. columnX]
--   references := References $(target-columns)
--   target-columns := target-column0 [target-column1 target-columns2 .. target-columnX]
--   </pre>
--   
--   Columns are the columns as defined on this entity.
--   <tt>target-columns</tt> are the columns as defined on the target
--   entity.
--   
--   Let's look at some examples.
--   
--   <h3>Composite Primary Key References</h3>
--   
--   The most common use for this is to refer to a composite primary key.
--   Since composite primary keys take up more than one column, we can't
--   refer to them with a single <tt>persistent</tt> column.
--   
--   <pre>
--   Email
--       firstPart   Text
--       secondPart  Text
--       Primary firstPart secondPart
--   
--   User
--       name            Text
--       emailFirstPart  Text
--       emailSecondPart Text
--   
--       Foreign Email fk_user_email emailFirstPart emailSecondPart
--   </pre>
--   
--   If you omit the <tt>References</tt> keyword, then it assumes that the
--   foreign key reference is for the target table's primary key. If we
--   wanted to be fully redundant, we could specify the <tt>References</tt>
--   keyword.
--   
--   <pre>
--   Foreign Email fk_user_email emailFirstPart emailSecondPart References firstPart secondPart
--   </pre>
--   
--   We can specify delete/cascade behavior directly after the target
--   table.
--   
--   <pre>
--   Foreign Email OnDeleteCascade OnUpdateCascade fk_user_email emailFirstPart emailSecondPart
--   </pre>
--   
--   Now, if the email is deleted or updated, the user will be deleted or
--   updated to match.
--   
--   <h3>Non-Primary Key References</h3>
--   
--   SQL database backends allow you to create a foreign key to any
--   column(s) with a Unique constraint. Persistent does not check this,
--   because you might be defining your uniqueness constraints outside of
--   Persistent. To do this, we must use the <tt>References</tt> keyword.
--   
--   <pre>
--   User
--       name    Text
--       email   Text
--   
--       UniqueEmail email
--   
--   Notification
--       content Text
--       sentTo  Text
--   
--       Foreign User fk_noti_user sentTo References email
--   </pre>
--   
--   If the target uniqueness constraint has multiple columns, then you
--   must specify them independently.
--   
--   <pre>
--   User
--       name            Text
--       emailFirst      Text
--       emailSecond     Text
--   
--       UniqueEmail emailFirst emailSecond
--   
--   Notification
--       content         Text
--       sentToFirst     Text
--       sentToSecond    Text
--   
--       Foreign User fk_noti_user sentToFirst sentToSecond References emailFirst emailSecond
--   </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 <tt>entityComments</tt> field on
--   the <tt>EntityDef</tt> 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
--   <tt>fieldComments</tt> field on the <tt>FieldDef</tt> present in the
--   <tt>EntityDef</tt>:
--   
--   <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>
--   
--   Since <tt>persistent-2.14.6.0</tt>, documentation comments are
--   included in documentation generated using Haddock if
--   <tt>mpsEntityHaddocks</tt> is enabled (defaults to False).
--   <tt>persistent</tt> backends can also 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.
--   
--   <h1>Sum types</h1>
--   
--   <h2>Field level</h2>
--   
--   You'll frequently want to store an enum of values in your database.
--   For example, you might describe a <tt>Person</tt>'s employment status
--   as being <tt>Employed</tt>, <tt>Unemployed</tt>, or <tt>Retired</tt>.
--   In Haskell this is represented with a sum type, and Persistent
--   provides a Template Haskell function to marshall these values to and
--   from the database:
--   
--   <pre>
--   -- @Employment.hs
--   {-# LANGUAGE TemplateHaskell #-}
--   module Employment where
--   
--   import Database.Persist.TH
--   import Prelude
--   
--   data Employment = Employed | Unemployed | Retired
--       deriving (Show, Read, Eq)
--   derivePersistField <a>Employment</a>
--   </pre>
--   
--   <tt>derivePersistField</tt> stores sum type values as strins in the
--   database. While not as efficient as using integers, this approach
--   simplifies adding and removing values from your enumeration.
--   
--   Due to the GHC Stage Restriction, the call to the Template Haskell
--   function <tt>derivePersistField</tt> must be in a separate module than
--   where the generated code is used.
--   
--   Note: If you created a new module, make sure add it to the
--   <tt>exposed-modules</tt> section of your Cabal file.
--   
--   Use the module by importing it into your <tt>Model.hs</tt> file:
--   
--   <pre>
--   -- @Model.hs
--   import Employment
--   </pre>
--   
--   and use it in the <tt>models</tt> DSL:
--   
--   <pre>
--   Person
--       employment Employment
--   </pre>
--   
--   You can export the Employment module from Import to use it across your
--   app:
--   
--   <pre>
--   -- @Import.hs
--   import Employment as Import
--   </pre>
--   
--   <h3>Entity-level</h3>
--   
--   NOTE: This feature is deprecated as of version 2.14 and will be
--   removed in 2.15 (unless there are many complaints).
--   
--   The <a>tests for this feature</a> demonstrate their usage. Note the
--   use of the sign <tt>+</tt> in front of the entity name.
--   
--   The schema in the test is reproduced here:
--   
--   <pre>
--   share [mkPersist persistSettings, mkMigrate "sumTypeMigrate"] [persistLowerCase|
--   Bicycle
--       brand T.Text
--   Car
--       make T.Text
--       model T.Text
--   +Vehicle
--       bicycle BicycleId
--       car CarId
--   |]
--   </pre>
--   
--   Let's check out the definition of the Haskell type <tt>Vehicle</tt>.
--   Using <tt>ghci</tt>, we can query for <tt>:info Vehicle</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; :i Vehicle
--   type Vehicle = VehicleGeneric SqlBackend
--           -- Defined at .../Projects/persistent/persistent-test/src/SumTypeTest.hs:26:1
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; :i VehicleGeneric
--   type role VehicleGeneric nominal
--   data VehicleGeneric backend
--     = VehicleBicycleSum (Key (BicycleGeneric backend))
--     | VehicleCarSum (Key (CarGeneric backend))
--           -- Defined at .../persistent/persistent-test/src/SumTypeTest.hs:26:1
--   -- lots of instances follow...
--   </pre>
--   
--   A <tt>VehicleGeneric</tt> has two constructors:
--   
--   <ul>
--   <li><tt>VehicleBicycleSum</tt> with a <tt>Key (BicycleGeneric
--   backend)</tt> field</li>
--   <li><tt>VehicleCarSum</tt> with a <tt>Key (CarGeneric backend)</tt>
--   field</li>
--   </ul>
--   
--   The <tt>Bicycle</tt> and <tt>Car</tt> are typical <tt>persistent</tt>
--   entities.
--   
--   This generates the following SQL migrations (formatted for
--   readability):
--   
--   <pre>
--   CREATE TABLE "bicycle" (
--       "id"        INTEGER PRIMARY KEY,
--       "brand"     VARCHAR NOT NULL
--   );
--   
--   CREATE TABLE "car"(
--       "id"        INTEGER PRIMARY KEY,
--       "make"      VARCHAR NOT NULL,
--       "model"     VARCHAR NOT NULL
--   );
--   
--   CREATE TABLE "vehicle"(
--       "id"        INTEGER PRIMARY KEY,
--       "bicycle"   INTEGER NULL REFERENCES "bicycle",
--       "car"       INTEGER NULL REFERENCES "car"
--   );
--   </pre>
--   
--   The <tt>vehicle</tt> table contains a nullable foreign key reference
--   to both the bicycle and the car tables.
--   
--   A SQL query that grabs all the vehicles from the database looks like
--   this (note the <tt>??</tt> is for the <tt>persistent</tt> raw SQL
--   query functions):
--   
--   <pre>
--   SELECT ??, ??, ??
--   FROM vehicle
--   LEFT JOIN car
--       ON vehicle.car = car.id
--   LEFT JOIN bicycle
--       ON vehicle.bicycle = bicycle.id
--   </pre>
--   
--   If we use the above query with <tt>rawSql</tt>, we'd get the following
--   result:
--   
--   <pre>
--   getVehicles
--       :: SqlPersistM
--           [ ( Entity Vehicle
--             , Maybe (Entity Bicycle)
--             , Maybe (Entity Car)
--             )
--           ]
--   </pre>
--   
--   This result has some post-conditions that are not guaranteed by the
--   types *or* the schema. The constructor for <tt>Entity Vehicle</tt> is
--   going to determine which of the other members of the tuple is
--   <tt>Nothing</tt>. We can convert this to a friendlier domain model
--   like this:
--   
--   <pre>
--   data Vehicle'
--       = Car' Text Text
--       | Bike Text
--   
--   check = do
--       result &lt;- getVehicles
--       pure (map convert result)
--   
--   convert
--       :: (Entity Vehicle, Maybe (Entity Bicycle), Maybe (Entity Car))
--       -&gt; Vehicle'
--   convert (Entity _ (VehicleBicycleSum _), Just (Entity _ (Bicycle brand)), _) =
--       Bike brand
--   convert (Entity _ (VehicleCarSum _), _, Just (Entity _ (Car make model))) =
--       Car make model
--   convert _ =
--       error "The database preconditions have been violated!"
--   </pre>
--   
--   <h2>Times with timezones</h2>
--   
--   Storing times with timezones in one type in databases is not possible,
--   although it seems that it should be possible (<tt>timezone</tt> and
--   <tt>timezonetz</tt> in PostgreSQL). That's why starting with
--   persistent 2.0, all times will be mapped to <tt>UTCTime</tt>. If you
--   need to store timezone information along with times in a database,
--   store the timezone in a second field. Here are some links about the
--   topic with further information:
--   
--   <ul>
--   <li><a>https://github.com/yesodweb/persistent/issues/290</a></li>
--   
--   <li><a>https://groups.google.com/forum/#!msg/yesodweb/MIfcV2bwM80/8QLFpgp1LykJ</a></li>
--   
--   <li><a>http://stackoverflow.com/questions/14615271/postgres-timestamp/14616640#14616640</a></li>
--   
--   <li><a>http://justatheory.com/computers/databases/postgresql/use-timestamptz.html</a></li>
--   <li><a>https://github.com/lpsmith/postgresql-simple/issues/69</a></li>
--   
--   <li><a>https://github.com/nikita-volkov/hasql-postgres/issues/1</a></li>
--   </ul>
--   
--   <h1>Conversion table (migrations)</h1>
--   
--   Here are the conversions between Haskell types and database types:
--   
--   TODO: table
--   
--   Notes:
--   
--   * Support for <tt>ZonedTime</tt> was dropped in persistent 2.0.
--   <tt>UTCTime</tt> can be used with <tt>timestamp without timezone</tt>
--   and <tt>timestamp with timezone</tt> in PostgreSQL. See also the
--   section "Times with timezones".
--   
--   ** The default resolution for <tt>TIME</tt> and <tt>DATETIME</tt> in
--   MySQL is one second. As of MySQL version 5.6.4, and
--   persistent-mysql-2.6.2, fractional seconds are handled correctly if
--   you declare an explicit precision by using <tt>sqltype</tt>. For
--   example, appending <tt>sqltype=TIME(6)</tt> to a <tt>TimeOfDay</tt>
--   field definition will give microsecond resolution.
--   
--   <h1>Compatibility tables</h1>
--   
--   MySQL:
--   
--   TODO: table
--   
--   * When <tt>Word</tt> size is 64bit
--   
--   ** Utf8 only
--   
--   Unsupported types:
--   
--   TODO: table
--   
--   See <a>MySQL.Simple.Result</a>.
module Database.Persist.Quasi

-- | Parses a quasi-quoted syntax into a list of entity definitions.
parse :: PersistSettings -> [(Maybe SourceLoc, Text)] -> CumulativeParseResult [UnboundEntityDef]
data PersistSettings
upperCaseSettings :: PersistSettings
lowerCaseSettings :: PersistSettings

-- | Retrieve the function in the <a>PersistSettings</a> that modifies the
--   names into database names.
getPsToDBName :: PersistSettings -> Text -> Text

-- | Set the name modification function that translates the QuasiQuoted
--   names for use in the database.
setPsToDBName :: (Text -> Text) -> PersistSettings -> PersistSettings

-- | Set a custom function used to create the constraint name for a foreign
--   key.
setPsToFKName :: (EntityNameHS -> ConstraintNameHS -> Text) -> PersistSettings -> PersistSettings

-- | A preset configuration function that puts an underscore between the
--   entity name and the constraint name when creating a foreign key
--   constraint name
setPsUseSnakeCaseForeignKeys :: PersistSettings -> PersistSettings

-- | Equivalent to <a>setPsUseSnakeCaseForeignKeys</a>, but misspelled.

-- | <i>Deprecated: use the correctly spelled, equivalent,
--   setPsUseSnakeCaseForeignKeys instead</i>
setPsUseSnakeCaseForiegnKeys :: PersistSettings -> PersistSettings

-- | Retrieve whether or not the <a>PersistSettings</a> will generate code
--   with strict fields.
getPsStrictFields :: PersistSettings -> Bool

-- | Set whether or not the <a>PersistSettings</a> will make fields strict.
setPsStrictFields :: Bool -> PersistSettings -> PersistSettings

-- | Retrieve the default name of the <tt>id</tt> column.
getPsIdName :: PersistSettings -> Text

-- | Set the default name of the <tt>id</tt> column.
setPsIdName :: Text -> PersistSettings -> PersistSettings

-- | Retrieve the severity of the error generated when the parser
--   encounters a tab. If it is <tt>Nothing</tt>, tabs are permitted in
--   entity definitions.
getPsTabErrorLevel :: PersistSettings -> Maybe ParserErrorLevel

-- | Set the severity of the error generated when the parser encounters a
--   tab. If set to <tt>Nothing</tt>, tabs are permitted in entity
--   definitions.
setPsTabErrorLevel :: Maybe ParserErrorLevel -> PersistSettings -> PersistSettings

-- | Retrieve the severity of the error generated when the parser
--   encounters a quoted entity field attribute or quoted directive
--   argument. If it is <tt>Nothing</tt>, quoted arguments are permitted in
--   both entity field definitions and directives.
getPsQuotedArgumentErrorLevel :: PersistSettings -> Maybe ParserErrorLevel

-- | Set the severity of the error generated when the parser encounters a
--   quoted entity field attribute. If set to <tt>Nothing</tt>, quoted
--   arguments are permitted in both entity field definitions and
--   directives.
setPsQuotedArgumentErrorLevel :: Maybe ParserErrorLevel -> PersistSettings -> PersistSettings


-- | This module provides the tools for defining your database schema and
--   using it to generate Haskell data types and migrations.
--   
--   For documentation on the domain specific language used for defining
--   database models, see <a>Database.Persist.Quasi</a>.
module Database.Persist.TH.Internal

-- | Converts a quasi-quoted syntax into a list of entity definitions, to
--   be used as input to the template haskell generation code (mkPersist).
persistWith :: PersistSettings -> QuasiQuoter

-- | Apply <a>persistWith</a> to <a>upperCaseSettings</a>.
persistUpperCase :: QuasiQuoter

-- | Apply <a>persistWith</a> to <a>lowerCaseSettings</a>.
persistLowerCase :: QuasiQuoter

-- | Same as <a>persistWith</a>, but uses an external file instead of a
--   quasiquotation. The recommended file extension is
--   <tt>.persistentmodels</tt>.
persistFileWith :: PersistSettings -> FilePath -> Q Exp

-- | Same as <a>persistFileWith</a>, but uses several external files
--   instead of one. Splitting your Persistent definitions into multiple
--   modules can potentially dramatically speed up compile times.
--   
--   The recommended file extension is <tt>.persistentmodels</tt>.
--   
--   <h4><b>Examples</b></h4>
--   
--   Split your Persistent definitions into multiple files
--   (<tt>models1</tt>, <tt>models2</tt>), then create a new module for
--   each new file and run <a>mkPersist</a> there:
--   
--   <pre>
--   -- Model1.hs
--   <a>share</a>
--       [<a>mkPersist</a> <a>sqlSettings</a>]
--       $(<a>persistFileWith</a> <a>lowerCaseSettings</a> "models1")
--   </pre>
--   
--   <pre>
--   -- Model2.hs
--   <a>share</a>
--       [<a>mkPersist</a> <a>sqlSettings</a>]
--       $(<a>persistFileWith</a> <a>lowerCaseSettings</a> "models2")
--   </pre>
--   
--   Use <a>persistManyFileWith</a> to create your migrations:
--   
--   <pre>
--   -- Migrate.hs
--   <a>mkMigrate</a> "migrateAll"
--       $(<a>persistManyFileWith</a> <a>lowerCaseSettings</a> ["models1.persistentmodels","models2.persistentmodels"])
--   </pre>
--   
--   Tip: To get the same import behavior as if you were declaring all your
--   models in one file, import your new files <tt>as Name</tt> into
--   another file, then export <tt>module Name</tt>.
--   
--   This approach may be used in the future to reduce memory usage during
--   compilation, but so far we've only seen mild reductions.
--   
--   See <a>persistent#778</a> and <a>persistent#791</a> for more details.
persistManyFileWith :: PersistSettings -> [FilePath] -> Q Exp

-- | Create data types and appropriate <a>PersistEntity</a> instances for
--   the given <a>UnboundEntityDef</a>s.
--   
--   This function should be used if you are only defining a single block
--   of Persistent models for the entire application. If you intend on
--   defining multiple blocks in different fiels, see <a>mkPersistWith</a>
--   which allows you to provide existing entity definitions so foreign key
--   references work.
--   
--   Example:
--   
--   <pre>
--   mkPersist <a>sqlSettings</a> [<a>persistLowerCase</a>|
--        User
--            name    Text
--            age     Int
--   
--        Dog
--            name    Text
--            owner   UserId
--   
--   |]
--   </pre>
--   
--   Example from a file:
--   
--   <pre>
--   mkPersist <a>sqlSettings</a> $(<a>persistFileWith</a> <a>lowerCaseSettings</a> "models.persistentmodels")
--   </pre>
--   
--   For full information on the <a>QuasiQuoter</a> syntax, see
--   <a>Database.Persist.Quasi</a> documentation.
mkPersist :: MkPersistSettings -> [UnboundEntityDef] -> Q [Dec]

-- | Like <a>mkPersist</a>, but allows you to provide a
--   <tt>[<a>EntityDef</a>]</tt> representing the predefined entities. This
--   function will include those <a>EntityDef</a> when looking for foreign
--   key references.
--   
--   You should use this if you intend on defining Persistent models in
--   multiple files.
--   
--   Suppose we define a table <tt>Foo</tt> which has no dependencies.
--   
--   <pre>
--   module DB.Foo where
--   
--       <a>mkPersistWith</a> <a>sqlSettings</a> [] [<a>persistLowerCase</a>|
--           Foo
--              name    Text
--          |]
--   </pre>
--   
--   Then, we define a table <tt>Bar</tt> which depends on <tt>Foo</tt>:
--   
--   <pre>
--   module DB.Bar where
--   
--       import DB.Foo
--   
--       <a>mkPersistWith</a> <a>sqlSettings</a> [entityDef (Proxy :: Proxy Foo)] [<a>persistLowerCase</a>|
--           Bar
--               fooId  FooId
--        |]
--   </pre>
--   
--   Writing out the list of <a>EntityDef</a> can be annoying. The
--   <tt>$(<a>discoverEntities</a>)</tt> shortcut will work to reduce this
--   boilerplate.
--   
--   <pre>
--   module DB.Quux where
--   
--       import DB.Foo
--       import DB.Bar
--   
--       <a>mkPersistWith</a> <a>sqlSettings</a> $(<a>discoverEntities</a>) [<a>persistLowerCase</a>|
--           Quux
--               name     Text
--               fooId    FooId
--               barId    BarId
--        |]
--   </pre>
mkPersistWith :: MkPersistSettings -> [EntityDef] -> [UnboundEntityDef] -> Q [Dec]

-- | Settings that can be passed to the <a>mkPersist</a> (mps) function to
--   control what code is generated. This is (just) the data type
--   definition, so you will most likely want to use and adapt concrete
--   values like <a>sqlSettings</a>.
data MkPersistSettings

-- | Create an <tt>MkPersistSettings</tt> with default values.
mkPersistSettings :: Type -> MkPersistSettings

-- | Use the <tt>SqlPersist</tt> backend.
sqlSettings :: MkPersistSettings

-- | Which database backend we're using. This type is used for the
--   <a>PersistEntityBackend</a> associated type in the entities that are
--   generated.
--   
--   If the <a>mpsGeneric</a> value is set to <a>True</a>, then this type
--   is used for the non-Generic type alias. The data and type will be
--   named:
--   
--   <pre>
--   data ModelGeneric backend = Model { ... }
--   </pre>
--   
--   And, for convenience's sake, we provide a type alias:
--   
--   <pre>
--   type Model = ModelGeneric $(the type you give here)
--   </pre>
mpsBackend :: MkPersistSettings -> Type

-- | Create generic types that can be used with multiple backends. Good for
--   reusable code, but makes error messages harder to understand. Default:
--   False.

-- | <i>Deprecated: The mpsGeneric function adds a considerable amount of
--   overhead and complexity to the library without bringing significant
--   benefit. We would like to remove it. If you require this feature,
--   please comment on the linked GitHub issue, and we'll either keep it
--   around, or we can figure out a nicer way to solve your problem.
--   Github: <a>https://github.com/yesodweb/persistent/issues/1204</a></i>
mpsGeneric :: MkPersistSettings -> Bool

-- | Prefix field names with the model name. Default: True.
--   
--   Note: this field is deprecated. Use the <a>mpsFieldLabelModifier</a>
--   and <a>mpsConstraintLabelModifier</a> instead.
mpsPrefixFields :: MkPersistSettings -> Bool

-- | Customise the field names (and lens names) for generated entity data
--   types.
--   
--   Default: appends entity name and field name, equivalent to
--   
--   <pre>
--   mpsFieldLabelModifier = \entityName fieldName -&gt; entityName &lt;&gt; fieldName
--   </pre>
--   
--   to avoid duplicate record field collisions.
--   
--   For example, with default <a>sqlSettings</a> and
--   
--   <pre>
--   <a>mkPersistWith</a> <a>sqlSettings</a> [] [<a>persistLowerCase</a>|
--       Person
--           name   Text
--           age    Int
--   |]
--   </pre>
--   
--   it will generate the entity data type
--   
--   <pre>
--   Person {
--       personName :: Text,  -- generated field name
--       personAge  :: Int    -- generated field name
--   }
--   </pre>
--   
--   Note: this setting is ignored if the deprecated <a>mpsPrefixFields</a>
--   is set to False.
--   
--   <h3><b>Example without entity name</b></h3>
--   
--   You may not want the entity name prefix for all fields, so use
--   
--   <pre>
--   <a>mkPersistWith</a> (<a>sqlSettings</a> { mpsFieldLabelModifier = \_entityName fieldName -&gt; fieldName }) [] [<a>persistLowerCase</a>|
--       Person
--           name   Text
--           age    Int
--   |]
--   </pre>
--   
--   instead. This will generate the entity data type
--   
--   <pre>
--   Person {
--       name :: Text,
--       age  :: Int
--   }
--   </pre>
--   
--   When you have multiple entites with the same field name, you might
--   need to add <tt>{-# LANGUAGE DuplicateRecordFields #-}</tt> for your
--   code to compile.
mpsFieldLabelModifier :: MkPersistSettings -> Text -> Text -> Text

-- | Customise function for field accessors applied only when the field
--   name matches any of Haskell keywords.
--   
--   Default: suffix "_".
mpsAvoidHsKeyword :: MkPersistSettings -> Text -> Text

-- | Customise the Constraint names using the entity and field name. The
--   result should be a valid haskell type (start with an upper cased
--   letter).
--   
--   Default: appends entity and field
--   
--   Note: this setting is ignored if the deprecated <a>mpsPrefixFields</a>
--   is set to False.
mpsConstraintLabelModifier :: MkPersistSettings -> Text -> Text -> Text

-- | Generate Haddocks from entity documentation comments. Default: False.
mpsEntityHaddocks :: MkPersistSettings -> Bool

-- | Generate <tt>ToJSON</tt>/<tt>FromJSON</tt> instances for each model
--   types. If it's <tt>Nothing</tt>, no instances will be generated.
--   Default:
--   
--   <pre>
--   Just <a>EntityJSON</a>
--       { <a>entityToJSON</a> = 'entityIdToJSON
--       , <a>entityFromJSON</a> = 'entityIdFromJSON
--       }
--   </pre>
mpsEntityJSON :: MkPersistSettings -> Maybe EntityJSON

-- | Instead of generating normal field accessors, generator lens-style
--   accessors.
--   
--   Default: False
mpsGenerateLenses :: MkPersistSettings -> Bool

-- | Automatically derive these typeclass instances for all record and key
--   types.
--   
--   Default: []
mpsDeriveInstances :: MkPersistSettings -> [Name]

-- | Should we generate composite key accessors in the correct CamelCase
--   style.
--   
--   If the <a>mpsCamelCaseCompositeKeySelector</a> value is set to
--   <a>False</a>, then the field part of the accessor starts with the
--   lowercase. This is a legacy style.
--   
--   <pre>
--   data Key CompanyUser = CompanyUserKey
--     { companyUserKeycompanyId :: CompanyId
--     , companyUserKeyuserId :: UserId
--     }
--   </pre>
--   
--   If the <a>mpsCamelCaseCompositeKeySelector</a> value is set to
--   <a>True</a>, then field accessors are generated in CamelCase style.
--   
--   <pre>
--   data Key CompanyUser = CompanyUserKey
--     { companyUserKeyCompanyId :: CompanyId
--     , companyUserKeyUserId :: UserId
--     }
--   </pre>
--   
--   Default: False
mpsCamelCaseCompositeKeySelector :: MkPersistSettings -> Bool
data EntityJSON
EntityJSON :: Name -> Name -> EntityJSON

-- | Name of the <tt>toJSON</tt> implementation for <tt>Entity a</tt>.
[entityToJSON] :: EntityJSON -> Name

-- | Name of the <tt>fromJSON</tt> implementation for <tt>Entity a</tt>.
[entityFromJSON] :: EntityJSON -> Name

-- | A specification for how the implied ID columns are created.
--   
--   By default, <tt>persistent</tt> will give each table a default column
--   named <tt>id</tt> (customizable by <tt>PersistSettings</tt>), and the
--   column type will be whatever you'd expect from <tt><tt>BackendKey</tt>
--   yourBackendType</tt>. For The <tt>SqlBackend</tt> type, this is an
--   auto incrementing integer primary key.
--   
--   You might want to give a different example. A common use case in
--   postgresql is to use the UUID type, and automatically generate them
--   using a SQL function.
--   
--   Previously, you'd need to add a custom <tt>Id</tt> annotation for each
--   model.
--   
--   <pre>
--   User
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--   
--   Dog
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--       user UserId
--   </pre>
--   
--   Now, you can simply create an <a>ImplicitIdDef</a> that corresponds to
--   this declaration.
--   
--   <pre>
--   newtype UUID = UUID <tt>ByteString</tt>
--   
--   instance <a>PersistField</a> UUID where
--       <tt>toPersistValue</tt> (UUID bs) =
--           <a>PersistLiteral_</a> <a>Escaped</a> bs
--       <tt>fromPersistValue</tt> pv =
--           case pv of
--               PersistLiteral_ Escaped bs -&gt;
--                   Right (UUID bs)
--               _ -&gt;
--                   Left "nope"
--   
--   instance <a>PersistFieldSql</a> UUID where
--       <a>sqlType</a> _ = <a>SqlOther</a> <a>UUID</a>
--   </pre>
--   
--   With this instance at the ready, we can now create our implicit
--   definition:
--   
--   <pre>
--   uuidDef :: ImplicitIdDef
--   uuidDef = mkImplicitIdDef @UUID "uuid_generate_v1mc()"
--   </pre>
--   
--   And we can use <tt>setImplicitIdDef</tt> to use this with the
--   <tt>MkPersistSettings</tt> for our block.
--   
--   <pre>
--   mkPersist (setImplicitIdDef uuidDef sqlSettings) [persistLowerCase| ... |]
--   </pre>
--   
--   TODO: either explain interaction with mkMigrate or fix it. see issue
--   #1249 for more details.
data ImplicitIdDef

-- | Set the <a>ImplicitIdDef</a> in the given <a>MkPersistSettings</a>.
--   The default value is <a>autoIncrementingInteger</a>.
setImplicitIdDef :: ImplicitIdDef -> MkPersistSettings -> MkPersistSettings

-- | Creates a single function to perform all migrations for the entities
--   defined here. One thing to be aware of is dependencies: if you have
--   entities with foreign references, make sure to place those definitions
--   after the entities they reference.
--   
--   In <tt>persistent-2.13.0.0</tt>, this was changed to *ignore* the
--   input entity def list, and instead defer to <a>mkEntityDefList</a> to
--   get the correct entities. This avoids problems where the QuasiQuoter
--   is unable to know what the right reference types are. This sets
--   <a>mkPersist</a> to be the "single source of truth" for entity
--   definitions.
mkMigrate :: String -> [UnboundEntityDef] -> Q [Dec]

-- | The basic function for migrating models, no Template Haskell required.
--   
--   It's probably best to use this in concert with <a>mkEntityDefList</a>,
--   and then call <a>migrateModels</a> with the result from that function.
--   
--   <pre>
--   share [mkPersist sqlSettings, mkEntityDefList "entities"] [persistLowerCase| ... |]
--   
--   migrateAll = <a>migrateModels</a> entities
--   </pre>
--   
--   The function <a>mkMigrate</a> currently implements exactly this
--   behavior now. If you're splitting up the entity definitions into
--   separate files, then it is better to use the entity definition list
--   and the concatenate all the models together into a big list to call
--   with <a>migrateModels</a>.
--   
--   <pre>
--   module Foo where
--   
--       share [mkPersist s, mkEntityDefList "fooModels"] ...
--   
--   
--   module Bar where
--   
--       share [mkPersist s, mkEntityDefList "barModels"] ...
--   
--   module Migration where
--   
--       import Foo
--       import Bar
--   
--       migrateAll = migrateModels (fooModels &lt;&gt; barModels)
--   </pre>
migrateModels :: [EntityDef] -> Migration

-- | Splice in a list of all <a>EntityDef</a> in scope. This is useful when
--   running <a>mkPersist</a> to ensure that all entity definitions are
--   available for setting foreign keys, and for performing migrations with
--   all entities available.
--   
--   <a>mkPersist</a> has the type <tt>MkPersistSettings -&gt; [EntityDef]
--   -&gt; DecsQ</tt>. So, to account for entities defined elsewhere,
--   you'll <tt>mappend $(discoverEntities)</tt>.
--   
--   For example,
--   
--   <pre>
--   share
--     [ mkPersistWith sqlSettings $(discoverEntities)
--     ]
--     [persistLowerCase| ... |]
--   </pre>
--   
--   Likewise, to run migrations with all entity instances in scope, you'd
--   write:
--   
--   <pre>
--   migrateAll = migrateModels $(discoverEntities)
--   </pre>
--   
--   Note that there is some odd behavior with Template Haskell and
--   splicing groups. If you call <a>discoverEntities</a> in the same
--   module that defines <a>PersistEntity</a> instances, you need to ensure
--   they are in different top-level binding groups. You can write
--   <tt>$(pure [])</tt> at the top level to do this.
--   
--   <pre>
--   -- Foo and Bar both export an instance of PersistEntity
--   import Foo
--   import Bar
--   
--   -- Since Foo and Bar are both imported, discoverEntities can find them here.
--   mkPersistWith sqlSettings $(discoverEntities) [persistLowerCase|
--     User
--       name Text
--       age  Int
--     |]
--   
--   -- onlyFooBar is defined in the same 'top level group' as the above generated
--   -- instance for User, so it isn't present in this list.
--   onlyFooBar :: [EntityDef]
--   onlyFooBar = $(discoverEntities)
--   
--   -- We can manually create a new binding group with this, which splices an
--   -- empty list of declarations in.
--   $(pure [])
--   
--   -- fooBarUser is able to see the <tt>User</tt> instance.
--   fooBarUser :: [EntityDef]
--   fooBarUser = $(discoverEntities)
--   </pre>
discoverEntities :: Q Exp

-- | Creates a declaration for the <tt>[<a>EntityDef</a>]</tt> from the
--   <tt>persistent</tt> schema. This is necessary because the Persistent
--   QuasiQuoter is unable to know the correct type of ID fields, and
--   assumes that they are all Int64.
--   
--   Provide this in the list you give to <a>share</a>, much like
--   <tt><a>mkMigrate</a></tt>.
--   
--   <pre>
--   <a>share</a> [<a>mkMigrate</a> "migrateAll", <a>mkEntityDefList</a> "entityDefs"] [...]
--   </pre>
mkEntityDefList :: String -> [UnboundEntityDef] -> Q [Dec]

-- | Apply the given list of functions to the same <tt>EntityDef</tt>s.
--   
--   This function is useful for cases such as:
--   
--   <pre>
--   share [<a>mkEntityDefList</a> "myDefs", <a>mkPersist</a> sqlSettings] [<a>persistLowerCase</a>|
--       -- ...
--   |]
--   </pre>
--   
--   If you only have a single function, though, you don't need this. The
--   following is redundant:
--   
--   <pre>
--   <a>share</a> [<a>mkPersist</a> <a>sqlSettings</a>] [<a>persistLowerCase</a>|
--        -- ...
--   |]
--   </pre>
--   
--   Most functions require a full <tt>[<a>EntityDef</a>]</tt>, which can
--   be provided using <tt>$(<a>discoverEntities</a>)</tt> for all entites
--   in scope, or defining <a>mkEntityDefList</a> to define a list of
--   entities from the given block.
share :: [[a] -> Q [Dec]] -> [a] -> Q [Dec]

-- | Automatically creates a valid <a>PersistField</a> instance for any
--   datatype that has valid <a>Show</a> and <a>Read</a> instances. Can be
--   very convenient for <a>Enum</a> types.
derivePersistField :: String -> Q [Dec]

-- | Automatically creates a valid <a>PersistField</a> instance for any
--   datatype that has valid <a>ToJSON</a> and <a>FromJSON</a> instances.
--   For a datatype <tt>T</tt> it generates instances similar to these:
--   
--   <pre>
--   instance PersistField T where
--       toPersistValue = PersistByteString . L.toStrict . encode
--       fromPersistValue = (left T.pack) . eitherDecodeStrict' &lt;=&lt; fromPersistValue
--   instance PersistFieldSql T where
--       sqlType _ = SqlString
--   </pre>
derivePersistFieldJSON :: String -> Q [Dec]

-- | Produce code similar to the following:
--   
--   <pre>
--   instance PersistEntity e =&gt; PersistField e where
--      toPersistValue = entityToPersistValueHelper
--      fromPersistValue = entityFromPersistValueHelper ["col1", "col2"]
--      sqlType _ = SqlString
--   </pre>
persistFieldFromEntity :: MkPersistSettings -> UnboundEntityDef -> Q [Dec]
lensPTH :: (s -> a) -> (s -> b -> t) -> Lens s t a b

-- | Calls <a>parse</a> to Quasi.parse individual entities in isolation
--   afterwards, sets references to other entities
--   
--   In 2.13.0.0, this was changed to splice in
--   <tt>[<a>UnboundEntityDef</a>]</tt> instead of
--   <tt>[<a>EntityDef</a>]</tt>.
parseReferences :: PersistSettings -> [(Maybe SourceLoc, Text)] -> Q Exp

-- | Takes a list of (potentially) independently defined entities and
--   properly links all foreign keys to reference the right
--   <a>EntityDef</a>, tying the knot between entities.
--   
--   Allows users to define entities indepedently or in separate modules
--   and then fix the cross-references between them at runtime to create a
--   <a>Migration</a>.
embedEntityDefs :: [EntityDef] -> [UnboundEntityDef] -> [UnboundEntityDef]

-- | Render an error message based on the <tt>tableName</tt> and
--   <tt>fieldName</tt> with the provided message.
fieldError :: Text -> Text -> Text -> Text

-- | 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 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

-- | Returns <a>True</a> if the key definition has less than 2 fields.
pkNewtype :: MkPersistSettings -> UnboundEntityDef -> Bool
instance GHC.Internal.Show.Show Database.Persist.TH.Internal.FTTypeConDescr
instance GHC.Internal.Show.Show Database.Persist.TH.Internal.SqlTypeExp


-- | This module provides the tools for defining your database schema and
--   using it to generate Haskell data types and migrations.
--   
--   For documentation on the domain specific language used for defining
--   database models, see <a>Database.Persist.Quasi</a>.
module Database.Persist.TH

-- | Converts a quasi-quoted syntax into a list of entity definitions, to
--   be used as input to the template haskell generation code (mkPersist).
persistWith :: PersistSettings -> QuasiQuoter

-- | Apply <a>persistWith</a> to <a>upperCaseSettings</a>.
persistUpperCase :: QuasiQuoter

-- | Apply <a>persistWith</a> to <a>lowerCaseSettings</a>.
persistLowerCase :: QuasiQuoter

-- | Same as <a>persistWith</a>, but uses an external file instead of a
--   quasiquotation. The recommended file extension is
--   <tt>.persistentmodels</tt>.
persistFileWith :: PersistSettings -> FilePath -> Q Exp

-- | Same as <a>persistFileWith</a>, but uses several external files
--   instead of one. Splitting your Persistent definitions into multiple
--   modules can potentially dramatically speed up compile times.
--   
--   The recommended file extension is <tt>.persistentmodels</tt>.
--   
--   <h4><b>Examples</b></h4>
--   
--   Split your Persistent definitions into multiple files
--   (<tt>models1</tt>, <tt>models2</tt>), then create a new module for
--   each new file and run <a>mkPersist</a> there:
--   
--   <pre>
--   -- Model1.hs
--   <a>share</a>
--       [<a>mkPersist</a> <a>sqlSettings</a>]
--       $(<a>persistFileWith</a> <a>lowerCaseSettings</a> "models1")
--   </pre>
--   
--   <pre>
--   -- Model2.hs
--   <a>share</a>
--       [<a>mkPersist</a> <a>sqlSettings</a>]
--       $(<a>persistFileWith</a> <a>lowerCaseSettings</a> "models2")
--   </pre>
--   
--   Use <a>persistManyFileWith</a> to create your migrations:
--   
--   <pre>
--   -- Migrate.hs
--   <a>mkMigrate</a> "migrateAll"
--       $(<a>persistManyFileWith</a> <a>lowerCaseSettings</a> ["models1.persistentmodels","models2.persistentmodels"])
--   </pre>
--   
--   Tip: To get the same import behavior as if you were declaring all your
--   models in one file, import your new files <tt>as Name</tt> into
--   another file, then export <tt>module Name</tt>.
--   
--   This approach may be used in the future to reduce memory usage during
--   compilation, but so far we've only seen mild reductions.
--   
--   See <a>persistent#778</a> and <a>persistent#791</a> for more details.
persistManyFileWith :: PersistSettings -> [FilePath] -> Q Exp

-- | Create data types and appropriate <a>PersistEntity</a> instances for
--   the given <a>UnboundEntityDef</a>s.
--   
--   This function should be used if you are only defining a single block
--   of Persistent models for the entire application. If you intend on
--   defining multiple blocks in different fiels, see <a>mkPersistWith</a>
--   which allows you to provide existing entity definitions so foreign key
--   references work.
--   
--   Example:
--   
--   <pre>
--   mkPersist <a>sqlSettings</a> [<a>persistLowerCase</a>|
--        User
--            name    Text
--            age     Int
--   
--        Dog
--            name    Text
--            owner   UserId
--   
--   |]
--   </pre>
--   
--   Example from a file:
--   
--   <pre>
--   mkPersist <a>sqlSettings</a> $(<a>persistFileWith</a> <a>lowerCaseSettings</a> "models.persistentmodels")
--   </pre>
--   
--   For full information on the <a>QuasiQuoter</a> syntax, see
--   <a>Database.Persist.Quasi</a> documentation.
mkPersist :: MkPersistSettings -> [UnboundEntityDef] -> Q [Dec]

-- | Like <a>mkPersist</a>, but allows you to provide a
--   <tt>[<a>EntityDef</a>]</tt> representing the predefined entities. This
--   function will include those <a>EntityDef</a> when looking for foreign
--   key references.
--   
--   You should use this if you intend on defining Persistent models in
--   multiple files.
--   
--   Suppose we define a table <tt>Foo</tt> which has no dependencies.
--   
--   <pre>
--   module DB.Foo where
--   
--       <a>mkPersistWith</a> <a>sqlSettings</a> [] [<a>persistLowerCase</a>|
--           Foo
--              name    Text
--          |]
--   </pre>
--   
--   Then, we define a table <tt>Bar</tt> which depends on <tt>Foo</tt>:
--   
--   <pre>
--   module DB.Bar where
--   
--       import DB.Foo
--   
--       <a>mkPersistWith</a> <a>sqlSettings</a> [entityDef (Proxy :: Proxy Foo)] [<a>persistLowerCase</a>|
--           Bar
--               fooId  FooId
--        |]
--   </pre>
--   
--   Writing out the list of <a>EntityDef</a> can be annoying. The
--   <tt>$(<a>discoverEntities</a>)</tt> shortcut will work to reduce this
--   boilerplate.
--   
--   <pre>
--   module DB.Quux where
--   
--       import DB.Foo
--       import DB.Bar
--   
--       <a>mkPersistWith</a> <a>sqlSettings</a> $(<a>discoverEntities</a>) [<a>persistLowerCase</a>|
--           Quux
--               name     Text
--               fooId    FooId
--               barId    BarId
--        |]
--   </pre>
mkPersistWith :: MkPersistSettings -> [EntityDef] -> [UnboundEntityDef] -> Q [Dec]

-- | Settings that can be passed to the <a>mkPersist</a> (mps) function to
--   control what code is generated. This is (just) the data type
--   definition, so you will most likely want to use and adapt concrete
--   values like <a>sqlSettings</a>.
data MkPersistSettings

-- | Create an <tt>MkPersistSettings</tt> with default values.
mkPersistSettings :: Type -> MkPersistSettings

-- | Use the <tt>SqlPersist</tt> backend.
sqlSettings :: MkPersistSettings

-- | Which database backend we're using. This type is used for the
--   <a>PersistEntityBackend</a> associated type in the entities that are
--   generated.
--   
--   If the <a>mpsGeneric</a> value is set to <a>True</a>, then this type
--   is used for the non-Generic type alias. The data and type will be
--   named:
--   
--   <pre>
--   data ModelGeneric backend = Model { ... }
--   </pre>
--   
--   And, for convenience's sake, we provide a type alias:
--   
--   <pre>
--   type Model = ModelGeneric $(the type you give here)
--   </pre>
mpsBackend :: MkPersistSettings -> Type

-- | Create generic types that can be used with multiple backends. Good for
--   reusable code, but makes error messages harder to understand. Default:
--   False.

-- | <i>Deprecated: The mpsGeneric function adds a considerable amount of
--   overhead and complexity to the library without bringing significant
--   benefit. We would like to remove it. If you require this feature,
--   please comment on the linked GitHub issue, and we'll either keep it
--   around, or we can figure out a nicer way to solve your problem.
--   Github: <a>https://github.com/yesodweb/persistent/issues/1204</a></i>
mpsGeneric :: MkPersistSettings -> Bool

-- | Prefix field names with the model name. Default: True.
--   
--   Note: this field is deprecated. Use the <a>mpsFieldLabelModifier</a>
--   and <a>mpsConstraintLabelModifier</a> instead.
mpsPrefixFields :: MkPersistSettings -> Bool

-- | Customise the field names (and lens names) for generated entity data
--   types.
--   
--   Default: appends entity name and field name, equivalent to
--   
--   <pre>
--   mpsFieldLabelModifier = \entityName fieldName -&gt; entityName &lt;&gt; fieldName
--   </pre>
--   
--   to avoid duplicate record field collisions.
--   
--   For example, with default <a>sqlSettings</a> and
--   
--   <pre>
--   <a>mkPersistWith</a> <a>sqlSettings</a> [] [<a>persistLowerCase</a>|
--       Person
--           name   Text
--           age    Int
--   |]
--   </pre>
--   
--   it will generate the entity data type
--   
--   <pre>
--   Person {
--       personName :: Text,  -- generated field name
--       personAge  :: Int    -- generated field name
--   }
--   </pre>
--   
--   Note: this setting is ignored if the deprecated <a>mpsPrefixFields</a>
--   is set to False.
--   
--   <h3><b>Example without entity name</b></h3>
--   
--   You may not want the entity name prefix for all fields, so use
--   
--   <pre>
--   <a>mkPersistWith</a> (<a>sqlSettings</a> { mpsFieldLabelModifier = \_entityName fieldName -&gt; fieldName }) [] [<a>persistLowerCase</a>|
--       Person
--           name   Text
--           age    Int
--   |]
--   </pre>
--   
--   instead. This will generate the entity data type
--   
--   <pre>
--   Person {
--       name :: Text,
--       age  :: Int
--   }
--   </pre>
--   
--   When you have multiple entites with the same field name, you might
--   need to add <tt>{-# LANGUAGE DuplicateRecordFields #-}</tt> for your
--   code to compile.
mpsFieldLabelModifier :: MkPersistSettings -> Text -> Text -> Text

-- | Customise function for field accessors applied only when the field
--   name matches any of Haskell keywords.
--   
--   Default: suffix "_".
mpsAvoidHsKeyword :: MkPersistSettings -> Text -> Text

-- | Customise the Constraint names using the entity and field name. The
--   result should be a valid haskell type (start with an upper cased
--   letter).
--   
--   Default: appends entity and field
--   
--   Note: this setting is ignored if the deprecated <a>mpsPrefixFields</a>
--   is set to False.
mpsConstraintLabelModifier :: MkPersistSettings -> Text -> Text -> Text

-- | Generate Haddocks from entity documentation comments. Default: False.
mpsEntityHaddocks :: MkPersistSettings -> Bool

-- | Generate <tt>ToJSON</tt>/<tt>FromJSON</tt> instances for each model
--   types. If it's <tt>Nothing</tt>, no instances will be generated.
--   Default:
--   
--   <pre>
--   Just <a>EntityJSON</a>
--       { <a>entityToJSON</a> = 'entityIdToJSON
--       , <a>entityFromJSON</a> = 'entityIdFromJSON
--       }
--   </pre>
mpsEntityJSON :: MkPersistSettings -> Maybe EntityJSON

-- | Instead of generating normal field accessors, generator lens-style
--   accessors.
--   
--   Default: False
mpsGenerateLenses :: MkPersistSettings -> Bool

-- | Automatically derive these typeclass instances for all record and key
--   types.
--   
--   Default: []
mpsDeriveInstances :: MkPersistSettings -> [Name]

-- | Should we generate composite key accessors in the correct CamelCase
--   style.
--   
--   If the <a>mpsCamelCaseCompositeKeySelector</a> value is set to
--   <a>False</a>, then the field part of the accessor starts with the
--   lowercase. This is a legacy style.
--   
--   <pre>
--   data Key CompanyUser = CompanyUserKey
--     { companyUserKeycompanyId :: CompanyId
--     , companyUserKeyuserId :: UserId
--     }
--   </pre>
--   
--   If the <a>mpsCamelCaseCompositeKeySelector</a> value is set to
--   <a>True</a>, then field accessors are generated in CamelCase style.
--   
--   <pre>
--   data Key CompanyUser = CompanyUserKey
--     { companyUserKeyCompanyId :: CompanyId
--     , companyUserKeyUserId :: UserId
--     }
--   </pre>
--   
--   Default: False
mpsCamelCaseCompositeKeySelector :: MkPersistSettings -> Bool
data EntityJSON
EntityJSON :: Name -> Name -> EntityJSON

-- | Name of the <tt>toJSON</tt> implementation for <tt>Entity a</tt>.
[entityToJSON] :: EntityJSON -> Name

-- | Name of the <tt>fromJSON</tt> implementation for <tt>Entity a</tt>.
[entityFromJSON] :: EntityJSON -> Name

-- | A specification for how the implied ID columns are created.
--   
--   By default, <tt>persistent</tt> will give each table a default column
--   named <tt>id</tt> (customizable by <tt>PersistSettings</tt>), and the
--   column type will be whatever you'd expect from <tt><tt>BackendKey</tt>
--   yourBackendType</tt>. For The <tt>SqlBackend</tt> type, this is an
--   auto incrementing integer primary key.
--   
--   You might want to give a different example. A common use case in
--   postgresql is to use the UUID type, and automatically generate them
--   using a SQL function.
--   
--   Previously, you'd need to add a custom <tt>Id</tt> annotation for each
--   model.
--   
--   <pre>
--   User
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--   
--   Dog
--       Id   UUID default="uuid_generate_v1mc()"
--       name Text
--       user UserId
--   </pre>
--   
--   Now, you can simply create an <a>ImplicitIdDef</a> that corresponds to
--   this declaration.
--   
--   <pre>
--   newtype UUID = UUID <tt>ByteString</tt>
--   
--   instance <a>PersistField</a> UUID where
--       <tt>toPersistValue</tt> (UUID bs) =
--           <a>PersistLiteral_</a> <a>Escaped</a> bs
--       <tt>fromPersistValue</tt> pv =
--           case pv of
--               PersistLiteral_ Escaped bs -&gt;
--                   Right (UUID bs)
--               _ -&gt;
--                   Left "nope"
--   
--   instance <a>PersistFieldSql</a> UUID where
--       <a>sqlType</a> _ = <a>SqlOther</a> <a>UUID</a>
--   </pre>
--   
--   With this instance at the ready, we can now create our implicit
--   definition:
--   
--   <pre>
--   uuidDef :: ImplicitIdDef
--   uuidDef = mkImplicitIdDef @UUID "uuid_generate_v1mc()"
--   </pre>
--   
--   And we can use <tt>setImplicitIdDef</tt> to use this with the
--   <tt>MkPersistSettings</tt> for our block.
--   
--   <pre>
--   mkPersist (setImplicitIdDef uuidDef sqlSettings) [persistLowerCase| ... |]
--   </pre>
--   
--   TODO: either explain interaction with mkMigrate or fix it. see issue
--   #1249 for more details.
data ImplicitIdDef

-- | Set the <a>ImplicitIdDef</a> in the given <a>MkPersistSettings</a>.
--   The default value is <a>autoIncrementingInteger</a>.
setImplicitIdDef :: ImplicitIdDef -> MkPersistSettings -> MkPersistSettings

-- | Creates a single function to perform all migrations for the entities
--   defined here. One thing to be aware of is dependencies: if you have
--   entities with foreign references, make sure to place those definitions
--   after the entities they reference.
--   
--   In <tt>persistent-2.13.0.0</tt>, this was changed to *ignore* the
--   input entity def list, and instead defer to <a>mkEntityDefList</a> to
--   get the correct entities. This avoids problems where the QuasiQuoter
--   is unable to know what the right reference types are. This sets
--   <a>mkPersist</a> to be the "single source of truth" for entity
--   definitions.
mkMigrate :: String -> [UnboundEntityDef] -> Q [Dec]

-- | The basic function for migrating models, no Template Haskell required.
--   
--   It's probably best to use this in concert with <a>mkEntityDefList</a>,
--   and then call <a>migrateModels</a> with the result from that function.
--   
--   <pre>
--   share [mkPersist sqlSettings, mkEntityDefList "entities"] [persistLowerCase| ... |]
--   
--   migrateAll = <a>migrateModels</a> entities
--   </pre>
--   
--   The function <a>mkMigrate</a> currently implements exactly this
--   behavior now. If you're splitting up the entity definitions into
--   separate files, then it is better to use the entity definition list
--   and the concatenate all the models together into a big list to call
--   with <a>migrateModels</a>.
--   
--   <pre>
--   module Foo where
--   
--       share [mkPersist s, mkEntityDefList "fooModels"] ...
--   
--   
--   module Bar where
--   
--       share [mkPersist s, mkEntityDefList "barModels"] ...
--   
--   module Migration where
--   
--       import Foo
--       import Bar
--   
--       migrateAll = migrateModels (fooModels &lt;&gt; barModels)
--   </pre>
migrateModels :: [EntityDef] -> Migration

-- | Splice in a list of all <a>EntityDef</a> in scope. This is useful when
--   running <a>mkPersist</a> to ensure that all entity definitions are
--   available for setting foreign keys, and for performing migrations with
--   all entities available.
--   
--   <a>mkPersist</a> has the type <tt>MkPersistSettings -&gt; [EntityDef]
--   -&gt; DecsQ</tt>. So, to account for entities defined elsewhere,
--   you'll <tt>mappend $(discoverEntities)</tt>.
--   
--   For example,
--   
--   <pre>
--   share
--     [ mkPersistWith sqlSettings $(discoverEntities)
--     ]
--     [persistLowerCase| ... |]
--   </pre>
--   
--   Likewise, to run migrations with all entity instances in scope, you'd
--   write:
--   
--   <pre>
--   migrateAll = migrateModels $(discoverEntities)
--   </pre>
--   
--   Note that there is some odd behavior with Template Haskell and
--   splicing groups. If you call <a>discoverEntities</a> in the same
--   module that defines <a>PersistEntity</a> instances, you need to ensure
--   they are in different top-level binding groups. You can write
--   <tt>$(pure [])</tt> at the top level to do this.
--   
--   <pre>
--   -- Foo and Bar both export an instance of PersistEntity
--   import Foo
--   import Bar
--   
--   -- Since Foo and Bar are both imported, discoverEntities can find them here.
--   mkPersistWith sqlSettings $(discoverEntities) [persistLowerCase|
--     User
--       name Text
--       age  Int
--     |]
--   
--   -- onlyFooBar is defined in the same 'top level group' as the above generated
--   -- instance for User, so it isn't present in this list.
--   onlyFooBar :: [EntityDef]
--   onlyFooBar = $(discoverEntities)
--   
--   -- We can manually create a new binding group with this, which splices an
--   -- empty list of declarations in.
--   $(pure [])
--   
--   -- fooBarUser is able to see the <tt>User</tt> instance.
--   fooBarUser :: [EntityDef]
--   fooBarUser = $(discoverEntities)
--   </pre>
discoverEntities :: Q Exp

-- | Creates a declaration for the <tt>[<a>EntityDef</a>]</tt> from the
--   <tt>persistent</tt> schema. This is necessary because the Persistent
--   QuasiQuoter is unable to know the correct type of ID fields, and
--   assumes that they are all Int64.
--   
--   Provide this in the list you give to <a>share</a>, much like
--   <tt><a>mkMigrate</a></tt>.
--   
--   <pre>
--   <a>share</a> [<a>mkMigrate</a> "migrateAll", <a>mkEntityDefList</a> "entityDefs"] [...]
--   </pre>
mkEntityDefList :: String -> [UnboundEntityDef] -> Q [Dec]

-- | Apply the given list of functions to the same <tt>EntityDef</tt>s.
--   
--   This function is useful for cases such as:
--   
--   <pre>
--   share [<a>mkEntityDefList</a> "myDefs", <a>mkPersist</a> sqlSettings] [<a>persistLowerCase</a>|
--       -- ...
--   |]
--   </pre>
--   
--   If you only have a single function, though, you don't need this. The
--   following is redundant:
--   
--   <pre>
--   <a>share</a> [<a>mkPersist</a> <a>sqlSettings</a>] [<a>persistLowerCase</a>|
--        -- ...
--   |]
--   </pre>
--   
--   Most functions require a full <tt>[<a>EntityDef</a>]</tt>, which can
--   be provided using <tt>$(<a>discoverEntities</a>)</tt> for all entites
--   in scope, or defining <a>mkEntityDefList</a> to define a list of
--   entities from the given block.
share :: [[a] -> Q [Dec]] -> [a] -> Q [Dec]

-- | Automatically creates a valid <a>PersistField</a> instance for any
--   datatype that has valid <a>Show</a> and <a>Read</a> instances. Can be
--   very convenient for <a>Enum</a> types.
derivePersistField :: String -> Q [Dec]

-- | Automatically creates a valid <a>PersistField</a> instance for any
--   datatype that has valid <a>ToJSON</a> and <a>FromJSON</a> instances.
--   For a datatype <tt>T</tt> it generates instances similar to these:
--   
--   <pre>
--   instance PersistField T where
--       toPersistValue = PersistByteString . L.toStrict . encode
--       fromPersistValue = (left T.pack) . eitherDecodeStrict' &lt;=&lt; fromPersistValue
--   instance PersistFieldSql T where
--       sqlType _ = SqlString
--   </pre>
derivePersistFieldJSON :: String -> Q [Dec]

-- | Produce code similar to the following:
--   
--   <pre>
--   instance PersistEntity e =&gt; PersistField e where
--      toPersistValue = entityToPersistValueHelper
--      fromPersistValue = entityFromPersistValueHelper ["col1", "col2"]
--      sqlType _ = SqlString
--   </pre>
persistFieldFromEntity :: MkPersistSettings -> UnboundEntityDef -> Q [Dec]
