/
dao.go
139 lines (113 loc) · 3.6 KB
/
dao.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
package impl
import (
"context"
"fmt"
"github.com/staryjie/keyauth/apps/book"
"github.com/infraboard/mcube/exception"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func (s *service) save(ctx context.Context, ins *book.Book) error {
if _, err := s.col.InsertOne(ctx, ins); err != nil {
return exception.NewInternalServerError("inserted book(%s) document error, %s",
ins.Data.Name, err)
}
return nil
}
// GET, Describe
// filter 过滤器(Collection),类似于MySQL中的WHERE条件 filter({ k = v })
// 调用Decode方法进行反序列化,将 bytes --> Object (通过BSON TAG进行转换)
func (s *service) get(ctx context.Context, id string) (*book.Book, error) {
filter := bson.M{"_id": id}
ins := book.NewDefaultBook()
if err := s.col.FindOne(ctx, filter).Decode(ins); err != nil {
if err == mongo.ErrNoDocuments {
return nil, exception.NewNotFound("book %s not found", id)
}
return nil, exception.NewInternalServerError("find book %s error, %s", id, err)
}
return ins, nil
}
func newQueryBookRequest(r *book.QueryBookRequest) *queryBookRequest {
return &queryBookRequest{
r,
}
}
// 把QueryReq转换成MongoDB中的过滤条件
type queryBookRequest struct {
*book.QueryBookRequest
}
// Find参数构建
func (r *queryBookRequest) FindOptions() *options.FindOptions {
pageSize := int64(r.Page.PageSize)
skip := int64(r.Page.PageSize) * int64(r.Page.PageNumber-1)
opt := &options.FindOptions{
// 排序
Sort: bson.D{
{Key: "create_at", Value: -1},
},
// 分页
Limit: &pageSize,
Skip: &skip,
}
return opt
}
// 过滤条件构建
// 由于MongoDB支持嵌套,类似于JSON,如何过滤嵌套里面的条件,使用.访问嵌套对象属性
func (r *queryBookRequest) FindFilter() bson.M {
filter := bson.M{}
if r.Keywords != "" {
filter["$or"] = bson.A{
bson.M{"data.name": bson.M{"$regex": r.Keywords, "$options": "im"}},
bson.M{"data.author": bson.M{"$regex": r.Keywords, "$options": "im"}},
}
}
return filter
}
// LIST, Query, 一般都会有很多条件(分页,关键字,条件过滤,排序 ...)
// 需要单独做一个过滤参数构建
func (s *service) query(ctx context.Context, req *queryBookRequest) (*book.BookSet, error) {
resp, err := s.col.Find(ctx, req.FindFilter(), req.FindOptions())
if err != nil {
return nil, exception.NewInternalServerError("find book error, error is %s", err)
}
set := book.NewBookSet()
// 循环
for resp.Next(ctx) {
ins := book.NewDefaultBook()
if err := resp.Decode(ins); err != nil {
return nil, exception.NewInternalServerError("decode book error, error is %s", err)
}
set.Add(ins)
}
// count
count, err := s.col.CountDocuments(ctx, req.FindFilter())
if err != nil {
return nil, exception.NewInternalServerError("get book count error, error is %s", err)
}
set.Total = count
return set, nil
}
// UpdateByID,通过主键更新一个对象
func (s *service) update(ctx context.Context, ins *book.Book) error {
if _, err := s.col.UpdateByID(ctx, ins.Id, ins); err != nil {
return exception.NewInternalServerError("inserted book(%s) document error, %s",
ins.Data.Name, err)
}
return nil
}
// 删除操作
func (s *service) deleteBook(ctx context.Context, ins *book.Book) error {
if ins == nil || ins.Id == "" {
return fmt.Errorf("book is nil")
}
result, err := s.col.DeleteOne(ctx, bson.M{"_id": ins.Id})
if err != nil {
return exception.NewInternalServerError("delete book(%s) error, %s", ins.Id, err)
}
if result.DeletedCount == 0 {
return exception.NewNotFound("book %s not found", ins.Id)
}
return nil
}