返回 DeepSeek-Reasonix
rebuild.go
根目录 / internal / usagecatalog / rebuild.go
1 package usagecatalog
2
3 import (
4 "context"
5 "database/sql"
6 "strings"
7 "time"
8
9 "reasonix/internal/projectiondb"
10 )
11
12 // Rebuild replaces only the disposable usage projection after replaying the
13 // authoritative daily JSONL directory into a validated sibling database.
14 func Rebuild(ctx context.Context, path, statsDir string) (Status, error) {
15 if path == "" {
16 path = DefaultPath()
17 }
18 if strings.TrimSpace(path) == "" {
19 catalog, err := Open(ctx, "")
20 if err != nil {
21 return Status{}, err
22 }
23 if err := catalog.ReconcileDir(ctx, statsDir); err != nil {
24 closeRebuildCatalog(catalog)
25 return catalog.Status(), err
26 }
27 status := catalog.Status()
28 closeRebuildCatalog(catalog)
29 return status, nil
30 }
31 err := projectiondb.Rebuild(ctx, projectiondb.OpenOptions{
32 Path: path, MemoryName: "usage-catalog-rebuild", Migrations: migrations(),
33 }, func(ctx context.Context, db *sql.DB) error {
34 catalog := &Catalog{db: db, status: Status{State: "ready", Mode: projectiondb.ModeDisk, Path: path}}
35 return catalog.ReconcileDir(ctx, statsDir)
36 })
37 if err != nil {
38 return Status{}, err
39 }
40 published, err := Open(ctx, path)
41 if err != nil {
42 return Status{}, err
43 }
44 status := published.Status()
45 closeRebuildCatalog(published)
46 return status, nil
47 }
48
49 func closeRebuildCatalog(catalog *Catalog) {
50 closeCtx, cancel := context.WithTimeout(context.Background(), time.Second)
51 defer cancel()
52 _ = catalog.Close(closeCtx)
53 }
54
54 lines GO