diff --git a/README.md b/README.md index 06dd42e..a9ddbcb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ MongoDB Template -[![Project status](https://img.shields.io/badge/version-v1.2.0-vividgreen.svg)](https://github.com/GabrielHCataldo/go-mongo-template/releases/tag/v1.2.0) +[![Project status](https://img.shields.io/badge/version-v1.2.1-vividgreen.svg)](https://github.com/GabrielHCataldo/go-mongo-template/releases/tag/v1.2.1) [![Go Report Card](https://goreportcard.com/badge/github.com/GabrielHCataldo/go-mongo-template)](https://goreportcard.com/report/github.com/GabrielHCataldo/go-mongo-template) [![Coverage Status](https://coveralls.io/repos/GabrielHCataldo/go-mongo-template/badge.svg?branch=main&service=github)](https://coveralls.io/github/GabrielHCataldo/go-mongo?branch=main) [![Open Source Helpers](https://www.codetriage.com/gabrielhcataldo/go-mongo-template/badges/users.svg)](https://www.codetriage.com/gabrielhcataldo/go-mongo) diff --git a/_example/insert/main.go b/_example/insert/main.go index 7c465a0..99f2457 100644 --- a/_example/insert/main.go +++ b/_example/insert/main.go @@ -109,7 +109,7 @@ func insertOneManualCloseSession() { CreatedAt: primitive.NewDateTimeFromTime(time.Now()), } //new document need a pointer - err = mongoTemplate.InsertOne(ctx, &testDocument, option.NewInsertOne(). + err = mongoTemplate.InsertOne(ctx, &testDocument, option.InsertOne(). SetForceRecreateSession(false).SetDisableAutoCloseSession(true)) if helper.IsNotNil(err) { logger.Error("error insert document:", err) diff --git a/go.mod b/go.mod index 3975528..26785bc 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,9 @@ module github.com/GabrielHCataldo/go-mongo-template go 1.21.3 require ( - github.com/GabrielHCataldo/go-errors v1.1.2 - github.com/GabrielHCataldo/go-helper v1.3.7 - github.com/GabrielHCataldo/go-logger v1.2.4 - go.mongodb.org/mongo-driver v1.13.1 + github.com/GabrielHCataldo/go-helper v1.4.7 + github.com/GabrielHCataldo/go-logger v1.2.7 + go.mongodb.org/mongo-driver v1.14.0 ) require ( diff --git a/go.sum b/go.sum index d52f09f..a409205 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ -github.com/GabrielHCataldo/go-errors v1.1.2 h1:pzfegYVLH6+7pUzymcSU2HreUWiahGTJCOz+FMtgqyQ= -github.com/GabrielHCataldo/go-errors v1.1.2/go.mod h1:tJH0y1gLoR8uJS5SeuMpBzmcasZpI00j/PnH4HXTHpE= -github.com/GabrielHCataldo/go-helper v1.3.7 h1:aAUdFNJJyx6YCx9q4+1qaO/jmBkztDwwZiLtnip0kcI= -github.com/GabrielHCataldo/go-helper v1.3.7/go.mod h1:+whI36aUg1BfvLpZWJ8j81+d5iPuxl58ApOJqTIliCU= -github.com/GabrielHCataldo/go-logger v1.2.4 h1:a0IrcAdBa0dh4UUvQEy2kGbif3gGzpvjmPA4nIJOEVA= -github.com/GabrielHCataldo/go-logger v1.2.4/go.mod h1:1Vn/557fErplbuV+1jT/5U4Xi6/8+6cyZaj8niSv2uA= +github.com/GabrielHCataldo/go-helper v1.4.7 h1:E7F0KXQYia2efeFoIKd/qgVvfjbrCujRxsyCzlnm8dk= +github.com/GabrielHCataldo/go-helper v1.4.7/go.mod h1:+whI36aUg1BfvLpZWJ8j81+d5iPuxl58ApOJqTIliCU= +github.com/GabrielHCataldo/go-logger v1.2.7 h1:SNAjQxLzPIuk8W1I892hxOthoB7dxLMwtQRARaJd0Vg= +github.com/GabrielHCataldo/go-logger v1.2.7/go.mod h1:1Vn/557fErplbuV+1jT/5U4Xi6/8+6cyZaj8niSv2uA= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -19,17 +17,14 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/klassmann/cpfcnpj v0.0.0-20200907140233-a595c5fd8de1 h1:nT1t/3YnkjBWdVl6zmvmim6S8gjAZOpZi19iEBq3/Ko= github.com/klassmann/cpfcnpj v0.0.0-20200907140233-a595c5fd8de1/go.mod h1:2lGFirXS+qsYDFtk4OAzWXyILL3mrSAluEH26Ao65ZY= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/leekchan/accounting v1.0.0 h1:+Wd7dJ//dFPa28rc1hjyy+qzCbXPMR91Fb6F1VGTQHg= @@ -38,7 +33,6 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/nyaruka/phonenumbers v1.3.0 h1:IFyyJfF2Elg8xGKFghWrRXzb6qAHk+Q3uPqmIgS20JQ= @@ -65,23 +59,20 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= -go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= +go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= +go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= @@ -92,7 +83,6 @@ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -102,10 +92,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/mongo/error.go b/mongo/error.go index 892f6fa..34e1be0 100644 --- a/mongo/error.go +++ b/mongo/error.go @@ -1,82 +1,15 @@ package mongo -import "github.com/GabrielHCataldo/go-errors/errors" - -var MsgErrRefDocument = "mongo: ref document needs to be structure or slice of the struct" -var MsgErrDatabaseNotConfigured = "mongo: database not correct configured" -var MsgErrCollectionNotConfigured = "mongo: collection not correct configured" -var MsgErrDocumentIsNotPointer = "mongo: document param is not a pointer" -var MsgErrDocumentIsNotStruct = "mongo: document param is not a struct" -var MsgErrDocumentIsEmpty = "mongo: document param is empty" -var MsgErrDocumentsIsEmpty = "mongo: documents param is empty" -var MsgErrDestIsNotPointer = "mongo: dest param is not a pointer" -var MsgErrDestIsNotStruct = "mongo: dest param is not a struct" -var MsgErrNoDocuments = "mongo: no documents in result" -var MsgErrNoOpenSession = "mongo: no open session" - -var ErrRefDocument = errors.New(MsgErrRefDocument) -var ErrDatabaseNotConfigured = errors.New(MsgErrDatabaseNotConfigured) -var ErrCollectionNotConfigured = errors.New(MsgErrCollectionNotConfigured) -var ErrDocumentIsNotPointer = errors.New(MsgErrDocumentIsNotPointer) -var ErrDocumentIsNotStruct = errors.New(MsgErrDocumentIsNotStruct) -var ErrDocumentIsEmpty = errors.New(MsgErrDocumentIsEmpty) -var ErrDocumentsIsEmpty = errors.New(MsgErrDocumentsIsEmpty) -var ErrDestIsNotPointer = errors.New(MsgErrDestIsNotPointer) -var ErrDestIsNotStruct = errors.New(MsgErrDestIsNotStruct) -var ErrNoDocuments = errors.New(MsgErrNoDocuments) -var ErrNoOpenSession = errors.New(MsgErrNoOpenSession) - -func errRefDocument(skip int) error { - ErrRefDocument = errors.NewSkipCaller(skip+1, MsgErrRefDocument) - return ErrRefDocument -} - -func errDatabaseNotConfigured(skip int) error { - ErrDatabaseNotConfigured = errors.NewSkipCaller(skip+1, MsgErrDatabaseNotConfigured) - return ErrDatabaseNotConfigured -} - -func errCollectionNotConfigured(skip int) error { - ErrCollectionNotConfigured = errors.NewSkipCaller(skip+1, MsgErrCollectionNotConfigured) - return ErrCollectionNotConfigured -} - -func errDocumentIsNotPointer(skip int) error { - ErrDocumentIsNotPointer = errors.NewSkipCaller(skip+1, MsgErrDocumentIsNotPointer) - return ErrDocumentIsNotPointer -} - -func errDocumentIsNotStruct(skip int) error { - ErrDocumentIsNotStruct = errors.NewSkipCaller(skip+1, MsgErrDocumentIsNotStruct) - return ErrDocumentIsNotStruct -} - -func errDocumentIsEmpty(skip int) error { - ErrDocumentIsEmpty = errors.NewSkipCaller(skip+1, MsgErrDocumentIsEmpty) - return ErrDocumentIsEmpty -} - -func errDocumentsIsEmpty(skip int) error { - ErrDocumentsIsEmpty = errors.NewSkipCaller(skip+1, MsgErrDocumentsIsEmpty) - return ErrDocumentsIsEmpty -} - -func errDestIsNotPointer(skip int) error { - ErrDestIsNotPointer = errors.NewSkipCaller(skip+1, MsgErrDestIsNotPointer) - return ErrDestIsNotPointer -} - -func errDestIsNotStruct(skip int) error { - ErrDestIsNotStruct = errors.NewSkipCaller(skip+1, MsgErrDestIsNotStruct) - return ErrDestIsNotStruct -} - -func errNoDocuments(skip int) error { - ErrNoDocuments = errors.NewSkipCaller(skip+1, MsgErrNoDocuments) - return ErrNoDocuments -} - -func errNoOpenSession(skip int) error { - ErrNoOpenSession = errors.NewSkipCaller(skip+1, MsgErrNoOpenSession) - return ErrNoOpenSession -} +import "errors" + +var ErrRefDocument = errors.New("mongo: ref document needs to be structure or slice of the struct") +var ErrDatabaseNotConfigured = errors.New("mongo: database not correct configured") +var ErrCollectionNotConfigured = errors.New("mongo: collection not correct configured") +var ErrDocumentIsNotPointer = errors.New("mongo: document param is not a pointer") +var ErrDocumentIsNotStruct = errors.New("mongo: document param is not a struct") +var ErrDocumentIsEmpty = errors.New("mongo: document param is empty") +var ErrDocumentsIsEmpty = errors.New("mongo: documents param is empty") +var ErrDestIsNotPointer = errors.New("mongo: dest param is not a pointer") +var ErrDestIsNotStruct = errors.New("mongo: dest param is not a struct") +var ErrNoDocuments = errors.New("mongo: no documents in result") +var ErrNoOpenSession = errors.New("mongo: no open session") diff --git a/mongo/main_test.go b/mongo/main_test.go index 2540cff..40362b3 100644 --- a/mongo/main_test.go +++ b/mongo/main_test.go @@ -119,6 +119,15 @@ type testFindOne struct { wantErr bool } +type testFindOneAndDeleteById struct { + name string + id any + dest any + option *option.FindOneAndDelete + durationTimeout time.Duration + wantErr bool +} + type testFindOneAndDelete struct { name string filter any @@ -128,6 +137,16 @@ type testFindOneAndDelete struct { wantErr bool } +type testFindOneAndReplaceById struct { + name string + id any + replacement any + dest any + option *option.FindOneAndReplace + durationTimeout time.Duration + wantErr bool +} + type testFindOneAndReplace struct { name string filter any @@ -148,6 +167,16 @@ type testFindOneAndUpdate struct { wantErr bool } +type testFindOneAndUpdateById struct { + name string + id any + update any + dest any + option *option.FindOneAndUpdate + durationTimeout time.Duration + wantErr bool +} + type testFind struct { name string filter any @@ -276,8 +305,6 @@ type testListIndexes struct { wantErr bool } -var mongoTemplate *Template - type testStruct struct { Id primitive.ObjectID `json:"id" bson:"_id,omitempty" database:"test" collection:"test"` Random int `json:"random,omitempty" bson:"random,omitempty"` @@ -306,6 +333,8 @@ type testInvalidCollectionStruct struct { type testEmptyStruct struct { } +var mongoTemplate *Template + func TestMain(t *testing.M) { initMongoTemplate() clearCollection() @@ -318,12 +347,13 @@ func initMongoTemplate() { if helper.IsNotNil(mongoTemplate) { return } - nMongoTemplate, err := NewTemplate(context.TODO(), options.Client().ApplyURI(os.Getenv("MONGODB_URL"))) + mt, err := NewTemplate(context.TODO(), options.Client().ApplyURI(os.Getenv("MONGODB_URL"))) if helper.IsNotNil(err) { logger.Error("error new Template:", err) return } - mongoTemplate = nMongoTemplate + mt.SetGlobalOption(initGlobalOption()) + mongoTemplate = mt } func initDocument() { @@ -331,14 +361,26 @@ func initDocument() { ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second) defer cancel() test := initTestStruct() - err := mongoTemplate.InsertOne(ctx, test) + err := mongoTemplate.StartSession(ctx) + if helper.IsNotNil(err) { + logger.Error("error start session init document:", err) + return + } + err = mongoTemplate.InsertOne(ctx, test) if helper.IsNotNil(err) { logger.Error("error init document:", err) return } + err = mongoTemplate.CommitTransaction(ctx) + if helper.IsNotNil(err) { + logger.Error("error commit init document:", err) + return + } err = os.Setenv(MongoDBTestId, test.Id.Hex()) if helper.IsNotNil(err) { logger.Error("err set MongoDBTestId env:", err) + } else { + logger.Info("set MongoDBTestId env successfully:", test.Id.Hex()) } } @@ -366,7 +408,7 @@ func disconnectMongoTemplate() { defer cancel() err := mongoTemplate.Disconnect(ctx) if helper.IsNotNil(err) { - logger.Error("error disconnect mongodb:", err) + logger.Error("Error disconnect mongodb:", err) } mongoTemplate = nil } @@ -479,9 +521,13 @@ func initListTestInsertOne() []testInsertOne { durationTimeout: 5 * time.Second, }, { - name: "success with error commit transaction", - value: initTestStruct(), - option: initOptionInsertOne().SetDisableAutoCloseSession(true), + name: "success with error commit transaction", + value: initTestStruct(), + option: initOptionInsertOne(). + SetBypassDocumentValidation(true). + SetComment("comment insert golang unit test"). + SetDisableAutoCloseSession(true). + SetDisableAutoRollbackSession(true), forceErrCloseMongoClient: true, durationTimeout: 5 * time.Second, }, @@ -559,6 +605,8 @@ func initListTestInsertMany() []testInsertMany { nil, }, option: initOptionInsertMany(). + SetBypassDocumentValidation(true). + SetComment("comment insert golang unit test"). SetDisableAutoRollback(true). SetDisableAutoCloseSession(true). SetForceRecreateSession(true), @@ -608,10 +656,14 @@ func initListTestDelete() []testDelete { wantErr: true, }, { - name: "failed type ref", - filter: bson.M{}, - ref: initTestString(), - option: initOptionDelete().SetForceRecreateSession(true).SetDisableAutoCloseSession(true), + name: "failed type ref", + filter: bson.M{}, + ref: initTestString(), + option: initOptionDelete(). + SetComment("comment delete golang unit test"). + SetForceRecreateSession(true). + SetDisableAutoRollbackSession(true). + SetDisableAutoCloseSession(true), durationTimeout: 5 * time.Second, wantErr: true, }, @@ -685,11 +737,15 @@ func initListTestUpdateOneById() []testUpdateOneById { wantErr: true, }, { - name: "failed update param", - id: objectId, - update: nil, - ref: testStruct{}, - option: initOptionUpdate().SetDisableAutoCloseSession(true), + name: "failed update param", + id: objectId, + update: nil, + ref: testStruct{}, + option: initOptionUpdate(). + SetBypassDocumentValidation(true). + SetComment("comment update golang unit test"). + SetDisableAutoRollbackSession(true). + SetDisableAutoCloseSession(true), durationTimeout: 5 * time.Second, wantErr: true, }, @@ -762,11 +818,16 @@ func initListTestReplaceOne() []testReplaceOne { wantErr: true, }, { - name: "failed update param", - filter: bson.M{"_id": objectId}, - replacement: nil, - ref: testStruct{}, - option: initOptionReplace().SetForceRecreateSession(true).SetDisableAutoCloseSession(true), + name: "failed update param", + filter: bson.M{"_id": objectId}, + replacement: nil, + ref: testStruct{}, + option: initOptionReplace(). + SetBypassDocumentValidation(true). + SetComment("comment replace golang unit test"). + SetForceRecreateSession(true). + SetDisableAutoRollbackSession(true). + SetDisableAutoCloseSession(true), durationTimeout: 5 * time.Second, wantErr: true, }, @@ -828,6 +889,7 @@ func initListTestFindOneById() []testFindOneById { dest: &testStruct{}, option: initOptionFindOneById(), durationTimeout: 5 * time.Second, + wantErr: true, }, { name: "failed", @@ -912,6 +974,64 @@ func initListTestFindOne() []testFindOne { } } +func initListTestFindOneAndDeleteById() []testFindOneAndDeleteById { + objectId, _ := primitive.ObjectIDFromHex(os.Getenv(MongoDBTestId)) + return []testFindOneAndDeleteById{ + { + name: "success", + id: objectId, + dest: &testStruct{}, + option: initOptionFindOneAndDelete(), + durationTimeout: 5 * time.Second, + }, + { + name: "failed not found", + id: primitive.NewObjectID(), + dest: &testStruct{}, + option: initOptionFindOneAndDelete(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed", + id: objectId, + dest: &testStruct{}, + option: initOptionFindOneAndDelete(). + SetComment("comment golang unit test"). + SetCollation(&option.Collation{}). + SetForceRecreateSession(true). + SetDisableAutoRollbackSession(true). + SetDisableAutoCloseSession(true), + durationTimeout: 1 * time.Millisecond, + wantErr: true, + }, + { + name: "failed struct dest", + id: nil, + dest: &testInvalidStruct{}, + option: initOptionFindOneAndDelete(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed type dest", + id: nil, + dest: initTestString(), + option: initOptionFindOneAndDelete(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed dest non pointer", + id: nil, + dest: *initTestString(), + option: initOptionFindOneAndDelete(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + } +} + func initListTestFindOneAndDelete() []testFindOneAndDelete { objectId, _ := primitive.ObjectIDFromHex(os.Getenv(MongoDBTestId)) return []testFindOneAndDelete{ @@ -937,6 +1057,7 @@ func initListTestFindOneAndDelete() []testFindOneAndDelete { option: initOptionFindOneAndDelete(). SetCollation(&option.Collation{}). SetForceRecreateSession(true). + SetDisableAutoRollbackSession(true). SetDisableAutoCloseSession(true), durationTimeout: 1 * time.Millisecond, wantErr: true, @@ -968,6 +1089,71 @@ func initListTestFindOneAndDelete() []testFindOneAndDelete { } } +func initListTestFindOneAndReplaceById() []testFindOneAndReplaceById { + objectId, _ := primitive.ObjectIDFromHex(os.Getenv(MongoDBTestId)) + return []testFindOneAndReplaceById{ + { + name: "success", + id: objectId, + replacement: *initTestStruct(), + dest: &testStruct{}, + option: initOptionFindOneAndReplace(), + durationTimeout: 5 * time.Second, + }, + { + name: "failed not found", + id: primitive.NewObjectID(), + replacement: *initTestStruct(), + dest: &testStruct{}, + option: initOptionFindOneAndReplace(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed", + id: objectId, + replacement: *initTestStruct(), + dest: &testStruct{}, + option: initOptionFindOneAndReplace(). + SetBypassDocumentValidation(true). + SetComment("comment golang unit test"). + SetCollation(&option.Collation{}). + SetReturnDocument(option.ReturnDocumentAfter). + SetForceRecreateSession(true). + SetDisableAutoRollbackSession(true). + SetDisableAutoCloseSession(true), + durationTimeout: 1 * time.Millisecond, + wantErr: true, + }, + { + name: "failed struct dest", + id: nil, + replacement: nil, + dest: &testInvalidStruct{}, + option: initOptionFindOneAndReplace(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed type dest", + id: nil, + replacement: nil, + dest: initTestString(), + option: initOptionFindOneAndReplace(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed dest non pointer", + id: nil, + dest: *initTestString(), + option: initOptionFindOneAndReplace(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + } +} + func initListTestFindOneAndReplace() []testFindOneAndReplace { objectId, _ := primitive.ObjectIDFromHex(os.Getenv(MongoDBTestId)) return []testFindOneAndReplace{ @@ -1031,6 +1217,73 @@ func initListTestFindOneAndReplace() []testFindOneAndReplace { } } +func initListTestFindOneAndUpdateById() []testFindOneAndUpdateById { + objectId, _ := primitive.ObjectIDFromHex(os.Getenv(MongoDBTestId)) + return []testFindOneAndUpdateById{ + { + name: "success", + id: objectId, + update: bson.M{"$set": bson.M{"name": "Updated Test Name"}}, + dest: &testStruct{}, + option: initOptionFindOneAndUpdate(), + durationTimeout: 5 * time.Second, + }, + { + name: "failed not found", + id: primitive.NewObjectID(), + update: bson.M{"$set": bson.M{"name": "Updated Test Name"}}, + dest: &testStruct{}, + option: initOptionFindOneAndUpdate(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed struct dest", + id: nil, + update: nil, + dest: &testInvalidStruct{}, + option: initOptionFindOneAndUpdate(). + SetBypassDocumentValidation(true). + SetComment("comment golang unit test"). + SetArrayFilters(&option.ArrayFilters{}). + SetCollation(&option.Collation{}). + SetReturnDocument(option.ReturnDocumentAfter). + SetForceRecreateSession(true). + SetDisableAutoRollbackSession(true). + SetDisableAutoCloseSession(true), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed type dest", + id: nil, + update: nil, + dest: initTestString(), + option: initOptionFindOneAndUpdate(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed dest non pointer", + id: nil, + update: nil, + dest: *initTestString(), + option: initOptionFindOneAndUpdate(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + { + name: "failed update", + id: objectId, + update: bson.M{"name": "Updated Test Name"}, + dest: &testStruct{}, + option: initOptionFindOneAndUpdate(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, + } +} + func initListTestFindOneAndUpdate() []testFindOneAndUpdate { objectId, _ := primitive.ObjectIDFromHex(os.Getenv(MongoDBTestId)) return []testFindOneAndUpdate{ @@ -1120,6 +1373,14 @@ func initListTestFind() []testFind { durationTimeout: 1 * time.Millisecond, wantErr: true, }, + { + name: "failed no documents", + filter: bson.D{{"_id", bson.D{{"$exists", false}}}}, + dest: &[]testInvalidStruct{}, + option: initOptionFind(), + durationTimeout: 5 * time.Second, + wantErr: true, + }, { name: "failed struct dest", filter: nil, @@ -1872,20 +2133,15 @@ func initListTestDropIndex() []testDropIndex { } func initOptionInsertOne() *option.InsertOne { - return option.NewInsertOne(). - SetBypassDocumentValidation(true). - SetComment("comment insert golang unit test") + return option.NewInsertOne() } func initOptionInsertMany() *option.InsertMany { - return option.NewInsertMany(). - SetBypassDocumentValidation(true). - SetComment("comment insert golang unit test") + return option.NewInsertMany() } func initOptionDelete() *option.Delete { return option.NewDelete(). - SetComment("comment delete golang unit test"). SetCollation(&option.Collation{}). SetHint(bson.M{}). SetLet(bson.M{}) @@ -1893,22 +2149,18 @@ func initOptionDelete() *option.Delete { func initOptionUpdate() *option.Update { return option.NewUpdate(). - SetComment("comment update golang unit test"). SetCollation(&option.Collation{}). SetHint(bson.M{}). SetLet(bson.M{}). - SetBypassDocumentValidation(true). SetArrayFilters(&option.ArrayFilters{}). SetUpsert(true) } func initOptionReplace() *option.Replace { return option.NewReplace(). - SetComment("comment replace golang unit test"). SetCollation(&option.Collation{}). SetHint(bson.M{}). - SetLet(bson.M{}). - SetBypassDocumentValidation(true) + SetLet(bson.M{}) } func initOptionFindOne() *option.FindOne { @@ -1946,7 +2198,6 @@ func initOptionFindOneById() *option.FindOneById { func initOptionFindOneAndDelete() *option.FindOneAndDelete { return option.NewFindOneAndDelete(). SetCollation(nil). - SetComment("comment golang unit test"). SetHint(bson.M{}). SetMaxTime(5 * time.Second). SetProjection(bson.M{}). @@ -1957,7 +2208,6 @@ func initOptionFindOneAndDelete() *option.FindOneAndDelete { func initOptionFindOneAndReplace() *option.FindOneAndReplace { return option.NewFindOneAndReplace(). SetCollation(nil). - SetComment("comment golang unit test"). SetHint(bson.M{}). SetMaxTime(5 * time.Second). SetProjection(bson.M{}). @@ -1969,7 +2219,6 @@ func initOptionFindOneAndReplace() *option.FindOneAndReplace { func initOptionFindOneAndUpdate() *option.FindOneAndUpdate { return option.NewFindOneAndUpdate(). SetCollation(nil). - SetComment("comment golang unit test"). SetHint(bson.M{}). SetMaxTime(5 * time.Second). SetProjection(bson.M{}). @@ -2085,3 +2334,13 @@ func initOptionListIndexes() *option.ListIndexes { return option.NewListIndexes(). SetMaxTime(5 * time.Second) } + +func initGlobalOption() *option.Global { + return &option.Global{ + BypassDocumentValidation: helper.RandomBool(), + Comment: "global option comment", + DisableAutoRollbackSession: helper.RandomBool(), + DisableAutoCloseSession: helper.RandomBool(), + ForceRecreateSession: helper.RandomBool(), + } +} diff --git a/mongo/option/count.go b/mongo/option/count.go index 042ba6a..77834e5 100644 --- a/mongo/option/count.go +++ b/mongo/option/count.go @@ -100,8 +100,8 @@ func (e *EstimatedDocumentCount) SetMaxTime(d time.Duration) *EstimatedDocumentC } // SetComment sets value for the Comment field. -func (e *EstimatedDocumentCount) SetComment(comment any) *EstimatedDocumentCount { - e.Comment = comment +func (e *EstimatedDocumentCount) SetComment(a any) *EstimatedDocumentCount { + e.Comment = a return e } diff --git a/mongo/option/delete.go b/mongo/option/delete.go index 4c7d31f..31d516b 100644 --- a/mongo/option/delete.go +++ b/mongo/option/delete.go @@ -23,6 +23,8 @@ type Delete struct { // Values must be constant or closed expressions that do not reference document fields. Parameters can then be // accessed as variables in an aggregate expression context (e.g. "$$var"). Let any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false @@ -62,6 +64,12 @@ func (d *Delete) SetLet(a any) *Delete { return d } +// SetDisableAutoRollbackSession sets value for the DisableAutoRollbackSession field. +func (d *Delete) SetDisableAutoRollbackSession(b bool) *Delete { + d.DisableAutoRollbackSession = &b + return d +} + // SetDisableAutoCloseSession sets value for the DisableAutoCloseSession field. func (d *Delete) SetDisableAutoCloseSession(b bool) *Delete { d.DisableAutoCloseSession = &b @@ -75,7 +83,7 @@ func (d *Delete) SetForceRecreateSession(b bool) *Delete { } // MergeDeleteByParams assembles the Delete object from optional parameters. -func MergeDeleteByParams(opts []*Delete) *Delete { +func MergeDeleteByParams(opts []*Delete, global *Global) *Delete { result := &Delete{} for _, opt := range opts { if helper.IsNil(opt) { @@ -93,6 +101,9 @@ func MergeDeleteByParams(opts []*Delete) *Delete { if helper.IsNotNil(opt.Let) { result.Let = opt.Let } + if helper.IsNotNil(opt.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = opt.DisableAutoRollbackSession + } if helper.IsNotNil(opt.DisableAutoCloseSession) { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } @@ -100,11 +111,17 @@ func MergeDeleteByParams(opts []*Delete) *Delete { result.ForceRecreateSession = opt.ForceRecreateSession } } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } diff --git a/mongo/option/enum.go b/mongo/option/enum.go index 0f8a028..e8607fc 100644 --- a/mongo/option/enum.go +++ b/mongo/option/enum.go @@ -8,7 +8,7 @@ type CursorType int8 // before the update or as it is after the update. type ReturnDocument int8 -// FullDocument specifies how a change stream should return the modified document. +// FullDocument specifies how a Change stream should return the modified document. type FullDocument string //goland:noinspection ALL @@ -22,7 +22,7 @@ const ( // FullDocumentUpdateLookup includes a delta describing the changes to the document and a copy of the entire document that // was changed. FullDocumentUpdateLookup FullDocument = "updateLookup" - // FullDocumentWhenAvailable includes a post-image of the modified document for replace and update change events + // FullDocumentWhenAvailable includes a post-image of the modified document for replace and update Change events // if the post-image for this event is available. FullDocumentWhenAvailable FullDocument = "whenAvailable" ) diff --git a/mongo/option/find.go b/mongo/option/find.go index f2618e3..6bca1f3 100644 --- a/mongo/option/find.go +++ b/mongo/option/find.go @@ -258,6 +258,8 @@ type FindOneAndDelete struct { // mapping parameter names to values. Values must be constant or closed expressions that do not reference document // fields. Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var"). Let any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false. @@ -314,6 +316,8 @@ type FindOneAndReplace struct { // parameter names to values. Values must be constant or closed expressions that do not reference document fields. // Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var"). Let any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false. @@ -374,6 +378,8 @@ type FindOneAndUpdate struct { // Values must be constant or closed expressions that do not reference document fields. Parameters can then be // accessed as variables in an aggregate expression context (e.g. "$$var"). Let any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false @@ -768,8 +774,8 @@ func (f *FindOneAndDelete) SetCollation(c *Collation) *FindOneAndDelete { } // SetComment creates a new Comment instance. -func (f *FindOneAndDelete) SetComment(s string) *FindOneAndDelete { - f.Comment = s +func (f *FindOneAndDelete) SetComment(a any) *FindOneAndDelete { + f.Comment = a return f } @@ -803,6 +809,12 @@ func (f *FindOneAndDelete) SetLet(v any) *FindOneAndDelete { return f } +// SetDisableAutoRollbackSession creates a new DisableAutoRollbackSession instance. +func (f *FindOneAndDelete) SetDisableAutoRollbackSession(b bool) *FindOneAndDelete { + f.DisableAutoRollbackSession = &b + return f +} + // SetDisableAutoCloseSession creates a new DisableAutoCloseSession instance. func (f *FindOneAndDelete) SetDisableAutoCloseSession(b bool) *FindOneAndDelete { f.DisableAutoCloseSession = &b @@ -815,6 +827,12 @@ func (f *FindOneAndDelete) SetForceRecreateSession(b bool) *FindOneAndDelete { return f } +// SetDisableAutoRollbackSession creates a new DisableAutoCloseSession instance. +func (f *FindOneAndReplace) SetDisableAutoRollbackSession(b bool) *FindOneAndReplace { + f.DisableAutoRollbackSession = &b + return f +} + // SetDisableAutoCloseSession creates a new DisableAutoCloseSession instance. func (f *FindOneAndReplace) SetDisableAutoCloseSession(b bool) *FindOneAndReplace { f.DisableAutoCloseSession = &b @@ -840,8 +858,8 @@ func (f *FindOneAndReplace) SetCollation(c *Collation) *FindOneAndReplace { } // SetComment sets value for the Comment field. -func (f *FindOneAndReplace) SetComment(s string) *FindOneAndReplace { - f.Comment = s +func (f *FindOneAndReplace) SetComment(a any) *FindOneAndReplace { + f.Comment = a return f } @@ -887,6 +905,12 @@ func (f *FindOneAndReplace) SetSort(a any) *FindOneAndReplace { return f } +// SetDisableAutoRollbackSession creates a new DisableAutoRollbackSession instance. +func (f *FindOneAndUpdate) SetDisableAutoRollbackSession(b bool) *FindOneAndUpdate { + f.DisableAutoRollbackSession = &b + return f +} + // SetDisableAutoCloseSession creates a new DisableAutoCloseSession instance. func (f *FindOneAndUpdate) SetDisableAutoCloseSession(b bool) *FindOneAndUpdate { f.DisableAutoCloseSession = &b @@ -1180,12 +1204,15 @@ func MergeFindOneByIdByParams(opts []*FindOneById) *FindOneById { } // MergeFindOneAndDeleteByParams assembles the FindOneAndDelete object from optional parameters. -func MergeFindOneAndDeleteByParams(opts []*FindOneAndDelete) *FindOneAndDelete { +func MergeFindOneAndDeleteByParams(opts []*FindOneAndDelete, global *Global) *FindOneAndDelete { result := &FindOneAndDelete{} for _, opt := range opts { if helper.IsNil(opt) { continue } + if helper.IsNotNil(opt.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = opt.DisableAutoRollbackSession + } if helper.IsNotNil(opt.DisableAutoCloseSession) { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } @@ -1214,17 +1241,23 @@ func MergeFindOneAndDeleteByParams(opts []*FindOneAndDelete) *FindOneAndDelete { result.MaxTime = opt.MaxTime } } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } // MergeFindOneAndReplaceByParams assembles the FindOneAndReplace object from optional parameters. -func MergeFindOneAndReplaceByParams(opts []*FindOneAndReplace) *FindOneAndReplace { +func MergeFindOneAndReplaceByParams(opts []*FindOneAndReplace, global *Global) *FindOneAndReplace { result := &FindOneAndReplace{} for _, opt := range opts { if helper.IsNil(opt) { @@ -1233,6 +1266,9 @@ func MergeFindOneAndReplaceByParams(opts []*FindOneAndReplace) *FindOneAndReplac if helper.IsNotNil(opt.BypassDocumentValidation) { result.BypassDocumentValidation = opt.BypassDocumentValidation } + if helper.IsNotNil(opt.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = opt.DisableAutoRollbackSession + } if helper.IsNotNil(opt.DisableAutoCloseSession) { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } @@ -1267,17 +1303,26 @@ func MergeFindOneAndReplaceByParams(opts []*FindOneAndReplace) *FindOneAndReplac result.ReturnDocument = opt.ReturnDocument } } + if helper.IsNil(result.BypassDocumentValidation) { + result.BypassDocumentValidation = helper.ConvertToPointer(global.BypassDocumentValidation) + } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } // MergeFindOneAndUpdateByParams assembles the FindOneAndUpdate object from optional parameters. -func MergeFindOneAndUpdateByParams(opts []*FindOneAndUpdate) *FindOneAndUpdate { +func MergeFindOneAndUpdateByParams(opts []*FindOneAndUpdate, global *Global) *FindOneAndUpdate { result := &FindOneAndUpdate{} for _, opt := range opts { if helper.IsNil(opt) { @@ -1286,6 +1331,9 @@ func MergeFindOneAndUpdateByParams(opts []*FindOneAndUpdate) *FindOneAndUpdate { if helper.IsNotNil(opt.BypassDocumentValidation) { result.BypassDocumentValidation = opt.BypassDocumentValidation } + if helper.IsNotNil(opt.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = opt.DisableAutoRollbackSession + } if helper.IsNotNil(opt.DisableAutoCloseSession) { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } @@ -1323,11 +1371,20 @@ func MergeFindOneAndUpdateByParams(opts []*FindOneAndUpdate) *FindOneAndUpdate { result.ReturnDocument = opt.ReturnDocument } } + if helper.IsNil(result.BypassDocumentValidation) { + result.BypassDocumentValidation = helper.ConvertToPointer(global.BypassDocumentValidation) + } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } diff --git a/mongo/option/global.go b/mongo/option/global.go new file mode 100644 index 0000000..a82d295 --- /dev/null +++ b/mongo/option/global.go @@ -0,0 +1,24 @@ +package option + +// Global represents options that can be used for all operations as a default form, it is important to highlight that it +// will not overwrite operation options. +type Global struct { + // BypassDocumentValidation If true, writes executed as part of the operation will opt out of document-level + // validation on the server. This option is valid for MongoDB versions >= 3.2 and is ignored for previous server + // versions. The default value is false. + // See https://www.mongodb.com/docs/manual/core/schema-validation/ for more information about document validation. + BypassDocumentValidation bool + // Comment A string or document that will be included in server logs, profiling logs, and currentOp queries to help + // trace the operation. The default value is nil, which means that no comment will be included in the logs. + Comment any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession bool + // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to + // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. + // default is false + DisableAutoCloseSession bool + // ForceRecreateSession Force the creation of the session, if any session is still open, we close it automatically, + // aborting all open transactions, and continue creating a new session. + // default is false + ForceRecreateSession bool +} diff --git a/mongo/option/insert.go b/mongo/option/insert.go index 1ab745d..5c2fc72 100644 --- a/mongo/option/insert.go +++ b/mongo/option/insert.go @@ -12,6 +12,8 @@ type InsertOne struct { // Comment A string or document that will be included in server logs, profiling logs, and currentOp queries to help // trace the operation. The default value is nil, which means that no comment will be included in the logs. Comment any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false @@ -66,6 +68,12 @@ func (i *InsertOne) SetComment(a any) *InsertOne { return i } +// SetDisableAutoRollbackSession creates a new DisableAutoRollbackSession instance. +func (i *InsertOne) SetDisableAutoRollbackSession(b bool) *InsertOne { + i.DisableAutoRollbackSession = &b + return i +} + // SetDisableAutoCloseSession creates a new DisableAutoCloseSession instance. func (i *InsertOne) SetDisableAutoCloseSession(b bool) *InsertOne { i.DisableAutoCloseSession = &b @@ -109,7 +117,7 @@ func (i *InsertMany) SetForceRecreateSession(b bool) *InsertMany { } // MergeInsertOneByParams assembles the InsertOne object from optional parameters. -func MergeInsertOneByParams(opts []*InsertOne) *InsertOne { +func MergeInsertOneByParams(opts []*InsertOne, global *Global) *InsertOne { result := &InsertOne{} for _, opt := range opts { if helper.IsNil(opt) { @@ -128,17 +136,26 @@ func MergeInsertOneByParams(opts []*InsertOne) *InsertOne { result.ForceRecreateSession = opt.ForceRecreateSession } } + if helper.IsNil(result.BypassDocumentValidation) { + result.BypassDocumentValidation = helper.ConvertToPointer(global.BypassDocumentValidation) + } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } // MergeInsertManyByParams assembles the InsertMany object from optional parameters. -func MergeInsertManyByParams(opts []*InsertMany) *InsertMany { +func MergeInsertManyByParams(opts []*InsertMany, global *Global) *InsertMany { result := &InsertMany{} for _, opt := range opts { if helper.IsNil(opt) { @@ -160,14 +177,20 @@ func MergeInsertManyByParams(opts []*InsertMany) *InsertMany { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } } - if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + if helper.IsNil(result.BypassDocumentValidation) { + result.BypassDocumentValidation = helper.ConvertToPointer(global.BypassDocumentValidation) + } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment } if helper.IsNil(result.DisableAutoRollbackSession) { - result.DisableAutoRollbackSession = helper.ConvertToPointer(false) + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } + if helper.IsNil(result.DisableAutoCloseSession) { + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } diff --git a/mongo/option/replace.go b/mongo/option/replace.go index b385667..725cd48 100644 --- a/mongo/option/replace.go +++ b/mongo/option/replace.go @@ -31,6 +31,8 @@ type Replace struct { // Values must be constant or closed expressions that do not reference document fields. Parameters can then be // accessed as variables in an aggregate expression context (e.g. "$$var"). Let any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false @@ -76,6 +78,12 @@ func (r *Replace) SetLet(a any) *Replace { return r } +// SetDisableAutoRollbackSession creates a new DisableAutoRollbackSession instance. +func (r *Replace) SetDisableAutoRollbackSession(b bool) *Replace { + r.DisableAutoRollbackSession = &b + return r +} + // SetDisableAutoCloseSession creates a new DisableAutoCloseSession instance. func (r *Replace) SetDisableAutoCloseSession(b bool) *Replace { r.DisableAutoCloseSession = &b @@ -89,7 +97,7 @@ func (r *Replace) SetForceRecreateSession(b bool) *Replace { } // MergeReplaceByParams assembles the Replace object from optional parameters. -func MergeReplaceByParams(opts []*Replace) *Replace { +func MergeReplaceByParams(opts []*Replace, global *Global) *Replace { result := &Replace{} for _, opt := range opts { if helper.IsNil(opt) { @@ -107,6 +115,9 @@ func MergeReplaceByParams(opts []*Replace) *Replace { if helper.IsNotNil(opt.Let) { result.Let = opt.Let } + if helper.IsNotNil(opt.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = opt.DisableAutoRollbackSession + } if helper.IsNotNil(opt.DisableAutoCloseSession) { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } @@ -114,11 +125,20 @@ func MergeReplaceByParams(opts []*Replace) *Replace { result.ForceRecreateSession = opt.ForceRecreateSession } } + if helper.IsNil(result.BypassDocumentValidation) { + result.BypassDocumentValidation = helper.ConvertToPointer(global.BypassDocumentValidation) + } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } diff --git a/mongo/option/update.go b/mongo/option/update.go index fc6e873..431ee8f 100644 --- a/mongo/option/update.go +++ b/mongo/option/update.go @@ -35,6 +35,8 @@ type Update struct { // Values must be constant or closed expressions that do not reference document fields. Parameters can then be // accessed as variables in an aggregate expression context (e.g. "$$var"). Let any + // DisableAutoRollbackSession disable auto rollback if an error occurs. + DisableAutoRollbackSession *bool // DisableAutoCloseSession Disable automatic closing session, if true, we automatically close session according to // the result, if an error occurs, we abort the transaction, otherwise, we commit the transaction. // default is false @@ -86,6 +88,12 @@ func (u *Update) SetLet(a any) *Update { return u } +// SetDisableAutoRollbackSession creates a new DisableAutoRollbackSession instance. +func (u *Update) SetDisableAutoRollbackSession(b bool) *Update { + u.DisableAutoRollbackSession = &b + return u +} + // SetDisableAutoCloseSession creates a new DisableAutoCloseSession instance. func (u *Update) SetDisableAutoCloseSession(b bool) *Update { u.DisableAutoCloseSession = &b @@ -105,7 +113,7 @@ func (u *Update) SetUpsert(b bool) *Update { } // MergeUpdateByParams assembles the Update object from optional parameters. -func MergeUpdateByParams(opts []*Update) *Update { +func MergeUpdateByParams(opts []*Update, global *Global) *Update { result := &Update{} for _, opt := range opts { if helper.IsNil(opt) { @@ -126,6 +134,9 @@ func MergeUpdateByParams(opts []*Update) *Update { if helper.IsNotNil(opt.Let) { result.Let = opt.Let } + if helper.IsNotNil(opt.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = opt.DisableAutoRollbackSession + } if helper.IsNotNil(opt.DisableAutoCloseSession) { result.DisableAutoCloseSession = opt.DisableAutoCloseSession } @@ -133,11 +144,20 @@ func MergeUpdateByParams(opts []*Update) *Update { result.ForceRecreateSession = opt.ForceRecreateSession } } + if helper.IsNil(result.BypassDocumentValidation) { + result.BypassDocumentValidation = helper.ConvertToPointer(global.BypassDocumentValidation) + } + if helper.IsNil(result.Comment) { + result.Comment = global.Comment + } + if helper.IsNil(result.DisableAutoRollbackSession) { + result.DisableAutoRollbackSession = helper.ConvertToPointer(global.DisableAutoRollbackSession) + } if helper.IsNil(result.DisableAutoCloseSession) { - result.DisableAutoCloseSession = helper.ConvertToPointer(false) + result.DisableAutoCloseSession = helper.ConvertToPointer(global.DisableAutoCloseSession) } if helper.IsNil(result.ForceRecreateSession) { - result.ForceRecreateSession = helper.ConvertToPointer(false) + result.ForceRecreateSession = helper.ConvertToPointer(global.ForceRecreateSession) } return result } diff --git a/mongo/option/watch.go b/mongo/option/watch.go index 304e237..0fcca6a 100644 --- a/mongo/option/watch.go +++ b/mongo/option/watch.go @@ -22,35 +22,35 @@ type Watch struct { // Comment A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation. // The default is nil, which means that no comment will be included in the logs. Comment *string - // FullDocument Specifies how the updated document should be returned in change notifications for update operations. - // The default is FullDocumentDefault, which means that only partial update deltas will be included in the change + // FullDocument Specifies how the updated document should be returned in Change notifications for update operations. + // The default is FullDocumentDefault, which means that only partial update deltas will be included in the Change // notification. FullDocument *FullDocument - // FullDocumentBeforeChange Specifies how the pre-update document should be returned in change notifications for + // FullDocumentBeforeChange Specifies how the pre-update document should be returned in Change notifications for // update operations. The default is FullDocumentOff, which means that the pre-update document will not be included - // in the change notification. + // in the Change notification. FullDocumentBeforeChange *FullDocument // MaxAwaitTime The maximum amount of time that the server should wait for new documents to satisfy a tailable cursor query. MaxAwaitTime *time.Duration - // ResumeAfter A document specifying the logical starting point for the change stream. Only changes corresponding to an oplog + // ResumeAfter A document specifying the logical starting point for the Change stream. Only changes corresponding to an oplog // entry immediately after the resume token will be returned. If this is specified, StartAtOperationTime and // StartAfter must not be set. ResumeAfter any - // ShowExpandedEvents specifies whether the server will return an expanded list of change stream events. Additional + // ShowExpandedEvents specifies whether the server will return an expanded list of Change stream events. Additional // events include: createIndexes, dropIndexes, modify, create, shardCollection, reshardCollection and // refineCollectionShardKey. This option is only valid for MongoDB versions >= 6.0. ShowExpandedEvents *bool - // StartAtOperationTime If specified, the change stream will only return changes that occurred at or after the given timestamp. This + // StartAtOperationTime If specified, the Change stream will only return changes that occurred at or after the given timestamp. This // option is only valid for MongoDB versions >= 4.0. If this is specified, ResumeAfter and StartAfter must not be // set. StartAtOperationTime *primitive.Timestamp - // StartAfter A document specifying the logical starting point for the change stream. This is similar to the ResumeAfter - // option, but allows a resume token from an "invalidate" notification to be used. This allows a change stream on a + // StartAfter A document specifying the logical starting point for the Change stream. This is similar to the ResumeAfter + // option, but allows a resume token from an "invalidate" notification to be used. This allows a Change stream on a // collection to be resumed after the collection has been dropped and recreated or renamed. Only changes // corresponding to an oplog entry immediately after the specified token will be returned. If this is specified, // ResumeAfter and StartAtOperationTime must not be set. This option is only valid for MongoDB versions >= 4.1.1. StartAfter any - // Custom options to be added to the initial aggregate for the change stream. Key-value pairs of the BSON map should + // Custom options to be added to the initial aggregate for the Change stream. Key-value pairs of the BSON map should // correlate with desired option names and values. Values must be Marshalable. Custom options may conflict with // non-custom options, and custom options bypass client-side validation. Prefer using non-custom options where possible. Custom bson.M @@ -83,35 +83,35 @@ type WatchWithHandler struct { // Comment A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation. // The default is nil, which means that no comment will be included in the logs. Comment *string - // FullDocument Specifies how the updated document should be returned in change notifications for update operations. - // The default is FullDocumentDefault, which means that only partial update deltas will be included in the change + // FullDocument Specifies how the updated document should be returned in Change notifications for update operations. + // The default is FullDocumentDefault, which means that only partial update deltas will be included in the Change // notification. FullDocument *FullDocument - // FullDocumentBeforeChange Specifies how the pre-update document should be returned in change notifications for + // FullDocumentBeforeChange Specifies how the pre-update document should be returned in Change notifications for // update operations. The default is FullDocumentOff, which means that the pre-update document will not be included - // in the change notification. + // in the Change notification. FullDocumentBeforeChange *FullDocument // MaxAwaitTime The maximum amount of time that the server should wait for new documents to satisfy a tailable cursor query. MaxAwaitTime *time.Duration - // ResumeAfter A document specifying the logical starting point for the change stream. Only changes corresponding to an oplog + // ResumeAfter A document specifying the logical starting point for the Change stream. Only changes corresponding to an oplog // entry immediately after the resume token will be returned. If this is specified, StartAtOperationTime and // StartAfter must not be set. ResumeAfter any - // ShowExpandedEvents specifies whether the server will return an expanded list of change stream events. Additional + // ShowExpandedEvents specifies whether the server will return an expanded list of Change stream events. Additional // events include: createIndexes, dropIndexes, modify, create, shardCollection, reshardCollection and // refineCollectionShardKey. This option is only valid for MongoDB versions >= 6.0. ShowExpandedEvents *bool - // StartAtOperationTime If specified, the change stream will only return changes that occurred at or after the given timestamp. This + // StartAtOperationTime If specified, the Change stream will only return changes that occurred at or after the given timestamp. This // option is only valid for MongoDB versions >= 4.0. If this is specified, ResumeAfter and StartAfter must not be // set. StartAtOperationTime *primitive.Timestamp - // StartAfter A document specifying the logical starting point for the change stream. This is similar to the ResumeAfter - // option, but allows a resume token from an "invalidate" notification to be used. This allows a change stream on a + // StartAfter A document specifying the logical starting point for the Change stream. This is similar to the ResumeAfter + // option, but allows a resume token from an "invalidate" notification to be used. This allows a Change stream on a // collection to be resumed after the collection has been dropped and recreated or renamed. Only changes // corresponding to an oplog entry immediately after the specified token will be returned. If this is specified, // ResumeAfter and StartAtOperationTime must not be set. This option is only valid for MongoDB versions >= 4.1.1. StartAfter any - // Custom options to be added to the initial aggregate for the change stream. Key-value pairs of the BSON map should + // Custom options to be added to the initial aggregate for the Change stream. Key-value pairs of the BSON map should // correlate with desired option names and values. Values must be Marshalable. Custom options may conflict with // non-custom options, and custom options bypass client-side validation. Prefer using non-custom options where possible. Custom bson.M diff --git a/mongo/page.go b/mongo/page.go index 617481c..7472e39 100644 --- a/mongo/page.go +++ b/mongo/page.go @@ -1,7 +1,6 @@ package mongo import ( - "github.com/GabrielHCataldo/go-errors/errors" "github.com/GabrielHCataldo/go-helper/helper" "math" "time" @@ -32,20 +31,17 @@ type pageItemContent map[string]any // Decode parse pageResult to dest param func (p PageResult) Decode(dest any) error { - err := helper.ConvertToDest(p, dest) - return errors.NewSkipCaller(2, err) + return helper.ConvertToDest(p, dest) } // Decode parse pageResult.Content to dest param func (p pageContent) Decode(dest any) error { - err := helper.ConvertToDest(p, dest) - return errors.NewSkipCaller(2, err) + return helper.ConvertToDest(p, dest) } // Decode parse pageResult item to dest param func (p pageItemContent) Decode(dest any) error { - err := helper.ConvertToDest(p, dest) - return errors.NewSkipCaller(2, err) + return helper.ConvertToDest(p, dest) } func newPageResult(pageInput PageInput, result any, countTotal int64) *PageResult { diff --git a/mongo/template.go b/mongo/template.go index b814aec..dd4b954 100644 --- a/mongo/template.go +++ b/mongo/template.go @@ -2,7 +2,7 @@ package mongo import ( "context" - "github.com/GabrielHCataldo/go-errors/errors" + "errors" "github.com/GabrielHCataldo/go-helper/helper" "github.com/GabrielHCataldo/go-logger/logger" "github.com/GabrielHCataldo/go-mongo-template/internal/util" @@ -72,54 +72,65 @@ type Template struct { session mongo.Session } +var globalOption = &option.Global{} + func NewTemplate(ctx context.Context, opts ...*options.ClientOptions) (*Template, error) { conn, err := mongo.Connect(ctx, opts...) if helper.IsNotNil(err) { - return nil, errors.NewSkipCaller(2, err) + return nil, err } err = conn.Ping(ctx, nil) if helper.IsNotNil(err) { - return nil, errors.NewSkipCaller(2, err) + return nil, err } return &Template{ client: conn, }, nil } +// SetGlobalOption sets value for the mongo global options. +func (t *Template) SetGlobalOption(opt *option.Global) { + if helper.IsNotNil(opt) { + globalOption = opt + } else { + globalOption = &option.Global{} + } +} + // InsertOne executes an insert command to insert a single document into the collection. // // The document parameter must be a structure pointer to be inserted, it must be non-zero. If it does not have the _id // field when transformed into BSON, the field value is automatically generated and will be added to the document // pointer provided. // -// The opts parameter can be used to specify options for the operation (see the option.InsertOne documentation.) +// The opts parameter can be used to specify options for the operation (see the option.Change documentation.) // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/insert/. func (t *Template) InsertOne(ctx context.Context, document any, opts ...*option.InsertOne) error { - opt := option.MergeInsertOneByParams(opts) - err := t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeInsertOneByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { - err = t.insertOne(sc, 4, document, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + err = t.insertOne(sc, document, opt) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return err } // InsertMany executes an insert command to insert multiple documents into the collection. If recording errors occur -// during operation you can configure automatic rollback, see the option.InsertMany documentation. +// during operation you can configure automatic rollback, see the option.insertMany documentation. // // The documents parameter must be a structure pointer slice to be inserted. The slice cannot be null or empty. // All elements must be non-zero. For any document that does not have the _id field when transformed into BSON, // the field value will be automatically generated and added to the slice pointer. // -// The opts parameter can be used to specify options for the operation (see the option.InsertMany documentation.) +// The opts parameter can be used to specify options for the operation (see the option.Change documentation.) // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/insert/. func (t *Template) InsertMany(ctx context.Context, documents any, opts ...*option.InsertMany) error { - opt := option.MergeInsertManyByParams(opts) - err := t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeInsertManyByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { err = t.insertMany(sc, documents, opt) @@ -144,12 +155,12 @@ func (t *Template) InsertMany(ctx context.Context, documents any, opts ...*optio func (t *Template) DeleteOne(ctx context.Context, filter, ref any, opts ...*option.Delete) (*DeleteResult, error) { var result *DeleteResult var err error - opt := option.MergeDeleteByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeDeleteByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.deleteOne(sc, filter, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -169,12 +180,12 @@ func (t *Template) DeleteOne(ctx context.Context, filter, ref any, opts ...*opti func (t *Template) DeleteOneById(ctx context.Context, id, ref any, opts ...*option.Delete) (*DeleteResult, error) { var result *DeleteResult var err error - opt := option.MergeDeleteByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeDeleteByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.deleteOne(sc, bson.D{{"_id", id}}, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -195,12 +206,12 @@ func (t *Template) DeleteOneById(ctx context.Context, id, ref any, opts ...*opti func (t *Template) DeleteMany(ctx context.Context, filter, ref any, opts ...*option.Delete) (*DeleteResult, error) { var result *DeleteResult var err error - opt := option.MergeDeleteByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeDeleteByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.deleteMany(sc, filter, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -224,12 +235,12 @@ func (t *Template) DeleteMany(ctx context.Context, filter, ref any, opts ...*opt func (t *Template) UpdateOneById(ctx context.Context, id, update, ref any, opts ...*option.Update) (*UpdateResult, error) { var result *UpdateResult var err error - opt := option.MergeUpdateByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeUpdateByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.updateOne(sc, bson.D{{"_id", id}}, update, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -255,12 +266,12 @@ func (t *Template) UpdateOne(ctx context.Context, filter any, update, ref any, o error) { var result *UpdateResult var err error - opt := option.MergeUpdateByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeUpdateByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.updateOne(sc, filter, update, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -285,12 +296,12 @@ func (t *Template) UpdateMany(ctx context.Context, filter any, update, ref any, error) { var result *UpdateResult var err error - opt := option.MergeUpdateByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeUpdateByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.updateMany(sc, filter, update, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -315,12 +326,12 @@ func (t *Template) ReplaceOne(ctx context.Context, filter any, update, ref any, error) { var result *UpdateResult var err error - opt := option.MergeReplaceByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeReplaceByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.replaceOne(sc, filter, update, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -339,12 +350,12 @@ func (t *Template) ReplaceOneById(ctx context.Context, id, replacement, ref any, error) { var result *UpdateResult var err error - opt := option.MergeReplaceByParams(opts) - err = t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeReplaceByParams(opts, globalOption) + err = t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { result, err = t.replaceOne(sc, bson.D{{"_id", id}}, replacement, ref, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return result, err @@ -354,7 +365,7 @@ func (t *Template) ReplaceOneById(ctx context.Context, id, replacement, ref any, // This is equivalent to running FindOne(ctx, bson.D{{"_id", id}}, dest, opts...). // // The id parameter must be a document containing query operators and can be used to select the document to be -// returned. It cannot be null. If the id does not match any document, the dest parameter will not be modified. +// returned. It cannot be null. If the id does not match any document, the error ErrNoDocuments will be returned. // // The dest parameter must be a pointer to the return expected by the operation, it is important to have the // database and collection tags configured. @@ -381,8 +392,8 @@ func (t *Template) FindOneById(ctx context.Context, id, dest any, opts ...*optio // FindOne executes a find command, if successful it returns the corresponding documents in the collection in the dest // parameter with return error nil. Otherwise, it returns corresponding error. // -// The id parameter must be a document id that is used to select the document to be -// returned. It cannot be null. If the id does not match any document, the dest parameter will not be modified. +// The id parameter must be a document containing query operators and can be used to select the document to be +// returned. It cannot be null. If the id does not match any document, the error ErrNoDocuments will be returned. // // The dest parameter must be a pointer to the return expected by the operation, it is important to have the // database and collection tags configured. @@ -394,6 +405,31 @@ func (t *Template) FindOne(ctx context.Context, filter, dest any, opts ...*optio return t.findOne(ctx, filter, dest, opts...) } +// FindOneAndDeleteById executes a findAndModify command whose _id value matches the ID given in the collection. +// This is equivalent to running FindOneAndDelete(ctx, bson.D{{"_id", id}}, dest, opts...) +// +// The id parameter is the _id of the document to be replaced. It cannot be null. If the filter does not match any +// documents, an error set to ErrNoDocuments will be returned. If the filter matches multiple documents, +// one will be selected from the matching set. +// +// The dest parameter must be a pointer to the return expected by the operation, it is important to have the +// database and collection tags configured. +// +// The opts parameter can be used to specify options for the operation (see the option.FindOneAndDelete documentation). +// +// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/. +func (t *Template) FindOneAndDeleteById(ctx context.Context, id, dest any, opts ...*option.FindOneAndDelete) error { + opt := option.MergeFindOneAndDeleteByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) + if helper.IsNil(err) { + err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { + err = t.findOneAndDelete(sc, bson.D{{"_id", id}}, dest, opt) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) + }) + } + return err +} + // FindOneAndDelete executes a findAndModify command to delete at most one document from the collection. and returns the // document as it appeared before deletion in the dest parameter. // @@ -408,12 +444,40 @@ func (t *Template) FindOne(ctx context.Context, filter, dest any, opts ...*optio // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/. func (t *Template) FindOneAndDelete(ctx context.Context, filter, dest any, opts ...*option.FindOneAndDelete) error { - opt := option.MergeFindOneAndDeleteByParams(opts) - err := t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeFindOneAndDeleteByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { err = t.findOneAndDelete(sc, filter, dest, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) + }) + } + return err +} + +// FindOneAndReplaceById executes a findAndModify command whose _id value matches the ID given in the collection. +// This is equivalent to running FindOneAndReplace(ctx, bson.D{{"_id", id}}, dest, opts...). +// +// The id parameter is the _id of the document to be replaced. It cannot be null. If the filter does not match any +// documents, an error set to ErrNoDocuments will be returned. If the filter matches multiple documents, +// one will be selected from the matching set. +// +// The replacement parameter must be a document that will be used to replace the selected document. It cannot be nil +// and cannot contain any update operators (https://www.mongodb.com/docs/manual/reference/operator/update/). +// +// The dest parameter must be a pointer to the return expected by the operation, it is important to have the +// database and collection tags configured. +// +// The opts parameter can be used to specify options for the operation (see the option.FindOneAndReplace documentation). +// +// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/. +func (t *Template) FindOneAndReplaceById(ctx context.Context, id, replacement, dest any, opts ...*option.FindOneAndReplace) error { + opt := option.MergeFindOneAndReplaceByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) + if helper.IsNil(err) { + err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { + err = t.findOneAndReplace(sc, bson.D{{"_id", id}}, replacement, dest, opt) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return err @@ -436,12 +500,39 @@ func (t *Template) FindOneAndDelete(ctx context.Context, filter, dest any, opts // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/. func (t *Template) FindOneAndReplace(ctx context.Context, filter, replacement, dest any, opts ...*option.FindOneAndReplace) error { - opt := option.MergeFindOneAndReplaceByParams(opts) - err := t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeFindOneAndReplaceByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { err = t.findOneAndReplace(sc, filter, replacement, dest, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) + }) + } + return err +} + +// FindOneAndUpdateById executes a findAndModify command whose _id value matches the ID given in the collection. +// This is equivalent to running FindOneAndUpdate(ctx, bson.D{{"_id", id}}, dest, opts...). +// +// The id parameter is the _id of the document to be updated. It cannot be null. If the filter does not match any +// documents, an error set to ErrNoDocuments will be returned. If the filter matches multiple documents, +// one will be selected from the matching set. +// +// The update parameter must be a document containing update operators +// (https://www.mongodb.com/docs/manual/reference/operator/update/) and can be used to specify the modifications to be made +// to the selected document. It cannot be nil or empty. +// +// The opts parameter can be used to specify options for the operation (see the options.FindOneAndUpdateOptions +// documentation). +// +// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/. +func (t *Template) FindOneAndUpdateById(ctx context.Context, id, update, dest any, opts ...*option.FindOneAndUpdate) error { + opt := option.MergeFindOneAndUpdateByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) + if helper.IsNil(err) { + err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { + err = t.findOneAndUpdate(sc, bson.D{{"_id", id}}, update, dest, opt) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return err @@ -463,12 +554,12 @@ func (t *Template) FindOneAndReplace(ctx context.Context, filter, replacement, d // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/findAndModify/. func (t *Template) FindOneAndUpdate(ctx context.Context, filter, update, dest any, opts ...*option.FindOneAndUpdate) error { - opt := option.MergeFindOneAndUpdateByParams(opts) - err := t.startSession(ctx, 2, *opt.ForceRecreateSession) + opt := option.MergeFindOneAndUpdateByParams(opts, globalOption) + err := t.startSession(ctx, *opt.ForceRecreateSession) if helper.IsNil(err) { err = mongo.WithSession(ctx, t.session, func(sc mongo.SessionContext) error { err = t.findOneAndUpdate(sc, filter, update, dest, opt) - return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, false, err) + return t.closeSessionAutomatically(sc, *opt.DisableAutoCloseSession, *opt.DisableAutoRollbackSession, err) }) } return err @@ -516,9 +607,9 @@ func (t *Template) FindAll(ctx context.Context, dest any, opts ...*option.Find) func (t *Template) FindPageable(ctx context.Context, filter any, input PageInput, opts ...*option.FindPageable) ( *PageResult, error) { if helper.IsNotStruct(input.Ref) { - return nil, errors.NewSkipCaller(2, "mongo: input.Ref need to be structure") + return nil, errors.New("mongo: input.Ref need to be structure") } - _, collection, err := t.getMongoInfosByAny(2, input.Ref) + _, collection, err := t.getMongoInfosByAny(input.Ref) if helper.IsNotNil(err) { return nil, err } @@ -553,7 +644,7 @@ func (t *Template) FindPageable(ctx context.Context, filter any, input PageInput return newPageResult(input, dest, countTotal), nil } } - return nil, errors.NewSkipCaller(2, err) + return nil, err } // Exists executes the count command, if the quantity is greater than 0 with a limit of 1, true is returned, @@ -563,7 +654,7 @@ func (t *Template) FindPageable(ctx context.Context, filter any, input PageInput // // The opts parameter can be used to specify options for the operation (see the option.Exists documentation). func (t *Template) Exists(ctx context.Context, filter, ref any, opts ...*option.Exists) (bool, error) { - return t.exists(ctx, 2, filter, ref, opts...) + return t.exists(ctx, filter, ref, opts...) } // ExistsById executes a count command whose _id value matches the ID given in the collection. @@ -573,7 +664,7 @@ func (t *Template) Exists(ctx context.Context, filter, ref any, opts ...*option. // // The opts parameter can be used to specify options for the operation (see the option.Exists documentation). func (t *Template) ExistsById(ctx context.Context, id, ref any, opts ...*option.Exists) (bool, error) { - return t.exists(ctx, 2, bson.D{{"_id", id}}, ref, opts...) + return t.exists(ctx, bson.D{{"_id", id}}, ref, opts...) } // Aggregate executes a find command, if successful it returns the corresponding documents in the collection in the dest @@ -593,9 +684,9 @@ func (t *Template) ExistsById(ctx context.Context, id, ref any, opts ...*option. // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/aggregate/. func (t *Template) Aggregate(ctx context.Context, pipeline any, dest any, opts ...*option.Aggregate) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(2) + return ErrDestIsNotPointer } - _, collection, err := t.getMongoInfosByAny(2, dest) + _, collection, err := t.getMongoInfosByAny(dest) if helper.IsNotNil(err) { return err } @@ -616,7 +707,7 @@ func (t *Template) Aggregate(ctx context.Context, pipeline any, dest any, opts . if helper.IsNil(err) { err = cursor.All(ctx, dest) } - return errors.NewSkipCaller(2, err) + return err } // CountDocuments returns the number of documents in the collection. For a fast count of the documents in the @@ -630,7 +721,7 @@ func (t *Template) Aggregate(ctx context.Context, pipeline any, dest any, opts . // // The opts parameter can be used to specify options for the operation (see the option.Count documentation). func (t *Template) CountDocuments(ctx context.Context, filter, ref any, opts ...*option.Count) (int64, error) { - return t.countDocuments(ctx, 2, filter, ref, opts...) + return t.countDocuments(ctx, filter, ref, opts...) } // EstimatedDocumentCount executes a count command and returns an estimate of the number of documents in the collection @@ -644,7 +735,7 @@ func (t *Template) CountDocuments(ctx context.Context, filter, ref any, opts ... // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/count/. func (t *Template) EstimatedDocumentCount(ctx context.Context, ref any, opts ...*option.EstimatedDocumentCount) (int64, error) { - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return 0, err } @@ -653,7 +744,7 @@ func (t *Template) EstimatedDocumentCount(ctx context.Context, ref any, opts ... Comment: opt.Comment, MaxTime: opt.MaxTime, }) - return count, errors.NewSkipCaller(2, err) + return count, err } // Distinct executes a distinct command to find the unique values for a specified field in the collection. @@ -672,10 +763,10 @@ func (t *Template) EstimatedDocumentCount(ctx context.Context, ref any, opts ... // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/distinct/. func (t *Template) Distinct(ctx context.Context, fieldName string, filter, dest, ref any, opts ...*option.Distinct) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(2) + return ErrDestIsNotPointer } opt := option.MergeDistinctByParams(opts) - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return err } @@ -687,7 +778,7 @@ func (t *Template) Distinct(ctx context.Context, fieldName string, filter, dest, if helper.IsNil(err) { err = helper.ConvertToDest(result, dest) } - return errors.NewSkipCaller(2, err) + return err } // Watch returns a change stream for all changes on the deployment. See @@ -776,7 +867,7 @@ func (t *Template) WatchWithHandler(ctx context.Context, pipeline any, handler E // // The ref parameter must be the collection structure with database and collection tags configured. func (t *Template) DropCollection(ctx context.Context, ref any) error { - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return err } @@ -788,7 +879,7 @@ func (t *Template) DropCollection(ctx context.Context, ref any) error { // // The ref parameter must be the collection structure with database and collection tags configured. func (t *Template) DropDatabase(ctx context.Context, ref any) error { - database, _, err := t.getMongoInfosByAny(2, ref) + database, _, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return err } @@ -803,7 +894,7 @@ func (t *Template) DropDatabase(ctx context.Context, ref any) error { // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/createIndexes/. func (t *Template) CreateOneIndex(ctx context.Context, input IndexInput) (string, error) { - return t.createOneIndex(ctx, input, 2) + return t.createOneIndex(ctx, input) } // CreateManyIndex executes a createIndexes command to create multiple indexes on the collection and returns the names of @@ -833,10 +924,9 @@ func (t *Template) CreateManyIndex(ctx context.Context, inputs []IndexInput) ([] // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/dropIndexes/. func (t *Template) DropOneIndex(ctx context.Context, name string, ref any, opts ...*option.DropIndex) error { opt := option.MergeDropIndexByParams(opts) - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNil(err) { - _, errDrop := collection.Indexes().DropOne(ctx, name, &options.DropIndexesOptions{MaxTime: opt.MaxTime}) - err = errors.NewSkipCaller(2, errDrop) + _, err = collection.Indexes().DropOne(ctx, name, &options.DropIndexesOptions{MaxTime: opt.MaxTime}) } return err } @@ -852,10 +942,9 @@ func (t *Template) DropOneIndex(ctx context.Context, name string, ref any, opts // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/dropIndexes/. func (t *Template) DropAllIndexes(ctx context.Context, ref any, opts ...*option.DropIndex) error { opt := option.MergeDropIndexByParams(opts) - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNil(err) { - _, errDrop := collection.Indexes().DropAll(ctx, &options.DropIndexesOptions{MaxTime: opt.MaxTime}) - err = errors.NewSkipCaller(2, errDrop) + _, err = collection.Indexes().DropAll(ctx, &options.DropIndexesOptions{MaxTime: opt.MaxTime}) } return err } @@ -868,7 +957,7 @@ func (t *Template) DropAllIndexes(ctx context.Context, ref any, opts ...*option. // // For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/listIndexes/. func (t *Template) ListIndexes(ctx context.Context, ref any, opts ...*option.ListIndexes) ([]IndexResult, error) { - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -882,7 +971,7 @@ func (t *Template) ListIndexes(ctx context.Context, ref any, opts ...*option.Lis if helper.IsNil(err) { err = cursor.All(ctx, &results) } - return results, errors.NewSkipCaller(2, err) + return results, err } // ListIndexSpecifications executes a List command and returns a slice of returned IndexSpecifications. @@ -890,7 +979,7 @@ func (t *Template) ListIndexes(ctx context.Context, ref any, opts ...*option.Lis // The ref parameter must be the collection structure with database and collection tags configured. func (t *Template) ListIndexSpecifications(ctx context.Context, ref any, opts ...*option.ListIndexes) ( []IndexSpecification, error) { - _, collection, err := t.getMongoInfosByAny(2, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -914,33 +1003,33 @@ func (t *Template) ListIndexSpecifications(ctx context.Context, ref any, opts .. }) } } - return result, errors.NewSkipCaller(2, err) + return result, err } // StartSession creates a new session and a new transaction and stores it in the template itself for the next operations. func (t *Template) StartSession(ctx context.Context) error { - return t.startSession(ctx, 2, true) + return t.startSession(ctx, true) } // CloseSession closes session and transaction, if param abort is false it will commit the changes, // otherwise it will abort all transactions. func (t *Template) CloseSession(ctx context.Context, abort bool) error { - return t.closeSession(ctx, 2, abort) + return t.closeSession(ctx, abort) } // CommitTransaction commit all transactions on session func (t *Template) CommitTransaction(ctx context.Context) error { - return t.commitTransaction(ctx, 2) + return t.commitTransaction(ctx) } // AbortTransaction abort all transactions on session func (t *Template) AbortTransaction(ctx context.Context) error { - return t.abortTransaction(ctx, 2) + return t.abortTransaction(ctx) } // Disconnect closes the mongodb connection client with return error func (t *Template) Disconnect(ctx context.Context) error { - return errors.NewSkipCaller(2, t.client.Disconnect(ctx)) + return t.client.Disconnect(ctx) } // SimpleDisconnect closes the mongodb connection client without return error @@ -958,16 +1047,15 @@ func (t *Template) GetClient() mongo.Client { return *t.client } -func (t *Template) insertOne(sc mongo.SessionContext, skipCaller int, document any, opt *option.InsertOne) error { - skipCaller++ +func (t *Template) insertOne(sc mongo.SessionContext, document any, opt *option.InsertOne) error { if helper.IsNotPointer(document) { - return errDocumentIsNotPointer(skipCaller) + return ErrDocumentIsNotPointer } else if helper.IsNotStruct(document) { - return errDocumentIsNotStruct(skipCaller) + return ErrDocumentIsNotStruct } else if helper.IsEmpty(document) { - return errDocumentIsEmpty(skipCaller) + return ErrDocumentIsEmpty } - _, collection, err := t.getMongoInfosByAny(skipCaller, document) + _, collection, err := t.getMongoInfosByAny(document) if helper.IsNotNil(err) { return err } @@ -976,7 +1064,7 @@ func (t *Template) insertOne(sc mongo.SessionContext, skipCaller int, document a Comment: opt.Comment, }) if helper.IsNotNil(err) { - return errors.NewSkipCaller(skipCaller, err) + return err } util.SetInsertedIdOnDocument(result.InsertedID, document) return nil @@ -984,9 +1072,9 @@ func (t *Template) insertOne(sc mongo.SessionContext, skipCaller int, document a func (t *Template) insertMany(sc mongo.SessionContext, a any, opt *option.InsertMany) error { if helper.IsNotSlice(a) { - return errors.NewSkipCaller(5, "mongo: document on insert many needs be a slice") + return errors.New("mongo: document on insert many needs be a slice") } else if helper.IsEmpty(a) { - return errDocumentsIsEmpty(5) + return ErrDocumentsIsEmpty } documents := reflect.ValueOf(a) var errs []string @@ -994,19 +1082,18 @@ func (t *Template) insertMany(sc mongo.SessionContext, a any, opt *option.Insert indexValue := documents.Index(i) document := indexValue.Interface() if helper.IsNotPointer(document) { - errs = append(errs, helper.Sprintln(MsgErrDocumentIsNotPointer, "index:", i)) + errs = append(errs, helper.Sprintln(ErrDocumentIsNotPointer.Error(), "index:", i)) } else if helper.IsNotStruct(document) { - errs = append(errs, helper.Sprintln(MsgErrDocumentIsNotStruct, "index:", i)) + errs = append(errs, helper.Sprintln(ErrDocumentIsNotStruct.Error(), "index:", i)) } else if helper.IsEmpty(document) { - errs = append(errs, helper.Sprintln(MsgErrDocumentIsEmpty, "index:", i)) + errs = append(errs, helper.Sprintln(ErrDocumentIsEmpty.Error(), "index:", i)) } else { - err := t.insertOne(sc, 5, document, &option.InsertOne{ + err := t.insertOne(sc, document, &option.InsertOne{ BypassDocumentValidation: opt.BypassDocumentValidation, Comment: opt.Comment, }) if helper.IsNotNil(err) { - errMessage := errors.Details(err).GetMessage() - errs = append(errs, helper.Sprintln(errMessage, "index:", i)) + errs = append(errs, helper.Sprintln(err.Error(), "index:", i)) } } } @@ -1018,13 +1105,13 @@ func (t *Template) insertMany(sc mongo.SessionContext, a any, opt *option.Insert } b.WriteString(err) } - return errors.NewSkipCaller(5, b.String()) + return errors.New(b.String()) } return nil } func (t *Template) deleteOne(sc mongo.SessionContext, filter, ref any, opt *option.Delete) (*DeleteResult, error) { - _, collection, err := t.getMongoInfosByAny(5, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -1040,11 +1127,11 @@ func (t *Template) deleteOne(sc mongo.SessionContext, filter, ref any, opt *opti DeletedCount: mongoResult.DeletedCount, } } - return result, errors.NewSkipCaller(5, err) + return result, err } func (t *Template) deleteMany(sc mongo.SessionContext, filter, ref any, opt *option.Delete) (*DeleteResult, error) { - _, collection, err := t.getMongoInfosByAny(5, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -1060,11 +1147,11 @@ func (t *Template) deleteMany(sc mongo.SessionContext, filter, ref any, opt *opt DeletedCount: mongoResult.DeletedCount, } } - return result, errors.NewSkipCaller(5, err) + return result, err } func (t *Template) updateOne(sc mongo.SessionContext, filter, update, ref any, opt *option.Update) (*UpdateResult, error) { - _, collection, err := t.getMongoInfosByAny(5, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -1086,11 +1173,11 @@ func (t *Template) updateOne(sc mongo.SessionContext, filter, update, ref any, o UpsertedID: mongoResult.UpsertedID, } } - return result, errors.NewSkipCaller(5, err) + return result, err } func (t *Template) updateMany(sc mongo.SessionContext, filter, update, ref any, opt *option.Update) (*UpdateResult, error) { - _, collection, err := t.getMongoInfosByAny(5, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -1112,12 +1199,12 @@ func (t *Template) updateMany(sc mongo.SessionContext, filter, update, ref any, UpsertedID: mongoResult.UpsertedID, } } - return result, errors.NewSkipCaller(5, err) + return result, err } func (t *Template) replaceOne(sc mongo.SessionContext, filter, update, ref any, opt *option.Replace) (*UpdateResult, error) { - _, collection, err := t.getMongoInfosByAny(5, ref) + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return nil, err } @@ -1138,14 +1225,14 @@ func (t *Template) replaceOne(sc mongo.SessionContext, filter, update, ref any, UpsertedID: mongoResult.UpsertedID, } } - return result, errors.NewSkipCaller(5, err) + return result, err } func (t *Template) find(ctx context.Context, filter, dest any, opts ...*option.Find) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(3) + return ErrDestIsNotPointer } - _, collection, err := t.getMongoInfosByAny(3, dest) + _, collection, err := t.getMongoInfosByAny(dest) if helper.IsNotNil(err) { return err } @@ -1175,16 +1262,16 @@ func (t *Template) find(ctx context.Context, filter, dest any, opts ...*option.F if helper.IsNil(err) { err = cursor.All(ctx, dest) } - return errors.NewSkipCaller(3, err) + return err } func (t *Template) findOne(ctx context.Context, filter, dest any, opts ...*option.FindOne) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(3) + return ErrDestIsNotPointer } else if helper.IsNotStruct(dest) { - return errDestIsNotStruct(3) + return ErrDestIsNotStruct } - _, collection, err := t.getMongoInfosByAny(3, dest) + _, collection, err := t.getMongoInfosByAny(dest) if helper.IsNotNil(err) { return err } @@ -1203,19 +1290,19 @@ func (t *Template) findOne(ctx context.Context, filter, dest any, opts ...*optio Skip: opt.Skip, Sort: opt.Sort, }).Decode(dest) - if helper.IsNotNil(err) && !errors.Is(err, mongo.ErrNoDocuments) { - return errors.NewSkipCaller(3, err) + if errors.Is(err, mongo.ErrNoDocuments) { + return ErrNoDocuments } - return nil + return err } func (t *Template) findOneAndDelete(sc mongo.SessionContext, filter, dest any, opt *option.FindOneAndDelete) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(5) + return ErrDestIsNotPointer } else if helper.IsNotStruct(dest) { - return errDestIsNotStruct(5) + return ErrDestIsNotStruct } - _, collection, err := t.getMongoInfosByAny(5, dest) + _, collection, err := t.getMongoInfosByAny(dest) if helper.IsNotNil(err) { return err } @@ -1228,21 +1315,19 @@ func (t *Template) findOneAndDelete(sc mongo.SessionContext, filter, dest any, o Hint: opt.Hint, Let: opt.Let, }).Decode(dest) - if helper.IsNotNil(err) && errors.Is(err, mongo.ErrNoDocuments) { - return errNoDocuments(5) - } else if helper.IsNotNil(err) { - return errors.NewSkipCaller(5, err) + if errors.Is(err, mongo.ErrNoDocuments) { + return ErrNoDocuments } - return nil + return err } func (t *Template) findOneAndReplace(sc mongo.SessionContext, filter, replacement, dest any, opt *option.FindOneAndReplace) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(5) + return ErrDestIsNotPointer } else if helper.IsNotStruct(dest) { - return errDestIsNotStruct(5) + return ErrDestIsNotStruct } - _, collection, err := t.getMongoInfosByAny(5, dest) + _, collection, err := t.getMongoInfosByAny(dest) if helper.IsNotNil(err) { return err } @@ -1258,21 +1343,19 @@ func (t *Template) findOneAndReplace(sc mongo.SessionContext, filter, replacemen Hint: opt.Hint, Let: opt.Let, }).Decode(dest) - if helper.IsNotNil(err) && errors.Is(err, mongo.ErrNoDocuments) { - return errNoDocuments(5) - } else if helper.IsNotNil(err) { - return errors.NewSkipCaller(5, err) + if errors.Is(err, mongo.ErrNoDocuments) { + return ErrNoDocuments } - return nil + return err } func (t *Template) findOneAndUpdate(sc mongo.SessionContext, filter, update, dest any, opt *option.FindOneAndUpdate) error { if helper.IsNotPointer(dest) { - return errDestIsNotPointer(5) + return ErrDestIsNotPointer } else if helper.IsNotStruct(dest) { - return errDestIsNotStruct(5) + return ErrDestIsNotStruct } - _, collection, err := t.getMongoInfosByAny(5, dest) + _, collection, err := t.getMongoInfosByAny(dest) if helper.IsNotNil(err) { return err } @@ -1289,22 +1372,19 @@ func (t *Template) findOneAndUpdate(sc mongo.SessionContext, filter, update, des Hint: opt.Hint, Let: opt.Let, }).Decode(dest) - if helper.IsNotNil(err) && errors.Is(err, mongo.ErrNoDocuments) { - return errNoDocuments(5) - } else if helper.IsNotNil(err) { - return errors.NewSkipCaller(5, err) + if errors.Is(err, mongo.ErrNoDocuments) { + return ErrNoDocuments } - return nil + return err } -func (t *Template) countDocuments(ctx context.Context, skipCaller int, filter, ref any, opts ...*option.Count) (int64, error) { - skipCaller++ - _, collection, err := t.getMongoInfosByAny(skipCaller, ref) +func (t *Template) countDocuments(ctx context.Context, filter, ref any, opts ...*option.Count) (int64, error) { + _, collection, err := t.getMongoInfosByAny(ref) if helper.IsNotNil(err) { return 0, err } opt := option.MergeCountByParams(opts) - count, err := collection.CountDocuments(ctx, filter, &options.CountOptions{ + return collection.CountDocuments(ctx, filter, &options.CountOptions{ Collation: option.ParseCollationMongoOptions(opt.Collation), Comment: opt.Comment, Hint: opt.Hint, @@ -1312,13 +1392,11 @@ func (t *Template) countDocuments(ctx context.Context, skipCaller int, filter, r MaxTime: opt.MaxTime, Skip: opt.Skip, }) - return count, errors.NewSkipCaller(skipCaller, err) } -func (t *Template) exists(ctx context.Context, skipCaller int, filter, ref any, opts ...*option.Exists) (bool, error) { - skipCaller++ +func (t *Template) exists(ctx context.Context, filter, ref any, opts ...*option.Exists) (bool, error) { opt := option.MergeExistsByParams(opts) - count, err := t.countDocuments(ctx, skipCaller, filter, ref, &option.Count{ + count, err := t.countDocuments(ctx, filter, ref, &option.Count{ Collation: opt.Collation, Comment: opt.Comment, Hint: opt.Hint, @@ -1329,9 +1407,8 @@ func (t *Template) exists(ctx context.Context, skipCaller int, filter, ref any, return helper.IsGreaterThan(count, 0), err } -func (t *Template) createOneIndex(ctx context.Context, input IndexInput, skipCaller int) (string, error) { - skipCaller++ - _, collection, err := t.getMongoInfosByAny(skipCaller, input.Ref) +func (t *Template) createOneIndex(ctx context.Context, input IndexInput) (string, error) { + _, collection, err := t.getMongoInfosByAny(input.Ref) if helper.IsNotNil(err) { return "", err } @@ -1339,34 +1416,33 @@ func (t *Template) createOneIndex(ctx context.Context, input IndexInput, skipCal } func (t *Template) createManyIndex(ctx context.Context, inputs []IndexInput) ([]string, error) { - var result []string if helper.IsEmpty(inputs) { - return result, errDocumentsIsEmpty(3) + return nil, ErrDocumentsIsEmpty } - var errs []string + var result []string + var msgErrs []string for i, input := range inputs { - r, err := t.createOneIndex(ctx, input, 3) + r, err := t.createOneIndex(ctx, input) if helper.IsNotNil(err) { - errs = append(errs, helper.Sprintln(err, "index:", i)) + msgErrs = append(msgErrs, helper.Sprintln(err, "index:", i)) } else { result = append(result, r) } } - if helper.IsNotEmpty(errs) { + if helper.IsNotEmpty(msgErrs) { var b strings.Builder - for i, err := range errs { + for i, err := range msgErrs { if helper.IsGreaterThan(i, 0) { b.WriteString(", ") } b.WriteString(err) } - return result, errors.NewSkipCaller(3, b.String()) + return nil, errors.New(b.String()) } return result, nil } -func (t *Template) startSession(ctx context.Context, skipCaller int, forceRecreate bool) error { - skipCaller++ +func (t *Template) startSession(ctx context.Context, forceRecreate bool) error { if helper.IsNotNil(t.session) && !forceRecreate { return nil } else if helper.IsNotNil(t.session) { @@ -1379,16 +1455,15 @@ func (t *Template) startSession(ctx context.Context, skipCaller int, forceRecrea t.session = session } } - return errors.NewSkipCaller(skipCaller, err) + return err } -func (t *Template) closeSession(ctx context.Context, skipCaller int, abort bool) error { - skipCaller++ +func (t *Template) closeSession(ctx context.Context, abort bool) error { var err error if abort { - err = t.abortTransaction(ctx, skipCaller) + err = t.abortTransaction(ctx) } else { - err = t.commitTransaction(ctx, skipCaller) + err = t.commitTransaction(ctx) } if helper.IsNil(err) { t.endSession(ctx) @@ -1404,28 +1479,26 @@ func (t *Template) closeSessionAutomatically( ) error { if !disableAutoCloseSession { abort := helper.IsNotNil(err) && !disableAutoRollbackSession - errClose := t.closeSession(sc, 5, abort) + errClose := t.closeSession(sc, abort) if helper.IsNil(err) && helper.IsNotNil(errClose) { - err = errors.NewSkipCaller(5, errClose) + err = errClose } } return err } -func (t *Template) commitTransaction(ctx context.Context, skipCaller int) error { - skipCaller++ +func (t *Template) commitTransaction(ctx context.Context) error { if helper.IsNil(t.session) { - return errNoOpenSession(skipCaller) + return ErrNoOpenSession } - return errors.NewSkipCaller(skipCaller, t.session.CommitTransaction(ctx)) + return t.session.CommitTransaction(ctx) } -func (t *Template) abortTransaction(ctx context.Context, skipCaller int) error { - skipCaller++ +func (t *Template) abortTransaction(ctx context.Context) error { if helper.IsNil(t.session) { - return errNoOpenSession(skipCaller) + return ErrNoOpenSession } - return errors.NewSkipCaller(skipCaller, t.session.AbortTransaction(ctx)) + return t.session.AbortTransaction(ctx) } func (t *Template) endSession(ctx context.Context) { @@ -1441,8 +1514,7 @@ func (t *Template) closeCursor(ctx context.Context, cursor *mongo.Cursor) { } } -func (t *Template) getMongoInfosByAny(skipCaller int, a any) (*mongo.Database, *mongo.Collection, error) { - skipCaller++ +func (t *Template) getMongoInfosByAny(a any) (*mongo.Database, *mongo.Collection, error) { var databaseName string var collectionName string v := reflect.ValueOf(a) @@ -1455,7 +1527,7 @@ func (t *Template) getMongoInfosByAny(skipCaller int, a any) (*mongo.Database, * databaseName = util.GetDatabaseNameBySlice(a) collectionName = util.GetCollectionNameBySlice(a) } else { - return nil, nil, errRefDocument(skipCaller) + return nil, nil, ErrRefDocument } break case reflect.Struct: @@ -1463,12 +1535,12 @@ func (t *Template) getMongoInfosByAny(skipCaller int, a any) (*mongo.Database, * collectionName = util.GetCollectionNameByStruct(a) break default: - return nil, nil, errRefDocument(skipCaller) + return nil, nil, ErrRefDocument } if helper.IsEmpty(databaseName) { - return nil, nil, errDatabaseNotConfigured(skipCaller) + return nil, nil, ErrDatabaseNotConfigured } else if helper.IsEmpty(collectionName) { - return nil, nil, errCollectionNotConfigured(skipCaller) + return nil, nil, ErrCollectionNotConfigured } database := t.client.Database(databaseName) collection := database.Collection(collectionName) diff --git a/mongo/template_test.go b/mongo/template_test.go index 85c0d32..c14c8fa 100644 --- a/mongo/template_test.go +++ b/mongo/template_test.go @@ -233,6 +233,23 @@ func TestTemplateFindOne(t *testing.T) { } } +func TestTemplateFindOneAndDeleteById(t *testing.T) { + initDocument() + for _, tt := range initListTestFindOneAndDeleteById() { + t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.TODO(), tt.durationTimeout) + defer cancel() + err := mongoTemplate.FindOneAndDeleteById(ctx, tt.id, tt.dest, tt.option, nil) + if helper.IsNotEqualTo(helper.IsNotNil(err), tt.wantErr) { + t.Errorf("FindOneAndDeleteById() error = %v, wantErr %v", err, tt.wantErr) + } else if helper.IsNotNil(err) { + t.Log("err expected:", err) + } + _ = mongoTemplate.CloseSession(ctx, helper.IsNotNil(err)) + }) + } +} + func TestTemplateFindOneAndDelete(t *testing.T) { initDocument() for _, tt := range initListTestFindOneAndDelete() { @@ -250,6 +267,23 @@ func TestTemplateFindOneAndDelete(t *testing.T) { } } +func TestTemplateFindOneAndReplaceById(t *testing.T) { + initDocument() + for _, tt := range initListTestFindOneAndReplaceById() { + t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.TODO(), tt.durationTimeout) + defer cancel() + err := mongoTemplate.FindOneAndReplaceById(ctx, tt.id, tt.replacement, tt.dest, tt.option, nil) + if helper.IsNotEqualTo(helper.IsNotNil(err), tt.wantErr) { + t.Errorf("FindOneAndReplaceById() error = %v, wantErr %v", err, tt.wantErr) + } else if helper.IsNotNil(err) { + t.Log("err expected:", err) + } + _ = mongoTemplate.CloseSession(ctx, helper.IsNotNil(err)) + }) + } +} + func TestTemplateFindOneAndReplace(t *testing.T) { initDocument() for _, tt := range initListTestFindOneAndReplace() { @@ -267,6 +301,23 @@ func TestTemplateFindOneAndReplace(t *testing.T) { } } +func TestTemplateFindOneAndUpdateById(t *testing.T) { + initDocument() + for _, tt := range initListTestFindOneAndUpdateById() { + t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.TODO(), tt.durationTimeout) + defer cancel() + err := mongoTemplate.FindOneAndUpdateById(ctx, tt.id, tt.update, tt.dest, tt.option, nil) + if helper.IsNotEqualTo(helper.IsNotNil(err), tt.wantErr) { + t.Errorf("FindOneAndUpdateById() error = %v, wantErr %v", err, tt.wantErr) + } else if helper.IsNotNil(err) { + t.Log("err expected:", err) + } + _ = mongoTemplate.CloseSession(ctx, helper.IsNotNil(err)) + }) + } +} + func TestTemplateFindOneAndUpdate(t *testing.T) { initDocument() for _, tt := range initListTestFindOneAndUpdate() { diff --git a/mongo/watch.go b/mongo/watch.go index 637662f..4770fa1 100644 --- a/mongo/watch.go +++ b/mongo/watch.go @@ -2,7 +2,6 @@ package mongo import ( "context" - "github.com/GabrielHCataldo/go-errors/errors" "github.com/GabrielHCataldo/go-helper/helper" "github.com/GabrielHCataldo/go-mongo-template/mongo/option" "go.mongodb.org/mongo-driver/bson" @@ -45,10 +44,9 @@ type EventHandler func(ctx *EventContext) // Decode convert Event.FullDocument to struct func (f FullDocument) Decode(dest any) error { if helper.IsNotStruct(dest) { - return errDestIsNotStruct(2) + return ErrDestIsNotStruct } - err := helper.ConvertToDest(f, dest) - return errors.NewSkipCaller(2, err) + return helper.ConvertToDest(f, dest) } func processNextEvent(handler EventHandler, event Event, opt *option.WatchWithHandler) {