From a3b530ab5ba59ede28fba01772ec95a18706a2ce Mon Sep 17 00:00:00 2001 From: brianchennn Date: Mon, 7 Aug 2023 15:51:09 +0000 Subject: [PATCH 1/4] add Strength option by Functional Options Pattern --- fsm/fsm.go | 6 +++--- idgenerator/idgenerator.go | 2 +- mongoapi/mongoapi.go | 41 ++++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/fsm/fsm.go b/fsm/fsm.go index 3c56e61..a7b0f04 100644 --- a/fsm/fsm.go +++ b/fsm/fsm.go @@ -87,9 +87,9 @@ func NewFSM(transitions Transitions, callbacks Callbacks) (*FSM, error) { // SendEvent triggers a callback with an event, and do transition after callback if need // There are 3 types of callback: -// - on exit callback: call when fsm leave one state, with ExitEvent event -// - event callback: call when user trigger a user-defined event -// - on entry callback: call when fsm enter one state, with EntryEvent event +// - on exit callback: call when fsm leave one state, with ExitEvent event +// - event callback: call when user trigger a user-defined event +// - on entry callback: call when fsm enter one state, with EntryEvent event func (fsm *FSM) SendEvent(state *State, event EventType, args ArgsType, log *logrus.Entry) error { key := eventKey{ From: state.Current(), diff --git a/idgenerator/idgenerator.go b/idgenerator/idgenerator.go index 0be1bca..b0df238 100644 --- a/idgenerator/idgenerator.go +++ b/idgenerator/idgenerator.go @@ -56,7 +56,7 @@ func (idGenerator *IDGenerator) Allocate() (int64, error) { } // param: -// - id: id to free +// - id: id to free func (idGenerator *IDGenerator) FreeID(id int64) { if id < idGenerator.minValue || id > idGenerator.maxValue { return diff --git a/mongoapi/mongoapi.go b/mongoapi/mongoapi.go index cab85c2..5f47b45 100644 --- a/mongoapi/mongoapi.go +++ b/mongoapi/mongoapi.go @@ -32,9 +32,15 @@ func SetMongoDB(setdbName string, url string) error { return nil } -func findOneAndDecode(collection *mongo.Collection, filter bson.M) (map[string]interface{}, error) { +func findOneAndDecode(collection *mongo.Collection, filter bson.M, argOpt ...int) (map[string]interface{}, error) { var result map[string]interface{} - if err := collection.FindOne(context.TODO(), filter).Decode(&result); err != nil { + opts := new(options.FindOneOptions) + if len(argOpt) > 0 { + myCollation := &options.Collation{Locale: "en_US", Strength: argOpt[0]} + opts.SetCollation(myCollation) + } + + if err := collection.FindOne(context.TODO(), filter, opts).Decode(&result); err != nil { // ErrNoDocuments means that the filter did not match any documents in // the collection. if err == mongo.ErrNoDocuments { @@ -45,8 +51,15 @@ func findOneAndDecode(collection *mongo.Collection, filter bson.M) (map[string]i return result, nil } -func getOrigData(collection *mongo.Collection, filter bson.M) (map[string]interface{}, error) { - result, err := findOneAndDecode(collection, filter) +func getOrigData(collection *mongo.Collection, filter bson.M, argOpt ...int) ( + result map[string]interface{}, err error, +) { + if len(argOpt) == 0 { + result, err = findOneAndDecode(collection, filter) + } else { + result, err = findOneAndDecode(collection, filter, argOpt[0]) + } + if err != nil { return nil, err } @@ -68,21 +81,33 @@ func checkDataExisted(collection *mongo.Collection, filter bson.M) (bool, error) return true, nil } -func RestfulAPIGetOne(collName string, filter bson.M) (map[string]interface{}, error) { +func RestfulAPIGetOne(collName string, filter bson.M, argOpt ...int) (result map[string]interface{}, err error) { collection := Client.Database(dbName).Collection(collName) - result, err := getOrigData(collection, filter) + if len(argOpt) == 0 { + result, err = getOrigData(collection, filter) + } else { + result, err = getOrigData(collection, filter, argOpt[0]) + } + if err != nil { return nil, fmt.Errorf("RestfulAPIGetOne err: %+v", err) } return result, nil } -func RestfulAPIGetMany(collName string, filter bson.M) ([]map[string]interface{}, error) { +func RestfulAPIGetMany(collName string, filter bson.M, argOpt ...int) ([]map[string]interface{}, error) { collection := Client.Database(dbName).Collection(collName) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - cur, err := collection.Find(ctx, filter) + + opts := new(options.FindOptions) + if len(argOpt) > 0 { + myCollation := &options.Collation{Locale: "en_US", Strength: argOpt[0]} + opts.SetCollation(myCollation) + } + + cur, err := collection.Find(ctx, filter, opts) if err != nil { return nil, fmt.Errorf("RestfulAPIGetMany err: %+v", err) } From 2491aae59d1444e1425e071cb6f82684b8078cea Mon Sep 17 00:00:00 2001 From: brianchennn Date: Tue, 8 Aug 2023 04:41:06 +0000 Subject: [PATCH 2/4] implement all function with WithStrength --- mongoapi/mongoapi.go | 163 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 129 insertions(+), 34 deletions(-) diff --git a/mongoapi/mongoapi.go b/mongoapi/mongoapi.go index 5f47b45..32fb5b8 100644 --- a/mongoapi/mongoapi.go +++ b/mongoapi/mongoapi.go @@ -32,11 +32,18 @@ func SetMongoDB(setdbName string, url string) error { return nil } -func findOneAndDecode(collection *mongo.Collection, filter bson.M, argOpt ...int) (map[string]interface{}, error) { +func findOneAndDecode(collection *mongo.Collection, filter bson.M, argOpt ...interface{}) ( + map[string]interface{}, error, +) { var result map[string]interface{} opts := new(options.FindOneOptions) if len(argOpt) > 0 { - myCollation := &options.Collation{Locale: "en_US", Strength: argOpt[0]} + strength, ok := argOpt[0].(int) + if !ok { + return nil, fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} opts.SetCollation(myCollation) } @@ -51,15 +58,10 @@ func findOneAndDecode(collection *mongo.Collection, filter bson.M, argOpt ...int return result, nil } -func getOrigData(collection *mongo.Collection, filter bson.M, argOpt ...int) ( +func getOrigData(collection *mongo.Collection, filter bson.M, argOpt ...interface{}) ( result map[string]interface{}, err error, ) { - if len(argOpt) == 0 { - result, err = findOneAndDecode(collection, filter) - } else { - result, err = findOneAndDecode(collection, filter, argOpt[0]) - } - + result, err = findOneAndDecode(collection, filter, argOpt...) if err != nil { return nil, err } @@ -70,8 +72,8 @@ func getOrigData(collection *mongo.Collection, filter bson.M, argOpt ...int) ( return result, nil } -func checkDataExisted(collection *mongo.Collection, filter bson.M) (bool, error) { - result, err := findOneAndDecode(collection, filter) +func checkDataExisted(collection *mongo.Collection, filter bson.M, argOpt ...interface{}) (bool, error) { + result, err := findOneAndDecode(collection, filter, argOpt...) if err != nil { return false, err } @@ -82,30 +84,34 @@ func checkDataExisted(collection *mongo.Collection, filter bson.M) (bool, error) } func RestfulAPIGetOne(collName string, filter bson.M, argOpt ...int) (result map[string]interface{}, err error) { - collection := Client.Database(dbName).Collection(collName) - if len(argOpt) == 0 { - result, err = getOrigData(collection, filter) - } else { - result, err = getOrigData(collection, filter, argOpt[0]) - } + return RestfulAPIGetOneWithStrength(collName, filter, 3) +} +func RestfulAPIGetOneWithStrength(collName string, filter bson.M, argOpt ...interface{}) ( + result map[string]interface{}, err error, +) { + collection := Client.Database(dbName).Collection(collName) + result, err = getOrigData(collection, filter, argOpt...) if err != nil { return nil, fmt.Errorf("RestfulAPIGetOne err: %+v", err) } + return result, nil } -func RestfulAPIGetMany(collName string, filter bson.M, argOpt ...int) ([]map[string]interface{}, error) { +func RestfulAPIGetMany(collName string, filter bson.M) ([]map[string]interface{}, error) { + return RestfulAPIGetManyWithStrength(collName, filter, 3) +} + +func RestfulAPIGetManyWithStrength(collName string, filter bson.M, strength int) ([]map[string]interface{}, error) { collection := Client.Database(dbName).Collection(collName) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() opts := new(options.FindOptions) - if len(argOpt) > 0 { - myCollation := &options.Collation{Locale: "en_US", Strength: argOpt[0]} - opts.SetCollation(myCollation) - } + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) cur, err := collection.Find(ctx, filter, opts) if err != nil { @@ -137,8 +143,14 @@ func RestfulAPIGetMany(collName string, filter bson.M, argOpt ...int) ([]map[str // if no error happened, return true means data existed and false means data not existed func RestfulAPIPutOne(collName string, filter bson.M, putData map[string]interface{}) (bool, error) { + return RestfulAPIPutOneWithStrength(collName, filter, putData, 3) +} + +func RestfulAPIPutOneWithStrength(collName string, filter bson.M, putData map[string]interface{}, strength int) ( + bool, error, +) { collection := Client.Database(dbName).Collection(collName) - existed, err := checkDataExisted(collection, filter) + existed, err := checkDataExisted(collection, filter, strength) if err != nil { return false, fmt.Errorf("RestfulAPIPutOne err: %+v", err) } @@ -157,8 +169,18 @@ func RestfulAPIPutOne(collName string, filter bson.M, putData map[string]interfa } func RestfulAPIPullOne(collName string, filter bson.M, putData map[string]interface{}) error { + return RestfulAPIPullOneWithStrength(collName, filter, putData, 3) +} + +func RestfulAPIPullOneWithStrength(collName string, filter bson.M, putData map[string]interface{}, strength int) error { collection := Client.Database(dbName).Collection(collName) - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$pull": putData}); err != nil { + + opts := new(options.UpdateOptions) + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + + if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$pull": putData}, opts); err != nil { return fmt.Errorf("RestfulAPIPullOne err: %+v", err) } return nil @@ -166,8 +188,15 @@ func RestfulAPIPullOne(collName string, filter bson.M, putData map[string]interf // if no error happened, return true means data existed (not updated) and false means data not existed func RestfulAPIPutOneNotUpdate(collName string, filter bson.M, putData map[string]interface{}) (bool, error) { + return RestfulAPIPutOneNotUpdateWithStrength(collName, filter, putData, 3) +} + +func RestfulAPIPutOneNotUpdateWithStrength( + collName string, filter bson.M, putData map[string]interface{}, strength int) ( + bool, error, +) { collection := Client.Database(dbName).Collection(collName) - existed, err := checkDataExisted(collection, filter) + existed, err := checkDataExisted(collection, filter, strength) if err != nil { return false, fmt.Errorf("RestfulAPIPutOneNotUpdate err: %+v", err) } @@ -183,11 +212,17 @@ func RestfulAPIPutOneNotUpdate(collName string, filter bson.M, putData map[strin } func RestfulAPIPutMany(collName string, filterArray []bson.M, putDataArray []map[string]interface{}) error { + return RestfulAPIPutManyWithStrength(collName, filterArray, putDataArray, 3) +} + +func RestfulAPIPutManyWithStrength( + collName string, filterArray []bson.M, putDataArray []map[string]interface{}, strength int, +) error { collection := Client.Database(dbName).Collection(collName) for i, putData := range putDataArray { filter := filterArray[i] - existed, err := checkDataExisted(collection, filter) + existed, err := checkDataExisted(collection, filter, strength) if err != nil { return fmt.Errorf("RestfulAPIPutMany err: %+v", err) } @@ -206,27 +241,51 @@ func RestfulAPIPutMany(collName string, filterArray []bson.M, putDataArray []map } func RestfulAPIDeleteOne(collName string, filter bson.M) error { + return RestfulAPIDeleteOneWithStrength(collName, filter, 3) +} + +func RestfulAPIDeleteOneWithStrength(collName string, filter bson.M, strength int) error { collection := Client.Database(dbName).Collection(collName) - if _, err := collection.DeleteOne(context.TODO(), filter); err != nil { + opts := new(options.DeleteOptions) + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + + if _, err := collection.DeleteOne(context.TODO(), filter, opts); err != nil { return fmt.Errorf("RestfulAPIDeleteOne err: %+v", err) } return nil } func RestfulAPIDeleteMany(collName string, filter bson.M) error { + return RestfulAPIDeleteManyWithStrength(collName, filter, 3) +} + +func RestfulAPIDeleteManyWithStrength(collName string, filter bson.M, strength int) error { collection := Client.Database(dbName).Collection(collName) - if _, err := collection.DeleteMany(context.TODO(), filter); err != nil { + opts := new(options.DeleteOptions) + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + + if _, err := collection.DeleteMany(context.TODO(), filter, opts); err != nil { return fmt.Errorf("RestfulAPIDeleteMany err: %+v", err) } return nil } func RestfulAPIMergePatch(collName string, filter bson.M, patchData map[string]interface{}) error { + return RestfulAPIMergePatchWithStrength(collName, filter, patchData, 3) +} + +func RestfulAPIMergePatchWithStrength( + collName string, filter bson.M, patchData map[string]interface{}, strength int, +) error { collection := Client.Database(dbName).Collection(collName) - originalData, err := getOrigData(collection, filter) + originalData, err := getOrigData(collection, filter, strength) if err != nil { return fmt.Errorf("RestfulAPIMergePatch getOrigData err: %+v", err) } @@ -250,16 +309,26 @@ func RestfulAPIMergePatch(collName string, filter bson.M, patchData map[string]i if err := json.Unmarshal(modifiedAlternative, &modifiedData); err != nil { return fmt.Errorf("RestfulAPIMergePatch Unmarshal err: %+v", err) } - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}); err != nil { + + opts := new(options.UpdateOptions) + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + + if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts); err != nil { return fmt.Errorf("RestfulAPIMergePatch UpdateOne err: %+v", err) } return nil } func RestfulAPIJSONPatch(collName string, filter bson.M, patchJSON []byte) error { + return RestfulAPIJSONPatchWithStrength(collName, filter, patchJSON, 3) +} + +func RestfulAPIJSONPatchWithStrength(collName string, filter bson.M, patchJSON []byte, strength int) error { collection := Client.Database(dbName).Collection(collName) - originalData, err := getOrigData(collection, filter) + originalData, err := getOrigData(collection, filter, strength) if err != nil { return fmt.Errorf("RestfulAPIJSONPatch getOrigData err: %+v", err) } @@ -283,16 +352,28 @@ func RestfulAPIJSONPatch(collName string, filter bson.M, patchJSON []byte) error if err := json.Unmarshal(modified, &modifiedData); err != nil { return fmt.Errorf("RestfulAPIJSONPatch Unmarshal err: %+v", err) } - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}); err != nil { + + opts := new(options.UpdateOptions) + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + + if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts); err != nil { return fmt.Errorf("RestfulAPIJSONPatch UpdateOne err: %+v", err) } return nil } func RestfulAPIJSONPatchExtend(collName string, filter bson.M, patchJSON []byte, dataName string) error { + return RestfulAPIJSONPatchExtendWithStrength(collName, filter, patchJSON, dataName, 3) +} + +func RestfulAPIJSONPatchExtendWithStrength( + collName string, filter bson.M, patchJSON []byte, dataName string, strength int, +) error { collection := Client.Database(dbName).Collection(collName) - originalDataCover, err := getOrigData(collection, filter) + originalDataCover, err := getOrigData(collection, filter, strength) if err != nil { return fmt.Errorf("RestfulAPIJSONPatchExtend getOrigData err: %+v", err) } @@ -317,7 +398,15 @@ func RestfulAPIJSONPatchExtend(collName string, filter bson.M, patchJSON []byte, if err := json.Unmarshal(modified, &modifiedData); err != nil { return fmt.Errorf("RestfulAPIJSONPatchExtend Unmarshal err: %+v", err) } - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": bson.M{dataName: modifiedData}}); err != nil { + + opts := new(options.UpdateOptions) + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + + if _, err := collection.UpdateOne( + context.TODO(), filter, bson.M{"$set": bson.M{dataName: modifiedData}}, opts, + ); err != nil { return fmt.Errorf("RestfulAPIJSONPatchExtend UpdateOne err: %+v", err) } return nil @@ -327,6 +416,12 @@ func RestfulAPIPost(collName string, filter bson.M, postData map[string]interfac return RestfulAPIPutOne(collName, filter, postData) } +func RestfulAPIPostWithStrength( + collName string, filter bson.M, postData map[string]interface{}, strength int, +) (bool, error) { + return RestfulAPIPutOneWithStrength(collName, filter, postData, strength) +} + func RestfulAPIPostMany(collName string, filter bson.M, postDataArray []interface{}) error { collection := Client.Database(dbName).Collection(collName) From b39645b36154428353d03a03a8321a87b123fbb1 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Thu, 10 Aug 2023 04:56:26 +0000 Subject: [PATCH 3/4] replace all function name to xxxWithArg() --- mongoapi/mongoapi.go | 155 ++++++++++++++++++++++++++++--------------- 1 file changed, 100 insertions(+), 55 deletions(-) diff --git a/mongoapi/mongoapi.go b/mongoapi/mongoapi.go index 32fb5b8..3e9500d 100644 --- a/mongoapi/mongoapi.go +++ b/mongoapi/mongoapi.go @@ -84,10 +84,10 @@ func checkDataExisted(collection *mongo.Collection, filter bson.M, argOpt ...int } func RestfulAPIGetOne(collName string, filter bson.M, argOpt ...int) (result map[string]interface{}, err error) { - return RestfulAPIGetOneWithStrength(collName, filter, 3) + return RestfulAPIGetOneWithArg(collName, filter) } -func RestfulAPIGetOneWithStrength(collName string, filter bson.M, argOpt ...interface{}) ( +func RestfulAPIGetOneWithArg(collName string, filter bson.M, argOpt ...interface{}) ( result map[string]interface{}, err error, ) { collection := Client.Database(dbName).Collection(collName) @@ -100,18 +100,25 @@ func RestfulAPIGetOneWithStrength(collName string, filter bson.M, argOpt ...inte } func RestfulAPIGetMany(collName string, filter bson.M) ([]map[string]interface{}, error) { - return RestfulAPIGetManyWithStrength(collName, filter, 3) + return RestfulAPIGetManyWithArg(collName, filter) } -func RestfulAPIGetManyWithStrength(collName string, filter bson.M, strength int) ([]map[string]interface{}, error) { +func RestfulAPIGetManyWithArg(collName string, filter bson.M, argOpt ...interface{}) ([]map[string]interface{}, error) { collection := Client.Database(dbName).Collection(collName) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() opts := new(options.FindOptions) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return nil, fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } cur, err := collection.Find(ctx, filter, opts) if err != nil { @@ -143,14 +150,14 @@ func RestfulAPIGetManyWithStrength(collName string, filter bson.M, strength int) // if no error happened, return true means data existed and false means data not existed func RestfulAPIPutOne(collName string, filter bson.M, putData map[string]interface{}) (bool, error) { - return RestfulAPIPutOneWithStrength(collName, filter, putData, 3) + return RestfulAPIPutOneWithArg(collName, filter, putData) } -func RestfulAPIPutOneWithStrength(collName string, filter bson.M, putData map[string]interface{}, strength int) ( +func RestfulAPIPutOneWithArg(collName string, filter bson.M, putData map[string]interface{}, argOpt ...interface{}) ( bool, error, ) { collection := Client.Database(dbName).Collection(collName) - existed, err := checkDataExisted(collection, filter, strength) + existed, err := checkDataExisted(collection, filter, argOpt...) if err != nil { return false, fmt.Errorf("RestfulAPIPutOne err: %+v", err) } @@ -169,16 +176,24 @@ func RestfulAPIPutOneWithStrength(collName string, filter bson.M, putData map[st } func RestfulAPIPullOne(collName string, filter bson.M, putData map[string]interface{}) error { - return RestfulAPIPullOneWithStrength(collName, filter, putData, 3) + return RestfulAPIPullOneWithArg(collName, filter, putData) } -func RestfulAPIPullOneWithStrength(collName string, filter bson.M, putData map[string]interface{}, strength int) error { +func RestfulAPIPullOneWithArg(collName string, filter bson.M, + putData map[string]interface{}, argOpt ...interface{}, +) error { collection := Client.Database(dbName).Collection(collName) opts := new(options.UpdateOptions) - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$pull": putData}, opts); err != nil { return fmt.Errorf("RestfulAPIPullOne err: %+v", err) @@ -188,15 +203,15 @@ func RestfulAPIPullOneWithStrength(collName string, filter bson.M, putData map[s // if no error happened, return true means data existed (not updated) and false means data not existed func RestfulAPIPutOneNotUpdate(collName string, filter bson.M, putData map[string]interface{}) (bool, error) { - return RestfulAPIPutOneNotUpdateWithStrength(collName, filter, putData, 3) + return RestfulAPIPutOneNotUpdateWithArg(collName, filter, putData) } -func RestfulAPIPutOneNotUpdateWithStrength( - collName string, filter bson.M, putData map[string]interface{}, strength int) ( +func RestfulAPIPutOneNotUpdateWithArg( + collName string, filter bson.M, putData map[string]interface{}, argOpt ...interface{}) ( bool, error, ) { collection := Client.Database(dbName).Collection(collName) - existed, err := checkDataExisted(collection, filter, strength) + existed, err := checkDataExisted(collection, filter, argOpt...) if err != nil { return false, fmt.Errorf("RestfulAPIPutOneNotUpdate err: %+v", err) } @@ -212,17 +227,17 @@ func RestfulAPIPutOneNotUpdateWithStrength( } func RestfulAPIPutMany(collName string, filterArray []bson.M, putDataArray []map[string]interface{}) error { - return RestfulAPIPutManyWithStrength(collName, filterArray, putDataArray, 3) + return RestfulAPIPutManyWithArg(collName, filterArray, putDataArray) } -func RestfulAPIPutManyWithStrength( - collName string, filterArray []bson.M, putDataArray []map[string]interface{}, strength int, +func RestfulAPIPutManyWithArg( + collName string, filterArray []bson.M, putDataArray []map[string]interface{}, argOpt ...interface{}, ) error { collection := Client.Database(dbName).Collection(collName) for i, putData := range putDataArray { filter := filterArray[i] - existed, err := checkDataExisted(collection, filter, strength) + existed, err := checkDataExisted(collection, filter, argOpt...) if err != nil { return fmt.Errorf("RestfulAPIPutMany err: %+v", err) } @@ -241,16 +256,22 @@ func RestfulAPIPutManyWithStrength( } func RestfulAPIDeleteOne(collName string, filter bson.M) error { - return RestfulAPIDeleteOneWithStrength(collName, filter, 3) + return RestfulAPIDeleteOneWithArg(collName, filter) } -func RestfulAPIDeleteOneWithStrength(collName string, filter bson.M, strength int) error { +func RestfulAPIDeleteOneWithArg(collName string, filter bson.M, argOpt ...interface{}) error { collection := Client.Database(dbName).Collection(collName) opts := new(options.DeleteOptions) - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } if _, err := collection.DeleteOne(context.TODO(), filter, opts); err != nil { return fmt.Errorf("RestfulAPIDeleteOne err: %+v", err) @@ -259,16 +280,22 @@ func RestfulAPIDeleteOneWithStrength(collName string, filter bson.M, strength in } func RestfulAPIDeleteMany(collName string, filter bson.M) error { - return RestfulAPIDeleteManyWithStrength(collName, filter, 3) + return RestfulAPIDeleteManyWithArg(collName, filter) } -func RestfulAPIDeleteManyWithStrength(collName string, filter bson.M, strength int) error { +func RestfulAPIDeleteManyWithArg(collName string, filter bson.M, argOpt ...interface{}) error { collection := Client.Database(dbName).Collection(collName) opts := new(options.DeleteOptions) - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } if _, err := collection.DeleteMany(context.TODO(), filter, opts); err != nil { return fmt.Errorf("RestfulAPIDeleteMany err: %+v", err) @@ -277,15 +304,15 @@ func RestfulAPIDeleteManyWithStrength(collName string, filter bson.M, strength i } func RestfulAPIMergePatch(collName string, filter bson.M, patchData map[string]interface{}) error { - return RestfulAPIMergePatchWithStrength(collName, filter, patchData, 3) + return RestfulAPIMergePatchWithArg(collName, filter, patchData) } -func RestfulAPIMergePatchWithStrength( - collName string, filter bson.M, patchData map[string]interface{}, strength int, +func RestfulAPIMergePatchWithArg( + collName string, filter bson.M, patchData map[string]interface{}, argOpt ...interface{}, ) error { collection := Client.Database(dbName).Collection(collName) - originalData, err := getOrigData(collection, filter, strength) + originalData, err := getOrigData(collection, filter, argOpt...) if err != nil { return fmt.Errorf("RestfulAPIMergePatch getOrigData err: %+v", err) } @@ -311,9 +338,15 @@ func RestfulAPIMergePatchWithStrength( } opts := new(options.UpdateOptions) - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts); err != nil { return fmt.Errorf("RestfulAPIMergePatch UpdateOne err: %+v", err) @@ -322,13 +355,13 @@ func RestfulAPIMergePatchWithStrength( } func RestfulAPIJSONPatch(collName string, filter bson.M, patchJSON []byte) error { - return RestfulAPIJSONPatchWithStrength(collName, filter, patchJSON, 3) + return RestfulAPIJSONPatchWithArg(collName, filter, patchJSON) } -func RestfulAPIJSONPatchWithStrength(collName string, filter bson.M, patchJSON []byte, strength int) error { +func RestfulAPIJSONPatchWithArg(collName string, filter bson.M, patchJSON []byte, argOpt ...interface{}) error { collection := Client.Database(dbName).Collection(collName) - originalData, err := getOrigData(collection, filter, strength) + originalData, err := getOrigData(collection, filter, argOpt...) if err != nil { return fmt.Errorf("RestfulAPIJSONPatch getOrigData err: %+v", err) } @@ -354,9 +387,15 @@ func RestfulAPIJSONPatchWithStrength(collName string, filter bson.M, patchJSON [ } opts := new(options.UpdateOptions) - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts); err != nil { return fmt.Errorf("RestfulAPIJSONPatch UpdateOne err: %+v", err) @@ -365,15 +404,15 @@ func RestfulAPIJSONPatchWithStrength(collName string, filter bson.M, patchJSON [ } func RestfulAPIJSONPatchExtend(collName string, filter bson.M, patchJSON []byte, dataName string) error { - return RestfulAPIJSONPatchExtendWithStrength(collName, filter, patchJSON, dataName, 3) + return RestfulAPIJSONPatchExtendWithArg(collName, filter, patchJSON, dataName) } -func RestfulAPIJSONPatchExtendWithStrength( - collName string, filter bson.M, patchJSON []byte, dataName string, strength int, +func RestfulAPIJSONPatchExtendWithArg( + collName string, filter bson.M, patchJSON []byte, dataName string, argOpt ...interface{}, ) error { collection := Client.Database(dbName).Collection(collName) - originalDataCover, err := getOrigData(collection, filter, strength) + originalDataCover, err := getOrigData(collection, filter, argOpt...) if err != nil { return fmt.Errorf("RestfulAPIJSONPatchExtend getOrigData err: %+v", err) } @@ -400,9 +439,15 @@ func RestfulAPIJSONPatchExtendWithStrength( } opts := new(options.UpdateOptions) - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + if len(argOpt) > 0 { + strength, ok := argOpt[0].(int) + if !ok { + return fmt.Errorf("argOpt[0] type is not int") + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + myCollation := &options.Collation{Locale: "en_US", Strength: strength} + opts.SetCollation(myCollation) + } if _, err := collection.UpdateOne( context.TODO(), filter, bson.M{"$set": bson.M{dataName: modifiedData}}, opts, @@ -416,10 +461,10 @@ func RestfulAPIPost(collName string, filter bson.M, postData map[string]interfac return RestfulAPIPutOne(collName, filter, postData) } -func RestfulAPIPostWithStrength( - collName string, filter bson.M, postData map[string]interface{}, strength int, +func RestfulAPIPostWithArg( + collName string, filter bson.M, postData map[string]interface{}, argOpt ...interface{}, ) (bool, error) { - return RestfulAPIPutOneWithStrength(collName, filter, postData, strength) + return RestfulAPIPutOneWithArg(collName, filter, postData, argOpt...) } func RestfulAPIPostMany(collName string, filter bson.M, postDataArray []interface{}) error { From 0f3fd971ab77e5ae6da83a6613fb154d04f920dc Mon Sep 17 00:00:00 2001 From: brianchennn Date: Wed, 16 Aug 2023 12:34:19 +0000 Subject: [PATCH 4/4] refactor mongoapi.go --- mongoapi/mongoapi.go | 172 +++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/mongoapi/mongoapi.go b/mongoapi/mongoapi.go index 3e9500d..1682e97 100644 --- a/mongoapi/mongoapi.go +++ b/mongoapi/mongoapi.go @@ -32,22 +32,33 @@ func SetMongoDB(setdbName string, url string) error { return nil } +func getCollation(argOpt ...interface{}) *options.Collation { + if len(argOpt) == 0 { + return nil + } + strength, ok := argOpt[0].(int) + if !ok { + return nil + } + // Strength 2: Case insensitive, 3: Case sensitive (default) + return &options.Collation{Locale: "en_US", Strength: strength} +} + func findOneAndDecode(collection *mongo.Collection, filter bson.M, argOpt ...interface{}) ( map[string]interface{}, error, ) { var result map[string]interface{} - opts := new(options.FindOneOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return nil, fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + var err error + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.FindOneOptions) + opts.SetCollation(collation) + err = collection.FindOne(context.TODO(), filter, opts).Decode(&result) + } else { + err = collection.FindOne(context.TODO(), filter).Decode(&result) } - if err := collection.FindOne(context.TODO(), filter, opts).Decode(&result); err != nil { + if err != nil { // ErrNoDocuments means that the filter did not match any documents in // the collection. if err == mongo.ErrNoDocuments { @@ -83,7 +94,7 @@ func checkDataExisted(collection *mongo.Collection, filter bson.M, argOpt ...int return true, nil } -func RestfulAPIGetOne(collName string, filter bson.M, argOpt ...int) (result map[string]interface{}, err error) { +func RestfulAPIGetOne(collName string, filter bson.M) (result map[string]interface{}, err error) { return RestfulAPIGetOneWithArg(collName, filter) } @@ -109,18 +120,17 @@ func RestfulAPIGetManyWithArg(collName string, filter bson.M, argOpt ...interfac ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - opts := new(options.FindOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return nil, fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + var cur *mongo.Cursor + var err error + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.FindOptions) + opts.SetCollation(collation) + cur, err = collection.Find(ctx, filter, opts) + } else { + cur, err = collection.Find(ctx, filter) } - cur, err := collection.Find(ctx, filter, opts) if err != nil { return nil, fmt.Errorf("RestfulAPIGetMany err: %+v", err) } @@ -184,18 +194,17 @@ func RestfulAPIPullOneWithArg(collName string, filter bson.M, ) error { collection := Client.Database(dbName).Collection(collName) - opts := new(options.UpdateOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + var err error + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.UpdateOptions) + opts.SetCollation(collation) + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$pull": putData}, opts) + } else { + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$pull": putData}) } - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$pull": putData}, opts); err != nil { + if err != nil { return fmt.Errorf("RestfulAPIPullOne err: %+v", err) } return nil @@ -262,18 +271,17 @@ func RestfulAPIDeleteOne(collName string, filter bson.M) error { func RestfulAPIDeleteOneWithArg(collName string, filter bson.M, argOpt ...interface{}) error { collection := Client.Database(dbName).Collection(collName) - opts := new(options.DeleteOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + var err error + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.DeleteOptions) + opts.SetCollation(collation) + _, err = collection.DeleteOne(context.TODO(), filter, opts) + } else { + _, err = collection.DeleteOne(context.TODO(), filter) } - if _, err := collection.DeleteOne(context.TODO(), filter, opts); err != nil { + if err != nil { return fmt.Errorf("RestfulAPIDeleteOne err: %+v", err) } return nil @@ -286,18 +294,17 @@ func RestfulAPIDeleteMany(collName string, filter bson.M) error { func RestfulAPIDeleteManyWithArg(collName string, filter bson.M, argOpt ...interface{}) error { collection := Client.Database(dbName).Collection(collName) - opts := new(options.DeleteOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + var err error + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.DeleteOptions) + opts.SetCollation(collation) + _, err = collection.DeleteMany(context.TODO(), filter, opts) + } else { + _, err = collection.DeleteMany(context.TODO(), filter) } - if _, err := collection.DeleteMany(context.TODO(), filter, opts); err != nil { + if err != nil { return fmt.Errorf("RestfulAPIDeleteMany err: %+v", err) } return nil @@ -333,22 +340,20 @@ func RestfulAPIMergePatchWithArg( } var modifiedData map[string]interface{} - if err := json.Unmarshal(modifiedAlternative, &modifiedData); err != nil { + if err = json.Unmarshal(modifiedAlternative, &modifiedData); err != nil { return fmt.Errorf("RestfulAPIMergePatch Unmarshal err: %+v", err) } - opts := new(options.UpdateOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.UpdateOptions) + opts.SetCollation(collation) + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts) + } else { + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}) } - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts); err != nil { + if err != nil { return fmt.Errorf("RestfulAPIMergePatch UpdateOne err: %+v", err) } return nil @@ -382,24 +387,23 @@ func RestfulAPIJSONPatchWithArg(collName string, filter bson.M, patchJSON []byte } var modifiedData map[string]interface{} - if err := json.Unmarshal(modified, &modifiedData); err != nil { + if err = json.Unmarshal(modified, &modifiedData); err != nil { return fmt.Errorf("RestfulAPIJSONPatch Unmarshal err: %+v", err) } - opts := new(options.UpdateOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.UpdateOptions) + opts.SetCollation(collation) + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts) + } else { + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}) } - if _, err := collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts); err != nil { + if err != nil { return fmt.Errorf("RestfulAPIJSONPatch UpdateOne err: %+v", err) } + return nil } @@ -434,24 +438,20 @@ func RestfulAPIJSONPatchExtendWithArg( } var modifiedData map[string]interface{} - if err := json.Unmarshal(modified, &modifiedData); err != nil { + if err = json.Unmarshal(modified, &modifiedData); err != nil { return fmt.Errorf("RestfulAPIJSONPatchExtend Unmarshal err: %+v", err) } - opts := new(options.UpdateOptions) - if len(argOpt) > 0 { - strength, ok := argOpt[0].(int) - if !ok { - return fmt.Errorf("argOpt[0] type is not int") - } - // Strength 2: Case insensitive, 3: Case sensitive (default) - myCollation := &options.Collation{Locale: "en_US", Strength: strength} - opts.SetCollation(myCollation) + collation := getCollation(argOpt...) + if collation != nil { + opts := new(options.UpdateOptions) + opts.SetCollation(collation) + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}, opts) + } else { + _, err = collection.UpdateOne(context.TODO(), filter, bson.M{"$set": modifiedData}) } - if _, err := collection.UpdateOne( - context.TODO(), filter, bson.M{"$set": bson.M{dataName: modifiedData}}, opts, - ); err != nil { + if err != nil { return fmt.Errorf("RestfulAPIJSONPatchExtend UpdateOne err: %+v", err) } return nil