szabadpalya/api/test/seed/main.go

92 lines
2.1 KiB
Go

// 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
}