Skip to content
This repository was archived by the owner on Sep 2, 2024. It is now read-only.

Commit f300e3d

Browse files
committed
chore: update branch
2 parents 92327f0 + 4c0fab7 commit f300e3d

File tree

14 files changed

+510
-72
lines changed

14 files changed

+510
-72
lines changed

database/memory/base.go

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -82,43 +82,7 @@ func (m *Memory) QueryDocuments(auth internal.Auth, dbName, col string, filter m
8282

8383
list = secureRead(auth, col, list)
8484

85-
var filtered []map[string]any
86-
for _, doc := range list {
87-
matches := 0
88-
for k, v := range filter {
89-
op, field := extractOperatorAndValue(k)
90-
switch op {
91-
case "=":
92-
if equal(doc[field], v) {
93-
matches++
94-
}
95-
case "!=":
96-
if notEqual(doc[field], v) {
97-
matches++
98-
}
99-
case ">":
100-
if greater(doc[field], v) {
101-
matches++
102-
}
103-
case "<":
104-
if lower(doc[field], v) {
105-
matches++
106-
}
107-
case ">=":
108-
if greaterThanEqual(doc[field], v) {
109-
matches++
110-
}
111-
case "<=":
112-
if lowerThanEqual(doc[field], v) {
113-
matches++
114-
}
115-
}
116-
}
117-
118-
if matches == len(filter) {
119-
filtered = append(filtered, doc)
120-
}
121-
}
85+
filtered := filterByClauses(list, filter)
12286

12387
start := (params.Page - 1) * params.Size
12488
end := start + params.Size - 1
@@ -156,9 +120,7 @@ func (m *Memory) UpdateDocument(auth internal.Auth, dbName, col, id string, doc
156120
return
157121
}
158122

159-
delete(doc, FieldID)
160-
delete(doc, FieldAccountID)
161-
delete(doc, FieldOwnerID)
123+
removeNotEditableFields(doc)
162124

163125
for k, v := range doc {
164126
exists[k] = v
@@ -168,6 +130,28 @@ func (m *Memory) UpdateDocument(auth internal.Auth, dbName, col, id string, doc
168130
return
169131
}
170132

133+
func (m *Memory) UpdateDocuments(auth internal.Auth, dbName, col string, filter map[string]interface{}, updateFields map[string]interface{}) (n int64, err error) {
134+
list, err := all[map[string]any](m, dbName, col)
135+
136+
if err != nil {
137+
return
138+
}
139+
list = secureRead(auth, col, list)
140+
141+
removeNotEditableFields(updateFields)
142+
filtered := filterByClauses(list, filter)
143+
144+
for _, v := range filtered {
145+
_, err := m.UpdateDocument(auth, dbName, col, v[FieldID].(string), updateFields)
146+
if err != nil {
147+
return n, err
148+
}
149+
n++
150+
}
151+
152+
return
153+
}
154+
171155
func (m *Memory) IncrementValue(auth internal.Auth, dbName, col, id, field string, n int) error {
172156
doc, err := m.GetDocumentByID(auth, dbName, col, id)
173157
if err != nil {
@@ -239,6 +223,12 @@ func extractOperatorAndValue(s string) (op string, field string) {
239223
return
240224
}
241225

226+
func removeNotEditableFields(m map[string]any) {
227+
delete(m, FieldID)
228+
delete(m, FieldAccountID)
229+
delete(m, FieldOwnerID)
230+
}
231+
242232
func equal(v any, val any) bool {
243233
return fmt.Sprintf("%v", v) == fmt.Sprintf("%v", val)
244234
}

database/memory/base_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,46 @@ func TestUpdateDocument(t *testing.T) {
208208
}
209209
}
210210

211+
func TestUpdateDocuments(t *testing.T) {
212+
task1 := newTask("should be completed", false)
213+
task2 := newTask("should be completed", false)
214+
215+
var many []interface{}
216+
many = append(many, task1)
217+
many = append(many, task2)
218+
219+
if err := datastore.BulkCreateDocument(adminAuth, confDBName, colName, many); err != nil {
220+
t.Fatal(err)
221+
}
222+
var clauses [][]interface{}
223+
clauses = append(clauses, []interface{}{"title", "=", "should be completed"})
224+
225+
filters, err := datastore.ParseQuery(clauses)
226+
if err != nil {
227+
t.Fatal(err)
228+
}
229+
230+
updateFields := map[string]any{"done": true}
231+
n, err := datastore.UpdateDocuments(adminAuth, confDBName, colName, filters, updateFields)
232+
if err != nil {
233+
t.Errorf("The documents are not updated because of an error\nExpected err = nil\nActual err: %s", err.Error())
234+
}
235+
if n != int64(len(many)) {
236+
t.Errorf("The incorrect number of documents are updated\nExpected: %v\nActual: %v", len(many), n)
237+
}
238+
239+
docs, err := datastore.QueryDocuments(adminAuth, confDBName, colName, filters, internal.ListParams{Page: 1, Size: 5})
240+
if err != nil {
241+
t.Fatal(err)
242+
}
243+
for _, v := range docs.Results {
244+
got := dec(v)
245+
if !got.Done {
246+
t.Errorf("The '%s' task is not updated; It should be completed (done=true)", got.Title)
247+
}
248+
}
249+
}
250+
211251
func TestIncrementValue(t *testing.T) {
212252
task1 := newTask("incr", false)
213253
m, err := datastore.CreateDocument(adminAuth, confDBName, colName, task1)

database/memory/memory.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,46 @@ func filter[T any](list []T, fn func(x T) bool) []T {
132132
return results
133133
}
134134

135+
func filterByClauses(list []map[string]any, filter map[string]any) (filtered []map[string]any) {
136+
for _, doc := range list {
137+
matches := 0
138+
for k, v := range filter {
139+
op, field := extractOperatorAndValue(k)
140+
switch op {
141+
case "=":
142+
if equal(doc[field], v) {
143+
matches++
144+
}
145+
case "!=":
146+
if notEqual(doc[field], v) {
147+
matches++
148+
}
149+
case ">":
150+
if greater(doc[field], v) {
151+
matches++
152+
}
153+
case "<":
154+
if lower(doc[field], v) {
155+
matches++
156+
}
157+
case ">=":
158+
if greaterThanEqual(doc[field], v) {
159+
matches++
160+
}
161+
case "<=":
162+
if lowerThanEqual(doc[field], v) {
163+
matches++
164+
}
165+
}
166+
}
167+
168+
if matches == len(filter) {
169+
filtered = append(filtered, doc)
170+
}
171+
}
172+
return
173+
}
174+
135175
func sortSlice[T any](list []T, fn func(a, b T) bool) []T {
136176
sort.Slice(list, func(i, j int) bool {
137177
return fn(list[i], list[j])

database/mongo/base.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,7 @@ func (mg *Mongo) UpdateDocument(auth internal.Auth, dbName, col, id string, doc
327327
return nil, err
328328
}
329329

330-
delete(doc, "id")
331-
delete(doc, FieldID)
332-
delete(doc, FieldAccountID)
333-
delete(doc, FieldOwnerID)
330+
removeNotEditableFields(doc)
334331

335332
filter := bson.M{FieldID: oid}
336333

@@ -363,6 +360,31 @@ func (mg *Mongo) UpdateDocument(auth internal.Auth, dbName, col, id string, doc
363360
return result, nil
364361
}
365362

363+
func (mg *Mongo) UpdateDocuments(auth internal.Auth, dbName, col string, filters map[string]interface{}, updateFields map[string]interface{}) (n int64, err error) {
364+
db := mg.Client.Database(dbName)
365+
366+
acctID, userID, err := parseObjectID(auth)
367+
if err != nil {
368+
return 0, err
369+
}
370+
371+
secureWrite(acctID, userID, auth.Role, col, filters)
372+
removeNotEditableFields(updateFields)
373+
374+
newProps := bson.M{}
375+
for k, v := range updateFields {
376+
newProps[k] = v
377+
}
378+
379+
update := bson.M{"$set": newProps}
380+
381+
res, err := db.Collection(internal.CleanCollectionName(col)).UpdateMany(mg.Ctx, filters, update)
382+
if err != nil {
383+
return 0, err
384+
}
385+
return res.ModifiedCount, err
386+
}
387+
366388
func (mg *Mongo) IncrementValue(auth internal.Auth, dbName, col, id, field string, n int) error {
367389
db := mg.Client.Database(dbName)
368390

@@ -474,3 +496,10 @@ func cleanMap(m map[string]interface{}) {
474496

475497
delete(m, FieldOwnerID)
476498
}
499+
500+
func removeNotEditableFields(m map[string]any) {
501+
delete(m, "id")
502+
delete(m, FieldID)
503+
delete(m, FieldAccountID)
504+
delete(m, FieldOwnerID)
505+
}

database/mongo/base_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,46 @@ func TestUpdateDocument(t *testing.T) {
208208
}
209209
}
210210

211+
func TestUpdateDocuments(t *testing.T) {
212+
task1 := newTask("should be completed", false)
213+
task2 := newTask("should be completed", false)
214+
215+
var many []interface{}
216+
many = append(many, task1)
217+
many = append(many, task2)
218+
219+
if err := datastore.BulkCreateDocument(adminAuth, confDBName, colName, many); err != nil {
220+
t.Fatal(err)
221+
}
222+
var clauses [][]interface{}
223+
clauses = append(clauses, []interface{}{"title", "=", "should be completed"})
224+
225+
filters, err := datastore.ParseQuery(clauses)
226+
if err != nil {
227+
t.Fatal(err)
228+
}
229+
230+
updateFields := map[string]any{"done": true}
231+
n, err := datastore.UpdateDocuments(adminAuth, confDBName, colName, filters, updateFields)
232+
if err != nil {
233+
t.Errorf("The documents are not updated because of an error\nExpected err = nil\nActual err: %s", err.Error())
234+
}
235+
if n != int64(len(many)) {
236+
t.Errorf("The incorrect number of documents are updated\nExpected: %v\nActual: %v", len(many), n)
237+
}
238+
239+
docs, err := datastore.QueryDocuments(adminAuth, confDBName, colName, filters, internal.ListParams{Page: 1, Size: 5})
240+
if err != nil {
241+
t.Fatal(err)
242+
}
243+
for _, v := range docs.Results {
244+
got := dec(v)
245+
if !got.Done {
246+
t.Errorf("The '%s' task is not updated; It should be completed (done=true)", got.Title)
247+
}
248+
}
249+
}
250+
211251
func TestIncrementValue(t *testing.T) {
212252
task1 := newTask("incr", false)
213253
m, err := datastore.CreateDocument(adminAuth, confDBName, colName, task1)

database/postgresql/base.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,31 @@ func (pg *PostgreSQL) UpdateDocument(auth internal.Auth, dbName, col, id string,
249249
return updated, nil
250250
}
251251

252+
func (pg *PostgreSQL) UpdateDocuments(auth internal.Auth, dbName, col string, filters map[string]interface{}, updateFields map[string]interface{}) (n int64, err error) {
253+
where := secureWrite(auth, col)
254+
where = applyFilter(where, filters)
255+
256+
qry := fmt.Sprintf(`
257+
UPDATE %s.%s SET
258+
data = data || $3
259+
%s
260+
`, dbName, internal.CleanCollectionName(col), where)
261+
262+
b, err := json.Marshal(updateFields)
263+
if err != nil {
264+
return 0, err
265+
}
266+
res, err := pg.DB.Exec(qry, auth.AccountID, auth.UserID, b)
267+
if err != nil {
268+
return 0, err
269+
}
270+
n, err = res.RowsAffected()
271+
if err != nil {
272+
return 0, err
273+
}
274+
return
275+
}
276+
252277
func (pg *PostgreSQL) IncrementValue(auth internal.Auth, dbName, col, id, field string, n int) error {
253278
where := secureWrite(auth, col)
254279

database/postgresql/base_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,46 @@ func TestUpdateDocument(t *testing.T) {
208208
}
209209
}
210210

211+
func TestUpdateDocuments(t *testing.T) {
212+
task1 := newTask("should be completed", false)
213+
task2 := newTask("should be completed", false)
214+
215+
var many []interface{}
216+
many = append(many, task1)
217+
many = append(many, task2)
218+
219+
if err := datastore.BulkCreateDocument(adminAuth, confDBName, colName, many); err != nil {
220+
t.Fatal(err)
221+
}
222+
var clauses [][]interface{}
223+
clauses = append(clauses, []interface{}{"title", "=", "should be completed"})
224+
225+
filters, err := datastore.ParseQuery(clauses)
226+
if err != nil {
227+
t.Fatal(err)
228+
}
229+
230+
updateFields := map[string]any{"done": true}
231+
n, err := datastore.UpdateDocuments(adminAuth, confDBName, colName, filters, updateFields)
232+
if err != nil {
233+
t.Errorf("The documents are not updated because of an error\nExpected err = nil\nActual err: %s", err.Error())
234+
}
235+
if n != int64(len(many)) {
236+
t.Errorf("The incorrect number of documents are updated\nExpected: %v\nActual: %v", len(many), n)
237+
}
238+
239+
docs, err := datastore.QueryDocuments(adminAuth, confDBName, colName, filters, internal.ListParams{Page: 1, Size: 5})
240+
if err != nil {
241+
t.Fatal(err)
242+
}
243+
for _, v := range docs.Results {
244+
got := dec(v)
245+
if !got.Done {
246+
t.Errorf("The '%s' task is not updated; It should be completed (done=true)", got.Title)
247+
}
248+
}
249+
}
250+
211251
func TestIncrementValue(t *testing.T) {
212252
task1 := newTask("incr", false)
213253
m, err := datastore.CreateDocument(adminAuth, confDBName, colName, task1)

database/postgresql/query.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ func applyFilter(where string, filters map[string]interface{}) string {
5353
}
5454

5555
func secureRead(auth internal.Auth, col string) string {
56-
if strings.HasPrefix(col, "pub_") && auth.Role < 100 {
57-
return "WHERE 1=1 "
56+
if strings.HasPrefix(col, "pub_") || auth.Role == 100 {
57+
return "WHERE $1=$1 AND $2=$2 "
5858
}
5959

6060
switch internal.ReadPermission(col) {
@@ -69,8 +69,8 @@ func secureRead(auth internal.Auth, col string) string {
6969
}
7070

7171
func secureWrite(auth internal.Auth, col string) string {
72-
if strings.HasPrefix(col, "pub_") && auth.Role < 100 {
73-
return "WHERE 1=1 "
72+
if strings.HasPrefix(col, "pub_") || auth.Role == 100 {
73+
return "WHERE $1=$1 AND $2=$2 "
7474
}
7575

7676
switch internal.WritePermission(col) {

0 commit comments

Comments
 (0)