Now all query filters can validate themselves using Valider interface

v2
Nikita Tokarchuk 4 years ago
parent 15bb53694f
commit 84ae518fe9
No known key found for this signature in database
GPG Key ID: DBFD964471BAE65C
  1. 8
      mongox/database/count.go
  2. 10
      mongox/database/deletearray.go
  3. 8
      mongox/database/deleteone.go
  4. 6
      mongox/database/loadarray.go
  5. 6
      mongox/database/loadone.go
  6. 8
      mongox/database/loadstream.go
  7. 8
      mongox/database/saveone.go
  8. 8
      mongox/database/updateone.go
  9. 17
      mongox/query/compose.go
  10. 6
      mongox/query/validate.go

@ -10,11 +10,15 @@ import (
// target is used only to get collection by tag so it'd be better to use nil ptr here // target is used only to get collection by tag so it'd be better to use nil ptr here
func (d *Database) Count(target interface{}, filters ...interface{}) (result int64, err error) { func (d *Database) Count(target interface{}, filters ...interface{}) (result int64, err error) {
composed, err := query.Compose(filters...)
if err != nil {
return
}
collection := d.GetCollectionOf(target) collection := d.GetCollectionOf(target)
opts := options.Count()
composed := query.Compose(filters...)
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)
opts := options.Count()
opts.Limit = composed.Limiter() opts.Limit = composed.Limiter()
opts.Skip = composed.Skipper() opts.Skip = composed.Skipper()

@ -35,10 +35,14 @@ func (d *Database) DeleteArray(target interface{}, filters ...interface{}) (err
zeroElem := reflect.Zero(targetSliceElemT) zeroElem := reflect.Zero(targetSliceElemT)
targetLen := targetSliceV.Len() targetLen := targetSliceV.Len()
composed, err := query.Compose(filters...)
if err != nil {
return
}
collection := d.GetCollectionOf(zeroElem.Interface()) collection := d.GetCollectionOf(zeroElem.Interface())
opts := options.Delete()
ids := primitive.A{} ids := primitive.A{}
composed := query.Compose(filters...)
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)
for i := 0; i < targetLen; i++ { for i := 0; i < targetLen; i++ {
@ -61,7 +65,7 @@ func (d *Database) DeleteArray(target interface{}, filters ...interface{}) (err
composed.And(primitive.M{"_id": primitive.M{"$in": ids}}) composed.And(primitive.M{"_id": primitive.M{"$in": ids}})
result, err := collection.DeleteMany(ctx, composed.M(), opts) result, err := collection.DeleteMany(ctx, composed.M(), options.Delete())
if err != nil { if err != nil {
return return
} }

@ -15,12 +15,16 @@ import (
// DeleteOne removes a document from a database and then returns it into target // DeleteOne removes a document from a database and then returns it into target
func (d *Database) DeleteOne(target interface{}, filters ...interface{}) (err error) { func (d *Database) DeleteOne(target interface{}, filters ...interface{}) (err error) {
composed, err := query.Compose(filters...)
if err != nil {
return
}
collection := d.GetCollectionOf(target) collection := d.GetCollectionOf(target)
opts := &options.FindOneAndDeleteOptions{}
composed := query.Compose(filters...)
protected := base.GetProtection(target) protected := base.GetProtection(target)
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)
opts := options.FindOneAndDelete()
opts.Sort = composed.Sorter() opts.Sort = composed.Sorter()
if !reflect2.IsNil(target) { if !reflect2.IsNil(target) {

@ -31,7 +31,11 @@ func (d *Database) LoadArray(target interface{}, filters ...interface{}) (err er
panic(fmt.Errorf("target slice should contain ptrs")) panic(fmt.Errorf("target slice should contain ptrs"))
} }
composed := query.Compose(filters...) composed, err := query.Compose(filters...)
if err != nil {
return
}
zeroElem := reflect.Zero(targetSliceElemT) zeroElem := reflect.Zero(targetSliceElemT)
hasPreloader, _ := composed.Preloader() hasPreloader, _ := composed.Preloader()
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)

@ -11,7 +11,11 @@ import (
// LoadOne function loads a first single target document by a query // LoadOne function loads a first single target document by a query
func (d *Database) LoadOne(target interface{}, filters ...interface{}) (err error) { func (d *Database) LoadOne(target interface{}, filters ...interface{}) (err error) {
composed := query.Compose(append(filters, query.Limit(1))...) composed, err := query.Compose(append(filters, query.Limit(1))...)
if err != nil {
return
}
hasPreloader, _ := composed.Preloader() hasPreloader, _ := composed.Preloader()
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)

@ -10,12 +10,16 @@ import (
// LoadStream function loads documents one by one into a target channel // LoadStream function loads documents one by one into a target channel
func (d *Database) LoadStream(target interface{}, filters ...interface{}) (loader mongox.StreamLoader, err error) { func (d *Database) LoadStream(target interface{}, filters ...interface{}) (loader mongox.StreamLoader, err error) {
var cursor *mongox.Cursor composed, err := query.Compose(filters...)
if err != nil {
return
}
composed := query.Compose(filters...)
hasPreloader, _ := composed.Preloader() hasPreloader, _ := composed.Preloader()
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)
var cursor *mongox.Cursor
if hasPreloader { if hasPreloader {
cursor, err = d.createAggregateLoad(target, composed) cursor, err = d.createAggregateLoad(target, composed)
} else { } else {

@ -13,15 +13,19 @@ import (
// SaveOne saves a single source document to the database // SaveOne saves a single source document to the database
func (d *Database) SaveOne(source interface{}, filters ...interface{}) (err error) { func (d *Database) SaveOne(source interface{}, filters ...interface{}) (err error) {
composed, err := query.Compose(filters...)
if err != nil {
return
}
collection := d.GetCollectionOf(source) collection := d.GetCollectionOf(source)
opts := options.FindOneAndReplace()
id := base.GetID(source) id := base.GetID(source)
protected := base.GetProtection(source) protected := base.GetProtection(source)
composed := query.Compose(filters...)
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)
composed.And(primitive.M{"_id": id}) composed.And(primitive.M{"_id": id})
opts := options.FindOneAndReplace()
opts.SetUpsert(true) opts.SetUpsert(true)
opts.SetReturnDocument(options.After) opts.SetReturnDocument(options.After)

@ -13,13 +13,17 @@ import (
// UpdateOne updates a single document in the database and loads it into target // UpdateOne updates a single document in the database and loads it into target
func (d *Database) UpdateOne(target interface{}, filters ...interface{}) (err error) { func (d *Database) UpdateOne(target interface{}, filters ...interface{}) (err error) {
composed, err := query.Compose(filters...)
if err != nil {
return
}
collection := d.GetCollectionOf(target) collection := d.GetCollectionOf(target)
opts := options.FindOneAndUpdate()
protected := base.GetProtection(target) protected := base.GetProtection(target)
composed := query.Compose(filters...)
ctx := query.WithContext(d.Context(), composed) ctx := query.WithContext(d.Context(), composed)
updater := composed.Updater() updater := composed.Updater()
opts := options.FindOneAndUpdate()
opts.SetReturnDocument(options.After) opts.SetReturnDocument(options.After)
if protected != nil { if protected != nil {

@ -12,12 +12,16 @@ import (
type applyFilterFunc = func(query *Query, filter interface{}) (ok bool) type applyFilterFunc = func(query *Query, filter interface{}) (ok bool)
// Compose is a function to compose filters into a single query // Compose is a function to compose filters into a single query
func Compose(filters ...interface{}) (query *Query) { func Compose(filters ...interface{}) (query *Query, err error) {
query = &Query{} query = &Query{}
for _, filter := range filters { for _, filter := range filters {
if !Push(query, filter) { ok, err := Push(query, filter)
if err != nil {
return nil, fmt.Errorf("invalid filter %v, %w", filter, err)
}
if !ok {
panic(fmt.Errorf("unknown filter %v", filter)) panic(fmt.Errorf("unknown filter %v", filter))
} }
} }
@ -26,12 +30,19 @@ func Compose(filters ...interface{}) (query *Query) {
} }
// Push applies single filter to a query // Push applies single filter to a query
func Push(query *Query, filter interface{}) (ok bool) { func Push(query *Query, filter interface{}) (ok bool, err error) {
ok = reflect2.IsNil(filter) ok = reflect2.IsNil(filter)
if ok { if ok {
return return
} }
valider, hasValider := filter.(Valider)
if hasValider {
err = valider.Valid()
}
if err != nil {
return
} }
for _, applier := range []applyFilterFunc{ for _, applier := range []applyFilterFunc{

@ -0,0 +1,6 @@
package query
// Valider is a filter to validate the filter
type Valider interface {
Valid() (err error)
}
Loading…
Cancel
Save