mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-18 13:02:11 +03:00
71af68e9e5
The only real use was for the dubious multitenant option --consoleAssetsVersion, which actually overrode not just the assets version. I.e., as far as I can tell, if you pass --consoleAssetsVersion to multitenant, that version will also make it into e.g. HTTP client user agent headers as the proper graphql-engine version. I'm dropping that option, since it seems unused in production and I don't want to go to the effort of fixing it, but am happy to look into that if folks feels strongly that it should be kept. (Reason for attacking this is that I was looking into http client things around blacklisting, and the versioning thing is a bit painful around http client headers.) PR-URL: https://github.com/hasura/graphql-engine-mono/pull/2458 GitOrigin-RevId: a02b05557124bdba9f65e96b3aa2746aeee03f4a
139 lines
4.2 KiB
Haskell
139 lines
4.2 KiB
Haskell
-- | The RQL query ('/v2/query')
|
|
module Hasura.Server.API.V2Query where
|
|
|
|
import Control.Monad.Trans.Control (MonadBaseControl)
|
|
import Data.Aeson
|
|
import Data.Aeson.Casing
|
|
import Data.Aeson.TH
|
|
import Data.Environment qualified as Env
|
|
import Hasura.Backends.BigQuery.DDL.RunSQL qualified as BigQuery
|
|
import Hasura.Backends.MSSQL.DDL.RunSQL qualified as MSSQL
|
|
import Hasura.Backends.MySQL.SQL qualified as MySQL
|
|
import Hasura.Backends.Postgres.DDL.RunSQL qualified as Postgres
|
|
import Hasura.Base.Error
|
|
import Hasura.EncJSON
|
|
import Hasura.GraphQL.Execute.Backend
|
|
import Hasura.Metadata.Class
|
|
import Hasura.Prelude
|
|
import Hasura.RQL.DDL.Schema
|
|
import Hasura.RQL.DML.Count
|
|
import Hasura.RQL.DML.Delete
|
|
import Hasura.RQL.DML.Insert
|
|
import Hasura.RQL.DML.Select
|
|
import Hasura.RQL.DML.Types
|
|
import Hasura.RQL.DML.Update
|
|
import Hasura.RQL.Types
|
|
import Hasura.RQL.Types.Run
|
|
import Hasura.Server.Types
|
|
import Hasura.Session
|
|
import Hasura.Tracing qualified as Tracing
|
|
import Network.HTTP.Client qualified as HTTP
|
|
|
|
data RQLQuery
|
|
= RQInsert !InsertQuery
|
|
| RQSelect !SelectQuery
|
|
| RQUpdate !UpdateQuery
|
|
| RQDelete !DeleteQuery
|
|
| RQCount !CountQuery
|
|
| RQRunSql !Postgres.RunSQL
|
|
| RQMssqlRunSql !MSSQL.MSSQLRunSQL
|
|
| RQCitusRunSql !Postgres.RunSQL
|
|
| RQMysqlRunSql !MySQL.RunSQL
|
|
| RQBigqueryRunSql !BigQuery.BigQueryRunSQL
|
|
| RQBigqueryDatabaseInspection !BigQuery.BigQueryRunSQL
|
|
| RQBulk ![RQLQuery]
|
|
|
|
$( deriveFromJSON
|
|
defaultOptions
|
|
{ constructorTagModifier = snakeCase . drop 2,
|
|
sumEncoding = TaggedObject "type" "args"
|
|
}
|
|
''RQLQuery
|
|
)
|
|
|
|
runQuery ::
|
|
( MonadIO m,
|
|
MonadBaseControl IO m,
|
|
Tracing.MonadTrace m,
|
|
MonadMetadataStorage m,
|
|
MonadResolveSource m,
|
|
MonadQueryTags m
|
|
) =>
|
|
Env.Environment ->
|
|
InstanceId ->
|
|
UserInfo ->
|
|
RebuildableSchemaCache ->
|
|
HTTP.Manager ->
|
|
ServerConfigCtx ->
|
|
RQLQuery ->
|
|
m (EncJSON, RebuildableSchemaCache)
|
|
runQuery env instanceId userInfo schemaCache httpManager serverConfigCtx rqlQuery = do
|
|
(metadata, currentResourceVersion) <- fetchMetadata
|
|
result <-
|
|
runQueryM env rqlQuery & \x -> do
|
|
((js, meta), rsc, ci) <-
|
|
x & runMetadataT metadata
|
|
& runCacheRWT schemaCache
|
|
& peelRun runCtx
|
|
& runExceptT
|
|
& liftEitherM
|
|
pure (js, rsc, ci, meta)
|
|
withReload currentResourceVersion result
|
|
where
|
|
runCtx = RunCtx userInfo httpManager serverConfigCtx
|
|
|
|
withReload currentResourceVersion (result, updatedCache, invalidations, updatedMetadata) = do
|
|
when (queryModifiesSchema rqlQuery) $ do
|
|
case _sccMaintenanceMode serverConfigCtx of
|
|
MaintenanceModeDisabled -> do
|
|
-- set modified metadata in storage
|
|
newResourceVersion <- setMetadata currentResourceVersion updatedMetadata
|
|
-- notify schema cache sync
|
|
notifySchemaCacheSync newResourceVersion instanceId invalidations
|
|
MaintenanceModeEnabled ->
|
|
throw500 "metadata cannot be modified in maintenance mode"
|
|
pure (result, updatedCache)
|
|
|
|
queryModifiesSchema :: RQLQuery -> Bool
|
|
queryModifiesSchema = \case
|
|
RQInsert _ -> False
|
|
RQSelect _ -> False
|
|
RQUpdate _ -> False
|
|
RQDelete _ -> False
|
|
RQCount _ -> False
|
|
RQRunSql q -> Postgres.isSchemaCacheBuildRequiredRunSQL q
|
|
RQCitusRunSql q -> Postgres.isSchemaCacheBuildRequiredRunSQL q
|
|
RQMssqlRunSql q -> MSSQL.sqlContainsDDLKeyword $ MSSQL._mrsSql q
|
|
RQMysqlRunSql _ -> False
|
|
RQBigqueryRunSql _ -> False
|
|
RQBigqueryDatabaseInspection _ -> False
|
|
RQBulk l -> any queryModifiesSchema l
|
|
|
|
runQueryM ::
|
|
( MonadError QErr m,
|
|
MonadIO m,
|
|
MonadBaseControl IO m,
|
|
UserInfoM m,
|
|
CacheRWM m,
|
|
HasServerConfigCtx m,
|
|
Tracing.MonadTrace m,
|
|
MetadataM m,
|
|
MonadQueryTags m
|
|
) =>
|
|
Env.Environment ->
|
|
RQLQuery ->
|
|
m EncJSON
|
|
runQueryM env = \case
|
|
RQInsert q -> runInsert q
|
|
RQSelect q -> runSelect q
|
|
RQUpdate q -> runUpdate q
|
|
RQDelete q -> runDelete q
|
|
RQCount q -> runCount q
|
|
RQRunSql q -> Postgres.runRunSQL @'Vanilla q
|
|
RQMssqlRunSql q -> MSSQL.runSQL q
|
|
RQMysqlRunSql q -> MySQL.runSQL q
|
|
RQCitusRunSql q -> Postgres.runRunSQL @'Citus q
|
|
RQBigqueryRunSql q -> BigQuery.runSQL q
|
|
RQBigqueryDatabaseInspection q -> BigQuery.runDatabaseInspection q
|
|
RQBulk l -> encJFromList <$> indexedMapM (runQueryM env) l
|