module Database.Persist.Sql.Types where
import Control.Exception (Exception)
import Control.Monad.Trans.Resource (MonadResource (..), MonadThrow (..), ResourceT)
import Control.Monad.Logger (MonadLogger (..), NoLoggingT)
import Control.Monad.Trans.Control
import Control.Monad.Trans.Class (MonadTrans (..))
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Trans.Reader (ReaderT (..))
import Control.Applicative (Applicative (..))
import Control.Monad.Trans.Writer (WriterT)
import Control.Monad.Base (MonadBase (..))
import Control.Monad (MonadPlus (..))
import Data.Typeable (Typeable)
import Control.Monad (liftM)
import Database.Persist.Types
import Data.Text (Text, pack)
import qualified Data.Text as T
import Data.IORef (IORef)
import Data.Map (Map)
import Data.Int (Int64)
import Data.Conduit (Source)
import Data.Conduit.Pool (Pool)
import Web.PathPieces
import Control.Exception (throw)
import qualified Data.Text.Read
data InsertSqlResult = ISRSingle Text
| ISRInsertGet Text Text
data Connection = Connection
{ connPrepare :: Text -> IO Statement
, connInsertSql :: DBName -> [DBName] -> DBName -> InsertSqlResult
, connStmtMap :: IORef (Map Text Statement)
, connClose :: IO ()
, connMigrateSql
:: [EntityDef SqlType]
-> (Text -> IO Statement)
-> EntityDef SqlType
-> IO (Either [Text] [(Bool, Text)])
, connBegin :: (Text -> IO Statement) -> IO ()
, connCommit :: (Text -> IO Statement) -> IO ()
, connRollback :: (Text -> IO Statement) -> IO ()
, connEscapeName :: DBName -> Text
, connNoLimit :: Text
, connRDBMS :: Text
}
data Statement = Statement
{ stmtFinalize :: IO ()
, stmtReset :: IO ()
, stmtExecute :: [PersistValue] -> IO Int64
, stmtQuery :: forall m. MonadResource m
=> [PersistValue]
-> Source m [PersistValue]
}
data Column = Column
{ cName :: !DBName
, cNull :: !Bool
, cSqlType :: !SqlType
, cDefault :: !(Maybe Text)
, cMaxLen :: !(Maybe Integer)
, cReference :: !(Maybe (DBName, DBName))
}
deriving (Eq, Ord, Show)
data PersistentSqlException = StatementAlreadyFinalized Text
| Couldn'tGetSQLConnection
deriving (Typeable, Show)
instance Exception PersistentSqlException
data SqlBackend
newtype SqlPersistT m a = SqlPersistT { unSqlPersistT :: ReaderT Connection m a }
deriving (Monad, MonadIO, MonadTrans, Functor, Applicative, MonadPlus)
type SqlPersist = SqlPersistT
type SqlPersistM = SqlPersistT (NoLoggingT (ResourceT IO))
instance MonadThrow m => MonadThrow (SqlPersistT m) where
monadThrow = lift . monadThrow
instance MonadBase backend m => MonadBase backend (SqlPersistT m) where
liftBase = lift . liftBase
instance MonadBaseControl backend m => MonadBaseControl backend (SqlPersistT m) where
newtype StM (SqlPersistT m) a = StMSP {unStMSP :: ComposeSt SqlPersistT m a}
liftBaseWith = defaultLiftBaseWith StMSP
restoreM = defaultRestoreM unStMSP
instance MonadTransControl SqlPersistT where
newtype StT SqlPersistT a = StReader {unStReader :: a}
liftWith f = SqlPersistT $ ReaderT $ \r -> f $ \t -> liftM StReader $ runReaderT (unSqlPersistT t) r
restoreT = SqlPersistT . ReaderT . const . liftM unStReader
instance MonadResource m => MonadResource (SqlPersistT m) where
liftResourceT = lift . liftResourceT
instance MonadLogger m => MonadLogger (SqlPersistT m) where
monadLoggerLog a b c = lift . monadLoggerLog a b c
type Sql = Text
type CautiousMigration = [(Bool, Sql)]
type Migration m = WriterT [Text] (WriterT CautiousMigration m) ()
type ConnectionPool = Pool Connection
instance PathPiece (KeyBackend SqlBackend entity) where
toPathPiece (Key (PersistInt64 i)) = toPathPiece i
toPathPiece k = throw $ PersistInvalidField $ pack $ "Invalid Key: " ++ show k
fromPathPiece t =
case Data.Text.Read.signed Data.Text.Read.decimal t of
Right (i, t') | T.null t' -> Just $ Key $ PersistInt64 i
_ -> Nothing
newtype Single a = Single {unSingle :: a}
deriving (Eq, Ord, Show, Read)