forked from mongodb/mongo-go-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
collectionopt.go
168 lines (140 loc) · 3.67 KB
/
collectionopt.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package collectionopt
import (
"reflect"
"github.com/mongodb/mongo-go-driver/core/readconcern"
"github.com/mongodb/mongo-go-driver/core/readpref"
"github.com/mongodb/mongo-go-driver/core/writeconcern"
)
var collectionBundle = new(CollectionBundle)
// Option represents a collection option.
type Option interface {
collectionOption()
}
// optionFunc adds the option to the client.
type optionFunc func(*Collection) error
// Collection represents a collection.
type Collection struct {
ReadConcern *readconcern.ReadConcern
WriteConcern *writeconcern.WriteConcern
ReadPreference *readpref.ReadPref
}
// CollectionBundle is a bundle of collection options.
type CollectionBundle struct {
option Option
next *CollectionBundle
}
// CollectionBundle implements Option.
func (*CollectionBundle) collectionOption() {}
// OptionFunc implements Option.
func (optionFunc) collectionOption() {}
// BundleCollection bundles collection options.
func BundleCollection(opts ...Option) *CollectionBundle {
head := collectionBundle
for _, opt := range opts {
newBundle := CollectionBundle{
option: opt,
next: head,
}
head = &newBundle
}
return head
}
// ReadConcern sets the read concern.
func (cb *CollectionBundle) ReadConcern(rc *readconcern.ReadConcern) *CollectionBundle {
return &CollectionBundle{
option: ReadConcern(rc),
next: cb,
}
}
// WriteConcern sets the write concern.
func (cb *CollectionBundle) WriteConcern(wc *writeconcern.WriteConcern) *CollectionBundle {
return &CollectionBundle{
option: WriteConcern(wc),
next: cb,
}
}
// ReadPreference sets the read preference.
func (cb *CollectionBundle) ReadPreference(rp *readpref.ReadPref) *CollectionBundle {
return &CollectionBundle{
option: ReadPreference(rp),
next: cb,
}
}
// String prints a string representation of the bundle for debug purposes
func (cb *CollectionBundle) String() string {
if cb == nil {
return ""
}
debugStr := ""
for head := cb; head != nil && head.option != nil; head = head.next {
switch opt := head.option.(type) {
case *CollectionBundle:
debugStr += opt.String()
case optionFunc:
debugStr += reflect.TypeOf(opt).String() + "\n"
default:
return debugStr + "(error: CollectionOption can only be *CollectionBundle or optionFunc)"
}
}
return debugStr
}
// Unbundle unbundles the options, returning a collection.
func (cb *CollectionBundle) Unbundle() (*Collection, error) {
client := &Collection{}
err := cb.unbundle(client)
if err != nil {
return nil, err
}
return client, nil
}
// Helper that recursively unwraps the bundle.
func (cb *CollectionBundle) unbundle(client *Collection) error {
if cb == nil {
return nil
}
for head := cb; head != nil && head.option != nil; head = head.next {
var err error
switch opt := head.option.(type) {
case *CollectionBundle:
err = opt.unbundle(client) // add all bundle's options to client
case optionFunc:
err = opt(client) // add option to client
default:
return nil
}
if err != nil {
return err
}
}
return nil
}
// ReadConcern sets the read concern.
func ReadConcern(rc *readconcern.ReadConcern) Option {
return optionFunc(
func(c *Collection) error {
if c.ReadConcern == nil {
c.ReadConcern = rc
}
return nil
})
}
// WriteConcern sets the write concern.
func WriteConcern(wc *writeconcern.WriteConcern) Option {
return optionFunc(
func(c *Collection) error {
if c.WriteConcern == nil {
c.WriteConcern = wc
}
return nil
})
}
// ReadPreference sets the read preference.
func ReadPreference(rp *readpref.ReadPref) Option {
return optionFunc(
func(c *Collection) error {
if c.ReadPreference == nil {
c.ReadPreference = rp
}
return nil
})
}