|
package main |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"os" |
|
"os/exec" |
|
"path/filepath" |
|
"strings" |
|
|
|
"github.com/pocketbase/pocketbase" |
|
"github.com/pocketbase/pocketbase/core" |
|
) |
|
|
|
func main() { |
|
dir, err := os.MkdirTemp("", "pb-backup-repro-") |
|
must(err) |
|
defer os.RemoveAll(dir) |
|
|
|
app := pocketbase.NewWithConfig(pocketbase.Config{ |
|
DefaultDataDir: dir, |
|
DataMaxOpenConns: 1, |
|
DataMaxIdleConns: 1, |
|
}) |
|
must(app.Bootstrap()) |
|
defer app.ResetBootstrapState() |
|
|
|
collection := core.NewBaseCollection("events") |
|
collection.Fields.Add(&core.TextField{Name: "value", Required: true}) |
|
must(app.Save(collection)) |
|
save(app, collection, "before") |
|
|
|
must(app.CreateBackup(context.Background(), "repro.zip")) |
|
dbPath := filepath.Join(dir, "data.db") |
|
backupPath := filepath.Join(dir, "online-backup.db") |
|
runSQLite(dbPath, fmt.Sprintf(".backup %q", backupPath)) |
|
|
|
save(app, collection, "after") |
|
records, err := app.FindRecordsByFilter(collection, "", "", 0, 0) |
|
must(err) |
|
freshCount := strings.TrimSpace(runSQLite(dbPath, "SELECT count(*) FROM events;")) |
|
|
|
fmt.Printf("PocketBase sees %d records; fresh SQLite sees %s\n", len(records), freshCount) |
|
if len(records) == 2 && freshCount == "1" { |
|
fmt.Println("REPRODUCED: readers disagree") |
|
return |
|
} |
|
fmt.Println("not reproduced") |
|
os.Exit(1) |
|
} |
|
|
|
func save(app core.App, collection *core.Collection, value string) { |
|
record := core.NewRecord(collection) |
|
record.Set("value", value) |
|
must(app.Save(record)) |
|
} |
|
|
|
func runSQLite(dbPath, statement string) string { |
|
out, err := exec.Command("sqlite3", dbPath, ".timeout 10000", statement).CombinedOutput() |
|
if err != nil { |
|
panic(fmt.Sprintf("sqlite3: %v: %s", err, out)) |
|
} |
|
return string(out) |
|
} |
|
|
|
func must(err error) { |
|
if err != nil { |
|
panic(err) |
|
} |
|
} |