-
Notifications
You must be signed in to change notification settings - Fork 1
/
db.go
128 lines (104 loc) · 3.61 KB
/
db.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
package wsHelpers
import (
"context"
"github.com/pixlise/core/v4/api/dbCollections"
"github.com/pixlise/core/v4/core/errorwithstatus"
"github.com/pixlise/core/v4/core/utils"
protos "github.com/pixlise/core/v4/generated-protos"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readconcern"
"go.mongodb.org/mongo-driver/mongo/writeconcern"
)
func DeleteUserObject[T any](objectId string, objectType protos.ObjectType, collectionName string, hctx HandlerContext) (*T, error) {
ctx := context.TODO()
_, err := CheckObjectAccess(true, objectId, objectType, hctx)
if err != nil {
return nil, err
}
// Delete element set AND corresponding ownership item
wc := writeconcern.New(writeconcern.WMajority())
rc := readconcern.Snapshot()
txnOpts := options.Transaction().SetWriteConcern(wc).SetReadConcern(rc)
sess, err := hctx.Svcs.MongoDB.Client().StartSession()
if err != nil {
return nil, err
}
defer sess.EndSession(ctx)
// Write the 2 items in a single transaction
callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
result, err := hctx.Svcs.MongoDB.Collection(collectionName).DeleteOne(context.TODO(), bson.M{"_id": objectId})
if err != nil {
return nil, errorwithstatus.MakeBadRequestError(err)
}
if result.DeletedCount != 1 {
return nil, errorwithstatus.MakeNotFoundError(objectId)
}
result, err = hctx.Svcs.MongoDB.Collection(dbCollections.OwnershipName).DeleteOne(context.TODO(), bson.M{"_id": objectId})
if err != nil {
return nil, errorwithstatus.MakeBadRequestError(err)
}
if result.DeletedCount != 1 {
return nil, errorwithstatus.MakeNotFoundError(objectId)
}
return nil, nil
}
_, err = sess.WithTransaction(ctx, callback, txnOpts)
if err != nil {
return nil, err
}
// Delete responses are just empty msgs
var resp T
return &resp, nil
}
func GetUserObjectById[T any](forEditing bool, objectId string, objectType protos.ObjectType, collectionName string, hctx HandlerContext) (*T, *protos.OwnershipItem, error) {
owner, err := CheckObjectAccess(forEditing, objectId, objectType, hctx)
if err != nil {
return nil, nil, err
}
result := hctx.Svcs.MongoDB.Collection(collectionName).FindOne(context.TODO(), bson.M{"_id": objectId})
if result.Err() != nil {
if result.Err() == mongo.ErrNoDocuments {
return nil, nil, errorwithstatus.MakeNotFoundError(objectId)
}
return nil, nil, result.Err()
}
var dbItem T
err = result.Decode(&dbItem)
return &dbItem, owner, err
}
func MakeFilter(
searchParams *protos.SearchParams,
requireEdit bool,
objectType protos.ObjectType,
hctx HandlerContext) (bson.M, map[string]*protos.OwnershipItem, error) {
// Firstly, get the list of ids that are accessible to this user, based on ownership
idToOwner, err := ListAccessibleIDs(false, objectType, hctx.Svcs, hctx.SessUser)
if err != nil {
return nil, idToOwner, err
}
if searchParams != nil && len(searchParams.CreatorUserId) > 0 {
// Filter any out which are not by the requested creator
for id, owner := range idToOwner {
if owner.CreatorUserId != searchParams.CreatorUserId {
delete(idToOwner, id)
}
}
}
ids := utils.GetMapKeys(idToOwner)
filter := bson.M{"_id": bson.M{"$in": ids}}
// Now apply any search params to it
if searchParams != nil {
if len(searchParams.ScanId) > 0 {
filter["scanid"] = searchParams.ScanId
}
if len(searchParams.NameSearch) > 0 {
filter["name"] = bson.M{"$regex": searchParams.NameSearch}
}
if len(searchParams.TagId) > 0 {
filter["tags"] = searchParams.TagId
}
}
return filter, idToOwner, nil
}