aboutsummaryrefslogtreecommitdiffstats
path: root/cache/query.go
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-09-09 20:21:49 +0200
committerMichael Muré <batolettre@gmail.com>2018-09-09 20:22:27 +0200
commit09e097e1bf32ad153c139e3f6befad9fb059fd6e (patch)
tree422db558f5ead4ec673bca6a2ede413514d49d5b /cache/query.go
parent21f9840e991ae569ec1efa404011e9a16ed2ab3b (diff)
downloadgit-bug-09e097e1bf32ad153c139e3f6befad9fb059fd6e.tar.gz
cache: combine sorting and filtering into a query with its micro-DSL
Diffstat (limited to 'cache/query.go')
-rw-r--r--cache/query.go128
1 files changed, 128 insertions, 0 deletions
diff --git a/cache/query.go b/cache/query.go
new file mode 100644
index 00000000..d8df00fe
--- /dev/null
+++ b/cache/query.go
@@ -0,0 +1,128 @@
+package cache
+
+import (
+ "fmt"
+ "strings"
+)
+
+type Query struct {
+ Filters
+ OrderBy
+ OrderDirection
+}
+
+// ParseQuery parse a query DSL
+//
+// Ex: "status:open author:descartes sort:edit-asc"
+//
+// Supported filter fields are:
+// - status:
+// - author:
+// - label:
+// - no:
+//
+// Sorting is done with:
+// - sort:
+//
+// Todo: write a complete doc
+func ParseQuery(query string) (*Query, error) {
+ fields := strings.Fields(query)
+
+ result := &Query{
+ OrderBy: OrderByCreation,
+ OrderDirection: OrderDescending,
+ }
+
+ sortingDone := false
+
+ for _, field := range fields {
+ split := strings.Split(field, ":")
+ if len(split) != 2 {
+ return nil, fmt.Errorf("can't parse \"%s\"", field)
+ }
+
+ switch split[0] {
+ case "status":
+ f, err := StatusFilter(split[1])
+ if err != nil {
+ return nil, err
+ }
+ result.Status = append(result.Status, f)
+
+ case "author":
+ f := AuthorFilter(split[1])
+ result.Author = append(result.Author, f)
+
+ case "label":
+ f := LabelFilter(split[1])
+ result.Label = append(result.Label, f)
+
+ case "no":
+ err := result.parseNoFilter(split[1])
+ if err != nil {
+ return nil, err
+ }
+
+ case "sort":
+ if sortingDone {
+ return nil, fmt.Errorf("multiple sorting")
+ }
+
+ err := result.parseSorting(split[1])
+ if err != nil {
+ return nil, err
+ }
+
+ sortingDone = true
+
+ default:
+ return nil, fmt.Errorf("unknow query field %s", split[0])
+ }
+ }
+
+ return result, nil
+}
+
+func (q *Query) parseNoFilter(query string) error {
+ switch query {
+ case "label":
+ q.NoFilters = append(q.NoFilters, NoLabelFilter())
+ default:
+ return fmt.Errorf("unknown \"no\" filter")
+ }
+
+ return nil
+}
+
+func (q *Query) parseSorting(query string) error {
+ switch query {
+ // default ASC
+ case "id-desc":
+ q.OrderBy = OrderById
+ q.OrderDirection = OrderDescending
+ case "id", "id-asc":
+ q.OrderBy = OrderById
+ q.OrderDirection = OrderAscending
+
+ // default DESC
+ case "creation", "creation-desc":
+ q.OrderBy = OrderByCreation
+ q.OrderDirection = OrderDescending
+ case "creation-asc":
+ q.OrderBy = OrderByCreation
+ q.OrderDirection = OrderAscending
+
+ // default DESC
+ case "edit", "edit-desc":
+ q.OrderBy = OrderByEdit
+ q.OrderDirection = OrderDescending
+ case "edit-asc":
+ q.OrderBy = OrderByEdit
+ q.OrderDirection = OrderAscending
+
+ default:
+ return fmt.Errorf("unknow sorting %s", query)
+ }
+
+ return nil
+}