-
Notifications
You must be signed in to change notification settings - Fork 46
/
query.go
90 lines (79 loc) · 2.53 KB
/
query.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
90
package weave
import (
"fmt"
)
const (
// KeyQueryMod means to query for exact match (key)
KeyQueryMod = ""
// PrefixQueryMod means to query for anything with this prefix
PrefixQueryMod = "prefix"
// RangeQueryMod means to expect complex range query.
//
// Using query data, it is possible to declare start and end of a
// query. Each result is limited to certain amount of results.
// For bucket range query, data format is <start>[:<end>]
// For index queries, format is <start>[:<offset>[:<end>]]
// Start is inclusive, end is exclusive. All values must be hex
// encoded.
// See each implementation for more details.
RangeQueryMod = "range"
)
// Model groups together key and value to return
type Model struct {
Key []byte
Value []byte
}
// Pair constructs a model from a key-value pair
func Pair(key, value []byte) Model {
return Model{
Key: key,
Value: value,
}
}
// QueryHandler is anything that can process ABCI queries
type QueryHandler interface {
Query(db ReadOnlyKVStore, mod string, data []byte) ([]Model, error)
}
// QueryRegister is a function that adds some handlers
// to this router
type QueryRegister func(QueryRouter)
// QueryRouter allows us to register many query handlers
// to different paths and then direct each query
// to the proper handler.
//
// Minimal interface modeled after net/http.ServeMux
type QueryRouter struct {
routes map[string]QueryHandler
}
// NewQueryRouter initializes a QueryRouter with no routes
func NewQueryRouter() QueryRouter {
return QueryRouter{
routes: make(map[string]QueryHandler, 10),
}
}
// RegisterAll registers a number of QueryRegister at once
func (r QueryRouter) RegisterAll(qr ...QueryRegister) {
for _, q := range qr {
q(r)
}
}
// Register adds a new Handler for the given path. This function panics if a
// handler for given path is already registered.
//
// Path should be constructed using following rules:
// - always use plural form of the model name it represents (unless uncountable)
// - use only lower case characters, no numbers, no underscore, dash or any
// other special characters
// For example, path for the UserProfile model handler is "userprofiles".
func (r QueryRouter) Register(path string, h QueryHandler) {
if _, ok := r.routes[path]; ok {
panic(fmt.Sprintf("Re-registering route: %s", path))
}
r.routes[path] = h
}
// Handler returns the registered Handler for this path.
// If no path is found, returns a noSuchPath Handler
// Always returns a non-nil Handler
func (r QueryRouter) Handler(path string) QueryHandler {
return r.routes[path]
}