Skip to content

Commit

Permalink
Point out that embed is the way to go now
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenv committed Dec 19, 2023
1 parent 791a117 commit f4a7ae3
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 95 deletions.
54 changes: 12 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ migrations := &migrate.FileMigrationSource{
}

// OR: Use migrations from a packr box
// Note: Packr is no longer supported, your best option these days is [embed](https://pkg.go.dev/embed)
migrations := &migrate.PackrMigrationSource{
Box: packr.New("migrations", "./migrations"),
}
Expand Down Expand Up @@ -316,62 +317,31 @@ CREATE UNIQUE INDEX CONCURRENTLY people_unique_id_idx ON people (id);
DROP INDEX people_unique_id_idx;
```

## Embedding migrations with [packr](https://github.com/gobuffalo/packr)
## Embedding migrations with [embed](https://pkg.go.dev/embed)

If you like your Go applications self-contained (that is: a single binary): use [packr](https://github.com/gobuffalo/packr) to embed the migration files.
If you like your Go applications self-contained (that is: a single binary): use [embed](https://pkg.go.dev/embed) to embed the migration files.

Just write your migration files as usual, as a set of SQL files in a folder.

Import the packr package into your application:
Import the embed package into your application and point it to your migrations:

```go
import "github.com/gobuffalo/packr/v2"
```

Use the `PackrMigrationSource` in your application to find the migrations:
import "embed"

```go
migrations := &migrate.PackrMigrationSource{
Box: packr.New("migrations", "./migrations"),
}
//go:embed migrations/*
var dbMigrations embed.FS
```

If you already have a box and would like to use a subdirectory:
Use the `EmbedFileSystemMigrationSource` in your application to find the migrations:

```go
migrations := &migrate.PackrMigrationSource{
Box: myBox,
Dir: "./migrations",
migrations := migrate.EmbedFileSystemMigrationSource{
FileSystem: dbMigrations,
Root: "migrations",
}
```

## Embedding migrations with [bindata](https://github.com/shuLhan/go-bindata)

As an alternative, but slightly less maintained, you can use [bindata](https://github.com/shuLhan/go-bindata) to embed the migration files.

Just write your migration files as usual, as a set of SQL files in a folder.

Then use bindata to generate a `.go` file with the migrations embedded:

```bash
go-bindata -pkg myapp -o bindata.go db/migrations/
```

The resulting `bindata.go` file will contain your migrations. Remember to regenerate your `bindata.go` file whenever you add/modify a migration (`go generate` will help here, once it arrives).

Use the `AssetMigrationSource` in your application to find the migrations:

```go
migrations := &migrate.AssetMigrationSource{
Asset: Asset,
AssetDir: AssetDir,
Dir: "db/migrations",
}
```

Both `Asset` and `AssetDir` are functions provided by bindata.

Then proceed as usual.
Other options such as [packr](https://github.com/gobuffalo/packr) or [go-bindata](https://github.com/shuLhan/go-bindata) are no longer recommended.

## Embedding migrations with libraries that implement `http.FileSystem`

Expand Down
14 changes: 14 additions & 0 deletions migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"database/sql"
"embed"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -343,6 +344,19 @@ func (a AssetMigrationSource) FindMigrations() ([]*Migration, error) {
return migrations, nil
}

// A set of migrations loaded from an go1.16 embed.FS
type EmbedFileSystemMigrationSource struct {
FileSystem embed.FS

Root string
}

var _ MigrationSource = (*EmbedFileSystemMigrationSource)(nil)

func (f EmbedFileSystemMigrationSource) FindMigrations() ([]*Migration, error) {
return findMigrations(http.FS(f.FileSystem), f.Root)
}

// Avoids pulling in the packr library for everyone, mimicks the bits of
// packr.Box that we need.
type PackrBox interface {
Expand Down
23 changes: 0 additions & 23 deletions migrate_go116.go

This file was deleted.

30 changes: 0 additions & 30 deletions migrate_go116_test.go

This file was deleted.

21 changes: 21 additions & 0 deletions migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package migrate
import (
"context"
"database/sql"
"embed"
"net/http"
"time"

Expand Down Expand Up @@ -809,3 +810,23 @@ func (s *SqliteMigrateSuite) TestContextTimeout(c *C) {
c.Assert(err, Not(IsNil))
c.Assert(n, Equals, 2)
}

//go:embed test-migrations/*
var testEmbedFS embed.FS

func (s *SqliteMigrateSuite) TestEmbedSource(c *C) {
migrations := EmbedFileSystemMigrationSource{
FileSystem: testEmbedFS,
Root: "test-migrations",
}

// Executes two migrations
n, err := Exec(s.Db, "sqlite3", migrations, Up)
c.Assert(err, IsNil)
c.Assert(n, Equals, 2)

// Has data
id, err := s.DbMap.SelectInt("SELECT id FROM people")
c.Assert(err, IsNil)
c.Assert(id, Equals, int64(1))
}

0 comments on commit f4a7ae3

Please sign in to comment.