// Command seed loads the development fixture. It wipes the campaign side of // the database first, so it is never something to point at production — which // is why it lives under test/ and is built into its own image target rather // than the one that ships. package main import ( "context" "fmt" "log" "os" "time" _ "time/tzdata" "github.com/jackc/pgx/v5/pgxpool" "github.com/szabadpalya/api/internal/config" "github.com/szabadpalya/api/internal/hu" "github.com/szabadpalya/api/internal/store" "github.com/szabadpalya/api/internal/store/dbgen" "github.com/szabadpalya/api/test/seeddata" ) // seeder owns its own connection pool: the fixture's SQL is test code, so it // does not reach into internal/store for a handle the production packages keep // unexported. The Store alongside it is only for Migrate and EndOfDay. type seeder struct { pool *pgxpool.Pool store *store.Store q *dbgen.Queries } func main() { if err := run(); err != nil { log.Fatal(err) } } func run() error { // The seeder needs a database and nothing else, so it does not insist on // the session secret the server requires. if os.Getenv("SESSION_SECRET") == "" { os.Setenv("SESSION_SECRET", "seed-only-unused") } cfg, err := config.Load() if err != nil { return err } ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() db, err := store.New(ctx, cfg.DatabaseURL) if err != nil { return err } defer db.Close() if err := db.Migrate(ctx); err != nil { return err } pool, err := pgxpool.New(ctx, cfg.DatabaseURL) if err != nil { return err } defer pool.Close() s := &seeder{pool: pool, store: db, q: dbgen.New(pool)} campaigns, err := seeddata.Load() if err != nil { return err } if err := s.reset(ctx); err != nil { return err } for _, c := range campaigns { pledges, raised, err := s.campaign(ctx, c) if err != nil { return fmt.Errorf("%s: %w", c.Slug, err) } fmt.Printf(" %s: %d pledges, %s (%d%%)\n", c.Slug, pledges, hu.FormatHUF(raised), hu.ProgressPct(raised, c.GoalAmount)) } fmt.Println("Seed data loaded.") return nil }