mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-09-11 10:46:25 +03:00
cli: optimize state copy
https://github.com/hasura/graphql-engine-mono/pull/2176 GitOrigin-RevId: 71f72704c3097ee05f3adca954b4c283701cf5e9
This commit is contained in:
parent
88aa42a986
commit
39f5d04ba8
@ -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
|
||||
|
||||
|
@ -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{}
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
87
cli/internal/statestore/migrations/hdbtable_test.go
Normal file
87
cli/internal/statestore/migrations/hdbtable_test.go
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user