forked from wshops/wgm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
300 lines (261 loc) · 7.35 KB
/
client.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
package wgm
import (
"context"
"errors"
"github.com/qiniu/qmgo"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
func (w *wgm) GetModelCollection(m IDefaultModel) *qmgo.Collection {
return w.client.Database(w.dbName).Collection(m.ColName())
}
func (w *wgm) GetCollection(name string) *qmgo.Collection {
return w.client.Database(w.dbName).Collection(name)
}
func (w *wgm) Ctx() context.Context {
return w.newCtx()
}
func Col(name string) *qmgo.Collection {
return instance.GetCollection(name)
}
func Ctx() context.Context {
return instance.Ctx()
}
// IsNoResult 是否结果不存在
// err 数据库查询后返回的 err
// bool 结果,true 为未查询到数据,反之亦然
func IsNoResult(err error) bool {
if errors.Is(err, mongo.ErrNoDocuments) || errors.Is(err, qmgo.ErrNoSuchDocuments) {
return true
}
return false
}
// FindPage 数据库分页查询
// m 查询的合集
// filter 查询条件,查询全部文档使用 nil,查询条件使用 bson.M
// res 结果集指针,必须为指向切片的指针!!!
// pageSize 页面大小
// currentPage 当前页面
// totalDoc 总数据数量
// totalPage 总页面数量
func FindPage(m IDefaultModel, filter any, res any, pageSize int64, currentPage int64) (totalDoc int64, totalPage int64) {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
if filter == nil {
filter = bson.D{}
}
countDoc, err := instance.GetModelCollection(m).Find(instance.Ctx(), filter).Count()
if IsNoResult(err) {
return 0, 0
}
if err != nil {
// Error: error
res = nil
return 0, 0
}
// 计算应该跳过的doc,
offset := (currentPage - 1) * pageSize
// 计算应该返回多少条记录
var size int64
if countDoc-offset < pageSize {
size = countDoc - offset
} else {
size = pageSize
}
if countDoc%pageSize == 0 {
totalPage = countDoc / pageSize
} else {
totalPage = 1 + countDoc/pageSize
}
err = instance.GetModelCollection(m).Find(instance.Ctx(), filter).Limit(size).Skip(offset).All(res)
if err != nil {
// Error: error
return 0, 0
}
// 判断总页数totalPage
return countDoc, totalPage
}
// FindPageWithOption 数据库多条件分页查询
// m 查询的合集
// filter 查询条件,查询全部文档使用 nil,查询条件使用 bson.M
// res 结果集指针,必须为指向切片的指针!!!
// pageSize 页面大小
// currentPage 当前页面
// totalDoc 总数据数量
// totalPage 总页面数量
func FindPageWithOption(m IDefaultModel, filter any, res any, pageSize int64, currentPage int64, option *FindPageOption) (totalDoc int64, totalPage int64) {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
if filter == nil {
filter = bson.D{}
}
countDoc, err := instance.GetModelCollection(m).Find(instance.Ctx(), filter).Count()
if IsNoResult(err) {
return 0, 0
}
if err != nil {
// Error: error
res = nil
return 0, 0
}
// 计算应该跳过的doc,
offset := (currentPage - 1) * pageSize
// 计算应该返回多少条记录
var size int64
if countDoc-offset < pageSize {
size = countDoc - offset
} else {
size = pageSize
}
if countDoc%pageSize == 0 {
totalPage = countDoc / pageSize
} else {
totalPage = 1 + countDoc/pageSize
}
err = instance.GetModelCollection(m).Find(instance.Ctx(), filter).
Select(option.selector).
Sort(option.fields...).
Limit(size).Skip(offset).All(res)
releaseFindPageOption(option)
if err != nil {
// Error: error
return 0, 0
}
// 判断总页数totalPage
return countDoc, totalPage
}
// FindOne 查询符合条件的第一条数据
// m 查询的合集,结果也会被绑定在这
// filter 查询条件,查询全部文档使用 nil,查询条件使用 bson.M
// hasResult 是否查询到结果
func FindOne(m IDefaultModel, filter map[string]any) (hasResult bool) {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
if filter == nil {
filter = bson.M{}
}
err := instance.GetModelCollection(m).Find(instance.Ctx(), filter).One(m)
if IsNoResult(err) {
return false
}
if err != nil {
// Error: error
return false
}
return true
}
func FindById(colName string, id string, res any) (bool, error) {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
err := instance.GetCollection(colName).Find(instance.Ctx(), bson.M{"_id": MustHexToObjectId(id)}).One(res)
if IsNoResult(err) {
return false, err
}
if err != nil {
// Error: error
return false, err
}
return true, nil
}
func MustHexToObjectId(strId string) primitive.ObjectID {
objId, err := primitive.ObjectIDFromHex(strId)
if err != nil {
// Error: error
return primitive.NilObjectID
}
return objId
}
func Insert(m IDefaultModel) (*qmgo.InsertOneResult, error) {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
result, err := instance.GetModelCollection(m).InsertOne(instance.Ctx(), m)
if err != nil {
return nil, err
}
return result, nil
}
func Update(m IDefaultModel, filter ...map[string]any) error {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
f := bson.M{}
if len(filter) > 0 {
f = filter[0]
f["_id"] = m.GetObjectID()
} else {
f["_id"] = m.GetObjectID()
}
m.setDefaultLastModifyTime()
err := instance.GetModelCollection(m).UpdateOne(instance.Ctx(), f, bson.M{"$set": m})
if err != nil {
return err
}
return nil
}
func Delete(m IDefaultModel) error {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
err := instance.GetModelCollection(m).RemoveId(instance.Ctx(), m.GetObjectID())
if err != nil {
return err
}
return nil
}
// ExistInDB 查询是否存在数据库
// m 查询的合集
// filter 查询条件,查询全部文档使用 nil,查询条件使用 bson.M
// bool 是否存在
func ExistInDB(m IDefaultModel, filter any) bool {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
if filter == nil {
filter = bson.D{}
}
err := instance.GetModelCollection(m).Find(instance.Ctx(), filter).One(nil)
if IsNoResult(err) {
return false
}
return true
}
// Distinct
// @param m: 查询合集
// @param filter: 查询前过滤doc
// @param field: 去重字段
// @param resultSlice: 查询结果,必须为指向数组的指针
// @Description: 去重查询,详情见 https://docs.mongodb.com/manual/reference/command/distinct/
func Distinct(m IDefaultModel, filter any, field string, result any) error {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
if filter == nil {
filter = bson.D{}
}
err := instance.GetModelCollection(m).Find(instance.Ctx(), filter).Distinct(field, result)
if err != nil {
return err
}
return nil
}
// Aggregate
// @param m: 查询合集
// @param pipeline: 聚合管道,必须为数组
// @param result: 查询结果,必须为指向数组的指针
// @Description: 聚合查询,详情见 https://www.mongodb.com/docs/manual/aggregation/
func Aggregate(m IDefaultModel, pipeline any, result any) error {
if instance == nil {
panic("must initialize WGM first, by calling NewWGM() method")
}
err := instance.GetModelCollection(m).Aggregate(instance.Ctx(), pipeline).All(result)
if err != nil {
return err
}
return nil
}