{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE RankNTypes #-}
module Database.Persist.Sql.Types.Internal
( HasPersistBackend (..)
, IsPersistBackend (..)
, SqlReadBackend (..)
, SqlWriteBackend (..)
, readToUnknown
, readToWrite
, writeToUnknown
, LogFunc
, InsertSqlResult (..)
, Statement (..)
, IsolationLevel (..)
, makeIsolationLevelStatement
, SqlBackend (..)
, SqlBackendCanRead
, SqlBackendCanWrite
, SqlReadT
, SqlWriteT
, IsSqlBackend
) where
import Data.List.NonEmpty (NonEmpty(..))
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Logger (LogSource, LogLevel, Loc)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Reader (ReaderT, runReaderT, ask)
import Data.Acquire (Acquire)
import Data.Conduit (ConduitM)
import Data.Int (Int64)
import Data.IORef (IORef)
import Data.Map (Map)
import Data.Monoid ((<>))
import Data.String (IsString)
import Data.Text (Text)
import System.Log.FastLogger (LogStr)
import Database.Persist.Class
( HasPersistBackend (..)
, PersistQueryRead, PersistQueryWrite
, PersistStoreRead, PersistStoreWrite
, PersistUniqueRead, PersistUniqueWrite
, BackendCompatible(..)
)
import Database.Persist.Class.PersistStore (IsPersistBackend (..))
import Database.Persist.Types
type LogFunc = Loc -> LogSource -> LogLevel -> LogStr -> IO ()
data InsertSqlResult = ISRSingle Text
| ISRInsertGet Text Text
| ISRManyKeys Text [PersistValue]
data Statement = Statement
{ Statement -> IO ()
stmtFinalize :: IO ()
, Statement -> IO ()
stmtReset :: IO ()
, Statement -> [PersistValue] -> IO Int64
stmtExecute :: [PersistValue] -> IO Int64
, Statement
-> forall (m :: * -> *).
MonadIO m =>
[PersistValue] -> Acquire (ConduitM () [PersistValue] m ())
stmtQuery :: forall m. MonadIO m
=> [PersistValue]
-> Acquire (ConduitM () [PersistValue] m ())
}
data IsolationLevel = ReadUncommitted
| ReadCommitted
| RepeatableRead
| Serializable
deriving (Int -> IsolationLevel -> ShowS
[IsolationLevel] -> ShowS
IsolationLevel -> String
(Int -> IsolationLevel -> ShowS)
-> (IsolationLevel -> String)
-> ([IsolationLevel] -> ShowS)
-> Show IsolationLevel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IsolationLevel] -> ShowS
$cshowList :: [IsolationLevel] -> ShowS
show :: IsolationLevel -> String
$cshow :: IsolationLevel -> String
showsPrec :: Int -> IsolationLevel -> ShowS
$cshowsPrec :: Int -> IsolationLevel -> ShowS
Show, IsolationLevel -> IsolationLevel -> Bool
(IsolationLevel -> IsolationLevel -> Bool)
-> (IsolationLevel -> IsolationLevel -> Bool) -> Eq IsolationLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IsolationLevel -> IsolationLevel -> Bool
$c/= :: IsolationLevel -> IsolationLevel -> Bool
== :: IsolationLevel -> IsolationLevel -> Bool
$c== :: IsolationLevel -> IsolationLevel -> Bool
Eq, Int -> IsolationLevel
IsolationLevel -> Int
IsolationLevel -> [IsolationLevel]
IsolationLevel -> IsolationLevel
IsolationLevel -> IsolationLevel -> [IsolationLevel]
IsolationLevel
-> IsolationLevel -> IsolationLevel -> [IsolationLevel]
(IsolationLevel -> IsolationLevel)
-> (IsolationLevel -> IsolationLevel)
-> (Int -> IsolationLevel)
-> (IsolationLevel -> Int)
-> (IsolationLevel -> [IsolationLevel])
-> (IsolationLevel -> IsolationLevel -> [IsolationLevel])
-> (IsolationLevel -> IsolationLevel -> [IsolationLevel])
-> (IsolationLevel
-> IsolationLevel -> IsolationLevel -> [IsolationLevel])
-> Enum IsolationLevel
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: IsolationLevel
-> IsolationLevel -> IsolationLevel -> [IsolationLevel]
$cenumFromThenTo :: IsolationLevel
-> IsolationLevel -> IsolationLevel -> [IsolationLevel]
enumFromTo :: IsolationLevel -> IsolationLevel -> [IsolationLevel]
$cenumFromTo :: IsolationLevel -> IsolationLevel -> [IsolationLevel]
enumFromThen :: IsolationLevel -> IsolationLevel -> [IsolationLevel]
$cenumFromThen :: IsolationLevel -> IsolationLevel -> [IsolationLevel]
enumFrom :: IsolationLevel -> [IsolationLevel]
$cenumFrom :: IsolationLevel -> [IsolationLevel]
fromEnum :: IsolationLevel -> Int
$cfromEnum :: IsolationLevel -> Int
toEnum :: Int -> IsolationLevel
$ctoEnum :: Int -> IsolationLevel
pred :: IsolationLevel -> IsolationLevel
$cpred :: IsolationLevel -> IsolationLevel
succ :: IsolationLevel -> IsolationLevel
$csucc :: IsolationLevel -> IsolationLevel
Enum, Eq IsolationLevel
Eq IsolationLevel
-> (IsolationLevel -> IsolationLevel -> Ordering)
-> (IsolationLevel -> IsolationLevel -> Bool)
-> (IsolationLevel -> IsolationLevel -> Bool)
-> (IsolationLevel -> IsolationLevel -> Bool)
-> (IsolationLevel -> IsolationLevel -> Bool)
-> (IsolationLevel -> IsolationLevel -> IsolationLevel)
-> (IsolationLevel -> IsolationLevel -> IsolationLevel)
-> Ord IsolationLevel
IsolationLevel -> IsolationLevel -> Bool
IsolationLevel -> IsolationLevel -> Ordering
IsolationLevel -> IsolationLevel -> IsolationLevel
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: IsolationLevel -> IsolationLevel -> IsolationLevel
$cmin :: IsolationLevel -> IsolationLevel -> IsolationLevel
max :: IsolationLevel -> IsolationLevel -> IsolationLevel
$cmax :: IsolationLevel -> IsolationLevel -> IsolationLevel
>= :: IsolationLevel -> IsolationLevel -> Bool
$c>= :: IsolationLevel -> IsolationLevel -> Bool
> :: IsolationLevel -> IsolationLevel -> Bool
$c> :: IsolationLevel -> IsolationLevel -> Bool
<= :: IsolationLevel -> IsolationLevel -> Bool
$c<= :: IsolationLevel -> IsolationLevel -> Bool
< :: IsolationLevel -> IsolationLevel -> Bool
$c< :: IsolationLevel -> IsolationLevel -> Bool
compare :: IsolationLevel -> IsolationLevel -> Ordering
$ccompare :: IsolationLevel -> IsolationLevel -> Ordering
$cp1Ord :: Eq IsolationLevel
Ord, IsolationLevel
IsolationLevel -> IsolationLevel -> Bounded IsolationLevel
forall a. a -> a -> Bounded a
maxBound :: IsolationLevel
$cmaxBound :: IsolationLevel
minBound :: IsolationLevel
$cminBound :: IsolationLevel
Bounded)
makeIsolationLevelStatement :: (Monoid s, IsString s) => IsolationLevel -> s
makeIsolationLevelStatement :: IsolationLevel -> s
makeIsolationLevelStatement IsolationLevel
l = s
"SET TRANSACTION ISOLATION LEVEL " s -> s -> s
forall a. Semigroup a => a -> a -> a
<> case IsolationLevel
l of
IsolationLevel
ReadUncommitted -> s
"READ UNCOMMITTED"
IsolationLevel
ReadCommitted -> s
"READ COMMITTED"
IsolationLevel
RepeatableRead -> s
"REPEATABLE READ"
IsolationLevel
Serializable -> s
"SERIALIZABLE"
data SqlBackend = SqlBackend
{ SqlBackend -> Text -> IO Statement
connPrepare :: Text -> IO Statement
, SqlBackend -> EntityDef -> [PersistValue] -> InsertSqlResult
connInsertSql :: EntityDef -> [PersistValue] -> InsertSqlResult
, SqlBackend
-> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult)
connInsertManySql :: Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult)
, SqlBackend
-> Maybe
(EntityDef -> NonEmpty (HaskellName, DBName) -> Text -> Text)
connUpsertSql :: Maybe (EntityDef -> NonEmpty (HaskellName,DBName) -> Text -> Text)
, SqlBackend -> Maybe (EntityDef -> Int -> Text)
connPutManySql :: Maybe (EntityDef -> Int -> Text)
, SqlBackend -> IORef (Map Text Statement)
connStmtMap :: IORef (Map Text Statement)
, SqlBackend -> IO ()
connClose :: IO ()
, SqlBackend
-> [EntityDef]
-> (Text -> IO Statement)
-> EntityDef
-> IO (Either [Text] [(Bool, Text)])
connMigrateSql
:: [EntityDef]
-> (Text -> IO Statement)
-> EntityDef
-> IO (Either [Text] [(Bool, Text)])
, SqlBackend
-> (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()
connBegin :: (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()
, SqlBackend -> (Text -> IO Statement) -> IO ()
connCommit :: (Text -> IO Statement) -> IO ()
, SqlBackend -> (Text -> IO Statement) -> IO ()
connRollback :: (Text -> IO Statement) -> IO ()
, SqlBackend -> DBName -> Text
connEscapeName :: DBName -> Text
, SqlBackend -> Text
connNoLimit :: Text
, SqlBackend -> Text
connRDBMS :: Text
, SqlBackend -> (Int, Int) -> Bool -> Text -> Text
connLimitOffset :: (Int,Int) -> Bool -> Text -> Text
, SqlBackend -> LogFunc
connLogFunc :: LogFunc
, SqlBackend -> Maybe Int
connMaxParams :: Maybe Int
, SqlBackend -> Maybe (EntityDef -> Int -> Text)
connRepsertManySql :: Maybe (EntityDef -> Int -> Text)
}
instance HasPersistBackend SqlBackend where
type BaseBackend SqlBackend = SqlBackend
persistBackend :: SqlBackend -> BaseBackend SqlBackend
persistBackend = SqlBackend -> BaseBackend SqlBackend
forall a. a -> a
id
instance IsPersistBackend SqlBackend where
mkPersistBackend :: BaseBackend SqlBackend -> SqlBackend
mkPersistBackend = BaseBackend SqlBackend -> SqlBackend
forall a. a -> a
id
newtype SqlReadBackend = SqlReadBackend { SqlReadBackend -> SqlBackend
unSqlReadBackend :: SqlBackend }
instance HasPersistBackend SqlReadBackend where
type BaseBackend SqlReadBackend = SqlBackend
persistBackend :: SqlReadBackend -> BaseBackend SqlReadBackend
persistBackend = SqlReadBackend -> BaseBackend SqlReadBackend
SqlReadBackend -> SqlBackend
unSqlReadBackend
instance IsPersistBackend SqlReadBackend where
mkPersistBackend :: BaseBackend SqlReadBackend -> SqlReadBackend
mkPersistBackend = BaseBackend SqlReadBackend -> SqlReadBackend
SqlBackend -> SqlReadBackend
SqlReadBackend
newtype SqlWriteBackend = SqlWriteBackend { SqlWriteBackend -> SqlBackend
unSqlWriteBackend :: SqlBackend }
instance HasPersistBackend SqlWriteBackend where
type BaseBackend SqlWriteBackend = SqlBackend
persistBackend :: SqlWriteBackend -> BaseBackend SqlWriteBackend
persistBackend = SqlWriteBackend -> BaseBackend SqlWriteBackend
SqlWriteBackend -> SqlBackend
unSqlWriteBackend
instance IsPersistBackend SqlWriteBackend where
mkPersistBackend :: BaseBackend SqlWriteBackend -> SqlWriteBackend
mkPersistBackend = BaseBackend SqlWriteBackend -> SqlWriteBackend
SqlBackend -> SqlWriteBackend
SqlWriteBackend
writeToUnknown :: Monad m => ReaderT SqlWriteBackend m a -> ReaderT SqlBackend m a
writeToUnknown :: ReaderT SqlWriteBackend m a -> ReaderT SqlBackend m a
writeToUnknown ReaderT SqlWriteBackend m a
ma = do
SqlBackend
unknown <- ReaderT SqlBackend m SqlBackend
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
m a -> ReaderT SqlBackend m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT SqlBackend m a)
-> (SqlWriteBackend -> m a)
-> SqlWriteBackend
-> ReaderT SqlBackend m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT SqlWriteBackend m a -> SqlWriteBackend -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT SqlWriteBackend m a
ma (SqlWriteBackend -> ReaderT SqlBackend m a)
-> SqlWriteBackend -> ReaderT SqlBackend m a
forall a b. (a -> b) -> a -> b
$ SqlBackend -> SqlWriteBackend
SqlWriteBackend SqlBackend
unknown
readToWrite :: Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlWriteBackend m a
readToWrite :: ReaderT SqlReadBackend m a -> ReaderT SqlWriteBackend m a
readToWrite ReaderT SqlReadBackend m a
ma = do
SqlWriteBackend
write <- ReaderT SqlWriteBackend m SqlWriteBackend
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
m a -> ReaderT SqlWriteBackend m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT SqlWriteBackend m a)
-> (SqlBackend -> m a) -> SqlBackend -> ReaderT SqlWriteBackend m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT SqlReadBackend m a -> SqlReadBackend -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT SqlReadBackend m a
ma (SqlReadBackend -> m a)
-> (SqlBackend -> SqlReadBackend) -> SqlBackend -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlBackend -> SqlReadBackend
SqlReadBackend (SqlBackend -> ReaderT SqlWriteBackend m a)
-> SqlBackend -> ReaderT SqlWriteBackend m a
forall a b. (a -> b) -> a -> b
$ SqlWriteBackend -> SqlBackend
unSqlWriteBackend SqlWriteBackend
write
readToUnknown :: Monad m => ReaderT SqlReadBackend m a -> ReaderT SqlBackend m a
readToUnknown :: ReaderT SqlReadBackend m a -> ReaderT SqlBackend m a
readToUnknown ReaderT SqlReadBackend m a
ma = do
SqlBackend
unknown <- ReaderT SqlBackend m SqlBackend
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
m a -> ReaderT SqlBackend m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT SqlBackend m a)
-> (SqlReadBackend -> m a)
-> SqlReadBackend
-> ReaderT SqlBackend m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT SqlReadBackend m a -> SqlReadBackend -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT SqlReadBackend m a
ma (SqlReadBackend -> ReaderT SqlBackend m a)
-> SqlReadBackend -> ReaderT SqlBackend m a
forall a b. (a -> b) -> a -> b
$ SqlBackend -> SqlReadBackend
SqlReadBackend SqlBackend
unknown
type SqlBackendCanRead backend =
( BackendCompatible SqlBackend backend
, PersistQueryRead backend, PersistStoreRead backend, PersistUniqueRead backend
)
type SqlBackendCanWrite backend =
( SqlBackendCanRead backend
, PersistQueryWrite backend, PersistStoreWrite backend, PersistUniqueWrite backend
)
type SqlReadT m a = forall backend. (SqlBackendCanRead backend) => ReaderT backend m a
type SqlWriteT m a = forall backend. (SqlBackendCanWrite backend) => ReaderT backend m a
type IsSqlBackend backend = (IsPersistBackend backend, BaseBackend backend ~ SqlBackend)