{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE CPP #-}
module Database.Beam.Postgres.Extensions where
import Database.Beam
import Database.Beam.Schema.Tables
import Database.Beam.Postgres.Types
import Database.Beam.Postgres.Syntax
import Database.Beam.Migrate
import Control.Monad
import Data.Aeson
import qualified Data.HashSet as HS
import Data.Hashable (Hashable)
import Data.Proxy
import Data.Text (Text)
#if !MIN_VERSION_base(4, 11, 0)
import Data.Semigroup
#endif
data PgExtensionEntity extension
class IsPgExtension extension where
pgExtensionName :: Proxy extension -> Text
pgExtensionBuild :: extension
instance RenamableWithRule (FieldRenamer (DatabaseEntityDescriptor Postgres (PgExtensionEntity e))) where
renamingFields :: (NonEmpty Text -> Text)
-> FieldRenamer
(DatabaseEntityDescriptor Postgres (PgExtensionEntity e))
renamingFields NonEmpty Text -> Text
_ = forall entity. (entity -> entity) -> FieldRenamer entity
FieldRenamer forall a. a -> a
id
instance IsDatabaseEntity Postgres (PgExtensionEntity extension) where
data DatabaseEntityDescriptor Postgres (PgExtensionEntity extension) where
PgDatabaseExtension :: IsPgExtension extension
=> Text
-> extension
-> DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
type DatabaseEntityDefaultRequirements Postgres (PgExtensionEntity extension) =
( IsPgExtension extension )
type DatabaseEntityRegularRequirements Postgres (PgExtensionEntity extension) =
( IsPgExtension extension )
dbEntityName :: Lens'
(DatabaseEntityDescriptor Postgres (PgExtensionEntity extension))
Text
dbEntityName Text -> f Text
f (PgDatabaseExtension Text
nm extension
ext) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Text
nm' -> forall extension.
IsPgExtension extension =>
Text
-> extension
-> DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
PgDatabaseExtension Text
nm' extension
ext) (Text -> f Text
f Text
nm)
dbEntitySchema :: Traversal'
(DatabaseEntityDescriptor Postgres (PgExtensionEntity extension))
(Maybe Text)
dbEntitySchema Maybe Text -> f (Maybe Text)
_ DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
n = forall (f :: * -> *) a. Applicative f => a -> f a
pure DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
n
dbEntityAuto :: DatabaseEntityDefaultRequirements
Postgres (PgExtensionEntity extension) =>
Text
-> DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
dbEntityAuto Text
_ = forall extension.
IsPgExtension extension =>
Text
-> extension
-> DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
PgDatabaseExtension (forall extension.
IsPgExtension extension =>
Proxy extension -> Text
pgExtensionName (forall {k} (t :: k). Proxy t
Proxy @extension)) forall extension. IsPgExtension extension => extension
pgExtensionBuild
instance IsCheckedDatabaseEntity Postgres (PgExtensionEntity extension) where
newtype CheckedDatabaseEntityDescriptor Postgres (PgExtensionEntity extension) =
CheckedPgExtension (DatabaseEntityDescriptor Postgres (PgExtensionEntity extension))
type CheckedDatabaseEntityDefaultRequirements Postgres (PgExtensionEntity extension) =
DatabaseEntityRegularRequirements Postgres (PgExtensionEntity extension)
unChecked :: Lens'
(CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension))
(DatabaseEntityDescriptor Postgres (PgExtensionEntity extension))
unChecked DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
-> f (DatabaseEntityDescriptor
Postgres (PgExtensionEntity extension))
f (CheckedPgExtension DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
ext) = forall extension.
DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
-> CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
CheckedPgExtension forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
-> f (DatabaseEntityDescriptor
Postgres (PgExtensionEntity extension))
f DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
ext
collectEntityChecks :: CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
-> [SomeDatabasePredicate]
collectEntityChecks (CheckedPgExtension (PgDatabaseExtension {})) =
[ forall p. DatabasePredicate p => p -> SomeDatabasePredicate
SomeDatabasePredicate (Text -> PgHasExtension
PgHasExtension (forall extension.
IsPgExtension extension =>
Proxy extension -> Text
pgExtensionName (forall {k} (t :: k). Proxy t
Proxy @extension))) ]
checkedDbEntityAuto :: CheckedDatabaseEntityDefaultRequirements
Postgres (PgExtensionEntity extension) =>
Text
-> CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
checkedDbEntityAuto = forall extension.
DatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
-> CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
CheckedPgExtension forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall be entityType.
(IsDatabaseEntity be entityType,
DatabaseEntityDefaultRequirements be entityType) =>
Text -> DatabaseEntityDescriptor be entityType
dbEntityAuto
getPgExtension :: DatabaseEntity Postgres db (PgExtensionEntity extension)
-> extension
getPgExtension :: forall (db :: (* -> *) -> *) extension.
DatabaseEntity Postgres db (PgExtensionEntity extension)
-> extension
getPgExtension (DatabaseEntity (PgDatabaseExtension Text
_ extension
ext)) = extension
ext
pgCreateExtension :: forall extension db
. IsPgExtension extension
=> Migration Postgres (CheckedDatabaseEntity Postgres db (PgExtensionEntity extension))
pgCreateExtension :: forall extension (db :: (* -> *) -> *).
IsPgExtension extension =>
Migration
Postgres
(CheckedDatabaseEntity Postgres db (PgExtensionEntity extension))
pgCreateExtension =
let entity :: CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
entity = forall be entity.
(IsCheckedDatabaseEntity be entity,
CheckedDatabaseEntityDefaultRequirements be entity) =>
Text -> CheckedDatabaseEntityDescriptor be entity
checkedDbEntityAuto Text
""
extName :: Text
extName = forall extension.
IsPgExtension extension =>
Proxy extension -> Text
pgExtensionName (forall {k} (t :: k). Proxy t
Proxy @extension)
in forall be.
BeamSqlBackendSyntax be
-> Maybe (BeamSqlBackendSyntax be) -> Migration be ()
upDown (Text -> PgCommandSyntax
pgCreateExtensionSyntax Text
extName) forall a. Maybe a
Nothing forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall be entityType (db :: (* -> *) -> *).
IsCheckedDatabaseEntity be entityType =>
CheckedDatabaseEntityDescriptor be entityType
-> [SomeDatabasePredicate]
-> CheckedDatabaseEntity be db entityType
CheckedDatabaseEntity CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
entity (forall be entity.
IsCheckedDatabaseEntity be entity =>
CheckedDatabaseEntityDescriptor be entity
-> [SomeDatabasePredicate]
collectEntityChecks CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
entity))
pgDropExtension :: forall extension
. CheckedDatabaseEntityDescriptor Postgres (PgExtensionEntity extension)
-> Migration Postgres ()
pgDropExtension :: forall extension.
CheckedDatabaseEntityDescriptor
Postgres (PgExtensionEntity extension)
-> Migration Postgres ()
pgDropExtension (CheckedPgExtension (PgDatabaseExtension {})) =
forall be.
BeamSqlBackendSyntax be
-> Maybe (BeamSqlBackendSyntax be) -> Migration be ()
upDown (Text -> PgCommandSyntax
pgDropExtensionSyntax (forall extension.
IsPgExtension extension =>
Proxy extension -> Text
pgExtensionName (forall {k} (t :: k). Proxy t
Proxy @extension))) forall a. Maybe a
Nothing
newtype PgHasExtension = PgHasExtension Text
deriving (Int -> PgHasExtension -> ShowS
[PgHasExtension] -> ShowS
PgHasExtension -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PgHasExtension] -> ShowS
$cshowList :: [PgHasExtension] -> ShowS
show :: PgHasExtension -> String
$cshow :: PgHasExtension -> String
showsPrec :: Int -> PgHasExtension -> ShowS
$cshowsPrec :: Int -> PgHasExtension -> ShowS
Show, PgHasExtension -> PgHasExtension -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PgHasExtension -> PgHasExtension -> Bool
$c/= :: PgHasExtension -> PgHasExtension -> Bool
== :: PgHasExtension -> PgHasExtension -> Bool
$c== :: PgHasExtension -> PgHasExtension -> Bool
Eq, forall x. Rep PgHasExtension x -> PgHasExtension
forall x. PgHasExtension -> Rep PgHasExtension x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PgHasExtension x -> PgHasExtension
$cfrom :: forall x. PgHasExtension -> Rep PgHasExtension x
Generic, Eq PgHasExtension
Int -> PgHasExtension -> Int
PgHasExtension -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: PgHasExtension -> Int
$chash :: PgHasExtension -> Int
hashWithSalt :: Int -> PgHasExtension -> Int
$chashWithSalt :: Int -> PgHasExtension -> Int
Hashable)
instance DatabasePredicate PgHasExtension where
englishDescription :: PgHasExtension -> String
englishDescription (PgHasExtension Text
extName) =
String
"Postgres extension " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
extName forall a. [a] -> [a] -> [a]
++ String
" is loaded"
predicateSpecificity :: forall (proxy :: * -> *).
proxy PgHasExtension -> PredicateSpecificity
predicateSpecificity proxy PgHasExtension
_ = String -> PredicateSpecificity
PredicateSpecificityOnlyBackend String
"postgres"
serializePredicate :: PgHasExtension -> Value
serializePredicate (PgHasExtension Text
nm) =
[Pair] -> Value
object [ Key
"has-postgres-extension" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
nm ]
pgExtensionActionProvider :: ActionProvider Postgres
pgExtensionActionProvider :: ActionProvider Postgres
pgExtensionActionProvider = ActionProvider Postgres
pgCreateExtensionProvider forall a. Semigroup a => a -> a -> a
<> ActionProvider Postgres
pgDropExtensionProvider
pgCreateExtensionProvider, pgDropExtensionProvider :: ActionProvider Postgres
pgCreateExtensionProvider :: ActionProvider Postgres
pgCreateExtensionProvider =
forall be. ActionProviderFn be -> ActionProvider be
ActionProvider forall a b. (a -> b) -> a -> b
$ \forall preCondition. Typeable preCondition => [preCondition]
findPre forall preCondition. Typeable preCondition => [preCondition]
findPost ->
do extP :: PgHasExtension
extP@(PgHasExtension Text
ext) <- forall preCondition. Typeable preCondition => [preCondition]
findPost
forall (m :: * -> *) a. Alternative m => [a] -> m ()
ensuringNot_ forall a b. (a -> b) -> a -> b
$
do PgHasExtension Text
ext' <- forall preCondition. Typeable preCondition => [preCondition]
findPre
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Text
ext forall a. Eq a => a -> a -> Bool
== Text
ext')
let cmd :: PgCommandSyntax
cmd = Text -> PgCommandSyntax
pgCreateExtensionSyntax Text
ext
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall be.
HashSet SomeDatabasePredicate
-> HashSet SomeDatabasePredicate
-> Seq (MigrationCommand be)
-> Text
-> Int
-> PotentialAction be
PotentialAction forall a. Monoid a => a
mempty (forall a. (Eq a, Hashable a) => [a] -> HashSet a
HS.fromList [forall p. DatabasePredicate p => p -> SomeDatabasePredicate
p PgHasExtension
extP])
(forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall be.
BeamSqlBackendSyntax be -> MigrationDataLoss -> MigrationCommand be
MigrationCommand PgCommandSyntax
cmd MigrationDataLoss
MigrationKeepsData))
(Text
"Load the postgres extension " forall a. Semigroup a => a -> a -> a
<> Text
ext) Int
1)
pgDropExtensionProvider :: ActionProvider Postgres
pgDropExtensionProvider =
forall be. ActionProviderFn be -> ActionProvider be
ActionProvider forall a b. (a -> b) -> a -> b
$ \forall preCondition. Typeable preCondition => [preCondition]
findPre forall preCondition. Typeable preCondition => [preCondition]
findPost ->
do extP :: PgHasExtension
extP@(PgHasExtension Text
ext) <- forall preCondition. Typeable preCondition => [preCondition]
findPre
forall (m :: * -> *) a. Alternative m => [a] -> m ()
ensuringNot_ forall a b. (a -> b) -> a -> b
$
do PgHasExtension Text
ext' <- forall preCondition. Typeable preCondition => [preCondition]
findPost
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Text
ext forall a. Eq a => a -> a -> Bool
== Text
ext')
let cmd :: PgCommandSyntax
cmd = Text -> PgCommandSyntax
pgDropExtensionSyntax Text
ext
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall be.
HashSet SomeDatabasePredicate
-> HashSet SomeDatabasePredicate
-> Seq (MigrationCommand be)
-> Text
-> Int
-> PotentialAction be
PotentialAction (forall a. (Eq a, Hashable a) => [a] -> HashSet a
HS.fromList [forall p. DatabasePredicate p => p -> SomeDatabasePredicate
p PgHasExtension
extP]) forall a. Monoid a => a
mempty
(forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall be.
BeamSqlBackendSyntax be -> MigrationDataLoss -> MigrationCommand be
MigrationCommand PgCommandSyntax
cmd MigrationDataLoss
MigrationKeepsData))
(Text
"Unload the postgres extension " forall a. Semigroup a => a -> a -> a
<> Text
ext) Int
1)