package units import ( "context" "fmt" "github.com/jackc/pgx/v5/pgxpool" ) // Record is a unit loaded from DB with all its translations. type Record struct { Code string SortOrder int Translations map[string]string // lang → localized name } // Records is the ordered list of active units, populated by LoadFromDB at startup. var Records []Record // LoadFromDB queries units + unit_translations and populates Records. func LoadFromDB(ctx context.Context, pool *pgxpool.Pool) error { rows, err := pool.Query(ctx, ` SELECT u.code, u.sort_order, ut.lang, ut.name FROM units u LEFT JOIN unit_translations ut ON ut.unit_code = u.code ORDER BY u.sort_order, ut.lang`) if err != nil { return fmt.Errorf("load units from db: %w", err) } defer rows.Close() byCode := map[string]*Record{} var order []string for rows.Next() { var code string var sortOrder int var lang, name *string if err := rows.Scan(&code, &sortOrder, &lang, &name); err != nil { return err } if _, ok := byCode[code]; !ok { byCode[code] = &Record{Code: code, SortOrder: sortOrder, Translations: map[string]string{}} order = append(order, code) } if lang != nil && name != nil { byCode[code].Translations[*lang] = *name } } if err := rows.Err(); err != nil { return err } result := make([]Record, 0, len(order)) for _, code := range order { result = append(result, *byCode[code]) } Records = result return nil } // NameFor returns the localized name for a unit code. // Falls back to the code itself when no translation exists. func NameFor(code, lang string) string { for _, u := range Records { if u.Code == code { if name, ok := u.Translations[lang]; ok { return name } return u.Code } } return code }