-
Notifications
You must be signed in to change notification settings - Fork 0
/
article_repository.go
126 lines (86 loc) · 3.02 KB
/
article_repository.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
package data
import (
"context"
"fmt"
"time"
"github.com/benk-techworld/www-backend/internal/db"
"github.com/benk-techworld/www-backend/internal/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type ArticleRepo struct {
storage *db.DB
}
func (ar ArticleRepo) Create(article *models.Article) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
res, err := ar.storage.Client.Database(ar.storage.Name).Collection("articles").InsertOne(ctx, article)
if err != nil {
return err
}
article.ID = res.InsertedID.(primitive.ObjectID)
return nil
}
func (ar ArticleRepo) GetByID(id primitive.ObjectID) (*models.Article, error) {
var article models.Article
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
filter := bson.M{"_id": id}
err := ar.storage.Client.Database(ar.storage.Name).Collection("articles").FindOne(ctx, filter).Decode(&article)
if err != nil {
return nil, err
}
return &article, nil
}
func (ar ArticleRepo) Delete(id primitive.ObjectID) (*mongo.DeleteResult, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
filter := bson.M{"_id": id}
res, err := ar.storage.Client.Database(ar.storage.Name).Collection("articles").DeleteOne(ctx, filter)
return res, err
}
func (ar ArticleRepo) Get(title string, tags []string, filters models.Filters) ([]models.Article, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
regexPattern := fmt.Sprintf(".*%s.*", title)
filter := bson.M{
"title": bson.M{"$regex": regexPattern, "$options": "i"},
}
if len(tags) > 0 {
filter["tags"] = bson.M{"$in": tags}
}
findOptions := options.Find()
findOptions.SetLimit(int64(filters.Limit()))
findOptions.SetSkip(int64(filters.Offset()))
findOptions.SetSort(bson.D{{Key: filters.SortField(), Value: filters.SortDirection()}})
cursor, err := ar.storage.Client.Database(ar.storage.Name).Collection("articles").Find(ctx, filter, findOptions)
if err != nil {
return nil, err
}
defer cursor.Close(context.Background())
articles := []models.Article{}
for cursor.Next(context.Background()) {
var article models.Article
err := cursor.Decode(&article)
if err != nil {
return nil, err
}
articles = append(articles, article)
}
if err := cursor.Err(); err != nil {
return nil, err
}
return articles, nil
}
func (ar ArticleRepo) Update(id primitive.ObjectID, updateDoc bson.M) *mongo.SingleResult {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
filter := bson.M{
"_id": id,
}
update := bson.M{"$set": updateDoc, "$currentDate": bson.M{"updated": true}, "$inc": bson.M{"version": 1}}
options := options.FindOneAndUpdate().SetReturnDocument(options.After)
return ar.storage.Client.Database(ar.storage.Name).Collection("articles").FindOneAndUpdate(ctx, filter, update, options)
}