-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.go
84 lines (65 loc) · 1.87 KB
/
service.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
package genericscrud
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
type MongoService[T any] struct {
db *mongo.Database
collectionName string
}
func (s *MongoService[T]) Find(ctx context.Context, id string) (*Model[T], error) {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, fmt.Errorf("invalid object id format: %w", err)
}
var m *Model[T]
if err := s.db.Collection(s.collectionName).FindOne(ctx, bson.M{"_id": objID}).Decode(&m); err != nil {
return nil, err
}
return m, nil
}
func (s *MongoService[T]) Create(ctx context.Context, create *T) (*Model[T], error) {
now := time.Now()
m := &Model[T]{
CreatedAt: now,
UpdatedAt: now,
Data: *create,
}
result, err := s.db.Collection(s.collectionName).InsertOne(ctx, m)
if err != nil {
return nil, err
}
m.ID = result.InsertedID.(primitive.ObjectID)
return m, nil
}
func (s *MongoService[T]) Update(ctx context.Context, id string, update *T) (*Model[T], error) {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, fmt.Errorf("invalid object id format: %w", err)
}
updateBSON := &updateBSON[*T]{Data: update, UpdatedAt: time.Now()}
_, err = s.db.Collection(s.collectionName).UpdateOne(ctx, bson.M{"_id": objID}, bson.M{"$set": updateBSON})
if err != nil {
return nil, err
}
return s.Find(ctx, id)
}
func (s *MongoService[T]) Delete(ctx context.Context, id string) error {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
return fmt.Errorf("invalid object id format: %w", err)
}
_, err = s.db.Collection(s.collectionName).DeleteOne(ctx, bson.M{"_id": objID})
if err != nil {
return err
}
return nil
}
type updateBSON[T any] struct {
Data T `bson:"inline"`
UpdatedAt time.Time `bson:"updated_at"`
}