Skip to content

Commit

Permalink
Added example of multiprovider
Browse files Browse the repository at this point in the history
Added and example that make use of Multiple providers.
  • Loading branch information
gdey committed Jun 9, 2022
1 parent 5f1f89b commit e4fcd5b
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 0 deletions.
14 changes: 14 additions & 0 deletions examples/multi-migrations/belle/00001_create_users_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- +goose Up
CREATE TABLE users (
id int NOT NULL PRIMARY KEY,
username text,
name text,
surname text
);

INSERT INTO users VALUES
(0, 'root', '', ''),
(1, 'vojtechvitek', 'Vojtech', 'Vitek');

-- +goose Down
DROP TABLE users;
21 changes: 21 additions & 0 deletions examples/multi-migrations/belle/00002_feature_1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package belle

import (
"database/sql"

)

func init() {
Provider.AddMigration(upFeature1, downFeature1)

}

func upFeature1(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return nil
}

func downFeature1(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}
17 changes: 17 additions & 0 deletions examples/multi-migrations/belle/belle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package belle

import (
"embed"
"github.com/pressly/goose/v3"
)

//go:embed [0-9]*_*.*
var migrationsFS embed.FS

var Provider = goose.NewProvider(
goose.ProviderPackage("belle", "Provider"),
goose.Filesystem(migrationsFS),
goose.Tablename("belle_db_version"),
goose.Dialect(goose.DialectSQLite3),
goose.BaseDir(""), // use the directory this package is in
)
156 changes: 156 additions & 0 deletions examples/multi-migrations/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package main

import (
"database/sql"
"flag"
"github.com/pressly/goose/v3"
"log"
"os"
"path/filepath"
"runtime"

_ "modernc.org/sqlite"

"github.com/pressly/goose/v3/examples/multi-migrations/belle"
"github.com/pressly/goose/v3/examples/multi-migrations/pardi"
)

var (
dir = flag.String("dir", dirPath(), "directory which hold the migration directories for pardi, belle and tests")
dbConnection = flag.String("connection", "database.db", "database connection string")
test = flag.String("test", "", "create test migrations for given test dir in testdata/migrations/")
forPardi = flag.Bool("pardi", false, "to create files for pardi set this flag to true, does not effect fix")
)

// dirPath finds the path where our migrations live, we assume it's the directories above
// where we are
func dirPath() string {
_, filename, _, _ := runtime.Caller(1)
return filepath.Dir(filename)
}

func testProvider(testDir string) (*goose.Provider, string) {
testPath := filepath.Join(*dir, "testdata", "migrations", testDir)
// insure test dir exits
_ = os.MkdirAll(testPath, os.ModePerm)
// Only supports sql files
p := goose.NewProvider(
goose.Tablename("test_"+testDir+"_db_version"),
goose.Dialect(goose.DialectSQLite3),
)
return p, testPath
}
func getAllTests() []string {
testPath := filepath.Join(*dir, "testdata", "migrations")
entries, err := os.ReadDir(testPath)
if err != nil {
log.Fatalf("Failed to read test dir: %v :%v", testPath, err)
}
testDirs := make([]string, 0, len(entries))
for _, entry := range entries {
if !entry.IsDir() {
continue
}
testDirs = append(testDirs, entry.Name())
}
return testDirs
}

func main() {
flag.Parse()
args := flag.Args()
command := "status"

if len(args) >= 1 {
command = args[0]
args = args[1:]
}
db, err := sql.Open("sqlite", *dbConnection)
if err != nil {
log.Fatalf("%v: failed to open db: %v ", os.Args[0], err)
}
p := belle.Provider
who := "belle"
if *forPardi {
p = pardi.Provider
who = "pardi"
}

switch command {
case "up":
err := p.Up(db, ".")
if err != nil {
log.Fatalf("%s error: %v", who, err)
}
if *test != "" {
p, path := testProvider(*test)
err = p.Up(db, path)
if err != nil {
log.Fatalf("test %s error: %v", *test, err)
}
}
case "fix":
// first fix pardi then belle, then all the test dirs
log.Printf("fixing pardi migration files:\n")
err := pardi.Provider.Fix(".")
if err != nil {
log.Fatalf("pardi error: %v", err)
}
log.Printf("fixing belle migration files:\n")
err = belle.Provider.Fix(".")
if err != nil {
log.Fatalf("belle error: %v", err)
}
for _, dir := range getAllTests() {
log.Printf("fixing test %v migration files:\n", dir)
p, path := testProvider(dir)
err = p.Fix(path)
if err != nil {
log.Fatalf("test %v error: %v", dir, err)
}
}

case "status":
log.Printf("For %s migration:\n", who)
err = p.Status(db, ".")
if err != nil {
log.Printf("Failed to get status for %s: %s", who, err)
}
if *test != "" {
// output the status of the test dir
// assume test dir always exists to keep example simple
log.Printf("For test migration: %v\n", *test)
p, path := testProvider(*test)
err = p.Status(db, path)
if err != nil {
log.Printf("Failed to get status for test %s: %s", *test, err)
}
}
case "create":
tplType := "sql"
if len(args) == 0 {
log.Fatalf("Create requires at lease the name")
}
if len(args) == 2 {
tplType = args[1]
}
if *test != "" {
if tplType == "go" {
log.Fatalf("test migrations files can only be sql")
}
p, path := testProvider(*test)
err = p.Create(db, path, args[0], "sql")
if err != nil {
log.Fatalf("test %s create error: %v", *test, err)
}
// if test only create test files
return
}

err = p.Create(db, ".", args[0], tplType)
if err != nil {
log.Fatalf("%s create error: %v", who, err)
}

}
}
14 changes: 14 additions & 0 deletions examples/multi-migrations/pardi/00001_create_users_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- +goose Up
CREATE TABLE party_users (
id int NOT NULL PRIMARY KEY,
username text,
name text,
surname text
);

INSERT INTO party_users VALUES
(0, 'root', '', ''),
(1, 'vojtechvitek', 'Vojtech', 'Vitek');

-- +goose Down
DROP TABLE party_users;
17 changes: 17 additions & 0 deletions examples/multi-migrations/pardi/pardi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package pardi

import (
"embed"
"github.com/pressly/goose/v3"
)

//go:embed [0-9]*_*.*
var migrationsFS embed.FS

var Provider = goose.NewProvider(
goose.ProviderPackage("pardi", "Provider"),
goose.Filesystem(migrationsFS),
goose.Tablename("pardi_db_version"),
goose.Dialect(goose.DialectSQLite3),
goose.BaseDir(""), // use the directory this package is in
)

0 comments on commit e4fcd5b

Please sign in to comment.