beam-0.3.0.0: src/Database/Beam/Internal.hs
module Database.Beam.Internal where
import Database.Beam.Schema.Tables
import Database.Beam.SQL.Types
import Control.Applicative
import Control.Monad
import Control.Arrow
import Control.Monad.Error
import Control.Monad.Reader
import Data.Text (Text, unpack)
import Data.Proxy
import Data.String
import Data.Typeable
import Database.HDBC
data DBSchemaComparison = Migration [MigrationAction]
| Unknown
deriving Show
data MigrationAction where
MACreateTable :: Table table => Text -> Proxy table -> MigrationAction
instance Show MigrationAction where
show (MACreateTable name t) = concat ["MACreateTable ", unpack name , " ", "(Proxy :: ", show (typeOf t), ")"]
class BeamBackend backendSettings where
openBeam :: (MonadIO m, Database d) => DatabaseSettings d -> backendSettings -> m (Beam d m)
data Beam d m = Beam
{ beamDbSettings :: DatabaseSettings d
, beamDebug :: Bool
, closeBeam :: m ()
, compareSchemas :: ReifiedDatabaseSchema -> DatabaseSettings d -> DBSchemaComparison
, adjustColDescForBackend :: SQLColumnSchema -> SQLColumnSchema
, getLastInsertedRow :: Text -> m [SqlValue]
, withHDBCConnection :: forall a. (forall conn. IConnection conn => conn -> m a) -> m a }
newtype BeamT e d m a = BeamT { runBeamT :: Beam d m -> m (BeamResult e a) }
data BeamResult e a = Success a
| Rollback (BeamRollbackReason e)
deriving Show
data BeamRollbackReason e = InternalError String
| UserError e
deriving Show
instance Error (BeamRollbackReason e) where
strMsg = InternalError
transBeam :: Functor m => (forall a. (s -> m (a, Maybe b)) -> n a) -> (forall a. n a -> s -> m (a, b)) -> Beam d m -> Beam d n
transBeam lift lower beam = beam
{ closeBeam = lift (const ((,Nothing) <$> closeBeam beam))
, getLastInsertedRow = \s -> lift (const ((, Nothing) <$> getLastInsertedRow beam s))
, withHDBCConnection = \f -> lift (\s -> second Just <$> withHDBCConnection beam (flip lower s . f)) }
instance Monad m => Monad (BeamT e d m) where
a >>= mkB = BeamT $ \beam ->
do x <- runBeamT a beam
case x of
Success x -> runBeamT (mkB x) beam
Rollback e -> return (Rollback e)
return = BeamT . const . return . Success
instance Monad m => Functor (BeamT e d m) where
fmap = liftM
instance Monad m => Applicative (BeamT e d m) where
pure = return
(<*>) = ap
instance MonadIO m => MonadIO (BeamT e d m) where
liftIO = lift . liftIO
instance MonadTrans (BeamT e d) where
lift x = BeamT $ \_ ->
do res <- x
return (Success res)