You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mongox-go-driver/mongox/common/loadarray.go

74 lines
1.8 KiB

6 years ago
package common
import (
"reflect"
"github.com/mainnika/mongox-go-driver/mongox"
"github.com/mainnika/mongox-go-driver/mongox/errors"
"github.com/mainnika/mongox-go-driver/mongox/query"
"github.com/mongodb/mongo-go-driver/mongo/options"
)
// LoadArray loads an array of documents from the database by query
func LoadArray(db *mongox.Database, target interface{}, composed *query.Query) error {
targetV := reflect.ValueOf(target)
targetT := targetV.Type()
targetK := targetV.Kind()
if targetK != reflect.Ptr {
panic(errors.InternalErrorf("target is not a ptr"))
}
targetSliceV := targetV.Elem()
targetSliceT := targetT.Elem()
if targetSliceT.Kind() != reflect.Slice {
panic(errors.InternalErrorf("target should be a ptr to a slice"))
}
targetSliceElemT := targetSliceT.Elem()
if targetSliceElemT.Kind() != reflect.Ptr {
panic(errors.InternalErrorf("target slice should contain ptrs"))
}
dummy := reflect.Zero(targetSliceElemT)
collection := db.GetCollectionOf(dummy.Interface())
opts := &options.FindOptions{}
if composed.Sorter() != nil {
opts.Sort = composed.Sorter().Sort()
}
if composed.Limiter() != nil {
limit := int64(composed.Limiter().Limit())
opts.Limit = &limit
}
result, err := collection.Find(db.Context(), composed.M(), opts)
if err != nil {
return errors.InternalErrorf("can't create find result: %s", err)
}
defer result.Close(db.Context())
var i int
for i = 0; result.Next(db.Context()); i++ {
if targetSliceV.Len() == i {
elem := reflect.New(targetSliceElemT.Elem())
if result.Decode(elem.Interface()) != nil {
continue
}
targetSliceV = reflect.Append(targetSliceV, elem)
// currentv = currentv.Slice(0, currentv.Cap())
continue
}
result.Decode(targetSliceV.Index(i).Interface())
}
targetSliceV = targetSliceV.Slice(0, i)
targetV.Elem().Set(targetSliceV)
return nil
}