cli: optimize state copy

https://github.com/hasura/graphql-engine-mono/pull/2176

GitOrigin-RevId: 71f72704c3097ee05f3adca954b4c283701cf5e9
This commit is contained in:
Aravind K P 2021-08-26 11:39:06 +05:30 committed by hasura-bot
parent 88aa42a986
commit 39f5d04ba8
8 changed files with 145 additions and 9 deletions

View File

@ -10,6 +10,7 @@
- server: Adding support for TLS allowlist by domain and service id (port)
- server: add support for `graphql-ws` clients
- console: fix error due too rendering inconsistent object's message
- cli: fix delay starting console using `hasura console` (#7255)
## v2.0.7

View File

@ -1,9 +1,9 @@
package querytags
import (
"github.com/google/go-cmp/cmp"
"io/ioutil"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -114,7 +114,7 @@ per_source_configuration:
got, err := obj.Export(tt.args.metadata)
if tt.wantErr {
require.Error(t, err)
}else {
} else {
require.NoError(t, err)
var wantContent = map[string]string{}
var gotContent = map[string]string{}

View File

@ -10,8 +10,8 @@ import (
"github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/functions"
graphqlschemaintrospection "github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/graphql_schema_introspection"
inheritedroles "github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/inherited_roles"
"github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/querycollections"
querytags "github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/query_tags"
"github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/querycollections"
"github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/remoteschemas"
restendpoints "github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/rest_endpoints"
"github.com/hasura/graphql-engine/cli/v2/internal/metadataobject/sources"

View File

@ -87,3 +87,15 @@ func (m *CatalogStateStore) GetVersions(database string) (map[uint64]bool, error
}
return versions, nil
}
func (m *CatalogStateStore) SetVersions(database string, versions []statestore.Version) error {
state, err := m.getCLIState()
if err != nil {
return err
}
for _, v := range versions {
versionString := fmt.Sprintf("%d", v.Version)
state.SetMigration(database, versionString, v.Dirty)
}
return m.setCLIState(*state)
}

View File

@ -2,9 +2,10 @@ package migrations
import (
"fmt"
"strconv"
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
"github.com/hasura/graphql-engine/cli/v2/internal/statestore"
"strconv"
"strings"
"github.com/hasura/graphql-engine/cli/v2/migrate/database"
)
@ -134,3 +135,25 @@ func (m *MigrationStateStoreHdbTable) GetVersions(sourceName string) (map[uint64
}
return versions, nil
}
// SetVersions is similar to SetVersion defined above. with the only difference, this is adapted to accept multiple versions
func (m *MigrationStateStoreHdbTable) SetVersions(sourceName string, versions []statestore.Version) error {
var insertSql []string
for _, v := range versions {
if v.Version >= 0 || (v.Version == database.NilVersion && v.Dirty) {
insertSql = append(insertSql, `INSERT INTO `+fmt.Sprintf("%s.%s", m.schema, m.table)+` (version, dirty) VALUES (`+strconv.FormatInt(v.Version, 10)+`, `+fmt.Sprintf("'%t'", v.Dirty)+`)`+fmt.Sprintf(` ON CONFLICT(version) DO UPDATE SET dirty='%t'`, v.Dirty))
}
}
if len(insertSql) > 0 {
query := hasura.PGRunSQLInput{
Source: sourceName,
SQL: strings.Join(insertSql, ";"),
}
_, err := m.client.PGRunSQL(query)
if err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,87 @@
package migrations
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
"github.com/hasura/graphql-engine/cli/v2/internal/hasura/sourceops/postgres"
"github.com/hasura/graphql-engine/cli/v2/internal/statestore"
"github.com/hasura/graphql-engine/cli/v2/internal/testutil"
)
func TestMigrationStateStoreHdbTable_SetVersions(t *testing.T) {
port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage)
defer teardown()
createSchemaMigrations := bytes.NewReader([]byte(`
{
"type": "run_sql",
"args": {
"sql": "CREATE TABLE hdb_catalog.schema_migrations (version bigint not null primary key, dirty boolean not null)"
}
}
`))
var body interface{}
require.NoError(t, json.NewDecoder(createSchemaMigrations).Decode(&body))
req := testutil.NewRequest(t, http.MethodPost, fmt.Sprintf("%s:%s/%s", testutil.BaseURL, port, "v2/query"), body)
r, err := http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, r.StatusCode, http.StatusOK)
type fields struct {
client hasura.PGSourceOps
schema string
table string
}
type args struct {
sourceName string
versions []statestore.Version
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
"can set versions",
fields{
postgres.New(testutil.NewHttpcClient(t, port, nil), "v2/query"),
"hdb_catalog",
"schema_migrations",
},
args{
"default",
[]statestore.Version{{1, false}, {2, false}, {3, false}},
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
m := &MigrationStateStoreHdbTable{
client: tt.fields.client,
schema: tt.fields.schema,
table: tt.fields.table,
}
if err := m.SetVersions(tt.args.sourceName, tt.args.versions); (err != nil) != tt.wantErr {
t.Errorf("SetVersions() error = %v, wantErr %v", err, tt.wantErr)
}
versions, err := m.GetVersions(tt.args.sourceName)
assert.NoError(t, err)
var got []statestore.Version
for v, d := range versions {
got = append(got, statestore.Version{Version: int64(v), Dirty: d})
}
assert.ElementsMatch(t, tt.args.versions, got)
})
}
}

View File

@ -7,12 +7,18 @@ import (
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
)
type Version struct {
Version int64
Dirty bool
}
// Abstraction for the storage layer for migration state
type MigrationsStateStore interface {
InsertVersion(database string, version int64) error
RemoveVersion(database string, version int64) error
SetVersion(database string, version int64, dirty bool) error
GetVersions(database string) (map[uint64]bool, error)
SetVersions(database string, versions []Version) error
PrepareMigrationsStateStore(database string) error
}
@ -120,8 +126,12 @@ func CopyMigrationState(src, dest MigrationsStateStore, srcdatabase, destdatabas
if err != nil {
return err
}
for k, v := range versions {
dest.SetVersion(destdatabase, int64(k), v)
var vs []Version
for v, dirty := range versions {
vs = append(vs, Version{int64(v), dirty})
}
if err := dest.SetVersions(destdatabase, vs); err != nil {
return err
}
return nil
}

View File

@ -19,7 +19,7 @@ func SendHTTPRequestWithFileAsBody(t *testing.T, filepath, url string) *http.Res
err = json.Unmarshal(b, &body)
require.NoError(t, err)
req := newPOSTRequest(t, "POST", url, body)
req := NewRequest(t, "POST", url, body)
c := http.Client{}
resp, err := c.Do(req)
@ -28,7 +28,7 @@ func SendHTTPRequestWithFileAsBody(t *testing.T, filepath, url string) *http.Res
return resp
}
func newPOSTRequest(t *testing.T, method, urlStr string, body interface{}) *http.Request {
func NewRequest(t *testing.T, method, urlStr string, body interface{}) *http.Request {
u, err := url.ParseRequestURI(urlStr)
require.NoError(t, err)
var buf io.ReadWriter
@ -46,5 +46,8 @@ func newPOSTRequest(t *testing.T, method, urlStr string, body interface{}) *http
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
if len(TestAdminSecret) > 0 {
req.Header.Set("x-hasura-admin-secret", TestAdminSecret)
}
return req
}