Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions db/mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,66 @@ func (c *mongoCollection) InsertOne(ctx context.Context, key interface{}, data i
return nil
}

// inserts or updates one entry with given key and data to the collection
// 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 {
if data == nil {
return errors.Wrap(errors.InvalidArgument, "db Insert error: No data to store")
}
if key == nil {
return errors.Wrap(errors.InvalidArgument, "db Insert error: No Key specified to store")
}

opts := options.Update().SetUpsert(upsert)
resp, err := c.col.UpdateOne(
ctx,
bson.M{"_id": key},
bson.D{
{Key: "$set", Value: data},
},
opts)

if err != nil {
return err
}

// check there should be at least one entry in matched count
// or upserted count to not return an error here
if resp.MatchedCount != 0 && resp.UpsertedCount != 0 {
return errors.Wrap(errors.NotFound, "No Document found")
}

return nil
}

// 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 {
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
if err := resp.Decode(data); err != nil {
// TODO(prabhjot) might have to identify not found error
return err
}
return nil
}

// 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 {
cursor, err := c.col.Find(ctx, filter)
if err != nil {
return err
}
if err = cursor.All(ctx, data); err != nil {
return err
}
return nil
}

// remove one entry from the collection matching the given key
func (c *mongoCollection) DeleteOne(ctx context.Context, key interface{}) error {
resp, err := c.col.DeleteOne(ctx, bson.M{"_id": key})
Expand Down
38 changes: 38 additions & 0 deletions db/mongo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ type MyKey struct {
Name string
}

type InternaData struct {
Test string
}

type MyData struct {
Desc string
Val *InternaData
}

func Test_ClientConnection(t *testing.T) {
Expand Down Expand Up @@ -46,12 +51,35 @@ func Test_ClientConnection(t *testing.T) {
}
data := &MyData{
Desc: "sample-description",
Val: &InternaData{
Test: "abc",
},
}

err = col.InsertOne(context.Background(), key, data)
if err != nil {
t.Errorf("failed to insert an entry to collection Error: %s", err)
}

val := &MyData{}
err = col.FindOne(context.Background(), key, val)
if err != nil {
t.Errorf("failed to find the entry Error: %s", err)
}

data.Desc = "new description"
data.Val.Test = "xyz"
err = col.UpdateOne(context.Background(), key, data, false)
if err != nil {
t.Errorf("failed to update an entry to collection Error: %s", err)
}

val = &MyData{}
err = col.FindOne(context.Background(), key, val)
if err != nil {
t.Errorf("failed to find the entry Error: %s", err)
}

err = col.DeleteOne(context.Background(), key)
if err != nil {
t.Errorf("failed to delete entry using key Error: %s", err)
Expand All @@ -61,6 +89,16 @@ func Test_ClientConnection(t *testing.T) {
if err == nil {
t.Errorf("attemptting delete on already deleted entry, but didn't receive expected error")
}

err = col.UpdateOne(context.Background(), key, data, true)
if err != nil {
t.Errorf("failed to update an entry to collection Error: %s", err)
}

err = col.DeleteOne(context.Background(), key)
if err != nil {
t.Errorf("failed to delete entry using key Error: %s", err)
}
})

t.Run("InValid_Port", func(t *testing.T) {
Expand Down
13 changes: 13 additions & 0 deletions db/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ type StoreCollection interface {
// insert one entry to the collection for the given key and data
InsertOne(ctx context.Context, key interface{}, data interface{}) 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

// 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

// 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

// remove one entry from the collection matching the given key
DeleteOne(ctx context.Context, key interface{}) error
}
Expand Down