310 lines
6.9 KiB
Go
310 lines
6.9 KiB
Go
|
package mdbc
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"gitter.top/common/goref"
|
||
|
"go.mongodb.org/mongo-driver/bson"
|
||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||
|
)
|
||
|
|
||
|
type findScope struct {
|
||
|
*scope
|
||
|
*mdbc
|
||
|
ctx context.Context
|
||
|
opts any
|
||
|
limit *int64
|
||
|
skip *int64
|
||
|
upsert *bool
|
||
|
sort bson.D
|
||
|
filter any
|
||
|
selects any
|
||
|
doc any
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetContext(ctx context.Context) *findScope {
|
||
|
fs.ctx = ctx
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetFindOptions(opts options.FindOptions) *findScope {
|
||
|
fs.opts = &opts
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetFindOneOptions(opts options.FindOneOptions) *findScope {
|
||
|
fs.opts = &opts
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetFindOneAndDeleteOptions(opts options.FindOneAndDeleteOptions) *findScope {
|
||
|
fs.opts = &opts
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetFindOneAndUpdateOptions(opts options.FindOneAndUpdateOptions) *findScope {
|
||
|
fs.opts = &opts
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetFindOneAndReplaceOptions(opts options.FindOneAndReplaceOptions) *findScope {
|
||
|
fs.opts = &opts
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetLimit(limit int64) *findScope {
|
||
|
fs.limit = &limit
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetSkip(skip int64) *findScope {
|
||
|
fs.skip = &skip
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetUpsert(upsert bool) *findScope {
|
||
|
fs.upsert = &upsert
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
// SetSelects select field, such as: {key: 1, key: 0}
|
||
|
// 1: display 0: hidden
|
||
|
func (fs *findScope) SetSelects(selects any) *findScope {
|
||
|
if !goref.IsBaseMap(selects) {
|
||
|
return fs
|
||
|
}
|
||
|
fs.selects = selects
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) SetSort(sort bson.D) *findScope {
|
||
|
fs.sort = sort
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) findMergeOptions() {
|
||
|
if fs.ctx == nil {
|
||
|
fs.ctx = context.Background()
|
||
|
}
|
||
|
if fs.filter == nil {
|
||
|
fs.filter = bson.M{}
|
||
|
}
|
||
|
if fs.opts == nil {
|
||
|
fs.opts = new(options.FindOptions)
|
||
|
}
|
||
|
opts := fs.opts.(*options.FindOptions)
|
||
|
if fs.limit != nil {
|
||
|
opts.Limit = fs.limit
|
||
|
}
|
||
|
if fs.skip == nil {
|
||
|
opts.Skip = fs.skip
|
||
|
}
|
||
|
if fs.sort != nil {
|
||
|
opts.Sort = fs.sort
|
||
|
}
|
||
|
if fs.selects != nil {
|
||
|
opts.Projection = fs.selects
|
||
|
}
|
||
|
fs.opts = opts
|
||
|
}
|
||
|
|
||
|
// GetList get record list, list type is *[]*struct
|
||
|
func (fs *findScope) GetList(list any) error {
|
||
|
if !goref.IsBaseList(list) {
|
||
|
return fmt.Errorf("invalid list type, must be *[]*struct")
|
||
|
}
|
||
|
fs.findMergeOptions()
|
||
|
cursor, err := fs.database.Collection(fs.tableName).Find(fs.ctx, fs.filter, fs.opts.(*options.FindOptions))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
err = cursor.All(fs.ctx, list)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// GetMap get record map, m type is *map[string]*struct, field is struct field
|
||
|
func (fs *findScope) GetMap(m any, field string) error {
|
||
|
if !goref.IsBaseMap(m) {
|
||
|
return fmt.Errorf("invalid m type, must be based on map")
|
||
|
}
|
||
|
fs.findMergeOptions()
|
||
|
cursor, err := fs.database.Collection(fs.tableName).Find(fs.ctx, fs.filter, fs.opts.(*options.FindOptions))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
list := goref.BuildSlice(fs.modelKind)
|
||
|
err = cursor.All(fs.ctx, list)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if err := goref.SliceStructToMap(list, m, field); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) findOneMergeOptions() {
|
||
|
if fs.ctx == nil {
|
||
|
fs.ctx = context.Background()
|
||
|
}
|
||
|
if fs.filter == nil {
|
||
|
fs.filter = bson.M{}
|
||
|
}
|
||
|
if fs.opts == nil {
|
||
|
fs.opts = new(options.FindOneOptions)
|
||
|
}
|
||
|
opts := fs.opts.(*options.FindOneOptions)
|
||
|
if fs.skip == nil {
|
||
|
opts.Skip = fs.skip
|
||
|
}
|
||
|
if fs.sort != nil {
|
||
|
opts.Sort = fs.sort
|
||
|
}
|
||
|
if fs.selects != nil {
|
||
|
opts.Projection = fs.selects
|
||
|
}
|
||
|
fs.opts = opts
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) FindOne(doc any) error {
|
||
|
if !goref.IsBaseStruct(doc) {
|
||
|
return fmt.Errorf("invalid doc type, must be *struct")
|
||
|
}
|
||
|
fs.findOneMergeOptions()
|
||
|
result := fs.database.Collection(fs.tableName).FindOne(fs.ctx, fs.filter, fs.opts.(*options.FindOneOptions))
|
||
|
if result.Err() != nil {
|
||
|
return result.Err()
|
||
|
}
|
||
|
if err := result.Decode(doc); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) findOneAndDeleteMergeOptions() {
|
||
|
if fs.ctx == nil {
|
||
|
fs.ctx = context.Background()
|
||
|
}
|
||
|
if fs.filter == nil {
|
||
|
fs.filter = bson.M{}
|
||
|
}
|
||
|
if fs.opts == nil {
|
||
|
fs.opts = new(options.FindOneAndDeleteOptions)
|
||
|
}
|
||
|
opts := fs.opts.(*options.FindOneAndDeleteOptions)
|
||
|
if fs.sort != nil {
|
||
|
opts.Sort = fs.sort
|
||
|
}
|
||
|
if fs.selects != nil {
|
||
|
opts.Projection = fs.selects
|
||
|
}
|
||
|
fs.opts = opts
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) FindOneAndDelete() error {
|
||
|
fs.findOneAndDeleteMergeOptions()
|
||
|
result := fs.database.Collection(fs.tableName).FindOneAndDelete(fs.ctx, fs.filter, fs.opts.(*options.FindOneAndDeleteOptions))
|
||
|
if result.Err() != nil {
|
||
|
return result.Err()
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) FindOneAndDeleteWithValue(doc any) error {
|
||
|
if !goref.IsBaseStruct(doc) {
|
||
|
return fmt.Errorf("invalid doc type, must be *struct")
|
||
|
}
|
||
|
fs.findOneAndDeleteMergeOptions()
|
||
|
result := fs.database.Collection(fs.tableName).FindOneAndDelete(fs.ctx, fs.filter, fs.opts.(*options.FindOneAndDeleteOptions))
|
||
|
if result.Err() != nil {
|
||
|
return result.Err()
|
||
|
}
|
||
|
if err := result.Decode(doc); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) findOneAndUpdateMergeOptions() {
|
||
|
if fs.ctx == nil {
|
||
|
fs.ctx = context.Background()
|
||
|
}
|
||
|
if fs.filter == nil {
|
||
|
fs.filter = bson.M{}
|
||
|
}
|
||
|
if fs.opts == nil {
|
||
|
fs.opts = new(options.FindOneAndUpdateOptions)
|
||
|
}
|
||
|
opts := fs.opts.(*options.FindOneAndUpdateOptions)
|
||
|
if fs.sort != nil {
|
||
|
opts.Sort = fs.sort
|
||
|
}
|
||
|
if fs.upsert != nil {
|
||
|
opts.Upsert = fs.upsert
|
||
|
}
|
||
|
if fs.selects != nil {
|
||
|
opts.Projection = fs.selects
|
||
|
}
|
||
|
fs.opts = opts
|
||
|
if goref.IsBaseStruct(fs.doc) {
|
||
|
fs.doc = bson.M{"$set": fs.doc}
|
||
|
}
|
||
|
if goref.IsBaseMap(fs.doc) && !goref.ExistMapKey(fs.doc, "$set") {
|
||
|
fs.doc = bson.M{"$set": fs.doc}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// FindOneAndUpdate find one and update, doc type *struct or map
|
||
|
func (fs *findScope) FindOneAndUpdate(doc any) error {
|
||
|
fs.doc = doc
|
||
|
fs.findOneAndUpdateMergeOptions()
|
||
|
result := fs.database.Collection(fs.tableName).FindOneAndUpdate(fs.ctx, fs.filter, fs.doc, fs.opts.(*options.FindOneAndUpdateOptions))
|
||
|
if result.Err() != nil {
|
||
|
return result.Err()
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (fs *findScope) findOneAndReplaceMergeOptions() {
|
||
|
if fs.ctx == nil {
|
||
|
fs.ctx = context.Background()
|
||
|
}
|
||
|
if fs.filter == nil {
|
||
|
fs.filter = bson.M{}
|
||
|
}
|
||
|
if fs.opts == nil {
|
||
|
fs.opts = new(options.FindOneAndReplaceOptions)
|
||
|
}
|
||
|
opts := fs.opts.(*options.FindOneAndReplaceOptions)
|
||
|
if fs.sort != nil {
|
||
|
opts.Sort = fs.sort
|
||
|
}
|
||
|
if fs.upsert != nil {
|
||
|
opts.Upsert = fs.upsert
|
||
|
}
|
||
|
if fs.selects != nil {
|
||
|
opts.Projection = fs.selects
|
||
|
}
|
||
|
fs.opts = opts
|
||
|
if goref.IsBaseStruct(fs.doc) {
|
||
|
fs.doc = bson.M{"$set": fs.doc}
|
||
|
}
|
||
|
if goref.IsBaseMap(fs.doc) && !goref.ExistMapKey(fs.doc, "$set") {
|
||
|
fs.doc = bson.M{"$set": fs.doc}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// FindOneAndReplace find one and replace, doc type *struct or map
|
||
|
func (fs *findScope) FindOneAndReplace(doc any) error {
|
||
|
fs.doc = doc
|
||
|
fs.findOneAndReplaceMergeOptions()
|
||
|
result := fs.database.Collection(fs.tableName).FindOneAndReplace(fs.ctx, fs.filter, fs.doc, fs.opts.(*options.FindOneAndReplaceOptions))
|
||
|
if result.Err() != nil {
|
||
|
return result.Err()
|
||
|
}
|
||
|
return nil
|
||
|
}
|