-
Notifications
You must be signed in to change notification settings - Fork 1
/
db.go
124 lines (101 loc) · 3.5 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
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 {
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
}