Skip to content

Commit

Permalink
refactor for multiple go migrations and add test fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
krehermann committed Jun 26, 2024
1 parent 76fc0b8 commit 3d2f239
Show file tree
Hide file tree
Showing 16 changed files with 719 additions and 111 deletions.
103 changes: 56 additions & 47 deletions core/store/migrate/plugins/relayer/evm/0002_initial.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,77 +6,86 @@ import (
"database/sql"
_ "embed"
"fmt"
"io"

"github.com/pressly/goose/v3"
)

//go:embed initUp.tmpl.sql
var upTmpl string
//go:embed forwardersUp.tmpl.sql
var forwardersUpTmpl string

func resolveUp(out io.Writer, val Cfg) error {
if upTmpl == "" {
return fmt.Errorf("upTmpl is empty")
}
return resolve(out, upTmpl, val)
}
//go:embed forwardersDown.tmpl.sql
var forwardersDownTmpl string

//go:embed initDown.tmpl.sql
var downTmpl string
//go:embed headsUp.tmpl.sql
var headsUpTmpl string

func resolveDown(out io.Writer, val Cfg) error {
return resolve(out, downTmpl, val)
}
//go:embed headsDown.tmpl.sql
var headsDownTmpl string

// Register0002 registers the migration with goose
/*
func Register0002(val Cfg) error {
upSQL := &bytes.Buffer{}
err := resolveUp(upSQL, val)
if err != nil {
return fmt.Errorf("failed to resolve up sql: %w", err)
}
upFunc := func(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, upSQL.String())
return err
}
//go:embed key_statesUp.tmpl.sql
var keyStatesUpTmpl string

downSQL := &bytes.Buffer{}
err = resolveDown(downSQL, val)
if err != nil {
return fmt.Errorf("failed to resolve down sql: %w", err)
}
downFunc := func(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, downSQL.String())
return err
}
goose.AddMigrationContext(upFunc, downFunc)
return nil
//go:embed key_statesDown.tmpl.sql
var keyStatesDownTmpl string

type initialMigration struct {
upTmpl string
downTmpl string
version int64
}
*/

func generate0002(val Cfg) (up *goose.GoFunc, down *goose.GoFunc, err error) {
var (
forwarderMigration = initialMigration{
upTmpl: forwardersUpTmpl,
downTmpl: forwardersDownTmpl,
version: 2}

headsMigration = initialMigration{
upTmpl: headsUpTmpl,
downTmpl: headsDownTmpl,
version: 3}

keyStatesMigration = initialMigration{
upTmpl: keyStatesUpTmpl,
downTmpl: keyStatesDownTmpl,
version: 4}

initialMigrations = []initialMigration{forwarderMigration, headsMigration, keyStatesMigration}
)

func generateGoMigration(val Cfg, m initialMigration) (*goose.Migration, error) {
upSQL := &bytes.Buffer{}
err = resolveUp(upSQL, val)
err := resolve(upSQL, m.upTmpl, val)
if err != nil {
return nil, nil, fmt.Errorf("failed to resolve up sql: %w", err)
return nil, fmt.Errorf("failed to resolve up sql: %w", err)
}
upFunc := func(ctx context.Context, tx *sql.Tx) error {
_, terr := tx.ExecContext(ctx, upSQL.String())
return terr
}

downSQL := &bytes.Buffer{}
err = resolveDown(downSQL, val)
err = resolve(downSQL, m.downTmpl, val)
if err != nil {
return nil, nil, fmt.Errorf("failed to resolve down sql: %w", err)
return nil, fmt.Errorf("failed to resolve down sql: %w", err)
}
downFunc := func(ctx context.Context, tx *sql.Tx) error {
_, terr := tx.ExecContext(ctx, downSQL.String())
return terr
}
up = &goose.GoFunc{RunTx: upFunc}
down = &goose.GoFunc{RunTx: downFunc}
//P goose.AddMigrationContext(upFunc, downFunc)
return up, down, nil
up := &goose.GoFunc{RunTx: upFunc}
down := &goose.GoFunc{RunTx: downFunc}
return goose.NewGoMigration(m.version, up, down), nil
}

func generateInitialMigrations(val Cfg) ([]*goose.Migration, error) {
migrations := []*goose.Migration{}
for _, m := range initialMigrations {
mig, err := generateGoMigration(val, m)
if err != nil {
return nil, fmt.Errorf("failed to generate migration: %w", err)
}
migrations = append(migrations, mig)
}
return migrations, nil
}
68 changes: 43 additions & 25 deletions core/store/migrate/plugins/relayer/evm/0002_initial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evm
import (
"bytes"
_ "embed"
"strings"
"testing"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
Expand All @@ -12,30 +13,47 @@ import (
)

func Test_resolveup(t *testing.T) {
type args struct {
val Cfg
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "evm template",
args: args{
val: Cfg{
Schema: "evm",
ChainID: big.NewI(int64(3266)),
},
t.Run("resolve up migrations", func(t *testing.T) {
type test struct {
name string
upTmpl string
}
cases := []test{
{
name: "forwarders",
upTmpl: forwardersUpTmpl,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out := &bytes.Buffer{}
err := resolveUp(out, tt.args.val)
require.NoError(t, err)
assert.NotEmpty(t, out.String())
})
}
}
for _, tt := range cases {
t.Run("do nothing for evm schema", func(t *testing.T) {
out := &bytes.Buffer{}
err := resolve(out, tt.upTmpl, Cfg{Schema: "evm", ChainID: big.NewI(int64(3266))})
require.NoError(t, err)
assert.Equal(t, "-- Do nothing for `evm` schema for backward compatibility\n", out.String())
})

t.Run("err no chain id", func(t *testing.T) {
out := &bytes.Buffer{}
err := resolve(out, tt.upTmpl, Cfg{Schema: "evm_213"})
require.Error(t, err)
assert.Empty(t, out.String())
})

t.Run("err no schema", func(t *testing.T) {
out := &bytes.Buffer{}
err := resolve(out, tt.upTmpl, Cfg{ChainID: big.NewI(int64(3266))})
require.Error(t, err)
assert.Empty(t, out.String())
})

t.Run("ok", func(t *testing.T) {
out := &bytes.Buffer{}
err := resolve(out, tt.upTmpl, Cfg{Schema: "evm_3266", ChainID: big.NewI(int64(3266))})
require.NoError(t, err)
lines := strings.Split(out.String(), "\n")
assert.Greater(t, len(lines), 2)
assert.Contains(t, out.String(), "CREATE TABLE evm_3266")
})
}
})
}
21 changes: 21 additions & 0 deletions core/store/migrate/plugins/relayer/evm/forwardersDown.tmpl.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- Do nothing for `evm` schema for backward compatibility
{{ if ne .Schema "evm"}}
/*
DROP TABLE {{ .Schema }}.receipts
DROP TABLE {{ .Schema }}.tx_attempts
DROP TABLE {{ .Schema }}.upkeep_states
DROP TABLE {{ .Schema }}.txes
DROP TABLE {{ .Schema }}.logs
DROP TABLE {{ .Schema }}.log_poller_filters
DROP TABLE {{ .Schema }}.log_poller_blocks
DROP TABLE {{ .Schema }}.key_states;
DROP TABLE {{ .Schema }}.heads;
*/

-- Copy data from old table to new table
INSERT INTO evm.forwarders (address, created_at, updated_at, evm_chain_id)
SELECT address, created_at, updated_at, '{{ .ChainID }}'
FROM {{ .Schema }}.forwarders;

DROP TABLE {{ .Schema }}.forwarders;
{{ end}}
Loading

0 comments on commit 3d2f239

Please sign in to comment.