package main import ( "context" "encoding/json" "flag" "log/slog" "os" "os/signal" "path/filepath" "git.sunturtle.xyz/zephyr/horse/umadump/replay" ) func main() { var ( uri, journalMode string fs []string ) flag.StringVar(&uri, "db", "race.sqlite3", "output database `URI` or filename") flag.StringVar(&journalMode, "journal", "memory", "journal `mode` to apply to database connections") flag.Func("d", "`dir`ectory containing race dumps to load (repeatable)", func(s string) error { es, err := os.ReadDir(s) for _, e := range es { if e.IsDir() { continue } fs = append(fs, filepath.Join(s, e.Name())) } return err }) flag.Parse() fs = append(fs, flag.Args()...) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) go func() { <-ctx.Done() stop() }() db := opendb(uri, journalMode) ok := 0 for _, n := range fs { log := slog.With(slog.String("file", n)) log.Info("begin") f, err := os.Open(n) if err != nil { log.Error("open", slog.Any("err", err)) continue } var race replay.Race d := json.NewDecoder(f) d.DisallowUnknownFields() log.Debug("decode") if err := d.Decode(&race); err != nil { log.Error("load", slog.Any("err", err)) continue } log.Debug("simdata") simdata, err := replay.DecodeSim(race.SimDataBase64) if err != nil { log.Error("simdata", slog.Any("err", err)) continue } log.Debug("insert") err = insert(ctx, db, log, &race, simdata) if err != nil { log.Error("insert", slog.Any("err", err)) continue } ok++ } slog.Info("done", slog.Int("races", ok)) }