diff --git a/.circleci/test-console.sh b/.circleci/test-console.sh index 1b1f17eda8b..67fd0bd2754 100755 --- a/.circleci/test-console.sh +++ b/.circleci/test-console.sh @@ -20,7 +20,7 @@ cd "$CONSOLE_ROOT" mkdir -p /build/_console_output touch /build/_console_output/server.log -# touch /build/_console_output/cli.log +touch /build/_console_output/cli.log # start graphql-engine /build/_server_output/graphql-engine \ @@ -29,19 +29,19 @@ touch /build/_console_output/server.log wait_for_port 8080 # start cli -# /build/_cli_output/binaries/cli-hasura-linux-amd64 init --directory gql-test && cd gql-test -# /build/_cli_output/binaries/cli-hasura-linux-amd64 console --no-browser > /build/_console_output/cli.log 2>&1 & +/build/_cli_output/binaries/cli-hasura-linux-amd64 init --directory gql-test && cd gql-test +/build/_cli_output/binaries/cli-hasura-linux-amd64 console --no-browser > /build/_console_output/cli.log 2>&1 & -# cd .. +cd .. -# wait_for_port 9693 +wait_for_port 9693 export PORT=3000 export NODE_ENV=development export DATA_API_URL=http://localhost:8080 -# export API_HOST=http://localhost -# export API_PORT=9693 -export CONSOLE_MODE=server +export API_HOST=http://localhost +export API_PORT=9693 +export CONSOLE_MODE=cli export DEV_DATA_API_URL=http://localhost:8080 export URL_PREFIX=/ export SERVER_VERSION=$(cat /build/_server_output/version.txt) diff --git a/cli/internal/client/client.go b/cli/internal/client/client.go index 2f3d640c7c8..dcdd4fbfb0a 100644 --- a/cli/internal/client/client.go +++ b/cli/internal/client/client.go @@ -35,7 +35,7 @@ const ( ) var ( - queryTypes = []string{"select", "insert", "select", "update", "delete", "count", "run_sql", "bulk"} + queryTypes = []string{"select", "insert", "select", "update", "delete", "count", "run_sql"} queryTypesMap = func() map[string]bool { var m = map[string]bool{} for _, v := range queryTypes { @@ -670,3 +670,6 @@ func (c *HasuraRestAPIClient) HasMultipleDatasources() (bool, error) { return true, nil } + +type ErrMetadataRequestsFailed error +type ErrQueryRequestsFailed error diff --git a/cli/migrate/database/hasuradb/hasuradb.go b/cli/migrate/database/hasuradb/hasuradb.go index 0f86ad6f503..e65264fea58 100644 --- a/cli/migrate/database/hasuradb/hasuradb.go +++ b/cli/migrate/database/hasuradb/hasuradb.go @@ -123,7 +123,7 @@ func WithInstance(config *Config, logger *log.Logger, hasuraOpts *database.Hasur default: if hasuraOpts.HasMetadataV3 { hx.migrationStateStore = NewMigrationStateStoreWithSQL(hx, hasuraOpts.MigrationExectionStrategy) - }else { + } else { hx.migrationStateStore = NewMigrationStateStoreWithSQL(hx, hasuraOpts.MigrationExectionStrategy) } hx.settingsStateStore = NewSettingsStateStoreWithSQL(hx) @@ -259,7 +259,7 @@ func (h *HasuraDB) RunSeq(migration io.Reader, fileType, fileName string) error break } sqlInput := RunSQLInput{ - SQL: string(body), + SQL: string(body), Source: h.hasuraOpts.Datasource, } if h.config.enableCheckMetadataConsistency { @@ -288,26 +288,82 @@ func (h *HasuraDB) RunSeq(migration io.Reader, fileType, fileName string) error return nil } -func sendMetadataMigrations(hasuradb *HasuraDB, metadataRequests []interface{}) error { - for _, v := range metadataRequests { +func sendMetadataMigrations(hasuradb *HasuraDB, requests []interface{}) error { + var metadataRequests []interface{} + var queryRequests []interface{} + isQueryRequest := func(req interface{}) bool { + var isIt = false + type request struct { + Type string `mapstructure:"type"` + Args []interface{} `mapstructure:"args"` + } + var r = new(request) + if err := mapstructure.Decode(req, r); err != nil { + if _, ok := queryTypesMap[r.Type]; ok { + isIt = true + } else { + return isIt + } + } + return isIt + } + for _, v := range requests { type bulkQuery struct { Type string `mapstructure:"type"` Args []interface{} `mapstructure:"args"` } var bulk = new(bulkQuery) if _ = mapstructure.Decode(v, bulk); bulk.Type == "bulk" { - if err := sendMetadataMigrations(hasuradb, bulk.Args); err != nil { - return err + queryBulk := HasuraInterfaceBulk{ + Type: "bulk", + Args: []interface{}{}, } - // was a bulk query and was already handled above so skip this iteration - continue + metadataBulk := HasuraInterfaceBulk{ + Type: "bulk", + Args: []interface{}{}, + } + for _, bulkRequest := range bulk.Args { + if ok := isQueryRequest(v); ok { + queryBulk.Args = append(queryBulk.Args, bulkRequest) + } else { + metadataBulk.Args = append(metadataBulk.Args, bulkRequest) + } + } + metadataRequests = append(metadataRequests, metadataBulk) + queryRequests = append(queryRequests, queryBulk) } - resp, body, err := hasuradb.SendMetadataOrQueryRequest(v, nil) + if ok := isQueryRequest(v); ok { + queryRequests = append(queryRequests, v) + } else { + metadataRequests = append(metadataRequests, v) + } + + } + if len(queryRequests) > 0 { + queryBulk := HasuraInterfaceBulk{ + Type: "bulk", + Args: queryRequests, + } + resp, body, err := hasuradb.SendMetadataOrQueryRequest(queryBulk, &client.MetadataOrQueryClientFuncOpts{QueryRequestOpts: &client.QueryRequestOpts{}}) if err != nil { - return err + return client.ErrQueryRequestsFailed(err) } if resp.StatusCode != http.StatusOK { - return errors.New(string(body)) + return client.ErrQueryRequestsFailed(errors.New(string(body))) + } + + } + if len(metadataRequests) > 0 { + metadataBulk := HasuraInterfaceBulk{ + Type: "bulk", + Args: metadataRequests, + } + resp, body, err := hasuradb.SendMetadataOrQueryRequest(metadataBulk, &client.MetadataOrQueryClientFuncOpts{MetadataRequestOpts: &client.MetadataRequestOpts{}}) + if err != nil { + return client.ErrMetadataRequestsFailed(err) + } + if resp.StatusCode != http.StatusOK { + return client.ErrMetadataRequestsFailed(errors.New(string(body))) } } return nil diff --git a/cli/migrate/database/hasuradb/settings.go b/cli/migrate/database/hasuradb/settings.go index ae0d50c2b57..74633fdf795 100644 --- a/cli/migrate/database/hasuradb/settings.go +++ b/cli/migrate/database/hasuradb/settings.go @@ -257,7 +257,9 @@ func (s SettingsStateStoreWithCatalogStateAPI) setDefaults() error { cliState.Settings = make(map[string]string) } for _, setting := range s.hasuraDB.settings { - cliState.Settings[setting.GetName()] = setting.GetDefaultValue() + if v, ok := cliState.Settings[setting.GetName()]; !ok || len(v) == 0 { + cliState.Settings[setting.GetName()] = setting.GetDefaultValue() + } } return catalogStateAPI.SetCLICatalogState(s.hasuraDB, *cliState) } diff --git a/cli/pkg/console/apiserver.go b/cli/pkg/console/apiserver.go index 60d6f4850b4..42e19d885cb 100644 --- a/cli/pkg/console/apiserver.go +++ b/cli/pkg/console/apiserver.go @@ -137,6 +137,7 @@ func allowCors() gin.HandlerFunc { config.AddAllowHeaders("X-Hasura-Allowed-Roles") config.AddAllowHeaders("Hasura-Internal-Request-Source") config.AddAllowMethods("DELETE") + config.AddAllowHeaders("Hasura-Internal-Request-Source") config.AllowAllOrigins = true config.AllowCredentials = false return cors.New(config) diff --git a/console/cypress/integration/data/raw-sql/spec.ts b/console/cypress/integration/data/raw-sql/spec.ts index 92a6e335e99..0a540d6a15b 100644 --- a/console/cypress/integration/data/raw-sql/spec.ts +++ b/console/cypress/integration/data/raw-sql/spec.ts @@ -66,10 +66,10 @@ export const delTestTables = () => { prevStr = 'DROP TABLE Apic_test_table_rsql CASCADE;'; cy.get('textarea').type(prevStr, { force: true }); cy.wait(1000); - // cy.get(getElementFromAlias('raw-sql-migration-check')).uncheck(); + cy.get(getElementFromAlias('raw-sql-migration-check')).uncheck(); cy.get(getElementFromAlias('run-sql')).click(); // NOTE: This is only visible, when the console is in CLI mode - // cy.get(getElementFromAlias('not-migration-confirm')).click(); + cy.get(getElementFromAlias('not-migration-confirm')).click(); cy.get(getElementFromAlias('raw-sql-statement-timeout')).type('20', { force: true, }); diff --git a/console/src/components/Services/Data/RawSQL/Actions.js b/console/src/components/Services/Data/RawSQL/Actions.js index 395efddb93f..2ebeb653af5 100644 --- a/console/src/components/Services/Data/RawSQL/Actions.js +++ b/console/src/components/Services/Data/RawSQL/Actions.js @@ -141,6 +141,7 @@ const executeSQL = (isMigration, migrationName, statementTimeout) => ( name: migrationName, up: schemaChangesUp, down: schemaChangesDown, + datasource: source, }; } const options = { diff --git a/console/src/components/Services/RemoteSchema/Actions.js b/console/src/components/Services/RemoteSchema/Actions.js index 84689ba0ced..c9c5c1049fa 100644 --- a/console/src/components/Services/RemoteSchema/Actions.js +++ b/console/src/components/Services/RemoteSchema/Actions.js @@ -74,6 +74,7 @@ const makeRequest = ( name: migrationName, up: upQuery.args, down: downQuery.args, + datasource: source, }; const currMigrationMode = getState().main.migrationMode;