Index: golden/go/types/ignorestore.go |
diff --git a/golden/go/types/ignorestore.go b/golden/go/types/ignorestore.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ee915dc7186aab928d5bf7663fbc71c0d4d0ed43 |
--- /dev/null |
+++ b/golden/go/types/ignorestore.go |
@@ -0,0 +1,149 @@ |
+package types |
+ |
+import ( |
+ "net/url" |
+ "time" |
+ |
+ "skia.googlesource.com/buildbot.git/go/database" |
+) |
+ |
+// RuleMatcher returns a list of rules in the IgnoreStore that match the given |
+// set of parameters. |
+type RuleMatcher func(map[string]string) ([]*IgnoreRule, bool) |
+ |
+// IgnoreStore stores and matches ignore rules. |
+type IgnoreStore interface { |
+ // Create adds a new rule to the ignore store. |
+ Create(*IgnoreRule) error |
+ |
+ // List returns all ignore rules in the ignore store. |
+ List() ([]*IgnoreRule, error) |
+ |
+ // Removes an IgnoreRule from the store. |
+ Delete(id int, userId string) (int, error) |
+ |
+ // BuildRuleMatcher returns a RuleMatcher based on the current content |
+ // of the ignore store. |
+ BuildRuleMatcher() (RuleMatcher, error) |
+} |
+ |
+// IgnoreRule is the GUI struct for dealing with Ignore rules. |
+type IgnoreRule struct { |
+ ID int `json:"id"` |
+ Name string `json:"name"` |
+ Expires time.Time `json:"expires"` |
+ Query string `json:"query"` |
+ Note string `json:"note"` |
+ Count int `json:"count"` |
+} |
+ |
+func NewIgnoreRule(name string, expires time.Time, queryStr string, note string) *IgnoreRule { |
+ return &IgnoreRule{ |
+ Name: name, |
+ Expires: expires, |
+ Query: queryStr, |
+ Note: note, |
+ } |
+} |
+ |
+// MemIgnoreStore is an in-memory implementation of IgnoreStore. |
+type MemIgnoreStore []*IgnoreRule |
+ |
+func NewMemIgnoreStore() IgnoreStore { |
+ return new(MemIgnoreStore) |
+} |
+ |
+// Create, see IgnoreStore interface. |
+func (m *MemIgnoreStore) Create(rule *IgnoreRule) error { |
+ rule.ID = len(*m) |
+ *m = append(*m, rule) |
+ return nil |
+} |
+ |
+// List, see IgnoreStore interface. |
+func (m *MemIgnoreStore) List() ([]*IgnoreRule, error) { |
+ result := make([]*IgnoreRule, 0, len(*m)) |
+ for _, r := range *m { |
+ if r != nil { |
+ result = append(result, r) |
+ } |
+ } |
+ return result, nil |
+} |
+ |
+// Delete, see IgnoreStore interface. |
+func (m *MemIgnoreStore) Delete(id int, userId string) (int, error) { |
+ for idx := range *m { |
+ if ((*m)[idx] != nil) && ((*m)[idx].ID == id) { |
+ (*m)[idx] = nil |
+ return 1, nil |
+ } |
+ } |
+ return 0, nil |
+} |
+ |
+// BuildRuleMatcher, see IgnoreStore interface. |
+func (m *MemIgnoreStore) BuildRuleMatcher() (RuleMatcher, error) { |
+ rulesList, err := m.List() |
+ if err != nil { |
+ return noopRuleMatcher, err |
+ } |
+ |
+ ignoreRules := make([]map[string]map[string]bool, len(rulesList)) |
+ for idx, rawRule := range rulesList { |
+ ignoreRules[idx], err = compileRule(rawRule.Query) |
+ if err != nil { |
+ return noopRuleMatcher, err |
+ } |
+ } |
+ |
+ return func(params map[string]string) ([]*IgnoreRule, bool) { |
+ result := []*IgnoreRule{} |
+ |
+ Loop: |
+ for ruleIdx, rule := range ignoreRules { |
+ // All elements in the rules are AND connected. If the list is |
+ // longer than available parameters the result will be false. |
+ if len(rule) > len(params) { |
+ continue Loop |
+ } |
+ |
+ // Check if the parameters match the rule. |
+ for ruleKey, ruleValues := range rule { |
+ if _, ok := params[ruleKey]; !ok { |
+ continue Loop |
+ } |
+ if !ruleValues[params[ruleKey]] { |
+ continue Loop |
+ } |
+ } |
+ result = append(result, rulesList[ruleIdx]) |
+ } |
+ |
+ return result, len(result) > 0 |
+ }, nil |
+} |
+ |
+func compileRule(query string) (map[string]map[string]bool, error) { |
+ v, err := url.ParseQuery(query) |
+ if err != nil { |
+ return nil, err |
+ } |
+ |
+ ret := make(map[string]map[string]bool, len(v)) |
+ for k, paramValues := range v { |
+ ret[k] = make(map[string]bool, len(paramValues)) |
+ for _, oneVal := range paramValues { |
+ ret[k][oneVal] = true |
+ } |
+ } |
+ return ret, nil |
+} |
+ |
+func noopRuleMatcher(p map[string]string) ([]*IgnoreRule, bool) { |
+ return nil, false |
+} |
+ |
+func NewSQLIgnoreStore(vdb *database.VersionedDB) IgnoreStore { |
+ return NewMemIgnoreStore() |
+} |