/
0_traverse.go
89 lines (72 loc) · 1.6 KB
/
0_traverse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package apicollectionv1
import (
"encoding/json"
"fmt"
"github.com/SierraSoftworks/connor"
"github.com/fulldump/inceptiondb/collection"
"github.com/fulldump/inceptiondb/utils"
)
func traverse(requestBody []byte, col *collection.Collection, f func(row *collection.Row) bool) error {
options := &struct {
Index *string
Filter map[string]interface{}
Skip int64
Limit int64
}{
Index: nil,
Filter: nil,
Skip: 0,
Limit: 1,
}
err := json.Unmarshal(requestBody, &options)
if err != nil {
return err
}
hasFilter := options.Filter != nil && len(options.Filter) > 0
skip := options.Skip
limit := options.Limit
iterator := func(r *collection.Row) bool {
if limit == 0 {
return false
}
if hasFilter {
rowData := map[string]interface{}{}
json.Unmarshal(r.Payload, &rowData) // todo: handle error here?
match, err := connor.Match(options.Filter, rowData)
if err != nil {
// todo: handle error?
// return fmt.Errorf("match: %w", err)
return false
}
if !match {
return true
}
}
if skip > 0 {
skip--
return true
}
limit--
return f(r)
}
// Fullscan
if options.Index == nil {
traverseFullscan(col, iterator)
return nil
}
index, exists := col.Indexes[*options.Index]
if !exists {
return fmt.Errorf("index '%s' not found, available indexes %v", *options.Index, utils.GetKeys(col.Indexes))
}
index.Traverse(requestBody, iterator)
return nil
}
func traverseFullscan(col *collection.Collection, f func(row *collection.Row) bool) error {
for _, row := range col.Rows {
next := f(row)
if !next {
break
}
}
return nil
}