From d2028143df8526cb16e3d90cb2d3bb8b272f7502 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Fri, 2 Dec 2022 11:36:13 +0200 Subject: [PATCH] skip empty automigrate templates --- plugins/migratecmd/automigrate.go | 57 ++++++++++++++++++++++++------- plugins/migratecmd/templates.go | 10 ++++++ tools/migrate/runner.go | 4 +-- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/plugins/migratecmd/automigrate.go b/plugins/migratecmd/automigrate.go index f6ba5f5f..f0dac6b2 100644 --- a/plugins/migratecmd/automigrate.go +++ b/plugins/migratecmd/automigrate.go @@ -8,8 +8,11 @@ import ( "path/filepath" "time" + "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/models" + "github.com/pocketbase/pocketbase/tools/migrate" ) const collectionsCacheKey = "migratecmd_collections" @@ -43,6 +46,9 @@ func (p *plugin) afterCollectionChange() func(*core.ModelEvent) error { template, templateErr = p.goDiffTemplate(new, old) } if templateErr != nil { + if errors.Is(templateErr, emptyTemplateErr) { + return nil // no changes + } return fmt.Errorf("failed to resolve template: %w", templateErr) } @@ -57,23 +63,48 @@ func (p *plugin) afterCollectionChange() func(*core.ModelEvent) error { } appliedTime := time.Now().Unix() - fileDest := filepath.Join(p.options.Dir, fmt.Sprintf("%d_%s.%s", appliedTime, action, p.options.TemplateLang)) + name := fmt.Sprintf("%d_%s.%s", appliedTime, action, p.options.TemplateLang) + filePath := filepath.Join(p.options.Dir, name) - // ensure that the local migrations dir exist - if err := os.MkdirAll(p.options.Dir, os.ModePerm); err != nil { - return fmt.Errorf("failed to create migration dir: %w", err) - } + return p.app.Dao().RunInTransaction(func(txDao *daos.Dao) error { + // insert the migration entry + _, err := txDao.DB().Insert(migrate.DefaultMigrationsTable, dbx.Params{ + "file": name, + "applied": appliedTime, + }).Execute() + if err != nil { + return err + } - if err := os.WriteFile(fileDest, []byte(template), 0644); err != nil { - return fmt.Errorf("failed to save automigrate file: %w", err) - } + // ensure that the local migrations dir exist + if err := os.MkdirAll(p.options.Dir, os.ModePerm); err != nil { + return fmt.Errorf("failed to create migration dir: %w", err) + } - p.refreshCachedCollections() + if err := os.WriteFile(filePath, []byte(template), 0644); err != nil { + return fmt.Errorf("failed to save automigrate file: %w", err) + } - return nil + p.updateSingleCachedCollection(new, old) + + return nil + }) } } +func (p *plugin) updateSingleCachedCollection(new, old *models.Collection) { + cached, _ := p.app.Cache().Get(collectionsCacheKey).(map[string]*models.Collection) + + switch { + case new == nil: + delete(cached, old.Id) + default: + cached[new.Id] = new + } + + p.app.Cache().Set(collectionsCacheKey, cached) +} + func (p *plugin) refreshCachedCollections() error { if p.app.Dao() == nil { return errors.New("app is not initialized yet") @@ -84,12 +115,12 @@ func (p *plugin) refreshCachedCollections() error { return err } - mapped := map[string]*models.Collection{} + cached := map[string]*models.Collection{} for _, c := range collections { - mapped[c.Id] = c + cached[c.Id] = c } - p.app.Cache().Set(collectionsCacheKey, mapped) + p.app.Cache().Set(collectionsCacheKey, cached) return nil } diff --git a/plugins/migratecmd/templates.go b/plugins/migratecmd/templates.go index dfeb425a..e20b3ca9 100644 --- a/plugins/migratecmd/templates.go +++ b/plugins/migratecmd/templates.go @@ -17,6 +17,8 @@ const ( TemplateLangGo = "go" ) +var emptyTemplateErr = errors.New("empty template") + // ------------------------------------------------------------------- // JavaScript templates // ------------------------------------------------------------------- @@ -271,6 +273,10 @@ func (p *plugin) jsDiffTemplate(new *models.Collection, old *models.Collection) // ----------------------------------------------------------------- + if len(upParts) == 0 && len(downParts) == 0 { + return "", emptyTemplateErr + } + up := strings.Join(upParts, "\n ") down := strings.Join(downParts, "\n ") @@ -646,6 +652,10 @@ func (p *plugin) goDiffTemplate(new *models.Collection, old *models.Collection) } // --------------------------------------------------------------- + if len(upParts) == 0 && len(downParts) == 0 { + return "", emptyTemplateErr + } + up := strings.Join(upParts, "\n\t\t") down := strings.Join(downParts, "\n\t\t") combined := up + down diff --git a/tools/migrate/runner.go b/tools/migrate/runner.go index 8e48cc82..7485e5e2 100644 --- a/tools/migrate/runner.go +++ b/tools/migrate/runner.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cast" ) -const migrationsTable = "_migrations" +const DefaultMigrationsTable = "_migrations" // Runner defines a simple struct for managing the execution of db migrations. type Runner struct { @@ -24,7 +24,7 @@ func NewRunner(db *dbx.DB, migrationsList MigrationsList) (*Runner, error) { runner := &Runner{ db: db, migrationsList: migrationsList, - tableName: migrationsTable, + tableName: DefaultMigrationsTable, } if err := runner.createMigrationsTable(); err != nil {