// rules.go:域名策略规则表(match_type=suffix|glob,action=direct|pool:|deny)。 // gateway policy 与 proxymanager 共享本表 + 热载(design-arch §5.3)。 package store import ( "fmt" ) // Rule 单条域名规则。 type Rule struct { ID int64 MatchType string // suffix | glob Value string // 如 .onesvm.com / *.github.com Action string // direct | pool: | deny Sort int // 越小越优先(由具体到一般) } // RulesAll 按 sort 升序取全部规则。 func (d *DB) RulesAll() ([]Rule, error) { rows, err := d.raw.Query( `SELECT id, match_type, value, action, sort FROM rules ORDER BY sort ASC, id ASC`) if err != nil { return nil, fmt.Errorf("store: RulesAll: %w", err) } defer rows.Close() var out []Rule for rows.Next() { var r Rule if err := rows.Scan(&r.ID, &r.MatchType, &r.Value, &r.Action, &r.Sort); err != nil { return nil, fmt.Errorf("store: RulesAll scan: %w", err) } out = append(out, r) } if err := rows.Err(); err != nil { return nil, fmt.Errorf("store: RulesAll rows: %w", err) } return out, nil } // RuleUpsert 按唯一键(match_type,value)插入或更新 action/sort。 func (d *DB) RuleUpsert(matchType, value, action string, sort int) error { if matchType != "suffix" && matchType != "glob" { return fmt.Errorf("store: RuleUpsert 非法 match_type %q", matchType) } _, err := d.raw.Exec( `INSERT INTO rules(match_type, value, action, sort) VALUES(?, ?, ?, ?) ON CONFLICT(match_type, value) DO UPDATE SET action = excluded.action, sort = excluded.sort`, matchType, value, action, sort) if err != nil { return fmt.Errorf("store: RuleUpsert: %w", err) } return nil } // RuleDelete 删除单条规则。 func (d *DB) RuleDelete(matchType, value string) error { res, err := d.raw.Exec( `DELETE FROM rules WHERE match_type = ? AND value = ?`, matchType, value) if err != nil { return fmt.Errorf("store: RuleDelete: %w", err) } if n, _ := res.RowsAffected(); n == 0 { return ErrNotFound } return nil }