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" version: "3"
env:
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_fk=1
tasks: tasks:
generate: generate:
desc: | desc: |
Generates collateral files from the backend project Generates collateral files from the backend project
including swagger docs and typescripts type for the frontend including swagger docs and typescripts type for the frontend
deps:
- db:generate
cmds: 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 fmt
- cd backend/app/api/ && swag init --dir=./,../../internal,../../pkgs - cd backend/app/api/ && swag init --dir=./,../../internal,../../pkgs
- | - |
@ -72,3 +74,21 @@ tasks:
desc: Run frontend development server desc: Run frontend development server
cmds: cmds:
- cd frontend && pnpm dev - 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 ( import (
"context" "context"
"os" "os"
"path/filepath"
"time" "time"
atlas "ariga.io/atlas/sql/migrate"
"entgo.io/ent/dialect/sql/schema" "entgo.io/ent/dialect/sql/schema"
"github.com/hay-kot/homebox/backend/app/api/docs" "github.com/hay-kot/homebox/backend/app/api/docs"
"github.com/hay-kot/homebox/backend/ent" "github.com/hay-kot/homebox/backend/ent"
"github.com/hay-kot/homebox/backend/internal/config" "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/repo"
"github.com/hay-kot/homebox/backend/internal/services" "github.com/hay-kot/homebox/backend/internal/services"
"github.com/hay-kot/homebox/backend/pkgs/server" "github.com/hay-kot/homebox/backend/pkgs/server"
@ -71,9 +74,63 @@ func run(cfg *config.Config) error {
Msg("failed opening connection to sqlite") Msg("failed opening connection to sqlite")
} }
defer func(c *ent.Client) { defer func(c *ent.Client) {
_ = c.Close() err := c.Close()
if err != nil {
log.Fatal().Err(err).Msg("failed to close database connection")
}
}(c) }(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(). log.Fatal().
Err(err). Err(err).
Str("driver", "sqlite"). 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