...
1
2
3
4
5
6
7
8
9
10
11
12
13 package kivik
14
15 import (
16 "fmt"
17 "net/url"
18 "strconv"
19 "strings"
20 "time"
21
22 "github.com/go-kivik/kivik/v4/driver"
23 )
24
25
26
27
28
29
30
31 type Option interface {
32
33
34 Apply(target interface{})
35 }
36
37 var _ Option = (driver.Options)(nil)
38
39 type multiOptions []Option
40
41 var _ Option = (multiOptions)(nil)
42
43 func (o multiOptions) Apply(t interface{}) {
44 for _, opt := range o {
45 if opt != nil {
46 opt.Apply(t)
47 }
48 }
49 }
50
51 func (o multiOptions) String() string {
52 parts := make([]string, 0, len(o))
53 for _, opt := range o {
54 if o != nil {
55 if part := fmt.Sprintf("%s", opt); part != "" {
56 parts = append(parts, part)
57 }
58 }
59 }
60 return strings.Join(parts, ",")
61 }
62
63 type params map[string]interface{}
64
65
66
67
68
69 func (o params) Apply(target interface{}) {
70 switch t := target.(type) {
71 case map[string]interface{}:
72 for k, v := range o {
73 t[k] = v
74 }
75 case *url.Values:
76 for key, i := range o {
77 var values []string
78 switch v := i.(type) {
79 case string:
80 values = []string{v}
81 case []string:
82 values = v
83 case bool:
84 values = []string{fmt.Sprintf("%t", v)}
85 case int, uint, uint8, uint16, uint32, uint64, int8, int16, int32, int64:
86 values = []string{fmt.Sprintf("%d", v)}
87 case float64:
88 values = []string{strconv.FormatFloat(v, 'f', -1, 64)}
89 case float32:
90 values = []string{strconv.FormatFloat(float64(v), 'f', -1, 32)}
91 default:
92 panic(fmt.Sprintf("kivik: unknown option type: %T", v))
93 }
94 for _, value := range values {
95 t.Add(key, value)
96 }
97 }
98 }
99 }
100
101 func (o params) String() string {
102 if len(o) == 0 {
103 return ""
104 }
105 return fmt.Sprintf("%v", map[string]interface{}(o))
106 }
107
108
109
110 func Params(p map[string]interface{}) Option {
111 return params(p)
112 }
113
114
115 func Param(key string, value interface{}) Option {
116 return params{key: value}
117 }
118
119
120
121 func Rev(rev string) Option {
122 return params{"rev": rev}
123 }
124
125
126
127 func IncludeDocs() Option {
128 return params{"include_docs": true}
129 }
130
131 type durationParam struct {
132 key string
133 value time.Duration
134 }
135
136 var _ Option = durationParam{}
137
138
139 func (p durationParam) Apply(target interface{}) {
140 switch t := target.(type) {
141 case map[string]interface{}:
142 t[p.key] = fmt.Sprintf("%d", p.value/time.Millisecond)
143 case *url.Values:
144 t.Add(p.key, fmt.Sprintf("%d", p.value/time.Millisecond))
145 }
146 }
147
148 func (p durationParam) String() string {
149 return fmt.Sprintf("[%s=%s]", p.key, p.value)
150 }
151
152
153
154
155
156
157
158 func Duration(key string, dur time.Duration) Option {
159 return durationParam{
160 key: key,
161 value: dur,
162 }
163 }
164
View as plain text