From 6b16b7856b6e2a484192ba46624369dc465f6eb3 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Wed, 24 May 2023 09:17:17 +0300 Subject: [PATCH 1/3] [#2551] auto register the initial generated snapshot migration to prevent incorrectly reapplying the snapshot on container restart --- CHANGELOG.md | 2 ++ plugins/migratecmd/migratecmd.go | 46 ++++++++++++++++---------- plugins/migratecmd/migratecmd_test.go | 36 ++++++++++++++++++++ tests/data/data.db | Bin 249856 -> 249856 bytes 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5f2c915..b282e677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Changed file field to not use `dataTransfer.effectAllowed` when dropping files since it is not reliable and consistent across different OS and browsers ([#2541](https://github.com/pocketbase/pocketbase/issues/2541)). +- Auto register the initial generated snapshot migration to prevent incorrectly reapplying the snapshot on container restart ([#2551](https://github.com/pocketbase/pocketbase/discussions/2551)). + ## v0.16.1 diff --git a/plugins/migratecmd/migratecmd.go b/plugins/migratecmd/migratecmd.go index 363cd3f3..614d83d7 100644 --- a/plugins/migratecmd/migratecmd.go +++ b/plugins/migratecmd/migratecmd.go @@ -23,6 +23,7 @@ import ( "time" "github.com/AlecAivazis/survey/v2" + "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/migrations" "github.com/pocketbase/pocketbase/models" @@ -102,7 +103,19 @@ func Register(app core.App, rootCmd *cobra.Command, options *Options) error { // migrations but there is already at least 1 collection created, // to ensure that the automigrate will work with up-to-date collections data if !p.hasCustomMigrations() && len(cachedCollections) > 1 { - p.migrateCollectionsHandler(nil, false) + snapshotFile, err := p.migrateCollectionsHandler(nil, false) + if err != nil { + return err + } + + // insert the snapshot migration entry + _, insertErr := p.app.Dao().NonconcurrentDB().Insert(migrate.DefaultMigrationsTable, dbx.Params{ + "file": snapshotFile, + "applied": time.Now().Unix(), + }).Execute() + if insertErr != nil { + return insertErr + } } return nil @@ -141,11 +154,11 @@ func (p *plugin) createCommand() *cobra.Command { switch cmd { case "create": - if err := p.migrateCreateHandler("", args[1:], true); err != nil { + if _, err := p.migrateCreateHandler("", args[1:], true); err != nil { return err } case "collections": - if err := p.migrateCollectionsHandler(args[1:], true); err != nil { + if _, err := p.migrateCollectionsHandler(args[1:], true); err != nil { return err } default: @@ -166,18 +179,17 @@ func (p *plugin) createCommand() *cobra.Command { return command } -func (p *plugin) migrateCreateHandler(template string, args []string, interactive bool) error { +func (p *plugin) migrateCreateHandler(template string, args []string, interactive bool) (string, error) { if len(args) < 1 { - return fmt.Errorf("Missing migration file name") + return "", fmt.Errorf("Missing migration file name") } name := args[0] dir := p.options.Dir - resultFilePath := path.Join( - dir, - fmt.Sprintf("%d_%s.%s", time.Now().Unix(), inflector.Snakecase(name), p.options.TemplateLang), - ) + filename := fmt.Sprintf("%d_%s.%s", time.Now().Unix(), inflector.Snakecase(name), p.options.TemplateLang) + + resultFilePath := path.Join(dir, filename) if interactive { confirm := false @@ -187,7 +199,7 @@ func (p *plugin) migrateCreateHandler(template string, args []string, interactiv survey.AskOne(prompt, &confirm) if !confirm { fmt.Println("The command has been cancelled") - return nil + return "", nil } } @@ -200,34 +212,34 @@ func (p *plugin) migrateCreateHandler(template string, args []string, interactiv template, templateErr = p.goBlankTemplate() } if templateErr != nil { - return fmt.Errorf("Failed to resolve create template: %v\n", templateErr) + return "", fmt.Errorf("Failed to resolve create template: %v\n", templateErr) } } // ensure that the migrations dir exist if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return err + return "", err } // save the migration file if err := os.WriteFile(resultFilePath, []byte(template), 0644); err != nil { - return fmt.Errorf("Failed to save migration file %q: %v\n", resultFilePath, err) + return "", fmt.Errorf("Failed to save migration file %q: %v\n", resultFilePath, err) } if interactive { fmt.Printf("Successfully created file %q\n", resultFilePath) } - return nil + return filename, nil } -func (p *plugin) migrateCollectionsHandler(args []string, interactive bool) error { +func (p *plugin) migrateCollectionsHandler(args []string, interactive bool) (string, error) { createArgs := []string{"collections_snapshot"} createArgs = append(createArgs, args...) collections := []*models.Collection{} if err := p.app.Dao().CollectionQuery().OrderBy("created ASC").All(&collections); err != nil { - return fmt.Errorf("Failed to fetch migrations list: %v", err) + return "", fmt.Errorf("Failed to fetch migrations list: %v", err) } var template string @@ -238,7 +250,7 @@ func (p *plugin) migrateCollectionsHandler(args []string, interactive bool) erro template, templateErr = p.goSnapshotTemplate(collections) } if templateErr != nil { - return fmt.Errorf("Failed to resolve template: %v", templateErr) + return "", fmt.Errorf("Failed to resolve template: %v", templateErr) } return p.migrateCreateHandler(template, createArgs, interactive) diff --git a/plugins/migratecmd/migratecmd_test.go b/plugins/migratecmd/migratecmd_test.go index afe2655c..baced7c0 100644 --- a/plugins/migratecmd/migratecmd_test.go +++ b/plugins/migratecmd/migratecmd_test.go @@ -6,11 +6,14 @@ import ( "strings" "testing" + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/models" "github.com/pocketbase/pocketbase/models/schema" "github.com/pocketbase/pocketbase/plugins/migratecmd" "github.com/pocketbase/pocketbase/tests" + "github.com/pocketbase/pocketbase/tools/migrate" "github.com/pocketbase/pocketbase/tools/types" ) @@ -776,3 +779,36 @@ func TestAutomigrateCollectionNoChanges(t *testing.T) { } } } + +func TestInitialAutoSnapshot(t *testing.T) { + app, _ := tests.NewTestApp() + defer app.Cleanup() + + migrationsDir := filepath.Join(app.DataDir(), "_test_auto_snapshot_") + + migratecmd.MustRegister(app, nil, &migratecmd.Options{ + TemplateLang: migratecmd.TemplateLangJS, + Automigrate: true, + Dir: migrationsDir, + }) + + app.Bootstrap() + + app.OnBeforeServe().Trigger(&core.ServeEvent{ + App: app, + }) + + var foundFiles []string + + err := app.Dao().NonconcurrentDB().Select("file"). + From(migrate.DefaultMigrationsTable). + Where(dbx.NewExp("file like '%collections_snapshot.js'")). + Column(&foundFiles) + if err != nil { + t.Fatal(err) + } + + if len(foundFiles) != 1 { + t.Fatalf("Expected 1 collections_snapshot migration, found %v", foundFiles) + } +} diff --git a/tests/data/data.db b/tests/data/data.db index 8e17df2f959985274c971e4ffb30921fd0c2ccb6..6b55e636ea826849dd372ddcc176b5195b2fa45d 100644 GIT binary patch delta 326 zcmZozz~8Wde*>d{D(`a!R^ECB{-^w%eEz&^c#m!p(vX+juA6(T!l?+s+U%`HidsD=&~`40K!+3;z*@=RkMKfEdRo--a-j zPd+av&B_53Y6rRrESC;+4w&ISIU2%HpByi*GNATk000^2U|s+K delta 326 zcmZozz~8Wde*>d{Dgy%pKW{w)|5N_${GI$!{AT<@eDC;9@h#(P;`8Sd;eF1#hPQsR zp+Y3@s4|9 From 511259ed10319abad9e2a1ef796a5dcbc325c3cd Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Wed, 24 May 2023 09:25:39 +0300 Subject: [PATCH 2/3] fixed missing view id field error message typo --- CHANGELOG.md | 2 ++ daos/view.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b282e677..80fa601f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Auto register the initial generated snapshot migration to prevent incorrectly reapplying the snapshot on container restart ([#2551](https://github.com/pocketbase/pocketbase/discussions/2551)). +- Fixed missing view id field error message typo. + ## v0.16.1 diff --git a/daos/view.go b/daos/view.go index 0181ee0f..421b4fab 100644 --- a/daos/view.go +++ b/daos/view.go @@ -127,7 +127,7 @@ func (dao *Dao) CreateViewSchema(selectQuery string) (schema.Schema, error) { } if !hasId { - return errors.New("missing required id column (you ca use `(ROW_NUMBER() OVER()) as id` if you don't have one)") + return errors.New("missing required id column (you can use `(ROW_NUMBER() OVER()) as id` if you don't have one)") } return nil From e9969ed6d1eab28d9821b862b497a3c82297edf7 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Wed, 24 May 2023 09:34:23 +0300 Subject: [PATCH 3/3] updated changelog --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80fa601f..7b6ece1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ -## v0.16.2-WIP +## v0.16.2 -- Fixed backups archive not excluding the local `backups` dir on Windows ([#2548](https://github.com/pocketbase/pocketbase/discussions/2548#discussioncomment-5979712)). +> _To update the prebuilt executable you can run `./pocketbase update`._ + +- Fixed backups archive not excluding the local `backups` directory on Windows ([#2548](https://github.com/pocketbase/pocketbase/discussions/2548#discussioncomment-5979712)). - Changed file field to not use `dataTransfer.effectAllowed` when dropping files since it is not reliable and consistent across different OS and browsers ([#2541](https://github.com/pocketbase/pocketbase/issues/2541)). -- Auto register the initial generated snapshot migration to prevent incorrectly reapplying the snapshot on container restart ([#2551](https://github.com/pocketbase/pocketbase/discussions/2551)). +- Auto register the initial generated snapshot migration to prevent incorrectly reapplying the snapshot on Docker restart ([#2551](https://github.com/pocketbase/pocketbase/discussions/2551)). - Fixed missing view id field error message typo.