module Database.HamSql.Setup where
import Data.Typeable
import Data.Yaml
import Database.HamSql.Internal.Utils
import Database.YamSql
import Database.YamSql.Parser
import Database.HamSql.Internal.Stmt
data SetupContext = SetupContext
{ setupContextSetup :: Setup
}
data SetupElement where SetupElement :: (ToSqlStmts a, Show b) => { setupElement :: a
, setupElementSource :: Maybe b
} -> SetupElement
instance ToSqlStmts SetupElement where
toSqlStmts x SetupElement{setupElement=y} = toSqlStmts x y
class (Typeable a) => ToSqlStmts a where
toSqlStmts :: SetupContext -> a -> [Maybe SqlStmt]
data Setup = Setup
{ setupSchemas :: [SqlName]
, setupSchemaDirs :: Maybe [FilePath]
, setupRolePrefix :: Maybe Text
, setupPreCode :: Maybe Text
, setupPostCode :: Maybe Text
, setupSchemaData :: Maybe [Schema]
} deriving (Generic, Show, Data)
instance FromJSON Setup where
parseJSON = parseYamSql
instance ToJSON Setup where
toJSON = toYamSqlJson
setupRolePrefix' :: Setup -> Text
setupRolePrefix' setup = fromMaybe "yamsql_" (setupRolePrefix setup)
data WithSchema a =
WithSchema Schema
a
deriving (Show)
class WithName a where
name :: a -> Text
instance WithName (WithSchema TableTpl) where
name (WithSchema m t) = toSqlCode $ schemaName m <.> tabletplTemplate t
instance WithName (WithSchema FunctionTpl) where
name (WithSchema m f) = toSqlCode $ schemaName m <.> functiontplTemplate f
withoutSchema :: WithSchema a -> a
withoutSchema (WithSchema _ t) = t
selectTemplates :: (ToSqlCode a, WithName (WithSchema t)) =>
Maybe [a] -> [WithSchema t] -> [t]
selectTemplates ns ts
=
[ withoutSchema $
selectUniqueReason ("table or function tpl " <> n) $
filter (\t -> n == name t) ts
| n <- maybeMap toSqlCode ns ]
selectTemplate :: (ToSqlCode a1, WithName (WithSchema a)) =>
a1 -> [WithSchema a] -> a
selectTemplate x ts =
head' $ map withoutSchema $ filter (\y -> name y == toSqlCode x) ts
where
head' = selectUniqueReason ("Column template " <> toSqlCode x)
setupAllSchemas :: Setup -> [Schema]
setupAllSchemas = fromMaybe [] . setupSchemaData
setupAllFunctionTemplates :: Setup -> [WithSchema FunctionTpl]
setupAllFunctionTemplates s =
concat
[ maybeMap (WithSchema m) (schemaFunctionTemplates m)
| m <- setupAllSchemas s ]
setupAllTableTemplates :: Setup -> [WithSchema TableTpl]
setupAllTableTemplates s =
concat
[ maybeMap (WithSchema m) (schemaTableTemplates m)
| m <- setupAllSchemas s ]
applyTpl :: Setup -> Setup
applyTpl s =
s
{ setupSchemaData = Just $ maybeMap applySchema (setupSchemaData s)
}
where
applySchema m =
m
{ schemaTables =
Just $
maybeMap applyTableTemplates (schemaTables m)
, schemaFunctions =
Just $ maybeMap applyFunctionTemplates (schemaFunctions m)
}
applyTableTemplates :: Table -> Table
applyTableTemplates t = foldr applyTableTpl t (tableTpls t)
tableTpls :: Table -> [TableTpl]
tableTpls t = selectTemplates (tableTemplates t) (setupAllTableTemplates s)
applyFunctionTemplates :: Function -> Function
applyFunctionTemplates f = foldr applyFunctionTpl f (functionTpls f)
functionTpls :: Function -> [FunctionTpl]
functionTpls f =
selectTemplates (functionTemplates f) (setupAllFunctionTemplates s)