Move protection query to explicit function

v2
Nikita Tokarchuk 6 years ago
parent c9f3a59969
commit 58a342057d
  1. 9
      mongox/common/deleteone.go
  2. 14
      mongox/common/saveone.go
  3. 51
      mongox/query/compose.go

@ -26,14 +26,7 @@ func DeleteOne(db *mongox.Database, target interface{}, filters ...interface{})
} }
if protected != nil { if protected != nil {
if protected.X.IsZero() { query.Push(composed, protected)
composed.And(primitive.M{"_x": primitive.M{"$exists": false}})
composed.And(primitive.M{"_v": primitive.M{"$exists": false}})
} else {
composed.And(primitive.M{"_x": protected.X})
composed.And(primitive.M{"_v": protected.V})
}
protected.X = primitive.NewObjectID() protected.X = primitive.NewObjectID()
protected.V = time.Now().Unix() protected.V = time.Now().Unix()
} }

@ -4,6 +4,7 @@ import (
"github.com/mainnika/mongox-go-driver/mongox" "github.com/mainnika/mongox-go-driver/mongox"
"github.com/mainnika/mongox-go-driver/mongox/base" "github.com/mainnika/mongox-go-driver/mongox/base"
"github.com/mainnika/mongox-go-driver/mongox/errors" "github.com/mainnika/mongox-go-driver/mongox/errors"
"github.com/mainnika/mongox-go-driver/mongox/query"
"github.com/mongodb/mongo-go-driver/bson" "github.com/mongodb/mongo-go-driver/bson"
"github.com/mongodb/mongo-go-driver/bson/primitive" "github.com/mongodb/mongo-go-driver/bson/primitive"
"github.com/mongodb/mongo-go-driver/mongo/options" "github.com/mongodb/mongo-go-driver/mongo/options"
@ -17,25 +18,18 @@ func SaveOne(db *mongox.Database, source interface{}) error {
opts := options.FindOneAndReplace() opts := options.FindOneAndReplace()
id := base.GetID(source) id := base.GetID(source)
protected := base.GetProtection(source) protected := base.GetProtection(source)
filter := bson.M{"_id": id} composed := query.Compose(bson.M{"_id": id})
opts.SetUpsert(true) opts.SetUpsert(true)
opts.SetReturnDocument(options.After) opts.SetReturnDocument(options.After)
if protected != nil { if protected != nil {
if protected.X.IsZero() { query.Push(composed, protected)
filter["_x"] = primitive.M{"$exists": false}
filter["_v"] = primitive.M{"$exists": false}
} else {
filter["_x"] = protected.X
filter["_v"] = protected.V
}
protected.X = primitive.NewObjectID() protected.X = primitive.NewObjectID()
protected.V = time.Now().Unix() protected.V = time.Now().Unix()
} }
result := collection.FindOneAndReplace(db.Context(), filter, source, opts) result := collection.FindOneAndReplace(db.Context(), composed.M(), source, opts)
if result.Err() != nil { if result.Err() != nil {
return errors.NotFoundErrorf("%s", result.Err()) return errors.NotFoundErrorf("%s", result.Err())
} }

@ -1,8 +1,10 @@
package query package query
import ( import (
"github.com/mainnika/mongox-go-driver/mongox/base"
"github.com/mainnika/mongox-go-driver/mongox/errors" "github.com/mainnika/mongox-go-driver/mongox/errors"
"github.com/mongodb/mongo-go-driver/bson" "github.com/mongodb/mongo-go-driver/bson"
"github.com/mongodb/mongo-go-driver/bson/primitive"
) )
// ComposeQuery is a function to compose filters into a single query // ComposeQuery is a function to compose filters into a single query
@ -11,19 +13,25 @@ func Compose(filters ...interface{}) *Query {
q := &Query{} q := &Query{}
for _, f := range filters { for _, f := range filters {
if !Push(q, f) {
panic(errors.InternalErrorf("unknown filter %v", f))
}
}
return q
}
// Push applies single filter to a query
func Push(q *Query, f interface{}) bool {
ok := false ok := false
ok = ok || applyBson(q, f) ok = ok || applyBson(q, f)
ok = ok || applyLimit(q, f) ok = ok || applyLimit(q, f)
ok = ok || applySort(q, f) ok = ok || applySort(q, f)
ok = ok || applySkip(q, f) ok = ok || applySkip(q, f)
ok = ok || applyProtection(q, f)
if !ok { return ok
panic(errors.InternalErrorf("unknown filter %v", f))
}
}
return q
} }
// applyBson is a fallback for a custom bson.M // applyBson is a fallback for a custom bson.M
@ -69,3 +77,34 @@ func applySkip(q *Query, f interface{}) bool {
return false return false
} }
func applyProtection(q *Query, f interface{}) bool {
var x *primitive.ObjectID
var v *int64
switch f := f.(type) {
case base.Protection:
x = &f.X
v = &f.V
case *base.Protection:
if f == nil {
return false
}
x = &f.X
v = &f.V
default:
return false
}
if x.IsZero() {
q.And(primitive.M{"_x": primitive.M{"$exists": false}})
q.And(primitive.M{"_v": primitive.M{"$exists": false}})
} else {
q.And(primitive.M{"_x": *x})
q.And(primitive.M{"_v": *v})
}
return true
}

Loading…
Cancel
Save