-
Notifications
You must be signed in to change notification settings - Fork 211
/
builder.go
92 lines (76 loc) · 1.73 KB
/
builder.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
91
92
package builder
import (
"fmt"
"strconv"
"strings"
"github.com/spacemeshos/go-spacemesh/sql"
)
type token string
const (
Eq token = "="
NotEq token = "!="
Gt token = ">"
Gte token = ">="
Lt token = "<"
Lte token = "<="
)
type field string
const (
Epoch field = "epoch"
Smesher field = "pubkey"
Coinbase field = "coinbase"
Id field = "id"
Layer field = "layer"
)
type modifier string
const (
Offset modifier = "offset"
Limit modifier = "limit"
OrderBy modifier = "order by"
)
type Op struct {
Field field
Token token
// Value will be type casted to one the expected types.
// Operation will panic if it doesn't match any of expected.
Value any
}
type Modifier struct {
Key modifier
// Value will be type casted to one the expected types.
// Modifier will panic if it doesn't match any of expected.
Value any
}
type Operations struct {
Filter []Op
Modifiers []Modifier
}
func FilterFrom(operations Operations) string {
var queryBuilder strings.Builder
for i, op := range operations.Filter {
if i == 0 {
queryBuilder.WriteString(" where")
} else {
queryBuilder.WriteString(" and")
}
queryBuilder.WriteString(" " + string(op.Field) + " " + string(op.Token) + " ?" + strconv.Itoa(i+1))
}
for _, m := range operations.Modifiers {
queryBuilder.WriteString(fmt.Sprintf(" %s %v", string(m.Key), m.Value))
}
return queryBuilder.String()
}
func BindingsFrom(operations Operations) sql.Encoder {
return func(stmt *sql.Statement) {
for i, op := range operations.Filter {
switch value := op.Value.(type) {
case int64:
stmt.BindInt64(i+1, value)
case []byte:
stmt.BindBytes(i+1, value)
default:
panic(fmt.Sprintf("unexpected type %T", value))
}
}
}
}