remove support for query templates (#2560)

query templates is a little known feature that lets you template rql
queries and serve them as rest apis. This is not relevant anymore
given the GraphQL interface and getting rid of it reduces the dev
time when adding features in few subsystems.

This feature has never been used outside hasura's internal projects or
documented or exposed through console and hence can safely be removed.
This commit is contained in:
Vamshi Surabhi 2019-07-24 00:41:34 +05:30 committed by Shahidh K Muhammed
parent b32cfc7d28
commit 4facb3c780
24 changed files with 47 additions and 651 deletions

View File

@ -31,27 +31,6 @@ var ravenVersions = []mt.Version{
}
var testMetadataPrev = map[string][]byte{
"metadata": []byte(`functions: []
query_templates: []
remote_schemas: []
tables:
- array_relationships: []
delete_permissions: []
event_triggers: []
insert_permissions: []
object_relationships: []
select_permissions: []
table: test
update_permissions: []
`),
"empty-metadata": []byte(`functions: []
query_templates: []
remote_schemas: []
tables: []
`),
}
var testMetadataCurrent = map[string][]byte{
"metadata": []byte(`allowlist: []
functions: []
query_collections: []
@ -76,6 +55,29 @@ tables: []
`),
}
var testMetadataCurrent = map[string][]byte{
"metadata": []byte(`allowlist: []
functions: []
query_collections: []
remote_schemas: []
tables:
- array_relationships: []
delete_permissions: []
event_triggers: []
insert_permissions: []
object_relationships: []
select_permissions: []
table: test
update_permissions: []
`),
"empty-metadata": []byte(`allowlist: []
functions: []
query_collections: []
remote_schemas: []
tables: []
`),
}
func isReadyPostgres(i mt.Instance) bool {
db, err := sql.Open("postgres", fmt.Sprintf("postgres://postgres@%v:%v/postgres?sslmode=disable", i.Host(), i.Port()))
if err != nil {
@ -262,7 +264,7 @@ func mustWriteFile(t testing.TB, dir, file string, body string) {
func compareMetadata(t testing.TB, metadataFile string, actualType string, serverVersion *semver.Version) {
var actualData []byte
c, err := semver.NewConstraint("<= 1.0.0-alpha45")
c, err := semver.NewConstraint("<= v1.0.0-beta.3")
if err != nil {
t.Fatal(err)
}

View File

@ -188,7 +188,6 @@ library
, Hasura.RQL.DDL.Relationship
, Hasura.RQL.DDL.Relationship.Rename
, Hasura.RQL.DDL.Relationship.Types
, Hasura.RQL.DDL.QueryTemplate
, Hasura.RQL.DDL.Schema.Table
, Hasura.RQL.DDL.Schema.Rename
, Hasura.RQL.DDL.Schema.Function
@ -209,7 +208,6 @@ library
, Hasura.RQL.DML.Select
, Hasura.RQL.DML.Update
, Hasura.RQL.DML.Count
, Hasura.RQL.DML.QueryTemplate
, Hasura.RQL.GBoolExp
, Hasura.GraphQL.Transport.HTTP.Protocol

View File

@ -19,7 +19,7 @@ import qualified Data.Yaml.TH as Y
import qualified Database.PG.Query as Q
curCatalogVer :: T.Text
curCatalogVer = "17"
curCatalogVer = "18"
migrateMetadata
:: ( MonadTx m
@ -327,6 +327,16 @@ from16To17 =
AND table_name = 'hdb_allowlist';
|]
from17To18 :: MonadTx m => m ()
from17To18 =
liftTx $ Q.catchE defaultTxErrorHandler $
Q.multiQ [Q.sql|
DELETE FROM hdb_catalog.hdb_table
WHERE table_schema = 'hdb_catalog'
AND table_name = 'hdb_query_template';
DROP table hdb_catalog.hdb_query_template
|]
migrateCatalog
:: ( MonadTx m
, CacheRWM m
@ -358,10 +368,13 @@ migrateCatalog migrationTime = do
| preVer == "14" -> from14ToCurrent
| preVer == "15" -> from15ToCurrent
| preVer == "16" -> from16ToCurrent
| preVer == "17" -> from17ToCurrent
| otherwise -> throw400 NotSupported $
"unsupported version : " <> preVer
where
from16ToCurrent = from16To17 >> postMigrate
from17ToCurrent = from17To18 >> postMigrate
from16ToCurrent = from16To17 >> from17ToCurrent
from15ToCurrent = from15To16 >> from16ToCurrent

View File

@ -123,7 +123,6 @@ setAllAsSystemDefined = liftTx $ Q.catchE defaultTxErrorHandler $ do
Q.unitQ "UPDATE hdb_catalog.hdb_table SET is_system_defined = 'true'" () False
Q.unitQ "UPDATE hdb_catalog.hdb_relationship SET is_system_defined = 'true'" () False
Q.unitQ "UPDATE hdb_catalog.hdb_permission SET is_system_defined = 'true'" () False
Q.unitQ "UPDATE hdb_catalog.hdb_query_template SET is_system_defined = 'true'" () False
cleanCatalog :: (MonadTx m) => m ()
cleanCatalog = liftTx $ Q.catchE defaultTxErrorHandler $ do

View File

@ -45,7 +45,6 @@ import qualified Hasura.RQL.DDL.EventTrigger as DE
import qualified Hasura.RQL.DDL.Permission as DP
import qualified Hasura.RQL.DDL.Permission.Internal as DP
import qualified Hasura.RQL.DDL.QueryCollection as DQC
import qualified Hasura.RQL.DDL.QueryTemplate as DQ
import qualified Hasura.RQL.DDL.Relationship as DR
import qualified Hasura.RQL.DDL.RemoteSchema as DRS
import qualified Hasura.RQL.DDL.Schema.Function as DF
@ -120,7 +119,6 @@ instance FromJSON ClearMetadata where
clearMetadata :: Q.TxE QErr ()
clearMetadata = Q.catchE defaultTxErrorHandler $ do
Q.unitQ "DELETE FROM hdb_catalog.hdb_query_template WHERE is_system_defined <> 'true'" () False
Q.unitQ "DELETE FROM hdb_catalog.hdb_function WHERE is_system_defined <> 'true'" () False
Q.unitQ "DELETE FROM hdb_catalog.hdb_permission WHERE is_system_defined <> 'true'" () False
Q.unitQ "DELETE FROM hdb_catalog.hdb_relationship WHERE is_system_defined <> 'true'" () False
@ -144,7 +142,6 @@ runClearMetadata _ = do
data ReplaceMetadata
= ReplaceMetadata
{ aqTables :: ![TableMeta]
, aqQueryTemplates :: ![DQ.CreateQueryTemplate]
, aqFunctions :: !(Maybe [QualifiedFunction])
, aqRemoteSchemas :: !(Maybe [TRS.AddRemoteSchemaQuery])
, aqQueryCollections :: !(Maybe [DQC.CreateCollection])
@ -156,7 +153,7 @@ $(deriveJSON (aesonDrop 2 snakeCase){omitNothingFields=True} ''ReplaceMetadata)
applyQP1
:: (QErrM m, UserInfoM m)
=> ReplaceMetadata -> m ()
applyQP1 (ReplaceMetadata tables templates mFunctions mSchemas mCollections mAllowlist) = do
applyQP1 (ReplaceMetadata tables mFunctions mSchemas mCollections mAllowlist) = do
adminOnly
@ -182,9 +179,6 @@ applyQP1 (ReplaceMetadata tables templates mFunctions mSchemas mCollections mAll
checkMultipleDecls "delete permissions" delPerms
checkMultipleDecls "event triggers" eventTriggers
withPathK "queryTemplates" $
checkMultipleDecls "query templates" $ map DQ.cqtName templates
withPathK "functions" $
checkMultipleDecls "functions" functions
@ -223,7 +217,7 @@ applyQP2
)
=> ReplaceMetadata
-> m EncJSON
applyQP2 (ReplaceMetadata tables templates mFunctions mSchemas mCollections mAllowlist) = do
applyQP2 (ReplaceMetadata tables mFunctions mSchemas mCollections mAllowlist) = do
liftTx clearMetadata
DT.buildSchemaCacheStrict
@ -261,12 +255,6 @@ applyQP2 (ReplaceMetadata tables templates mFunctions mSchemas mCollections mAll
indexedForM_ (table ^. tmEventTriggers) $ \etc ->
DE.subTableP2 (table ^. tmTable) False etc
-- query templates
withPathK "queryTemplates" $
indexedForM_ templates $ \template -> do
qti <- DQ.createQueryTemplateP1 template
void $ DQ.createQueryTemplateP2 template qti
-- sql functions
withPathK "functions" $
indexedMapM_ (void . DF.trackFunctionP2) functions
@ -341,13 +329,6 @@ fetchMetadata = do
updPermDefs <- mkPermDefs PTUpdate permissions
delPermDefs <- mkPermDefs PTDelete permissions
-- Fetch all the query templates
qTmpltRows <- Q.catchE defaultTxErrorHandler fetchQTemplates
qTmpltDefs <- forM qTmpltRows $ \(qtn, Q.AltJ qtDefVal, mComment) -> do
qtDef <- decodeValue qtDefVal
return $ DQ.CreateQueryTemplate qtn qtDef mComment
-- Fetch all event triggers
eventTriggers <- Q.catchE defaultTxErrorHandler fetchEventTriggers
triggerMetaDefs <- mkTriggerMetaDefs eventTriggers
@ -374,7 +355,7 @@ fetchMetadata = do
-- fetch allow list
allowlist <- map DQC.CollectionReq <$> DQC.fetchAllowlist
return $ ReplaceMetadata (M.elems postRelMap) qTmpltDefs (Just functions)
return $ ReplaceMetadata (M.elems postRelMap) (Just functions)
(Just schemas) (Just collections) (Just allowlist)
where
@ -421,12 +402,6 @@ fetchMetadata = do
WHERE is_system_defined = 'false'
|] () False
fetchQTemplates =
Q.listQ [Q.sql|
SELECT template_name, template_defn :: json, comment
FROM hdb_catalog.hdb_query_template
WHERE is_system_defined = 'false'
|] () False
fetchEventTriggers =
Q.listQ [Q.sql|
SELECT e.schema_name, e.table_name, e.configuration::json
@ -528,7 +503,6 @@ purgeMetadataObj = liftTx . \case
Q.catchE defaultTxErrorHandler $ DT.delTableFromCatalog qt
(MOFunction qf) -> DF.delFunctionFromCatalog qf
(MORemoteSchema rsn) -> DRS.removeRemoteSchemaFromCatalog rsn
(MOQTemplate qtn) -> DQ.delQTemplateFromCatalog qtn
(MOTableObj qt (MTORel rn _)) -> DR.delRelFromCatalog qt rn
(MOTableObj qt (MTOPerm rn pt)) -> DP.dropPermFromCatalog qt rn pt
(MOTableObj _ (MTOTrigger trn)) -> DE.delEventTriggerFromCatalog trn

View File

@ -1,236 +0,0 @@
module Hasura.RQL.DDL.QueryTemplate
( createQueryTemplateP1
, createQueryTemplateP2
, delQTemplateFromCatalog
, TemplateParamConf(..)
, CreateQueryTemplate(..)
, runCreateQueryTemplate
, QueryTP1
, DropQueryTemplate(..)
, runDropQueryTemplate
, SetQueryTemplateComment(..)
, runSetQueryTemplateComment
) where
import Hasura.EncJSON
import Hasura.Prelude
import Hasura.RQL.DML.Internal (sessVarFromCurrentSetting)
import Hasura.RQL.GBoolExp (txtRHSBuilder)
import Hasura.RQL.Types
import Hasura.SQL.Types
import Hasura.SQL.Value
import qualified Database.PG.Query as Q
import qualified Hasura.RQL.DML.Count as R
import qualified Hasura.RQL.DML.Delete as R
import qualified Hasura.RQL.DML.Insert as R
import qualified Hasura.RQL.DML.Select as R
import qualified Hasura.RQL.DML.Update as R
import qualified Hasura.SQL.DML as PS
import Data.Aeson
import Data.Aeson.Casing
import Data.Aeson.TH
import Instances.TH.Lift ()
import Language.Haskell.TH.Syntax (Lift)
import qualified Data.HashMap.Strict as M
import qualified Data.Text as T
data TemplateParamConf
= TemplateParamConf
{ tpcParam :: !TemplateParam
, tpcDefault :: !(Maybe Value)
} deriving (Show, Eq, Lift)
$(deriveJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''TemplateParamConf)
data CreateQueryTemplate
= CreateQueryTemplate
{ cqtName :: !TQueryName
, cqtTemplate :: !QueryT
, cqtComment :: !(Maybe T.Text)
} deriving (Show, Eq, Lift)
$(deriveJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''CreateQueryTemplate)
validateParam
:: (QErrM m)
=> PGColType
-> Value
-> m PS.SQLExp
validateParam pct val =
case val of
Object _ -> do
tpc <- decodeValue val
withPathK "default" $
maybe (return ()) validateDefault $ tpcDefault tpc
return $ PS.SELit "NULL"
_ -> txtRHSBuilder pct val
where
validateDefault =
void . runAesonParser (convToBin pct)
mkSelQ :: (QErrM m) => SelectQueryT -> m SelectQuery
mkSelQ (DMLQuery tn (SelectG c w o lim offset)) = do
intLim <- withPathK "limit" $ maybe returnNothing parseAsInt lim
intOffset <- withPathK "offset" $ maybe returnNothing parseAsInt offset
return $ DMLQuery tn $ SelectG c w o intLim intOffset
where
returnNothing = return Nothing
parseAsInt v = case v of
Object _ -> do
tpc <- decodeValue v
withPathK "default" $
mapM decodeValue $ tpcDefault tpc
_ -> Just <$> decodeValue v
data QueryTP1
= QTP1Insert R.InsertQueryP1
| QTP1Select R.AnnSimpleSel
| QTP1Update R.AnnUpd
| QTP1Delete R.AnnDel
| QTP1Count R.CountQueryP1
| QTP1Bulk [QueryTP1]
deriving (Show, Eq)
validateTQuery
:: (QErrM m, UserInfoM m, CacheRM m, HasSQLGenCtx m)
=> QueryT
-> m QueryTP1
validateTQuery qt = withPathK "args" $ case qt of
QTInsert q -> QTP1Insert <$>
R.convInsertQuery decodeInsObjs sessVarFromCurrentSetting validateParam q
QTSelect q -> QTP1Select <$>
(mkSelQ q >>= R.convSelectQuery sessVarFromCurrentSetting validateParam)
QTUpdate q -> QTP1Update <$>
R.validateUpdateQueryWith sessVarFromCurrentSetting validateParam q
QTDelete q -> QTP1Delete <$>
R.validateDeleteQWith sessVarFromCurrentSetting validateParam q
QTCount q -> QTP1Count <$>
R.validateCountQWith sessVarFromCurrentSetting validateParam q
QTBulk q -> QTP1Bulk <$> mapM validateTQuery q
where
decodeInsObjs val = do
tpc <- decodeValue val
mDefObjs <- mapM decodeValue $ tpcDefault tpc
return $ fromMaybe [] mDefObjs
collectDeps
:: QueryTP1 -> [SchemaDependency]
collectDeps qt = case qt of
QTP1Insert qp1 -> R.getInsertDeps qp1
QTP1Select qp1 -> R.getSelectDeps qp1
QTP1Update qp1 -> R.getUpdateDeps qp1
QTP1Delete qp1 -> R.getDeleteDeps qp1
QTP1Count qp1 -> R.getCountDeps qp1
QTP1Bulk qp1 -> concatMap collectDeps qp1
createQueryTemplateP1
:: (UserInfoM m, QErrM m, CacheRM m, HasSQLGenCtx m)
=> CreateQueryTemplate
-> m (WithDeps QueryTemplateInfo)
createQueryTemplateP1 (CreateQueryTemplate qtn qt _) = do
adminOnly
sc <- askSchemaCache
withPathK "name" $ when (isJust $ M.lookup qtn $ scQTemplates sc) $
throw400 AlreadyExists $ "the query template already exists : " <>> qtn
qtp1 <- withPathK "template" $ liftP1 $ validateTQuery qt
let deps = collectDeps qtp1
return (QueryTemplateInfo qtn qt, deps)
addQTemplateToCatalog
:: CreateQueryTemplate
-> Q.TxE QErr ()
addQTemplateToCatalog (CreateQueryTemplate qtName qtDef mComment) =
Q.unitQE defaultTxErrorHandler [Q.sql|
INSERT INTO
hdb_catalog.hdb_query_template
(template_name, template_defn, comment)
VALUES ($1, $2 :: jsonb, $3)
|] (qtName, Q.AltJ qtDef, mComment) False
createQueryTemplateP2
:: (QErrM m, CacheRWM m, MonadTx m)
=> CreateQueryTemplate
-> WithDeps QueryTemplateInfo
-> m EncJSON
createQueryTemplateP2 cqt (qti, deps) = do
addQTemplateToCache qti deps
liftTx $ addQTemplateToCatalog cqt
return successMsg
runCreateQueryTemplate
:: (QErrM m, UserInfoM m, CacheRWM m, MonadTx m, HasSQLGenCtx m)
=> CreateQueryTemplate -> m EncJSON
runCreateQueryTemplate q =
createQueryTemplateP1 q >>= createQueryTemplateP2 q
data DropQueryTemplate
= DropQueryTemplate
{ dqtName :: !TQueryName
} deriving (Show, Eq, Lift)
$(deriveJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''DropQueryTemplate)
delQTemplateFromCatalog
:: TQueryName
-> Q.TxE QErr ()
delQTemplateFromCatalog qtn =
Q.unitQE defaultTxErrorHandler [Q.sql|
DELETE FROM
hdb_catalog.hdb_query_template
WHERE template_name = $1
|] (Identity qtn) False
runDropQueryTemplate
:: (QErrM m, UserInfoM m, CacheRWM m, MonadTx m)
=> DropQueryTemplate -> m EncJSON
runDropQueryTemplate q = do
withPathK "name" $ void $ askQTemplateInfo qtn
delQTemplateFromCache qtn
liftTx $ delQTemplateFromCatalog qtn
return successMsg
where
qtn = dqtName q
data SetQueryTemplateComment
= SetQueryTemplateComment
{ sqtcName :: !TQueryName
, sqtcComment :: !(Maybe T.Text)
} deriving (Show, Eq, Lift)
$(deriveJSON (aesonDrop 4 snakeCase) ''SetQueryTemplateComment)
setQueryTemplateCommentP1
:: (UserInfoM m, QErrM m, CacheRM m)
=> SetQueryTemplateComment -> m ()
setQueryTemplateCommentP1 (SetQueryTemplateComment qtn _) = do
adminOnly
void $ askQTemplateInfo qtn
setQueryTemplateCommentP2
:: (QErrM m, MonadTx m) => SetQueryTemplateComment -> m EncJSON
setQueryTemplateCommentP2 apc = do
liftTx $ setQueryTemplateCommentTx apc
return successMsg
setQueryTemplateCommentTx
:: SetQueryTemplateComment
-> Q.TxE QErr ()
setQueryTemplateCommentTx (SetQueryTemplateComment qtn comment) =
Q.unitQE defaultTxErrorHandler
[Q.sql|
UPDATE hdb_catalog.hdb_query_template
SET comment = $1
WHERE template_name = $2
|] (comment, qtn) False
runSetQueryTemplateComment
:: (QErrM m, UserInfoM m, CacheRWM m, MonadTx m)
=> SetQueryTemplateComment -> m EncJSON
runSetQueryTemplateComment q = do
setQueryTemplateCommentP1 q
setQueryTemplateCommentP2 q

View File

@ -36,14 +36,9 @@ data RenameField
type RenameTable = (QualifiedTable, QualifiedTable)
otherDeps :: QErrM m => Text -> SchemaObjId -> m ()
otherDeps errMsg = \case
SOQTemplate name ->
throw400 NotSupported $
"found dependant query template " <> name <<> "; " <> errMsg
d ->
throw500 $ "unexpected dependancy "
<> reportSchemaObj d <> "; " <> errMsg
otherDeps errMsg d =
throw500 $ "unexpected dependancy "
<> reportSchemaObj d <> "; " <> errMsg
renameTableInCatalog
:: (MonadTx m, CacheRM m)

View File

@ -13,7 +13,6 @@ import Hasura.RQL.DDL.Deps
import Hasura.RQL.DDL.EventTrigger
import Hasura.RQL.DDL.Permission
import Hasura.RQL.DDL.Permission.Internal
import Hasura.RQL.DDL.QueryTemplate
import Hasura.RQL.DDL.Relationship
import Hasura.RQL.DDL.RemoteSchema
import Hasura.RQL.DDL.Schema.Diff
@ -123,10 +122,6 @@ purgeDep schemaObjId = case schemaObjId of
liftTx $ delRelFromCatalog qt rn
delRelFromCache rn qt
(SOQTemplate qtn) -> do
liftTx $ delQTemplateFromCatalog qtn
delQTemplateFromCache qtn
(SOFunction qf) -> do
liftTx $ delFunctionFromCatalog qf
delFunctionFromCache qf
@ -352,7 +347,7 @@ buildSchemaCacheG withSetup = do
sqlGenCtx <- askSQLGenCtx
-- fetch all catalog metadata
CatalogMetadata tables relationships permissions qTemplates
CatalogMetadata tables relationships permissions
eventTriggers remoteSchemas functions fkeys' allowlistDefs
<- liftTx fetchCatalogData
@ -403,18 +398,6 @@ buildSchemaCacheG withSetup = do
PTUpdate -> permHelper withSetup sqlGenCtx qt rn pDef PAUpdate
PTDelete -> permHelper withSetup sqlGenCtx qt rn pDef PADelete
-- query templates
forM_ qTemplates $ \(CatalogQueryTemplate qtn qtDefVal) -> do
let def = object ["name" .= qtn, "template" .= qtDefVal]
mkInconsObj =
InconsistentMetadataObj (MOQTemplate qtn) MOTQTemplate def
handleInconsistentObj mkInconsObj $ do
qtDef <- decodeValue qtDefVal
qCtx <- mkAdminQCtx sqlGenCtx <$> askSchemaCache
(qti, deps) <- liftP1WithQCtx qCtx $ createQueryTemplateP1 $
CreateQueryTemplate qtn qtDef Nothing
addQTemplateToCache qti deps
-- event triggers
forM_ eventTriggers $ \(CatalogEventTrigger qt trn configuration) -> do
let objId = MOTableObj qt $ MTOTrigger trn

View File

@ -1,148 +0,0 @@
module Hasura.RQL.DML.QueryTemplate
( ExecQueryTemplate(..)
, runExecQueryTemplate
) where
import Hasura.EncJSON
import Hasura.Prelude
import Hasura.RQL.DDL.QueryTemplate
import Hasura.RQL.DML.Internal
import Hasura.RQL.GBoolExp (txtRHSBuilder)
import Hasura.RQL.Instances ()
import Hasura.RQL.Types
import Hasura.SQL.Types
import qualified Database.PG.Query as Q
import qualified Hasura.RQL.DML.Count as RC
import qualified Hasura.RQL.DML.Delete as R
import qualified Hasura.RQL.DML.Insert as R
import qualified Hasura.RQL.DML.Select as R
import qualified Hasura.RQL.DML.Update as R
import qualified Hasura.SQL.DML as S
import Data.Aeson.Casing
import Data.Aeson.TH
import Data.Aeson.Types
import Instances.TH.Lift ()
import Language.Haskell.TH.Syntax (Lift)
import qualified Data.HashMap.Strict as M
import qualified Data.Sequence as DS
type TemplateArgs = M.HashMap TemplateParam Value
data ExecQueryTemplate
= ExecQueryTemplate
{ eqtName :: !TQueryName
, eqtArgs :: !TemplateArgs
} deriving (Show, Eq, Lift)
$(deriveJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''ExecQueryTemplate)
getParamValue
:: TemplateArgs
-> TemplateParamConf
-> DMLP1 Value
getParamValue params (TemplateParamConf paramName paramVal) =
maybe paramMissing return $ M.lookup paramName params <|> paramVal
where
paramMissing = throw400 InvalidParams $
"missing parameter : " <>> paramName
data QueryTProc
= QTPInsert !(R.InsertQueryP1, DS.Seq Q.PrepArg)
| QTPSelect !(R.AnnSimpleSel, DS.Seq Q.PrepArg)
| QTPUpdate !(R.AnnUpd, DS.Seq Q.PrepArg)
| QTPDelete !(R.AnnDel, DS.Seq Q.PrepArg)
| QTPCount !(RC.CountQueryP1, DS.Seq Q.PrepArg)
| QTPBulk ![QueryTProc]
deriving (Show, Eq)
buildPrepArg
:: TemplateArgs
-> PGColType
-> Value
-> DMLP1 S.SQLExp
buildPrepArg args pct val =
case val of
Object _ -> do
tpc <- decodeValue val
v <- getParamValue args tpc
modifyErr (withParamErrMsg tpc) $ binRHSBuilder pct v
_ -> txtRHSBuilder pct val
where
withParamErrMsg tpc t =
"when processing parameter " <> tpcParam tpc <<> " : " <> t
decodeIntValue :: TemplateArgs -> Value -> DMLP1 Int
decodeIntValue args val =
case val of
Object _ -> do
tpc <- decodeValue val
v <- getParamValue args tpc
decodeValue v
_ -> decodeValue val
mkSelQWithArgs :: SelectQueryT -> TemplateArgs -> DMLP1 SelectQuery
mkSelQWithArgs (DMLQuery tn (SelectG c w o lim offset)) args = do
intLim <- mapM (decodeIntValue args) lim
intOffset <- mapM (decodeIntValue args) offset
return $ DMLQuery tn $ SelectG c w o intLim intOffset
convQT
:: (UserInfoM m, QErrM m, CacheRM m, HasSQLGenCtx m)
=> TemplateArgs
-> QueryT
-> m QueryTProc
convQT args qt = case qt of
QTInsert q ->
fmap QTPInsert $ liftDMLP1 $
R.convInsertQuery decodeParam sessVarFromCurrentSetting binRHSBuilder q
QTSelect q ->
fmap QTPSelect $ liftDMLP1 $ mkSelQWithArgs q args
>>= R.convSelectQuery sessVarFromCurrentSetting f
QTUpdate q ->
fmap QTPUpdate $ liftDMLP1 $
R.validateUpdateQueryWith sessVarFromCurrentSetting f q
QTDelete q ->
fmap QTPDelete $ liftDMLP1 $
R.validateDeleteQWith sessVarFromCurrentSetting f q
QTCount q ->
fmap QTPCount $ liftDMLP1 $
RC.validateCountQWith sessVarFromCurrentSetting f q
QTBulk q -> fmap QTPBulk $ mapM (convQT args) q
where
decodeParam val = do
tpc <- decodeValue val
v <- getParamValue args tpc
R.decodeInsObjs v
f = buildPrepArg args
execQueryTemplateP1
:: (UserInfoM m, QErrM m, CacheRM m, HasSQLGenCtx m)
=> ExecQueryTemplate -> m QueryTProc
execQueryTemplateP1 (ExecQueryTemplate qtn args) = do
(QueryTemplateInfo _ qt) <- askQTemplateInfo qtn
convQT args qt
execQueryTP2
:: (QErrM m, CacheRM m, MonadTx m, HasSQLGenCtx m)
=> QueryTProc -> m EncJSON
execQueryTP2 qtProc = do
strfyNum <- stringifyNum <$> askSQLGenCtx
case qtProc of
QTPInsert qp -> liftTx $ R.insertP2 strfyNum qp
QTPSelect qp -> liftTx $ R.selectP2 False qp
QTPUpdate qp -> liftTx $ R.updateQueryToTx strfyNum qp
QTPDelete qp -> liftTx $ R.deleteQueryToTx strfyNum qp
QTPCount qp -> RC.countQToTx qp
QTPBulk qps -> encJFromList <$> mapM execQueryTP2 qps
runExecQueryTemplate
:: ( QErrM m, UserInfoM m, CacheRM m
, MonadTx m, HasSQLGenCtx m
)
=> ExecQueryTemplate -> m EncJSON
runExecQueryTemplate q =
execQueryTemplateP1 q >>= execQueryTP2

View File

@ -29,8 +29,6 @@ module Hasura.RQL.Types
, askEventTriggerInfo
, askTabInfoFromTrigger
, askQTemplateInfo
, adminOnly
, HeaderObj
@ -85,8 +83,6 @@ mkAdminQCtx soc sc = QCtx adminUserInfo sc soc
class (Monad m) => UserInfoM m where
askUserInfo :: m UserInfo
type P1C m = (UserInfoM m, QErrM m, CacheRM m)
askTabInfo
:: (QErrM m, CacheRM m)
=> QualifiedTable -> m TableInfo
@ -116,16 +112,6 @@ askEventTriggerInfo trn = do
where
errMsg = "event trigger " <> triggerNameToTxt trn <<> " does not exist"
askQTemplateInfo
:: (P1C m)
=> TQueryName
-> m QueryTemplateInfo
askQTemplateInfo qtn = do
rawSchemaCache <- askSchemaCache
liftMaybe (err400 NotExists errMsg) $ M.lookup qtn $ scQTemplates rawSchemaCache
where
errMsg = "query-template " <> qtn <<> " does not exist"
instance UserInfoM P1 where
askUserInfo = qcUserInfo <$> ask

View File

@ -43,13 +43,6 @@ data CatalogPermission
} deriving (Show, Eq)
$(deriveJSON (aesonDrop 3 snakeCase) ''CatalogPermission)
data CatalogQueryTemplate
= CatalogQueryTemplate
{ _cqtName :: !TQueryName
, _cqtDef :: !Value
} deriving (Show, Eq)
$(deriveJSON (aesonDrop 4 snakeCase) ''CatalogQueryTemplate)
data CatalogEventTrigger
= CatalogEventTrigger
{ _cetTable :: !QualifiedTable
@ -70,7 +63,6 @@ data CatalogMetadata
{ _cmTables :: ![CatalogTable]
, _cmRelations :: ![CatalogRelation]
, _cmPermissions :: ![CatalogPermission]
, _cmQueryTemplates :: ![CatalogQueryTemplate]
, _cmEventTriggers :: ![CatalogEventTrigger]
, _cmRemoteSchemas :: ![AddRemoteSchemaQuery]
, _cmFunctions :: ![CatalogFunction]

View File

@ -11,9 +11,6 @@ module Hasura.RQL.Types.Common
, fromPGCol
, fromRel
, TQueryName(..)
, TemplateParam(..)
, ToAesonPairs(..)
, WithTable(..)
, ColVals
@ -146,24 +143,6 @@ fromPGCol (PGCol c) = FieldName c
fromRel :: RelName -> FieldName
fromRel = FieldName . relNameToTxt
newtype TQueryName
= TQueryName { getTQueryName :: NonEmptyText }
deriving ( Show, Eq, Hashable, FromJSONKey, ToJSONKey
, FromJSON, ToJSON, Q.ToPrepArg, Q.FromCol, Lift)
instance IsIden TQueryName where
toIden (TQueryName r) = Iden $ unNonEmptyText r
instance DQuote TQueryName where
dquoteTxt (TQueryName r) = unNonEmptyText r
newtype TemplateParam
= TemplateParam { getTemplateParam :: T.Text }
deriving (Show, Eq, Hashable, FromJSON, FromJSONKey, ToJSONKey, ToJSON, Lift)
instance DQuote TemplateParam where
dquoteTxt (TemplateParam r) = r
class ToAesonPairs a where
toAesonPairs :: (KeyValue v) => a -> [v]

View File

@ -15,7 +15,6 @@ data MetadataObjType
= MOTTable
| MOTRel !RelType
| MOTPerm !PermType
| MOTQTemplate
| MOTEventTrigger
| MOTFunction
| MOTRemoteSchema
@ -25,7 +24,6 @@ instance Show MetadataObjType where
show MOTTable = "table"
show (MOTRel ty) = T.unpack (relTypeToTxt ty) <> "_relation"
show (MOTPerm ty) = show ty <> "_permission"
show MOTQTemplate = "query_template"
show MOTEventTrigger = "event_trigger"
show MOTFunction = "function"
show MOTRemoteSchema = "remote_schema"
@ -43,7 +41,6 @@ instance Hashable TableMetadataObjId
data MetadataObjId
= MOTable !QualifiedTable
| MOQTemplate !TQueryName
| MOFunction !QualifiedFunction
| MORemoteSchema !RemoteSchemaName
| MOTableObj !QualifiedTable !TableMetadataObjId

View File

@ -73,11 +73,6 @@ module Hasura.RQL.Types.SchemaCache
, delPermFromCache
, PreSetColsPartial
, QueryTemplateInfo(..)
, addQTemplateToCache
, delQTemplateFromCache
, TemplateParamInfo(..)
, addEventTriggerToCache
, delEventTriggerFromCache
, EventTriggerInfo(..)
@ -112,7 +107,6 @@ import qualified Hasura.GraphQL.Context as GC
import Hasura.Prelude
import Hasura.RQL.Types.BoolExp
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.DML
import Hasura.RQL.Types.Error
import Hasura.RQL.Types.EventTrigger
import Hasura.RQL.Types.Metadata
@ -142,16 +136,6 @@ mkColDep :: T.Text -> QualifiedTable -> PGCol -> SchemaDependency
mkColDep reason tn col =
flip SchemaDependency reason . SOTableObj tn $ TOCol col
data QueryTemplateInfo
= QueryTemplateInfo
{ qtiName :: !TQueryName
, qtiQuery :: !QueryT
} deriving (Show, Eq)
$(deriveToJSON (aesonDrop 3 snakeCase) ''QueryTemplateInfo)
type QTemplateCache = M.HashMap TQueryName QueryTemplateInfo
onlyIntCols :: [PGColInfo] -> [PGColInfo]
onlyIntCols = filter (isIntegerType . pgiType)
@ -460,7 +444,6 @@ data SchemaCache
= SchemaCache
{ scTables :: !TableCache
, scFunctions :: !FunctionCache
, scQTemplates :: !QTemplateCache
, scRemoteSchemas :: !RemoteSchemaMap
, scAllowlist :: !(HS.HashSet GQLQuery)
, scGCtxMap :: !GC.GCtxMap
@ -497,41 +480,9 @@ class (CacheRM m) => CacheRWM m where
instance (Monad m) => CacheRWM (StateT SchemaCache m) where
writeSchemaCache = put
addQTemplateToCache
:: (QErrM m, CacheRWM m)
=> QueryTemplateInfo
-> [SchemaDependency]
-> m ()
addQTemplateToCache qti deps = do
sc <- askSchemaCache
let templateCache = scQTemplates sc
case M.lookup qtn templateCache of
Just _ -> throw500 $ "template already exists in cache " <>> qtn
Nothing -> do
let newTemplateCache = M.insert qtn qti templateCache
writeSchemaCache $ sc {scQTemplates = newTemplateCache}
modDepMapInCache (addToDepMap objId deps)
where
qtn = qtiName qti
objId = SOQTemplate qtn
delQTemplateFromCache :: (QErrM m, CacheRWM m)
=> TQueryName -> m ()
delQTemplateFromCache qtn = do
sc <- askSchemaCache
let templateCache = scQTemplates sc
case M.lookup qtn templateCache of
Nothing -> throw500 $ "template does not exist in cache " <>> qtn
Just _ -> do
let newTemplateCache = M.delete qtn templateCache
writeSchemaCache $ sc {scQTemplates = newTemplateCache}
modDepMapInCache (removeFromDepMap objId)
where
objId = SOQTemplate qtn
emptySchemaCache :: SchemaCache
emptySchemaCache =
SchemaCache M.empty M.empty M.empty M.empty
SchemaCache M.empty M.empty M.empty
HS.empty M.empty GC.emptyGCtx mempty []
modTableCache :: (CacheRWM m) => TableCache -> m ()
@ -801,12 +752,6 @@ delPermFromCache pa rn tn = do
return $ ti { tiRolePermInfoMap = M.insert rn newRPI rpim }
schObjId = SOTableObj tn $ TOPerm rn $ permAccToType pa
data TemplateParamInfo
= TemplateParamInfo
{ tpiName :: !TemplateParam
, tpiDefault :: !(Maybe Value)
} deriving (Show, Eq)
addRemoteSchemaToCache
:: (QErrM m, CacheRWM m) => RemoteSchemaCtx -> m ()
addRemoteSchemaToCache rmCtx = do

View File

@ -25,7 +25,6 @@ instance Hashable TableObjId
data SchemaObjId
= SOTable !QualifiedTable
| SOQTemplate !TQueryName
| SOTableObj !QualifiedTable !TableObjId
| SOFunction !QualifiedFunction
deriving (Eq, Generic)
@ -35,8 +34,6 @@ instance Hashable SchemaObjId
reportSchemaObj :: SchemaObjId -> T.Text
reportSchemaObj (SOTable tn) = "table " <> qualObjectToText tn
reportSchemaObj (SOFunction fn) = "function " <> qualObjectToText fn
reportSchemaObj (SOQTemplate qtn) =
"query-template " <> unNonEmptyText (getTQueryName qtn)
reportSchemaObj (SOTableObj tn (TOCol cn)) =
"column " <> qualObjectToText tn <> "." <> getPGColTxt cn
reportSchemaObj (SOTableObj tn (TORel cn)) =

View File

@ -4,7 +4,6 @@
module Hasura.Server.App where
import Control.Arrow ((***))
import Control.Concurrent.MVar
import Control.Exception (IOException, try)
import Data.Aeson hiding (json)
@ -47,7 +46,6 @@ import qualified Hasura.Server.PGDump as PGD
import Hasura.EncJSON
import Hasura.Prelude hiding (get, put)
import Hasura.RQL.DDL.Schema.Table
import Hasura.RQL.DML.QueryTemplate
import Hasura.RQL.Types
import Hasura.Server.Auth (AuthMode (..),
getUserInfo)
@ -515,10 +513,6 @@ httpApp corsCfg serverCtx enableConsole consoleAssetsDir enableTelemetry = do
lazyBytes $ encode $ object [ "version" .= currentVersion ]
when enableMetadata $ do
get ("v1/template" <//> var) tmpltGetOrDeleteH
post ("v1/template" <//> var) tmpltPutOrPostH
put ("v1/template" <//> var) tmpltPutOrPostH
delete ("v1/template" <//> var) tmpltGetOrDeleteH
post "v1/query" $ mkSpockAction encodeQErr id serverCtx $
mkPostHandler $ mkAPIRespHandler v1QueryHandler
@ -585,36 +579,11 @@ httpApp corsCfg serverCtx enableConsole consoleAssetsDir enableTelemetry = do
mkSpockAction encodeQErr id serverCtx $ mkPostHandler $
mkAPIRespHandler gqlExplainHandler
mkTmpltName tmpltText =
onNothing (mkNonEmptyText tmpltText) $ throw400 NotSupported "template name is empty string"
enableGraphQL = isGraphQLEnabled serverCtx
enableMetadata = isMetadataEnabled serverCtx
enablePGDump = isPGDumpEnabled serverCtx
enableConfig = isConfigEnabled serverCtx
tmpltGetOrDeleteH tmpltText = do
tmpltArgs <- tmpltArgsFromQueryParams
mkSpockAction encodeQErr id serverCtx $ mkGetHandler $ do
tmpltName <- mkTmpltName tmpltText
JSONResp <$> mkQTemplateAction tmpltName tmpltArgs
tmpltPutOrPostH tmpltText = do
tmpltArgs <- tmpltArgsFromQueryParams
mkSpockAction encodeQErr id serverCtx $ mkPostHandler $
mkAPIRespHandler $ \bodyTmpltArgs -> do
tmpltName <- mkTmpltName tmpltText
mkQTemplateAction tmpltName $ M.union bodyTmpltArgs tmpltArgs
tmpltArgsFromQueryParams = do
qparams <- params
return $ M.fromList $ flip map qparams $
TemplateParam *** String
mkQTemplateAction tmpltName tmpltArgs =
v1QueryHandler $ RQExecuteQueryTemplate $
ExecQueryTemplate (TQueryName tmpltName) tmpltArgs
serveApiConsole = do
-- redirect / to /console
get root $ redirect "console"

View File

@ -13,7 +13,6 @@ import Hasura.RQL.DDL.EventTrigger
import Hasura.RQL.DDL.Metadata
import Hasura.RQL.DDL.Permission
import Hasura.RQL.DDL.QueryCollection
import Hasura.RQL.DDL.QueryTemplate
import Hasura.RQL.DDL.Relationship
import Hasura.RQL.DDL.Relationship.Rename
import Hasura.RQL.DDL.RemoteSchema
@ -22,7 +21,6 @@ import Hasura.RQL.DDL.Schema.Table
import Hasura.RQL.DML.Count
import Hasura.RQL.DML.Delete
import Hasura.RQL.DML.Insert
import Hasura.RQL.DML.QueryTemplate
import Hasura.RQL.DML.Select
import Hasura.RQL.DML.Update
import Hasura.RQL.Types
@ -76,11 +74,6 @@ data RQLQuery
| RQRedeliverEvent !RedeliverEventQuery
| RQInvokeEventTrigger !InvokeEventTriggerQuery
| RQCreateQueryTemplate !CreateQueryTemplate
| RQDropQueryTemplate !DropQueryTemplate
| RQExecuteQueryTemplate !ExecQueryTemplate
| RQSetQueryTemplateComment !SetQueryTemplateComment
-- query collections, allow list related
| RQCreateQueryCollection !CreateCollection
| RQDropQueryCollection !DropCollection
@ -222,11 +215,6 @@ queryNeedsReload qi = case qi of
RQRedeliverEvent _ -> False
RQInvokeEventTrigger _ -> False
RQCreateQueryTemplate _ -> True
RQDropQueryTemplate _ -> True
RQExecuteQueryTemplate _ -> False
RQSetQueryTemplateComment _ -> False
RQCreateQueryCollection _ -> True
RQDropQueryCollection _ -> True
RQAddQueryToCollection _ -> True
@ -299,11 +287,6 @@ runQueryM rq =
RQRedeliverEvent q -> runRedeliverEvent q
RQInvokeEventTrigger q -> runInvokeEventTrigger q
RQCreateQueryTemplate q -> runCreateQueryTemplate q
RQDropQueryTemplate q -> runDropQueryTemplate q
RQExecuteQueryTemplate q -> runExecQueryTemplate q
RQSetQueryTemplateComment q -> runSetQueryTemplateComment q
RQCreateQueryCollection q -> runCreateCollection q
RQDropQueryCollection q -> runDropCollection q
RQAddQueryToCollection q -> runAddQueryToCollection q

View File

@ -3,7 +3,6 @@ select
'tables', tables.items,
'relations', relations.items,
'permissions', permissions.items,
'query_templates', query_templates.items,
'event_triggers', event_triggers.items,
'remote_schemas', remote_schemas.items,
'functions', functions.items,
@ -90,20 +89,6 @@ from
from
hdb_catalog.hdb_permission
) as permissions,
(
select
coalesce(
json_agg(
json_build_object(
'name', template_name,
'def', template_defn :: json
)
),
'[]'
) as items
from
hdb_catalog.hdb_query_template
) as query_templates,
(
select
coalesce(

View File

@ -175,11 +175,6 @@ args:
table_schema : table_schema
table_name : table_name
- type: add_existing_table_or_view
args:
schema: hdb_catalog
name: hdb_query_template
- type: add_existing_table_or_view
args:
schema: hdb_catalog

View File

@ -73,14 +73,6 @@ FROM
GROUP BY
table_schema, table_name, role_name;
CREATE TABLE hdb_catalog.hdb_query_template
(
template_name TEXT PRIMARY KEY,
template_defn JSONB NOT NULL,
comment TEXT NULL,
is_system_defined boolean default false
);
CREATE VIEW hdb_catalog.hdb_foreign_key_constraint AS
SELECT
q.table_schema :: text,

View File

@ -14,7 +14,6 @@
allowlist: []
functions: []
query_collections: []
query_templates: []
tables: []
remote_schemas: []
query:

View File

@ -30,7 +30,6 @@ response:
update_permissions: []
delete_permissions: []
event_triggers: []
query_templates: []
query_collections: []
allowlist: []
functions:

View File

@ -6,7 +6,6 @@ response:
query:
type: replace_metadata
args:
query_templates: []
remote_schemas:
- name: test
comment: testing replace metadata with remote schemas

View File

@ -6,7 +6,6 @@ response:
query:
type: replace_metadata
args:
query_templates: []
functions:
- schema: public
name: search_articles