{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE CPP #-}
module Database.Beam.Migrate.Backend
( BeamMigrationBackend(..)
, DdlError
, HaskellPredicateConverter(..)
, sql92HsPredicateConverters
, hasColumnConverter
, trivialHsConverter, hsPredicateConverter
, SomeBeamMigrationBackend(..), SomeCheckedDatabaseSettings(..) )
where
import Database.Beam
import Database.Beam.Backend.SQL
import Database.Beam.Migrate.Actions
import Database.Beam.Migrate.Checks
import Database.Beam.Migrate.Serialization
import Database.Beam.Migrate.SQL
import Database.Beam.Migrate.Types
( SomeDatabasePredicate(..), CheckedDatabaseSettings )
import Database.Beam.Haskell.Syntax
import Control.Applicative
import qualified Control.Monad.Fail as Fail
#if ! MIN_VERSION_base(4,11,0)
import Data.Semigroup
#endif
import Data.Text (Text)
import Data.Time
import Data.Typeable
type DdlError = String
data BeamMigrationBackend be m where
BeamMigrationBackend ::
( MonadBeam be m
, Fail.MonadFail m
, HasQBuilder be
, BeamMigrateSqlBackend be
, HasDataTypeCreatedCheck (BeamMigrateSqlBackendDataTypeSyntax be)
, BeamSqlBackendCanSerialize be LocalTime
, BeamSqlBackendCanSerialize be (Maybe LocalTime)
, BeamSqlBackendCanSerialize be Text
, BeamSqlBackendCanSerialize be SqlNull
, Sql92ReasonableMarshaller be ) =>
{ BeamMigrationBackend be m -> String
backendName :: String
, BeamMigrationBackend be m -> String
backendConnStringExplanation :: String
, BeamMigrationBackend be m -> m [SomeDatabasePredicate]
backendGetDbConstraints :: m [ SomeDatabasePredicate ]
, BeamMigrationBackend be m -> BeamDeserializers be
backendPredicateParsers :: BeamDeserializers be
, BeamMigrationBackend be m -> BeamSqlBackendSyntax be -> String
backendRenderSyntax :: BeamSqlBackendSyntax be -> String
, BeamMigrationBackend be m -> String
backendFileExtension :: String
, BeamMigrationBackend be m -> HaskellPredicateConverter
backendConvertToHaskell :: HaskellPredicateConverter
, BeamMigrationBackend be m -> ActionProvider be
backendActionProvider :: ActionProvider be
, BeamMigrationBackend be m
-> forall a. String -> m a -> IO (Either String a)
backendTransact :: forall a. String -> m a -> IO (Either DdlError a)
} -> BeamMigrationBackend be m
data SomeBeamMigrationBackend where
SomeBeamMigrationBackend :: Typeable be
=> BeamMigrationBackend be m
-> SomeBeamMigrationBackend
data SomeCheckedDatabaseSettings where
SomeCheckedDatabaseSettings :: Database be db => CheckedDatabaseSettings be db
-> SomeCheckedDatabaseSettings
newtype HaskellPredicateConverter
= HaskellPredicateConverter (SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
instance Semigroup HaskellPredicateConverter where
<> :: HaskellPredicateConverter
-> HaskellPredicateConverter -> HaskellPredicateConverter
(<>) = HaskellPredicateConverter
-> HaskellPredicateConverter -> HaskellPredicateConverter
forall a. Monoid a => a -> a -> a
mappend
instance Monoid HaskellPredicateConverter where
mempty :: HaskellPredicateConverter
mempty = (SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
HaskellPredicateConverter ((SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter)
-> (SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
forall a b. (a -> b) -> a -> b
$ \SomeDatabasePredicate
_ -> Maybe SomeDatabasePredicate
forall a. Maybe a
Nothing
mappend :: HaskellPredicateConverter
-> HaskellPredicateConverter -> HaskellPredicateConverter
mappend (HaskellPredicateConverter SomeDatabasePredicate -> Maybe SomeDatabasePredicate
a) (HaskellPredicateConverter SomeDatabasePredicate -> Maybe SomeDatabasePredicate
b) =
(SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
HaskellPredicateConverter ((SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter)
-> (SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
forall a b. (a -> b) -> a -> b
$ \SomeDatabasePredicate
r -> SomeDatabasePredicate -> Maybe SomeDatabasePredicate
a SomeDatabasePredicate
r Maybe SomeDatabasePredicate
-> Maybe SomeDatabasePredicate -> Maybe SomeDatabasePredicate
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> SomeDatabasePredicate -> Maybe SomeDatabasePredicate
b SomeDatabasePredicate
r
sql92HsPredicateConverters :: forall fromBe
. Typeable fromBe
=> (BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType)
-> HaskellPredicateConverter
sql92HsPredicateConverters :: (BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType)
-> HaskellPredicateConverter
sql92HsPredicateConverters BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType
convType =
Typeable TableExistsPredicate => HaskellPredicateConverter
forall pred. Typeable pred => HaskellPredicateConverter
trivialHsConverter @TableExistsPredicate HaskellPredicateConverter
-> HaskellPredicateConverter -> HaskellPredicateConverter
forall a. Semigroup a => a -> a -> a
<>
Typeable TableHasPrimaryKey => HaskellPredicateConverter
forall pred. Typeable pred => HaskellPredicateConverter
trivialHsConverter @TableHasPrimaryKey HaskellPredicateConverter
-> HaskellPredicateConverter -> HaskellPredicateConverter
forall a. Semigroup a => a -> a -> a
<>
(BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType)
-> HaskellPredicateConverter
forall fromBe.
Typeable fromBe =>
(BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType)
-> HaskellPredicateConverter
hasColumnConverter @fromBe BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType
convType
hasColumnConverter :: forall fromBe
. Typeable fromBe
=> (BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType)
-> HaskellPredicateConverter
hasColumnConverter :: (BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType)
-> HaskellPredicateConverter
hasColumnConverter BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType
convType =
(TableHasColumn fromBe -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
forall pred.
Typeable pred =>
(pred -> Maybe SomeDatabasePredicate) -> HaskellPredicateConverter
hsPredicateConverter ((TableHasColumn fromBe -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter)
-> (TableHasColumn fromBe -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
forall a b. (a -> b) -> a -> b
$
\(TableHasColumn QualifiedName
tbl Text
col BeamMigrateSqlBackendDataTypeSyntax fromBe
ty :: TableHasColumn fromBe) ->
(TableHasColumn HsMigrateBackend -> SomeDatabasePredicate)
-> Maybe (TableHasColumn HsMigrateBackend)
-> Maybe SomeDatabasePredicate
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TableHasColumn HsMigrateBackend -> SomeDatabasePredicate
forall p. DatabasePredicate p => p -> SomeDatabasePredicate
SomeDatabasePredicate (QualifiedName
-> Text
-> BeamMigrateSqlBackendDataTypeSyntax HsMigrateBackend
-> TableHasColumn HsMigrateBackend
forall be.
HasDataTypeCreatedCheck (BeamMigrateSqlBackendDataTypeSyntax be) =>
QualifiedName
-> Text
-> BeamMigrateSqlBackendDataTypeSyntax be
-> TableHasColumn be
TableHasColumn QualifiedName
tbl Text
col (HsDataType -> TableHasColumn HsMigrateBackend)
-> Maybe HsDataType -> Maybe (TableHasColumn HsMigrateBackend)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BeamMigrateSqlBackendDataTypeSyntax fromBe -> Maybe HsDataType
convType BeamMigrateSqlBackendDataTypeSyntax fromBe
ty :: Maybe (TableHasColumn HsMigrateBackend))
trivialHsConverter :: forall pred. Typeable pred => HaskellPredicateConverter
trivialHsConverter :: HaskellPredicateConverter
trivialHsConverter =
(SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
HaskellPredicateConverter ((SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter)
-> (SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
forall a b. (a -> b) -> a -> b
$ \orig :: SomeDatabasePredicate
orig@(SomeDatabasePredicate p
p') ->
case p -> Maybe pred
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast p
p' of
Maybe pred
Nothing -> Maybe SomeDatabasePredicate
forall a. Maybe a
Nothing
Just (pred
_ :: pred) -> SomeDatabasePredicate -> Maybe SomeDatabasePredicate
forall a. a -> Maybe a
Just SomeDatabasePredicate
orig
hsPredicateConverter :: Typeable pred => (pred -> Maybe SomeDatabasePredicate) -> HaskellPredicateConverter
hsPredicateConverter :: (pred -> Maybe SomeDatabasePredicate) -> HaskellPredicateConverter
hsPredicateConverter pred -> Maybe SomeDatabasePredicate
f =
(SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
HaskellPredicateConverter ((SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter)
-> (SomeDatabasePredicate -> Maybe SomeDatabasePredicate)
-> HaskellPredicateConverter
forall a b. (a -> b) -> a -> b
$ \(SomeDatabasePredicate p
p') ->
case p -> Maybe pred
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast p
p' of
Maybe pred
Nothing -> Maybe SomeDatabasePredicate
forall a. Maybe a
Nothing
Just pred
p'' -> pred -> Maybe SomeDatabasePredicate
f pred
p''