2023-02-21 16:45:12 +03:00
|
|
|
-- | Validate logical models against postgres-like flavors.
|
|
|
|
module Hasura.Backends.Postgres.Instances.LogicalModels
|
|
|
|
( validateLogicalModel,
|
2023-02-03 19:27:44 +03:00
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Data.Aeson (toJSON)
|
2023-02-14 15:14:33 +03:00
|
|
|
import Data.Environment qualified as Env
|
2023-02-08 18:46:09 +03:00
|
|
|
import Data.Text.Extended (toTxt)
|
2023-02-03 19:27:44 +03:00
|
|
|
import Database.PG.Query qualified as PG
|
|
|
|
import Hasura.Backends.Postgres.Connection qualified as PG
|
|
|
|
import Hasura.Backends.Postgres.Connection.Connect (withPostgresDB)
|
|
|
|
import Hasura.Base.Error
|
2023-03-02 19:02:27 +03:00
|
|
|
import Hasura.LogicalModel.Metadata (InterpolatedItem (IIText, IIVariable), LogicalModelMetadata (..), getInterpolatedQuery)
|
|
|
|
import Hasura.LogicalModel.Types (getLogicalModelName)
|
2023-02-03 19:27:44 +03:00
|
|
|
import Hasura.Prelude
|
|
|
|
import Hasura.SQL.Backend
|
|
|
|
|
2023-02-21 16:45:12 +03:00
|
|
|
-- | Prepare a logical model query against a postgres-like database to validate it.
|
|
|
|
validateLogicalModel ::
|
|
|
|
(MonadIO m, MonadError QErr m) =>
|
|
|
|
Env.Environment ->
|
|
|
|
PG.PostgresConnConfiguration ->
|
2023-03-02 19:02:27 +03:00
|
|
|
LogicalModelMetadata ('Postgres pgKind) ->
|
2023-02-21 16:45:12 +03:00
|
|
|
m ()
|
|
|
|
validateLogicalModel env connConf model = do
|
2023-03-02 19:02:27 +03:00
|
|
|
let name = getLogicalModelName $ _lmmRootFieldName model
|
2023-02-03 19:27:44 +03:00
|
|
|
let code :: Text
|
|
|
|
code = fold $ flip evalState (1 :: Int) do
|
2023-03-02 19:02:27 +03:00
|
|
|
for (getInterpolatedQuery $ _lmmCode model) \case
|
2023-02-03 19:27:44 +03:00
|
|
|
IIText t -> pure t
|
|
|
|
IIVariable _v -> do
|
|
|
|
i <- get
|
|
|
|
modify (+ 1)
|
|
|
|
pure $ "$" <> tshow i
|
2023-03-02 18:28:56 +03:00
|
|
|
runRaw :: (MonadIO m, MonadError QErr m) => PG.Query -> m ()
|
|
|
|
runRaw stmt =
|
|
|
|
liftEither
|
|
|
|
=<< liftIO
|
|
|
|
( withPostgresDB
|
|
|
|
env
|
|
|
|
connConf
|
|
|
|
( PG.rawQE
|
|
|
|
( \e ->
|
|
|
|
(err400 ValidationFailed "Failed to validate query")
|
|
|
|
{ qeInternal = Just $ ExtraInternal $ toJSON e
|
|
|
|
}
|
|
|
|
)
|
|
|
|
stmt
|
|
|
|
[]
|
|
|
|
False
|
|
|
|
)
|
|
|
|
)
|
|
|
|
prepname = "_logimo_vali_" <> toTxt name
|
|
|
|
|
|
|
|
-- We don't need to deallocate because 'withPostgresDB' opens a connection,
|
|
|
|
-- runs a statement, and then closes the connection. Since a prepared statement only
|
|
|
|
-- lasts the duration of the session, once it closes, it is deallocated as well.
|
|
|
|
runRaw (PG.fromText $ "PREPARE " <> prepname <> " AS " <> code)
|