Skip to content

Commit

Permalink
Add Transaction feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
mehran-prs committed Jan 21, 2020
1 parent dccce09 commit 65560ef
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 24 deletions.
65 changes: 55 additions & 10 deletions collection.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mgm

import (
"context"
"github.com/Kamva/mgm/builder"
"github.com/Kamva/mgm/field"
"go.mongodb.org/mongo-driver/bson"
Expand All @@ -17,51 +18,91 @@ type Collection struct {
// id field can be any value that if passed to `PrepareID` method, it return
// valid id(e.g string,bson.ObjectId).
func (coll *Collection) FindByID(id interface{}, model Model) error {
return coll.FindByIDWithCtx(ctx(), id, model)
}

// FindByIDWithCtx method find a doc and decode it to model, otherwise return error.
// id field can be any value that if passed to `PrepareID` method, it return
// valid id(e.g string,bson.ObjectId).
func (coll *Collection) FindByIDWithCtx(ctx context.Context, id interface{}, model Model) error {
id, err := model.PrepareID(id)

if err != nil {
return err
}

return first(coll, bson.M{field.ID: id}, model)
return first(ctx, coll, bson.M{field.ID: id}, model)
}

// First method search and return first document of search result.
func (coll *Collection) First(filter interface{}, model Model, opts ...*options.FindOneOptions) error {
return first(coll, filter, model, opts...)
return coll.FirstWithCtx(ctx(), filter, model, opts...)
}

// FirstWithCtx method search and return first document of search result.
func (coll *Collection) FirstWithCtx(ctx context.Context, filter interface{}, model Model, opts ...*options.FindOneOptions) error {
return first(ctx, coll, filter, model, opts...)
}

// Create method insert new model into database.
func (coll *Collection) Create(model Model) error {
return create(coll, model)
return coll.CreateWithCtx(ctx(), model)
}

// CreateWithCtx method insert new model into database.
func (coll *Collection) CreateWithCtx(ctx context.Context, model Model) error {
return create(ctx, coll, model)
}

// Update function update save changed model into database.
// On call to this method also mgm call to model's updating,updated,
// saving,saved hooks.
func (coll *Collection) Update(model Model) error {
return update(coll, model)
return coll.UpdateWithCtx(ctx(), model)
}

// UpdateWithCtx function update save changed model into database.
// On call to this method also mgm call to model's updating,updated,
// saving,saved hooks.
func (coll *Collection) UpdateWithCtx(ctx context.Context, model Model) error {
return update(ctx, coll, model)
}

// Save method save model(insert,update).
func (coll *Collection) Save(model Model) error {
return coll.SaveWithCtx(ctx(), model)
}

// SaveWithCtx method save model(insert,update).
func (coll *Collection) SaveWithCtx(ctx context.Context, model Model) error {
if model.IsNew() {
return create(coll, model)
return create(ctx, coll, model)
}

return update(coll, model)
return update(ctx, coll, model)
}

// Delete method delete model (doc) from collection.
// If you want to doing something on deleting some model
// use hooks, don't need to override this method.
func (coll *Collection) Delete(model Model) error {
return del(coll, model)
return del(ctx(), coll, model)
}

// SimpleFind find and decode result to results.
// DeleteWithCtx method delete model (doc) from collection.
// If you want to doing something on deleting some model
// use hooks, don't need to override this method.
func (coll *Collection) DeleteWithCtx(ctx context.Context, model Model) error {
return del(ctx, coll, model)
}

// SimpleFindWithCtx find and decode result to results.
func (coll *Collection) SimpleFind(results interface{}, filter interface{}, opts ...*options.FindOptions) error {
ctx := ctx()
return coll.SimpleFindWithCtx(ctx(), results, filter, opts...)
}

// SimpleFind find and decode result to results.
func (coll *Collection) SimpleFindWithCtx(ctx context.Context, results interface{}, filter interface{}, opts ...*options.FindOptions) error {
cur, err := coll.Find(ctx, filter, opts...)

if err != nil {
Expand All @@ -77,6 +118,8 @@ func (coll *Collection) SimpleFind(results interface{}, filter interface{}, opts

// SimpleAggregate doing simple aggregation and decode aggregate result to the results.
// stages value can be Operator|bson.M
// Note: you can not use this method in a transaction because it does not get context.
//So you should use the regular aggregation method in transactions.
func (coll *Collection) SimpleAggregate(results interface{}, stages ...interface{}) error {
cur, err := coll.SimpleAggregateCursor(stages...)
if err != nil {
Expand All @@ -87,6 +130,8 @@ func (coll *Collection) SimpleAggregate(results interface{}, stages ...interface
}

// SimpleAggregateCursor doing simple aggregation and return cursor.
// Note: you can not use this method in a transaction because it does not get context.
// So you should use the regular aggregation method in transactions.
func (coll *Collection) SimpleAggregateCursor(stages ...interface{}) (*mongo.Cursor, error) {
pipeline := bson.A{}

Expand All @@ -99,4 +144,4 @@ func (coll *Collection) SimpleAggregateCursor(stages ...interface{}) (*mongo.Cur
}

return coll.Aggregate(ctx(), pipeline, nil)
}
}
167 changes: 167 additions & 0 deletions cover.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
mode: set
github.com/Kamva/mgm/builder/types.go:13.31,16.32 2 1
github.com/Kamva/mgm/builder/types.go:20.2,20.10 1 1
github.com/Kamva/mgm/builder/types.go:16.32,18.3 1 1
github.com/Kamva/mgm/builder/types.go:24.38,28.2 2 1
github.com/Kamva/mgm/builder/util.go:9.60,10.22 1 1
github.com/Kamva/mgm/builder/util.go:10.22,12.3 1 1
github.com/Kamva/mgm/builder/aggregate_stages.go:10.68,19.2 6 1
github.com/Kamva/mgm/builder/aggregate_stages.go:22.77,31.2 6 1
github.com/Kamva/mgm/builder/aggregate_stages.go:34.72,42.2 5 1
github.com/Kamva/mgm/builder/aggregate_stages.go:45.101,55.2 7 1
github.com/Kamva/mgm/builder/aggregate_stages.go:61.52,66.31 3 1
github.com/Kamva/mgm/builder/aggregate_stages.go:70.2,70.24 1 1
github.com/Kamva/mgm/builder/aggregate_stages.go:66.31,68.3 1 1
github.com/Kamva/mgm/builder/aggregate_stages.go:74.70,83.2 6 1
github.com/Kamva/mgm/builder/aggregate_stages.go:86.71,95.2 6 1
github.com/Kamva/mgm/builder/aggregate_stages.go:98.77,108.2 7 1
github.com/Kamva/mgm/builder/aggregate_stages.go:111.48,117.2 3 1
github.com/Kamva/mgm/builder/aggregate_stages.go:120.40,126.2 3 1
github.com/Kamva/mgm/builder/aggregate_stages.go:129.87,137.2 5 1
github.com/Kamva/mgm/builder/operator.go:17.47,19.2 1 1
github.com/Kamva/mgm/builder/operator.go:22.52,24.2 1 1
github.com/Kamva/mgm/builder/operator.go:27.48,32.2 1 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:10.13,17.2 4 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:19.22,22.2 2 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:24.21,38.16 6 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:42.2,44.20 2 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:55.2,55.12 1 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:38.16,40.3 1 0
github.com/Kamva/mgm/examples/aggregate/aggregate.go:44.20,47.17 3 1
github.com/Kamva/mgm/examples/aggregate/aggregate.go:47.17,49.4 1 0
github.com/Kamva/mgm/examples/aggregate/connection.go:8.13,10.2 1 1
github.com/Kamva/mgm/examples/aggregate/model.go:15.71,21.2 1 1
github.com/Kamva/mgm/examples/aggregate/model.go:28.37,32.2 1 1
github.com/Kamva/mgm/examples/crud/crud.go:5.19,10.47 3 1
github.com/Kamva/mgm/examples/crud/crud.go:14.2,15.45 2 1
github.com/Kamva/mgm/examples/crud/crud.go:19.2,19.31 1 1
github.com/Kamva/mgm/examples/crud/crud.go:10.47,12.3 1 0
github.com/Kamva/mgm/examples/crud/crud.go:15.45,17.3 1 0
github.com/Kamva/mgm/examples/crud/crud.go:22.13,25.2 1 0
github.com/Kamva/mgm/examples/crud/model.go:13.44,18.2 1 1
github.com/Kamva/mgm/examples/crud/connection.go:8.13,10.2 1 1
github.com/Kamva/mgm/model.go:37.45,39.2 1 1
github.com/Kamva/mgm/model.go:42.43,44.2 1 1
github.com/Kamva/mgm/model_field.go:22.66,23.34 1 1
github.com/Kamva/mgm/model_field.go:28.2,28.16 1 1
github.com/Kamva/mgm/model_field.go:23.34,25.3 1 1
github.com/Kamva/mgm/model_field.go:32.32,34.2 1 1
github.com/Kamva/mgm/model_field.go:37.39,39.2 1 1
github.com/Kamva/mgm/model_field.go:42.41,44.2 1 1
github.com/Kamva/mgm/model_field.go:52.39,55.2 2 1
github.com/Kamva/mgm/model_field.go:59.37,62.2 2 1
github.com/Kamva/mgm/operation.go:10.68,12.55 1 1
github.com/Kamva/mgm/operation.go:16.2,18.16 2 1
github.com/Kamva/mgm/operation.go:23.2,25.38 2 1
github.com/Kamva/mgm/operation.go:12.55,14.3 1 1
github.com/Kamva/mgm/operation.go:18.16,20.3 1 0
github.com/Kamva/mgm/operation.go:28.120,30.2 1 1
github.com/Kamva/mgm/operation.go:32.68,34.55 1 1
github.com/Kamva/mgm/operation.go:38.2,40.16 2 1
github.com/Kamva/mgm/operation.go:44.2,44.43 1 1
github.com/Kamva/mgm/operation.go:34.55,36.3 1 1
github.com/Kamva/mgm/operation.go:40.16,42.3 1 0
github.com/Kamva/mgm/operation.go:47.65,48.55 1 1
github.com/Kamva/mgm/operation.go:51.2,52.16 2 1
github.com/Kamva/mgm/operation.go:56.2,56.43 1 1
github.com/Kamva/mgm/operation.go:48.55,50.3 1 1
github.com/Kamva/mgm/operation.go:52.16,54.3 1 0
github.com/Kamva/mgm/collection.go:20.69,22.2 1 1
github.com/Kamva/mgm/collection.go:27.97,30.16 2 1
github.com/Kamva/mgm/collection.go:34.2,34.54 1 1
github.com/Kamva/mgm/collection.go:30.16,32.3 1 1
github.com/Kamva/mgm/collection.go:38.103,40.2 1 1
github.com/Kamva/mgm/collection.go:43.131,45.2 1 1
github.com/Kamva/mgm/collection.go:48.51,50.2 1 1
github.com/Kamva/mgm/collection.go:53.79,55.2 1 1
github.com/Kamva/mgm/collection.go:60.51,62.2 1 1
github.com/Kamva/mgm/collection.go:67.79,69.2 1 1
github.com/Kamva/mgm/collection.go:72.49,74.2 1 1
github.com/Kamva/mgm/collection.go:77.77,78.19 1 1
github.com/Kamva/mgm/collection.go:82.2,82.33 1 1
github.com/Kamva/mgm/collection.go:78.19,80.3 1 1
github.com/Kamva/mgm/collection.go:88.51,90.2 1 1
github.com/Kamva/mgm/collection.go:95.79,97.2 1 0
github.com/Kamva/mgm/collection.go:100.113,102.2 1 1
github.com/Kamva/mgm/collection.go:105.141,108.16 2 1
github.com/Kamva/mgm/collection.go:112.2,112.30 1 1
github.com/Kamva/mgm/collection.go:108.16,110.3 1 0
github.com/Kamva/mgm/collection.go:123.91,125.16 2 1
github.com/Kamva/mgm/collection.go:129.2,129.32 1 1
github.com/Kamva/mgm/collection.go:125.16,127.3 1 0
github.com/Kamva/mgm/collection.go:135.93,138.31 2 1
github.com/Kamva/mgm/collection.go:146.2,146.45 1 1
github.com/Kamva/mgm/collection.go:138.31,139.51 1 1
github.com/Kamva/mgm/collection.go:139.51,141.4 1 1
github.com/Kamva/mgm/collection.go:141.9,143.4 1 1
github.com/Kamva/mgm/hooks.go:46.49,47.42 1 1
github.com/Kamva/mgm/hooks.go:53.2,53.40 1 1
github.com/Kamva/mgm/hooks.go:59.2,59.12 1 1
github.com/Kamva/mgm/hooks.go:47.42,48.41 1 1
github.com/Kamva/mgm/hooks.go:48.41,50.4 1 1
github.com/Kamva/mgm/hooks.go:53.40,54.39 1 1
github.com/Kamva/mgm/hooks.go:54.39,56.4 1 1
github.com/Kamva/mgm/hooks.go:62.49,63.42 1 1
github.com/Kamva/mgm/hooks.go:69.2,69.40 1 1
github.com/Kamva/mgm/hooks.go:75.2,75.12 1 1
github.com/Kamva/mgm/hooks.go:63.42,64.41 1 1
github.com/Kamva/mgm/hooks.go:64.41,66.4 1 1
github.com/Kamva/mgm/hooks.go:69.40,70.39 1 1
github.com/Kamva/mgm/hooks.go:70.39,72.4 1 0
github.com/Kamva/mgm/hooks.go:78.48,79.41 1 1
github.com/Kamva/mgm/hooks.go:85.2,85.39 1 1
github.com/Kamva/mgm/hooks.go:91.2,91.12 1 1
github.com/Kamva/mgm/hooks.go:79.41,80.40 1 1
github.com/Kamva/mgm/hooks.go:80.40,82.4 1 0
github.com/Kamva/mgm/hooks.go:85.39,86.38 1 1
github.com/Kamva/mgm/hooks.go:86.38,88.4 1 0
github.com/Kamva/mgm/hooks.go:94.82,95.41 1 1
github.com/Kamva/mgm/hooks.go:101.2,101.39 1 1
github.com/Kamva/mgm/hooks.go:107.2,107.12 1 1
github.com/Kamva/mgm/hooks.go:95.41,96.52 1 1
github.com/Kamva/mgm/hooks.go:96.52,98.4 1 0
github.com/Kamva/mgm/hooks.go:101.39,102.38 1 1
github.com/Kamva/mgm/hooks.go:102.38,104.4 1 0
github.com/Kamva/mgm/hooks.go:110.49,111.42 1 1
github.com/Kamva/mgm/hooks.go:117.2,117.12 1 1
github.com/Kamva/mgm/hooks.go:111.42,112.41 1 1
github.com/Kamva/mgm/hooks.go:112.41,114.4 1 1
github.com/Kamva/mgm/hooks.go:120.82,121.41 1 1
github.com/Kamva/mgm/hooks.go:127.2,127.12 1 1
github.com/Kamva/mgm/hooks.go:121.41,122.52 1 1
github.com/Kamva/mgm/hooks.go:122.52,124.4 1 0
github.com/Kamva/mgm/util.go:10.32,12.48 1 1
github.com/Kamva/mgm/util.go:16.2,16.38 1 1
github.com/Kamva/mgm/util.go:12.48,14.3 1 0
github.com/Kamva/mgm/util.go:22.31,24.56 1 1
github.com/Kamva/mgm/util.go:28.2,30.50 2 1
github.com/Kamva/mgm/util.go:24.56,26.3 1 1
github.com/Kamva/mgm/connection.go:23.52,27.2 2 1
github.com/Kamva/mgm/connection.go:31.28,33.2 1 1
github.com/Kamva/mgm/connection.go:35.28,37.2 1 1
github.com/Kamva/mgm/connection.go:40.71,42.16 2 1
github.com/Kamva/mgm/connection.go:46.2,46.45 1 1
github.com/Kamva/mgm/connection.go:50.2,50.20 1 1
github.com/Kamva/mgm/connection.go:42.16,44.3 1 0
github.com/Kamva/mgm/connection.go:46.45,48.3 1 0
github.com/Kamva/mgm/connection.go:54.101,58.2 2 1
github.com/Kamva/mgm/connection.go:61.27,65.2 3 1
github.com/Kamva/mgm/connection.go:68.96,72.17 1 1
github.com/Kamva/mgm/connection.go:76.2,78.50 2 1
github.com/Kamva/mgm/connection.go:82.2,84.12 2 1
github.com/Kamva/mgm/connection.go:72.17,74.3 1 1
github.com/Kamva/mgm/connection.go:78.50,80.3 1 0
github.com/Kamva/mgm/connection.go:88.84,90.2 1 1
github.com/Kamva/mgm/connection.go:93.72,94.37 1 1
github.com/Kamva/mgm/connection.go:98.2,98.32 1 1
github.com/Kamva/mgm/connection.go:94.37,96.3 1 1
github.com/Kamva/mgm/connection.go:103.28,105.2 1 1
github.com/Kamva/mgm/transaction.go:11.43,13.2 1 1
github.com/Kamva/mgm/transaction.go:16.71,18.2 1 1
github.com/Kamva/mgm/transaction.go:21.96,23.16 2 1
github.com/Kamva/mgm/transaction.go:27.2,29.50 2 1
github.com/Kamva/mgm/transaction.go:33.2,33.51 1 1
github.com/Kamva/mgm/transaction.go:37.2,37.51 1 1
github.com/Kamva/mgm/transaction.go:23.16,25.3 1 0
github.com/Kamva/mgm/transaction.go:29.50,31.3 1 0
github.com/Kamva/mgm/transaction.go:33.51,35.3 1 1
5 changes: 0 additions & 5 deletions examples/crud/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,3 @@ func crud() error {

return booksColl.Delete(book)
}

func find() {
// Get document's collection
mgm.Coll(&book{})
}
2 changes: 1 addition & 1 deletion internal/util/reflection.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package util

import "reflect"

// IsNil function check value is nil or no.To check real value of interface
// IsNil function check value is nil or no. To check real value of interface
// is nil or not, should using reflection, check this
// https://play.golang.org/p/Isoo0CcAvr. Firstly check
// `val==nil` because reflection can not get value of
Expand Down
17 changes: 9 additions & 8 deletions operation.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package mgm

import (
"context"
"github.com/Kamva/mgm/field"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)

func create(c *Collection, model Model) error {
func create(ctx context.Context, c *Collection, model Model) error {
// Call to saving hook
if err := callToBeforeCreateHooks(model); err != nil {
return err
}

res, err := c.InsertOne(ctx(), model)
res, err := c.InsertOne(ctx, model)

if err != nil {
return err
Expand All @@ -24,17 +25,17 @@ func create(c *Collection, model Model) error {
return callToAfterCreateHooks(model)
}

func first(c *Collection, filter interface{}, model Model, opts ...*options.FindOneOptions) error {
return c.FindOne(ctx(), filter, opts...).Decode(model)
func first(ctx context.Context, c *Collection, filter interface{}, model Model, opts ...*options.FindOneOptions) error {
return c.FindOne(ctx, filter, opts...).Decode(model)
}

func update(c *Collection, model Model) error {
func update(ctx context.Context, c *Collection, model Model) error {
// Call to saving hook
if err := callToBeforeUpdateHooks(model); err != nil {
return err
}

res, err := c.UpdateOne(ctx(), bson.M{field.ID: model.GetID()}, bson.M{"$set": model})
res, err := c.UpdateOne(ctx, bson.M{field.ID: model.GetID()}, bson.M{"$set": model})

if err != nil {
return err
Expand All @@ -43,11 +44,11 @@ func update(c *Collection, model Model) error {
return callToAfterUpdateHooks(res, model)
}

func del(c *Collection, model Model) error {
func del(ctx context.Context, c *Collection, model Model) error {
if err := callToBeforeDeleteHooks(model); err != nil {
return err
}
res, err := c.DeleteOne(ctx(), bson.M{field.ID: model.GetID()})
res, err := c.DeleteOne(ctx, bson.M{field.ID: model.GetID()})
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 65560ef

Please sign in to comment.