Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: PostgreSQL service example
on: push

jobs:
container-job:
runs-on: ubuntu-latest
strategy:
fail-fast: true
services:
postgres:
image: postgres:14.4
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- name: Checkout code
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # latest

- name: Install Go
uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923 # latest
with:
go-version: 1.17

- name: Test Postgres pgx
run: cd dbump_pgx && go test -v -race -shuffle=on -coverprofile=coverage.txt ./...
2 changes: 1 addition & 1 deletion dbump.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type Config struct {
Mode MigratorMode

// UseForce to get a lock on a database. MUST be used with the caution.
// Should be used when previos migration run didn't unlock the database,
// Should be used when previous migration run didn't unlock the database,
// and this blocks subsequent runs.
UseForce bool

Expand Down
16 changes: 15 additions & 1 deletion dbump_pgx/go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
module github.com/cristalhq/dbump/dbump_pgx

go 1.16
go 1.17

require (
github.com/cristalhq/dbump v0.2.0
github.com/jackc/pgx/v4 v4.16.1
)

replace github.com/cristalhq/dbump => ../

require (
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.12.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.11.0 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/text v0.3.7 // indirect
)
2 changes: 0 additions & 2 deletions dbump_pgx/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMe
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/cristalhq/dbump v0.2.0 h1:zwk0d4UFBGtXswYh6lAZ5KDCEgnn9px9HMzLCUQSDso=
github.com/cristalhq/dbump v0.2.0/go.mod h1:rAjULuStbuNPCLrJT62Eu7Sp/2gVt/4URUvsnPK1yFA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
13 changes: 6 additions & 7 deletions dbump_pgx/pgx.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func NewMigrator(conn *pgx.Conn) *Migrator {

// Init migrator.
func (pg *Migrator) Init(ctx context.Context) error {
query := `CREATE TABLE IF NOT EXISTS _dbump_schema_version (
version BIGINT NOT NULL PRIMARY KEY,
query := `CREATE TABLE IF NOT EXISTS _dbump_log (
version BIGINT NOT NULL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE NOT NULL
);`
_, err := pg.conn.Exec(ctx, query)
Expand All @@ -48,18 +48,17 @@ func (pg *Migrator) UnlockDB(ctx context.Context) error {

// Version is a method for Migrator interface.
func (pg *Migrator) Version(ctx context.Context) (version int, err error) {
query := "SELECT COUNT(*) FROM _dbump_schema_version;"
query := "SELECT COUNT(*) FROM _dbump_log;"
row := pg.conn.QueryRow(ctx, query)
err = row.Scan(&version)
return version, err
}

// SetVersion is a method for Migrator interface.
func (pg *Migrator) SetVersion(ctx context.Context, version int) error {
query := `INSERT INTO _dbump_schema_version (version, created_at)
VALUES ($1, NOW())
ON CONFLICT (version) DO UPDATE
SET created_at = NOW();`
query := `DELETE FROM _dbump_log WHERE version >= $1;
INSERT INTO _dbump_log (version, created_at) VALUES ($1, NOW())
ON CONFLICT (version) DO UPDATE SET created_at = NOW();`
_, err := pg.conn.Exec(ctx, query, version)
return err
}
Expand Down
73 changes: 73 additions & 0 deletions dbump_pgx/pgx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package dbump_pgx

import (
"context"
"fmt"
"os"
"testing"

"github.com/cristalhq/dbump"
"github.com/jackc/pgx/v4"
)

var conn *pgx.Conn

func init() {
host := envOrDef("DBUMP_PG_HOST", "127.0.0.1")
port := envOrDef("DBUMP_PG_PORT", "5432")
username := envOrDef("DBUMP_PG_USER", "postgres")
password := envOrDef("DBUMP_PG_PASS", "postgres")
db := envOrDef("DBUMP_PG_DB", "postgres")
sslmode := envOrDef("DBUMP_PG_SSL", "disable")

dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host, port, username, password, db, sslmode)

var err error
conn, err = pgx.Connect(context.Background(), dsn)
if err != nil {
panic(err)
}
}

func TestPGX_Simple(t *testing.T) {
m := NewMigrator(conn)
l := dbump.NewSliceLoader([]*dbump.Migration{
{
ID: 1,
Apply: "SELECT 1;",
Revert: "SELECT 1;",
},
{
ID: 2,
Apply: "SELECT 1;",
Revert: "SELECT 1;",
},
{
ID: 3,
Apply: "SELECT 1;",
Revert: "SELECT 1;",
},
})

errRun := dbump.Run(context.Background(), dbump.Config{
Migrator: m,
Loader: l,
Mode: dbump.ModeUp,
})
failIfErr(t, errRun)
}

func envOrDef(env, def string) string {
if val := os.Getenv(env); val != "" {
return val
}
return def
}

func failIfErr(tb testing.TB, err error) {
tb.Helper()
if err != nil {
tb.Fatal(err)
}
}
3 changes: 0 additions & 3 deletions dbump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ func TestRunCheck(t *testing.T) {
}
}

func TestLoaderError(t *testing.T) {
}

func TestMigrateUp(t *testing.T) {
wantLog := []string{
"init", "lockdb", "getversion",
Expand Down
18 changes: 9 additions & 9 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,21 @@ func (dl *DiskLoader) Load() ([]*Migration, error) {

// FileSysLoader can load migrations from fs.FS.
type FileSysLoader struct {
fs FS
fsys FS
path string
}

// NewFileSysLoader instantiates a new FileSysLoader.
func NewFileSysLoader(fs FS, path string) *FileSysLoader {
func NewFileSysLoader(fsys FS, path string) *FileSysLoader {
return &FileSysLoader{
fs: fs,
fsys: fsys,
path: strings.TrimRight(path, string(os.PathSeparator)),
}
}

// Load is a method for Loader interface.
func (el *FileSysLoader) Load() ([]*Migration, error) {
return loadMigrationsFromFS(el.fs, el.path)
return loadMigrationsFromFS(el.fsys, el.path)
}

// SliceLoader loads given migrations.
Expand Down Expand Up @@ -78,8 +78,8 @@ func (sl *SliceLoader) AddMigration(m *Migration) {

var migrationRE = regexp.MustCompile(`^(\d+)_.+\.sql$`)

func loadMigrationsFromFS(fs FS, path string) ([]*Migration, error) {
files, err := fs.ReadDir(path)
func loadMigrationsFromFS(fsys FS, path string) ([]*Migration, error) {
files, err := fsys.ReadDir(path)
if err != nil {
return nil, err
}
Expand All @@ -95,7 +95,7 @@ func loadMigrationsFromFS(fs FS, path string) ([]*Migration, error) {
continue
}

m, err := loadMigrationFromFS(fs, path, matches[1], fi.Name())
m, err := loadMigrationFromFS(fsys, path, matches[1], fi.Name())
if err != nil {
return nil, err
}
Expand All @@ -105,13 +105,13 @@ func loadMigrationsFromFS(fs FS, path string) ([]*Migration, error) {
return migs, nil
}

func loadMigrationFromFS(fs FS, path, id, name string) (*Migration, error) {
func loadMigrationFromFS(fsys FS, path, id, name string) (*Migration, error) {
n, err := strconv.ParseInt(id, 10, 32)
if err != nil {
return nil, err
}

body, err := fs.ReadFile(filepath.Join(path, name))
body, err := fsys.ReadFile(filepath.Join(path, name))
if err != nil {
return nil, err
}
Expand Down