Files
sub2api-cn-relay-manager/internal/store/sqlite/route_sticky_audit_repo.go
2026-05-28 21:24:05 +08:00

168 lines
4.6 KiB
Go

package sqlite
import (
"context"
"fmt"
"strings"
)
type RouteStickyAudit struct {
ID int64
StickyKey string
StickyKeyType string
LogicalGroupID string
PublicModel string
RouteID string
Action string
ExpiresAt string
CreatedAt string
}
type RouteStickyAuditFilter struct {
StickyKey string
StickyKeyType string
LogicalGroupID string
PublicModel string
RouteID string
Action string
Limit int
}
type RouteStickyAuditRepo struct {
db execQuerier
}
func newRouteStickyAuditRepo(db execQuerier) *RouteStickyAuditRepo {
return &RouteStickyAuditRepo{db: db}
}
func (r *RouteStickyAuditRepo) Create(ctx context.Context, row RouteStickyAudit) (int64, error) {
row, err := normalizeRouteStickyAudit(row)
if err != nil {
return 0, err
}
result, err := r.db.ExecContext(
ctx,
`INSERT INTO route_sticky_audit (
sticky_key,
sticky_key_type,
logical_group_id,
public_model,
route_id,
action,
expires_at
) VALUES (?, ?, ?, ?, ?, ?, ?)`,
row.StickyKey,
row.StickyKeyType,
row.LogicalGroupID,
row.PublicModel,
row.RouteID,
row.Action,
row.ExpiresAt,
)
if err != nil {
return 0, fmt.Errorf("insert route sticky audit %q: %w", row.StickyKey, err)
}
id, err := result.LastInsertId()
if err != nil {
return 0, fmt.Errorf("read inserted route sticky audit id for %q: %w", row.StickyKey, err)
}
return id, nil
}
func (r *RouteStickyAuditRepo) ListRecent(ctx context.Context, filter RouteStickyAuditFilter) ([]RouteStickyAudit, error) {
clauses := make([]string, 0, 6)
args := make([]any, 0, 7)
if stickyKey := strings.TrimSpace(filter.StickyKey); stickyKey != "" {
clauses = append(clauses, "sticky_key = ?")
args = append(args, stickyKey)
}
if stickyKeyType := strings.TrimSpace(filter.StickyKeyType); stickyKeyType != "" {
clauses = append(clauses, "sticky_key_type = ?")
args = append(args, stickyKeyType)
}
if logicalGroupID := strings.TrimSpace(filter.LogicalGroupID); logicalGroupID != "" {
clauses = append(clauses, "logical_group_id = ?")
args = append(args, logicalGroupID)
}
if publicModel := strings.TrimSpace(filter.PublicModel); publicModel != "" {
clauses = append(clauses, "public_model = ?")
args = append(args, publicModel)
}
if routeID := strings.TrimSpace(filter.RouteID); routeID != "" {
clauses = append(clauses, "route_id = ?")
args = append(args, routeID)
}
if action := strings.TrimSpace(filter.Action); action != "" {
clauses = append(clauses, "action = ?")
args = append(args, action)
}
query := `SELECT id, sticky_key, sticky_key_type, logical_group_id, public_model, route_id, action, expires_at, created_at
FROM route_sticky_audit`
if len(clauses) > 0 {
query += " WHERE " + strings.Join(clauses, " AND ")
}
query += " ORDER BY id DESC LIMIT ?"
args = append(args, normalizeRouteLogListLimit(filter.Limit))
rows, err := r.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("list route sticky audit: %w", err)
}
defer rows.Close()
items := make([]RouteStickyAudit, 0)
for rows.Next() {
var item RouteStickyAudit
if err := rows.Scan(
&item.ID,
&item.StickyKey,
&item.StickyKeyType,
&item.LogicalGroupID,
&item.PublicModel,
&item.RouteID,
&item.Action,
&item.ExpiresAt,
&item.CreatedAt,
); err != nil {
return nil, fmt.Errorf("scan route sticky audit: %w", err)
}
items = append(items, item)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate route sticky audit: %w", err)
}
return items, nil
}
func normalizeRouteStickyAudit(row RouteStickyAudit) (RouteStickyAudit, error) {
row.StickyKey = strings.TrimSpace(row.StickyKey)
row.StickyKeyType = strings.TrimSpace(row.StickyKeyType)
row.LogicalGroupID = strings.TrimSpace(row.LogicalGroupID)
row.PublicModel = strings.TrimSpace(row.PublicModel)
row.RouteID = strings.TrimSpace(row.RouteID)
row.Action = strings.TrimSpace(row.Action)
row.ExpiresAt = strings.TrimSpace(row.ExpiresAt)
switch {
case row.StickyKey == "":
return RouteStickyAudit{}, fmt.Errorf("sticky_key is required")
case row.StickyKeyType == "":
return RouteStickyAudit{}, fmt.Errorf("sticky_key_type is required")
case row.LogicalGroupID == "":
return RouteStickyAudit{}, fmt.Errorf("logical_group_id is required")
case row.PublicModel == "":
return RouteStickyAudit{}, fmt.Errorf("public_model is required")
case row.RouteID == "":
return RouteStickyAudit{}, fmt.Errorf("route_id is required")
case row.Action == "":
return RouteStickyAudit{}, fmt.Errorf("action is required")
}
return row, nil
}