[#2551] auto register the initial generated snapshot migration to prevent incorrectly reapplying the snapshot on container restart
This commit is contained in:
parent
231ddc9791
commit
6b16b7856b
|
@ -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)).
|
- 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
|
## v0.16.1
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/migrations"
|
"github.com/pocketbase/pocketbase/migrations"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"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,
|
// migrations but there is already at least 1 collection created,
|
||||||
// to ensure that the automigrate will work with up-to-date collections data
|
// to ensure that the automigrate will work with up-to-date collections data
|
||||||
if !p.hasCustomMigrations() && len(cachedCollections) > 1 {
|
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
|
return nil
|
||||||
|
@ -141,11 +154,11 @@ func (p *plugin) createCommand() *cobra.Command {
|
||||||
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case "create":
|
case "create":
|
||||||
if err := p.migrateCreateHandler("", args[1:], true); err != nil {
|
if _, err := p.migrateCreateHandler("", args[1:], true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "collections":
|
case "collections":
|
||||||
if err := p.migrateCollectionsHandler(args[1:], true); err != nil {
|
if _, err := p.migrateCollectionsHandler(args[1:], true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -166,18 +179,17 @@ func (p *plugin) createCommand() *cobra.Command {
|
||||||
return 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 {
|
if len(args) < 1 {
|
||||||
return fmt.Errorf("Missing migration file name")
|
return "", fmt.Errorf("Missing migration file name")
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
dir := p.options.Dir
|
dir := p.options.Dir
|
||||||
|
|
||||||
resultFilePath := path.Join(
|
filename := fmt.Sprintf("%d_%s.%s", time.Now().Unix(), inflector.Snakecase(name), p.options.TemplateLang)
|
||||||
dir,
|
|
||||||
fmt.Sprintf("%d_%s.%s", time.Now().Unix(), inflector.Snakecase(name), p.options.TemplateLang),
|
resultFilePath := path.Join(dir, filename)
|
||||||
)
|
|
||||||
|
|
||||||
if interactive {
|
if interactive {
|
||||||
confirm := false
|
confirm := false
|
||||||
|
@ -187,7 +199,7 @@ func (p *plugin) migrateCreateHandler(template string, args []string, interactiv
|
||||||
survey.AskOne(prompt, &confirm)
|
survey.AskOne(prompt, &confirm)
|
||||||
if !confirm {
|
if !confirm {
|
||||||
fmt.Println("The command has been cancelled")
|
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()
|
template, templateErr = p.goBlankTemplate()
|
||||||
}
|
}
|
||||||
if templateErr != nil {
|
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
|
// ensure that the migrations dir exist
|
||||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the migration file
|
// save the migration file
|
||||||
if err := os.WriteFile(resultFilePath, []byte(template), 0644); err != nil {
|
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 {
|
if interactive {
|
||||||
fmt.Printf("Successfully created file %q\n", resultFilePath)
|
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 := []string{"collections_snapshot"}
|
||||||
createArgs = append(createArgs, args...)
|
createArgs = append(createArgs, args...)
|
||||||
|
|
||||||
collections := []*models.Collection{}
|
collections := []*models.Collection{}
|
||||||
if err := p.app.Dao().CollectionQuery().OrderBy("created ASC").All(&collections); err != nil {
|
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
|
var template string
|
||||||
|
@ -238,7 +250,7 @@ func (p *plugin) migrateCollectionsHandler(args []string, interactive bool) erro
|
||||||
template, templateErr = p.goSnapshotTemplate(collections)
|
template, templateErr = p.goSnapshotTemplate(collections)
|
||||||
}
|
}
|
||||||
if templateErr != nil {
|
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)
|
return p.migrateCreateHandler(template, createArgs, interactive)
|
||||||
|
|
|
@ -6,11 +6,14 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/daos"
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
"github.com/pocketbase/pocketbase/plugins/migratecmd"
|
"github.com/pocketbase/pocketbase/plugins/migratecmd"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/migrate"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue