feat: update and find action

This commit is contained in:
xuthus5 2023-06-23 23:09:36 +08:00
parent e7038a44e9
commit bf11ba6f68
Signed by: xuthus5
GPG Key ID: A23CF9620CBB55F9
7 changed files with 557 additions and 16 deletions

105
delete.go Normal file
View File

@ -0,0 +1,105 @@
package mdbc
import (
"context"
"gitter.top/common/goref"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type deleteScope struct {
*scope
*mdbc
ctx context.Context
opts *options.DeleteOptions
filter interface{}
err error
}
func (ds *deleteScope) SetContext(ctx context.Context) *deleteScope {
ds.ctx = ctx
return ds
}
func (ds *deleteScope) SetOptions(opts options.DeleteOptions) *deleteScope {
ds.opts = &opts
return ds
}
// SetID delete documents based on ID, has the highest priority.
func (ds *deleteScope) SetID(id ...string) *deleteScope {
if len(id) == 0 {
return ds
}
if len(id) == 1 {
ds.filter = bson.M{
"_id": id,
}
}
if len(id) > 1 {
ds.filter = bson.M{
"_id": bson.M{"$in": id},
}
}
return ds
}
// SetFilter delete documents based on filter condition, filter type only support map or struct
func (ds *deleteScope) SetFilter(filter interface{}) *deleteScope {
if ds.filter != nil {
return ds
}
if filter == nil {
ds.filter = bson.M{}
return ds
}
if goref.IsBaseStruct(filter) {
ds.filter, ds.err = goref.StructToMap(filter, goref.WithOmitempty(true), goref.WithTag("bson"))
return ds
}
if goref.IsBaseMap(filter) {
ds.filter = filter
return ds
}
return ds
}
func (ds *deleteScope) mergeOptins() {
if ds.ctx == nil {
ds.ctx = context.Background()
}
if ds.opts == nil {
ds.opts = new(options.DeleteOptions)
}
if ds.filter == nil {
ds.filter = bson.M{}
}
}
func (ds *deleteScope) One() (int64, error) {
ds.mergeOptins()
if ds.err != nil {
return 0, ds.err
}
result, err := ds.database.Collection(ds.tableName).DeleteOne(ds.ctx, ds.filter, ds.opts)
if err != nil {
return 0, err
}
return result.DeletedCount, nil
}
func (ds *deleteScope) Many() (int64, error) {
ds.mergeOptins()
if ds.err != nil {
return 0, ds.err
}
result, err := ds.database.Collection(ds.tableName).DeleteMany(ds.ctx, ds.filter, ds.opts)
if err != nil {
return 0, err
}
return result.DeletedCount, nil
}

309
find.go Normal file
View File

@ -0,0 +1,309 @@
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
}

4
go.mod
View File

@ -4,9 +4,9 @@ go 1.20
require (
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.8.4
gitter.top/coco/lormatter v0.0.0-20230409145644-f9cb43f740dc
gitter.top/common/goref v0.0.0-20230622151024-9b220e13c7cd
gitter.top/common/goref v0.0.0-20230623144827-8cd99d7ed68f
go.mongodb.org/mongo-driver v1.11.7
google.golang.org/protobuf v1.30.0
)

11
go.sum
View File

@ -27,9 +27,12 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@ -44,6 +47,14 @@ gitter.top/coco/lormatter v0.0.0-20230409145644-f9cb43f740dc h1:B0bnfX8Y/dETV+zd
gitter.top/coco/lormatter v0.0.0-20230409145644-f9cb43f740dc/go.mod h1:vyfU6MQ56tkoFKSzEzhYSwXjgZHMcu3AViHC3hIyO7I=
gitter.top/common/goref v0.0.0-20230622151024-9b220e13c7cd h1:EeOtSwGexcx0u1AE91wnemiOGedENxaKcJUXxpzcgiE=
gitter.top/common/goref v0.0.0-20230622151024-9b220e13c7cd/go.mod h1:oK6jZQ/ISS8gZ78rvww6p7FuLUzaJ+S5F5UXSqO7Lr0=
gitter.top/common/goref v0.0.0-20230623104541-a0005020066e h1:y56ZGlp2Pz+pia3gEeRAgrRoCOoiecxg0RtoaCEj7bY=
gitter.top/common/goref v0.0.0-20230623104541-a0005020066e/go.mod h1:oK6jZQ/ISS8gZ78rvww6p7FuLUzaJ+S5F5UXSqO7Lr0=
gitter.top/common/goref v0.0.0-20230623122346-fa52c8a5753e h1:er7LiuFgv7+vFGdJosiHLWgWdjpOQxoL+qi5roxYyTk=
gitter.top/common/goref v0.0.0-20230623122346-fa52c8a5753e/go.mod h1:oK6jZQ/ISS8gZ78rvww6p7FuLUzaJ+S5F5UXSqO7Lr0=
gitter.top/common/goref v0.0.0-20230623134616-9d375bad30e4 h1:yivG8g8Hty/rMiPLWhGDPmRJQXvcZwBtLvmminEEAd0=
gitter.top/common/goref v0.0.0-20230623134616-9d375bad30e4/go.mod h1:oK6jZQ/ISS8gZ78rvww6p7FuLUzaJ+S5F5UXSqO7Lr0=
gitter.top/common/goref v0.0.0-20230623144827-8cd99d7ed68f h1:+b+DwvEDKS6hgtJ49H+F0m310NO0zMVGn2kfXh2UWwA=
gitter.top/common/goref v0.0.0-20230623144827-8cd99d7ed68f/go.mod h1:9ZCvSyMgyJ6ODKdgvHgnNuRlBhvlzIOBcwhP3Buz5SA=
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=

View File

@ -70,12 +70,12 @@ func (is *insertScope) SetContext(ctx context.Context) *insertScope {
}
func (is *insertScope) SetInsertOneOptions(opts options.InsertOneOptions) *insertScope {
is.opts = opts
is.opts = &opts
return is
}
func (is *insertScope) SetInsertManyOptions(opts options.InsertManyOptions) *insertScope {
is.opts = opts
is.opts = &opts
return is
}

View File

@ -24,12 +24,12 @@ type Collection interface {
BulkWrite()
Clone()
Count() *countScope
Delete()
Find()
Delete() *deleteScope
Find() *findScope
Drop() *dropScope
Indexes() *indexesScope
Insert()
Update()
Insert() *insertScope
Update() *updateScope
Watch()
}
@ -53,12 +53,18 @@ func (s *scope) Count() *countScope {
}
}
func (s *scope) Delete() {
func (s *scope) Delete() *deleteScope {
return &deleteScope{
scope: s,
mdbc: s.mdbc,
}
}
func (s *scope) Find() {
func (s *scope) Find() *findScope {
return &findScope{
scope: s,
mdbc: s.mdbc,
}
}
func (s *scope) Drop() *dropScope {
@ -75,12 +81,18 @@ func (s *scope) Indexes() *indexesScope {
}
}
func (s *scope) Insert() {
func (s *scope) Insert() *insertScope {
return &insertScope{
scope: s,
mdbc: s.mdbc,
}
}
func (s *scope) Update() {
func (s *scope) Update() *updateScope {
return &updateScope{
scope: s,
mdbc: s.mdbc,
}
}
func (s *scope) Watch() {

104
update.go Normal file
View File

@ -0,0 +1,104 @@
package mdbc
import (
"context"
"fmt"
"gitter.top/common/goref"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type updateScope struct {
*scope
*mdbc
ctx context.Context
filter any
docs any
opts any
err error
}
func (us *updateScope) SetContext(ctx context.Context) *updateScope {
us.ctx = ctx
return us
}
func (us *updateScope) SetUpdateOptions(opts options.UpdateOptions) *updateScope {
us.opts = &opts
return us
}
func (us *updateScope) SetReplaceOptions(opts options.ReplaceOptions) *updateScope {
us.opts = &opts
return us
}
func (us *updateScope) SetID(id ...string) *updateScope {
if len(id) == 0 {
return us
}
if len(id) == 1 {
us.filter = bson.M{
"_id": id,
}
}
if len(id) > 1 {
us.filter = bson.M{
"_id": bson.M{"$in": id},
}
}
return us
}
func (us *updateScope) SetFilter(filter interface{}) *updateScope {
if us.filter != nil {
return us
}
if filter == nil {
us.filter = bson.M{}
return us
}
if goref.IsBaseStruct(filter) || goref.IsBaseMap(filter) {
us.filter = filter
return us
}
us.err = fmt.Errorf("filter type must be struct or map")
return us
}
func (us *updateScope) mergeOptions() {
if us.ctx == nil {
us.ctx = context.Background()
}
if us.filter == nil {
us.filter = bson.M{}
}
if us.opts == nil {
us.opts = new(options.UpdateOptions)
}
if goref.IsBaseStruct(us.docs) {
us.docs = bson.M{"$set": us.docs}
}
if goref.IsBaseMap(us.docs) && !goref.ExistMapKey(us.docs, "$set") {
us.docs = bson.M{"$set": us.docs}
}
}
func (us *updateScope) One(docs interface{}) (*mongo.UpdateResult, error) {
us.docs = docs
us.mergeOptions()
return us.database.Collection(us.tableName).UpdateOne(us.ctx, us.filter, us.docs, us.opts.(*options.UpdateOptions))
}
func (us *updateScope) Many(docs interface{}) (*mongo.UpdateResult, error) {
us.docs = docs
us.mergeOptions()
return us.database.Collection(us.tableName).UpdateMany(us.ctx, us.filter, us.docs, us.opts.(*options.UpdateOptions))
}
func (us *updateScope) Replace(docs interface{}) (*mongo.UpdateResult, error) {
us.docs = docs
us.mergeOptions()
return us.database.Collection(us.tableName).ReplaceOne(us.ctx, us.filter, us.docs, us.opts.(*options.ReplaceOptions))
}