{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}
module Database.Beam.Migrate.Generics.Tables
(
HasDefaultSqlDataType(..)
, GMigratableTableSettings(..)
, HasNullableConstraint, NullableStatus
) where
import Database.Beam
import Database.Beam.Backend.Internal.Compat
import Database.Beam.Backend.SQL
import Database.Beam.Migrate.Types.Predicates
import Database.Beam.Migrate.SQL.Types
import Database.Beam.Migrate.SQL.SQL92
import Database.Beam.Migrate.Checks
import Control.Applicative (Const(..))
import Data.Proxy
import Data.Text (Text)
import Data.Scientific (Scientific)
import Data.Time.Calendar (Day)
import Data.Time (TimeOfDay)
import Data.Int
import Data.Word
import GHC.Generics
import GHC.TypeLits
class BeamMigrateSqlBackend be => GMigratableTableSettings be (i :: * -> *) fieldCheck where
gDefaultTblSettingsChecks :: Proxy be -> Proxy i -> Bool -> fieldCheck ()
instance (BeamMigrateSqlBackend be, GMigratableTableSettings be xId fieldCheckId) =>
GMigratableTableSettings be (M1 t s xId) (M1 t s fieldCheckId) where
gDefaultTblSettingsChecks be Proxy embedded =
M1 (gDefaultTblSettingsChecks be (Proxy @xId) embedded)
instance ( BeamMigrateSqlBackend be
, GMigratableTableSettings be aId aFieldCheck
, GMigratableTableSettings be bId bFieldCheck ) =>
GMigratableTableSettings be (aId :*: bId) (aFieldCheck :*: bFieldCheck) where
gDefaultTblSettingsChecks be Proxy embedded =
gDefaultTblSettingsChecks be (Proxy @aId) embedded :*:
gDefaultTblSettingsChecks be (Proxy @bId) embedded
instance ( HasDefaultSqlDataType be haskTy
, HasNullableConstraint (NullableStatus haskTy) be
, HasDataTypeCreatedCheck (BeamMigrateSqlBackendDataTypeSyntax be)
, Typeable be, BeamMigrateSqlBackend be ) =>
GMigratableTableSettings be (Rec0 haskTy) (Rec0 (Const [FieldCheck] haskTy)) where
gDefaultTblSettingsChecks _ _ embedded =
K1 (Const (nullableConstraint (Proxy @(NullableStatus haskTy)) (Proxy @be) ++
defaultSqlDataTypeConstraints (Proxy @haskTy) (Proxy @be) embedded ++
[ FieldCheck (\tblNm nm -> p (TableHasColumn tblNm nm (defaultSqlDataType (Proxy @haskTy) (Proxy @be) embedded)
:: TableHasColumn be )) ]))
instance ( Generic (embeddedTbl (Const [FieldCheck]))
, BeamMigrateSqlBackend be
, GMigratableTableSettings be (Rep (embeddedTbl Identity)) (Rep (embeddedTbl (Const [FieldCheck]))) ) =>
GMigratableTableSettings be (Rec0 (embeddedTbl Identity)) (Rec0 (embeddedTbl (Const [FieldCheck]))) where
gDefaultTblSettingsChecks be _ _ =
K1 (to (gDefaultTblSettingsChecks be (Proxy :: Proxy (Rep (embeddedTbl Identity))) True))
instance ( Generic (embeddedTbl (Nullable (Const [FieldCheck])))
, BeamMigrateSqlBackend be
, GMigratableTableSettings be (Rep (embeddedTbl (Nullable Identity))) (Rep (embeddedTbl (Nullable (Const [FieldCheck])))) ) =>
GMigratableTableSettings be (Rec0 (embeddedTbl (Nullable Identity))) (Rec0 (embeddedTbl (Nullable (Const [FieldCheck])))) where
gDefaultTblSettingsChecks be _ _ =
K1 (to (gDefaultTblSettingsChecks be (Proxy :: Proxy (Rep (embeddedTbl (Nullable Identity)))) True))
type family NullableStatus (x :: *) :: Bool where
NullableStatus (Maybe x) = 'True
NullableStatus x = 'False
class BeamMigrateSqlBackend be => HasNullableConstraint (x :: Bool) be where
nullableConstraint :: Proxy x -> Proxy be -> [ FieldCheck ]
instance ( Typeable be, BeamMigrateSqlBackend be ) =>
HasNullableConstraint 'False be where
nullableConstraint _ _ =
let c = constraintDefinitionSyntax Nothing notNullConstraintSyntax Nothing
in [ FieldCheck $ \tblNm colNm -> p (TableColumnHasConstraint tblNm colNm c :: TableColumnHasConstraint be) ]
instance BeamMigrateSqlBackend be =>
HasNullableConstraint 'True be where
nullableConstraint _ _ = []
class BeamMigrateSqlBackend be => HasDefaultSqlDataType be ty where
defaultSqlDataType :: Proxy ty
-> Proxy be
-> Bool
-> BeamSqlBackendDataTypeSyntax be
defaultSqlDataTypeConstraints
:: Proxy ty
-> Proxy be
-> Bool
-> [ FieldCheck ]
defaultSqlDataTypeConstraints _ _ _ = []
instance (BeamMigrateSqlBackend be, HasDefaultSqlDataType be ty) =>
HasDefaultSqlDataType be (Maybe ty) where
defaultSqlDataType _ = defaultSqlDataType (Proxy @ty)
defaultSqlDataTypeConstraints _ = defaultSqlDataTypeConstraints (Proxy @ty)
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Int32 where
defaultSqlDataType _ _ _ = intType
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Int16 where
defaultSqlDataType _ _ _ = smallIntType
instance ( BeamMigrateSqlBackend be, BeamSqlT071Backend be ) => HasDefaultSqlDataType be Int64 where
defaultSqlDataType _ _ _ = bigIntType
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Word16 where
defaultSqlDataType _ _ _ = numericType (Just (5, Nothing))
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Word32 where
defaultSqlDataType _ _ _ = numericType (Just (10, Nothing))
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Word64 where
defaultSqlDataType _ _ _ = numericType (Just (20, Nothing))
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Text where
defaultSqlDataType _ _ _ = varCharType Nothing Nothing
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be SqlBitString where
defaultSqlDataType _ _ _ = varBitType Nothing
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Double where
defaultSqlDataType _ _ _ = doubleType
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Scientific where
defaultSqlDataType _ _ _ = numericType (Just (20, Just 10))
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be Day where
defaultSqlDataType _ _ _ = dateType
instance BeamMigrateSqlBackend be => HasDefaultSqlDataType be TimeOfDay where
defaultSqlDataType _ _ _ = timeType Nothing False
instance BeamMigrateSql99Backend be => HasDefaultSqlDataType be Bool where
defaultSqlDataType _ _ _ = booleanType
instance (TypeError (PreferExplicitSize Int Int32), BeamMigrateSqlBackend be) => HasDefaultSqlDataType be Int where
defaultSqlDataType _ = defaultSqlDataType (Proxy @Int32)
instance (TypeError (PreferExplicitSize Word Word32), BeamMigrateSqlBackend be) => HasDefaultSqlDataType be Word where
defaultSqlDataType _ _ _ = numericType (Just (10, Nothing))