diff --git a/db/mongo.go b/db/mongo.go index f9ee41d..1183cc1 100644 --- a/db/mongo.go +++ b/db/mongo.go @@ -59,7 +59,7 @@ func (c *mongoCollection) SetKeyType(keyType reflect.Type) error { // inserts one entry with given key and data to the collection // returns errors if entry already exists or if there is a connection // error with the database server -func (c *mongoCollection) InsertOne(ctx context.Context, key interface{}, data interface{}) error { +func (c *mongoCollection) InsertOne(ctx context.Context, key any, data any) error { if data == nil { return errors.Wrap(errors.InvalidArgument, "db Insert error: No data to store") } @@ -105,7 +105,7 @@ func (c *mongoCollection) InsertOne(ctx context.Context, key interface{}, data i // acts based on the flag passed for upsert // returns errors if entry not found while upsert flag is false or if // there is a connection error with the database server -func (c *mongoCollection) UpdateOne(ctx context.Context, key interface{}, data interface{}, upsert bool) error { +func (c *mongoCollection) UpdateOne(ctx context.Context, key any, data any, upsert bool) error { if data == nil { return errors.Wrap(errors.InvalidArgument, "db Insert error: No data to store") } @@ -137,7 +137,7 @@ func (c *mongoCollection) UpdateOne(ctx context.Context, key interface{}, data i // Find one entry from the store collection for the given key, where the data // value is returned based on the object type passed to it -func (c *mongoCollection) FindOne(ctx context.Context, key interface{}, data interface{}) error { +func (c *mongoCollection) FindOne(ctx context.Context, key any, data any) error { resp := c.col.FindOne(ctx, bson.M{"_id": key}) // decode the value returned by the mongodb client into the data // object passed by the caller @@ -150,7 +150,7 @@ func (c *mongoCollection) FindOne(ctx context.Context, key interface{}, data int // Find multiple entries from the store collection for the given filter, where the data // value is returned as a list based on the object type passed to it -func (c *mongoCollection) FindMany(ctx context.Context, filter interface{}, data interface{}) error { +func (c *mongoCollection) FindMany(ctx context.Context, filter any, data any) error { if filter == nil { filter = bson.D{} } @@ -164,8 +164,20 @@ func (c *mongoCollection) FindMany(ctx context.Context, filter interface{}, data return nil } +// Return count of entries matching the provided filter +func (c *mongoCollection) Count(ctx context.Context, filter any) (int64, error) { + if filter == nil { + filter = bson.D{} + } + count, err := c.col.CountDocuments(ctx, filter) + if err != nil { + return 0, interpretMongoError(err) + } + return count, nil +} + // remove one entry from the collection matching the given key -func (c *mongoCollection) DeleteOne(ctx context.Context, key interface{}) error { +func (c *mongoCollection) DeleteOne(ctx context.Context, key any) error { resp, err := c.col.DeleteOne(ctx, bson.M{"_id": key}) if err != nil { // TODO(prabhjot) we may need to identify and differentiate @@ -181,7 +193,7 @@ func (c *mongoCollection) DeleteOne(ctx context.Context, key interface{}) error // Delete Many entries matching the delete criteria // returns number of entries deleted and if there is any error processing the request -func (c *mongoCollection) DeleteMany(ctx context.Context, filter interface{}) (int64, error) { +func (c *mongoCollection) DeleteMany(ctx context.Context, filter any) (int64, error) { resp, err := c.col.DeleteMany(ctx, filter) if err != nil { return 0, interpretMongoError(err) @@ -197,7 +209,7 @@ func (c *mongoCollection) DeleteMany(ctx context.Context, filter interface{}) (i // allow provisiong for a filter to be passed on, where the callback // function to receive only conditional notifications of the events // listener is interested about -func (c *mongoCollection) Watch(ctx context.Context, filter interface{}, cb WatchCallbackfn) error { +func (c *mongoCollection) Watch(ctx context.Context, filter any, cb WatchCallbackfn) error { if filter == nil { // if passed filter is nil, initialize it to empty pipeline object filter = mongo.Pipeline{} @@ -262,7 +274,7 @@ func (c *mongoCollection) Watch(ctx context.Context, filter interface{}, cb Watc } // key that will be shared with callback function - var key interface{} + var key any if keyType != nil { key = reflect.New(keyType.Elem()).Interface() } else { diff --git a/db/mongo_test.go b/db/mongo_test.go index 363c47a..0edb30d 100644 --- a/db/mongo_test.go +++ b/db/mongo_test.go @@ -270,6 +270,15 @@ func Test_CollectionWatch(t *testing.T) { t.Errorf("failed to update an entry to collection Error: %s", err) } + count, err := col.Count(context.Background(), nil) + if err != nil { + t.Errorf("failed to get count of entries in collection: %s", err) + } + + if count != 1 { + t.Errorf("Expected 1 entries in table but got %d", count) + } + err = col.DeleteOne(context.Background(), key) if err != nil { t.Errorf("failed to delete entry using key Error: %s", err) diff --git a/db/store.go b/db/store.go index f39e42f..35f5407 100644 --- a/db/store.go +++ b/db/store.go @@ -12,7 +12,7 @@ import ( ) // WatchCallbackfn responsible for -type WatchCallbackfn func(op string, key interface{}) +type WatchCallbackfn func(op string, key any) // interface definition for a collection in store type StoreCollection interface { @@ -26,34 +26,37 @@ type StoreCollection interface { SetKeyType(keyType reflect.Type) error // insert one entry to the collection for the given key and data - InsertOne(ctx context.Context, key interface{}, data interface{}) error + InsertOne(ctx context.Context, key any, data any) error // update one entry in the collection for the given key and data // if upsert flag is set, it would insert an entry if it doesn't // exist while updating - UpdateOne(ctx context.Context, key interface{}, data interface{}, upsert bool) error + UpdateOne(ctx context.Context, key any, data any, upsert bool) error // Find one entry from the store collection for the given key, where the data // value is returned based on the object type passed to it - FindOne(ctx context.Context, key interface{}, data interface{}) error + FindOne(ctx context.Context, key any, data any) error // Find multiple entries from the store collection for the given filter, where the data // value is returned as a list based on the object type passed to it - FindMany(ctx context.Context, filter interface{}, data interface{}) error + FindMany(ctx context.Context, filter any, data any) error + + // Return count of entries matching the provided filter + Count(ctx context.Context, filter any) (int64, error) // remove one entry from the collection matching the given key - DeleteOne(ctx context.Context, key interface{}) error + DeleteOne(ctx context.Context, key any) error // Delete Many entries matching the delete criteria // returns number of entries deleted and if there is any error processing the request - DeleteMany(ctx context.Context, filter interface{}) (int64, error) + DeleteMany(ctx context.Context, filter any) (int64, error) // watch allows getting notified whenever a change happens to a document // in the collection // allow provisiong for a filter to be passed on, where the callback // function to receive only conditional notifications of the events // listener is interested about - Watch(ctx context.Context, filter interface{}, cb WatchCallbackfn) error + Watch(ctx context.Context, filter any, cb WatchCallbackfn) error } // interface definition for a store, responsible for holding group