use embedded atlas migrations

This commit is contained in:
Hayden 2022-09-24 15:10:25 -08:00
parent 24084726fb
commit ddc32af1f2
4 changed files with 131 additions and 5 deletions

View file

@ -1,14 +1,16 @@
version: "3"
env:
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_fk=1
tasks:
generate:
desc: |
Generates collateral files from the backend project
including swagger docs and typescripts type for the frontend
deps:
- db:generate
cmds:
- |
cd backend && ent generate ./ent/schema \
--template=ent/schema/templates/has_id.tmpl
- cd backend/app/api/ && swag fmt
- cd backend/app/api/ && swag init --dir=./,../../internal,../../pkgs
- |
@ -72,3 +74,21 @@ tasks:
desc: Run frontend development server
cmds:
- cd frontend && pnpm dev
db:generate:
desc: Run Entgo.io Code Generation
cmds:
- |
cd backend && go generate ./... \
--template=ent/schema/templates/has_id.tmpl
sources:
- "./backend/ent/schema/**/*"
generates:
- "./backend/ent/"
db:migration:
desc: Runs the database diff engine to generate a SQL migration files
deps:
- db:generate
cmds:
- cd backend && go run app/migrations/main.go {{ .CLI_ARGS }}

View file

@ -3,12 +3,15 @@ package main
import (
"context"
"os"
"path/filepath"
"time"
atlas "ariga.io/atlas/sql/migrate"
"entgo.io/ent/dialect/sql/schema"
"github.com/hay-kot/homebox/backend/app/api/docs"
"github.com/hay-kot/homebox/backend/ent"
"github.com/hay-kot/homebox/backend/internal/config"
"github.com/hay-kot/homebox/backend/internal/migrations"
"github.com/hay-kot/homebox/backend/internal/repo"
"github.com/hay-kot/homebox/backend/internal/services"
"github.com/hay-kot/homebox/backend/pkgs/server"
@ -71,9 +74,63 @@ func run(cfg *config.Config) error {
Msg("failed opening connection to sqlite")
}
defer func(c *ent.Client) {
_ = c.Close()
err := c.Close()
if err != nil {
log.Fatal().Err(err).Msg("failed to close database connection")
}
}(c)
if err := c.Schema.Create(context.Background(), schema.WithAtlas(true)); err != nil {
err = func() error {
temp := filepath.Join(os.TempDir(), "migrations")
defer func() {
err := os.RemoveAll(temp)
if err != nil {
log.Err(err).Msg("failed to remove temp directory")
}
}()
err := os.MkdirAll(temp, 0755)
if err != nil {
return err
}
// Write the embed migrations to the temp directory.
fsDir, err := migrations.Files.ReadDir(".")
if err != nil {
}
for _, f := range fsDir {
if f.IsDir() {
continue
}
b, err := migrations.Files.ReadFile(filepath.Join("migrations", f.Name()))
if err != nil {
return err
}
err = os.WriteFile(filepath.Join(temp, f.Name()), b, 0644)
if err != nil {
return err
}
}
dir, err := atlas.NewLocalDir(temp)
if err != nil {
return err
}
options := []schema.MigrateOption{
schema.WithAtlas(true),
schema.WithDir(dir),
schema.WithDropColumn(true),
schema.WithDropIndex(true),
}
return c.Schema.Create(context.Background(), options...)
}()
if err != nil {
log.Fatal().
Err(err).
Str("driver", "sqlite").

View file

@ -0,0 +1,43 @@
package main
import (
"context"
"log"
"os"
"github.com/hay-kot/homebox/backend/ent/migrate"
atlas "ariga.io/atlas/sql/migrate"
_ "ariga.io/atlas/sql/sqlite"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql/schema"
_ "github.com/mattn/go-sqlite3"
)
func main() {
ctx := context.Background()
// Create a local migration directory able to understand Atlas migration file format for replay.
dir, err := atlas.NewLocalDir("internal/migrations/migrations")
if err != nil {
log.Fatalf("failed creating atlas migration directory: %v", err)
}
// Migrate diff options.
opts := []schema.MigrateOption{
schema.WithAtlas(true),
schema.WithDir(dir), // provide migration directory
schema.WithMigrationMode(schema.ModeReplay), // provide migration mode
schema.WithDialect(dialect.SQLite), // Ent dialect to use
schema.WithFormatter(atlas.DefaultFormatter),
schema.WithDropIndex(true),
schema.WithDropColumn(true),
}
if len(os.Args) != 2 {
log.Fatalln("migration name is required. Use: 'go run -mod=mod ent/migrate/main.go <name>'")
}
// Generate migrations using Atlas support for MySQL (note the Ent dialect option passed above).
err = migrate.NamedDiff(ctx, "sqlite://.data/homebox.migration.db?_fk=1", os.Args[1], opts...)
if err != nil {
log.Fatalf("failed generating migration file: %v", err)
}
}

View file

@ -0,0 +1,6 @@
package migrations
import "embed"
// go:embed all:migrations
var Files embed.FS