Skip to content
This repository has been archived by the owner on Apr 5, 2023. It is now read-only.

Commit

Permalink
src: update one is just a computed field
Browse files Browse the repository at this point in the history
  • Loading branch information
remorses committed Jun 11, 2020
1 parent c8f6de5 commit 529a06e
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 195 deletions.
1 change: 0 additions & 1 deletion src/database_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type DatabaseInterface interface {
// FindMany should return p.First + 1 nodes, or p.Last + 1 nodes, so goke can compute `hasNextPage` and `hasPreviousPage`
FindMany(ctx context.Context, p FindManyParams, hook TransformDocument) ([]Map, error)
InsertMany(ctx context.Context, p InsertManyParams, hook TransformDocument) (NodesMutationPayload, error)
UpdateOne(ctx context.Context, p UpdateParams, hook TransformDocument) (NodeMutationPayload, error)
UpdateMany(ctx context.Context, p UpdateParams, hook TransformDocument) (NodesMutationPayload, error)
DeleteMany(ctx context.Context, p DeleteManyParams, hook TransformDocument) (NodesMutationPayload, error)
}
Expand Down
62 changes: 4 additions & 58 deletions src/fakedata/fakedata.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (self *FakeDatabaseFunctions) FindMany(ctx context.Context, p goke.FindMany
if err != nil {
return nil, err
}
nodes, err = goke.FilterDocuments(nodes, hook)
nodes, err = goke.FilterDocuments(nodes, hook) // TODO filtering after will potentially remove documents, making the limit lower than the query one
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -101,64 +101,11 @@ func (self *FakeDatabaseFunctions) InsertMany(ctx context.Context, p goke.Insert
}, nil
}

func (self *FakeDatabaseFunctions) UpdateOne(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument) (goke.NodeMutationPayload, error) {
db, err := self.Init(ctx)
payload := goke.NodeMutationPayload{
Returning: nil,
AffectedCount: 0,
}
if err != nil {
return payload, err
}

// TODO this step of checking could be skipped if there are no guards
nodes, err := self.FindMany(ctx, goke.FindManyParams{
Collection: p.Collection,
Limit: 1,
Where: p.Where,
}, hook)
if err != nil {
return payload, err
}
if len(nodes) == 0 {
return payload, nil
}

// make sure we update the document we checked with the hook
where := goke.ExtendWhereMatch(
p.Where,
map[string]goke.Filter{
"_id": {
Eq: nodes[0]["_id"],
},
},
)
match := mongodb.MakeMongodbMatch(where)

opts := options.FindOneAndUpdate()
opts.SetReturnDocument(options.After)
testutil.PrettyPrint(p)

res := db.Collection(p.Collection).FindOneAndUpdate(ctx, match, bson.M{"$set": p.Set}, opts)
if res.Err() == mongo.ErrNoDocuments {
println("no docs to update")
return payload, nil
} else if res.Err() != nil {
return payload, err
}
data := goke.Map{}
err = res.Decode(&data)
if err != nil {
return payload, err
}
return goke.NodeMutationPayload{
AffectedCount: 1,
Returning: data,
}, nil
}

// first updateMany documents, then query again the documents and return them, all inside a transaction that prevents other writes happen before the query
func (self *FakeDatabaseFunctions) UpdateMany(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument) (goke.NodesMutationPayload, error) {
if p.Limit == 0 {
p.Limit = math.MaxInt16
}
db, err := self.Init(ctx)
payload := goke.NodesMutationPayload{
Returning: nil,
Expand Down Expand Up @@ -190,7 +137,6 @@ func (self *FakeDatabaseFunctions) UpdateMany(ctx context.Context, p goke.Update

res := db.Collection(p.Collection).FindOneAndUpdate(ctx, match, bson.M{"$set": p.Set}, opts)
if res.Err() == mongo.ErrNoDocuments {
println("no docs to update")
return payload, nil
} else if res.Err() != nil {
return payload, err
Expand Down
17 changes: 13 additions & 4 deletions src/fields/update_one.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/graphql-go/graphql"
"github.com/mitchellh/mapstructure"
goke "github.com/remorses/goke/src"
"github.com/remorses/goke/src/testutil"
"github.com/remorses/goke/src/types"
)

Expand All @@ -23,6 +22,7 @@ func UpdateOne(p CreateFieldParams) (*graphql.Field, error) {
args := params.Args
opts := goke.UpdateParams{
Collection: p.Collection,
Limit: 1,
}
err := mapstructure.Decode(args, &opts)
if err != nil {
Expand All @@ -35,7 +35,7 @@ func UpdateOne(p CreateFieldParams) (*graphql.Field, error) {
}
opts.Where = where
}
res, err := p.Config.DatabaseFunctions.UpdateOne(
res, err := p.Config.DatabaseFunctions.UpdateMany(
params.Context,
opts,
func(document goke.Map) (goke.Map, error) {
Expand All @@ -47,11 +47,20 @@ func UpdateOne(p CreateFieldParams) (*graphql.Field, error) {
})
},
)
println(testutil.Pretty(res))
// println(testutil.Pretty(res))
if err != nil {
return nil, err
}
return res, nil
if len(res.Returning) == 0 {
return goke.NodeMutationPayload{
AffectedCount: res.AffectedCount,
}, nil
}

return goke.NodeMutationPayload{
AffectedCount: res.AffectedCount,
Returning: res.Returning[0],
}, nil
}

// if err != nil {
Expand Down
23 changes: 4 additions & 19 deletions src/firestore/firestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,10 @@ func (self *FirestoreDatabaseFunctions) InsertMany(ctx context.Context, p goke.I
return payload, nil
}

func (self *FirestoreDatabaseFunctions) UpdateOne(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument) (goke.NodeMutationPayload, error) {
res, err := self.updateMany(ctx, p, hook, 1)
payload := goke.NodeMutationPayload{}
if err != nil {
return payload, err
}
if len(res.Returning) == 0 {
return payload, nil
}
payload.Returning = res.Returning[0]
payload.AffectedCount = 1
return payload, nil
}

func (self *FirestoreDatabaseFunctions) UpdateMany(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument) (goke.NodesMutationPayload, error) {
return self.updateMany(ctx, p, hook, math.MaxInt16)
}

func (self *FirestoreDatabaseFunctions) updateMany(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument, count int) (goke.NodesMutationPayload, error) {
if p.Limit == 0 {
p.Limit = math.MaxInt16
}
db, err := self.Init(ctx)
payload := goke.NodesMutationPayload{}
if err != nil {
Expand All @@ -126,7 +111,7 @@ func (self *FirestoreDatabaseFunctions) updateMany(ctx context.Context, p goke.U
iter := query.Documents(ctx)
defer iter.Stop()
// TODO use batching for firestore's updateMany
for payload.AffectedCount < count {
for payload.AffectedCount < p.Limit {
doc, err := iter.Next()
if err == iterator.Done {
break
Expand Down
55 changes: 0 additions & 55 deletions src/mock/database_interface_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 4 additions & 58 deletions src/mongodb/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,67 +102,14 @@ func (self *MongodbDatabaseFunctions) InsertMany(ctx context.Context, p goke.Ins
}, nil
}

func (self *MongodbDatabaseFunctions) UpdateOne(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument) (goke.NodeMutationPayload, error) {
db, err := self.Init(ctx)
payload := goke.NodeMutationPayload{
Returning: nil,
AffectedCount: 0,
}
if err != nil {
return payload, err
}

// TODO this step of checking could be skipped if there are no guards
nodes, err := self.FindMany(ctx, goke.FindManyParams{
Collection: p.Collection,
Limit: 1,
Where: p.Where,
}, hook)
if err != nil {
return payload, err
}
if len(nodes) == 0 {
return payload, nil
}

// make sure we update the document we checked with the hook
where := goke.ExtendWhereMatch(
p.Where,
map[string]goke.Filter{
"_id": {
Eq: nodes[0]["_id"],
},
},
)
match := MakeMongodbMatch(where)

opts := options.FindOneAndUpdate()
opts.SetReturnDocument(options.After)
testutil.PrettyPrint(p)

res := db.Collection(p.Collection).FindOneAndUpdate(ctx, match, bson.M{"$set": p.Set}, opts)
if res.Err() == mongo.ErrNoDocuments {
println("no docs to update")
return payload, nil
} else if res.Err() != nil {
return payload, err
}
data := goke.Map{}
err = res.Decode(&data)
if err != nil {
return payload, err
}
return goke.NodeMutationPayload{
AffectedCount: 1,
Returning: data,
}, nil
}

// first updateMany documents, then query again the documents and return them, all inside a transaction that prevents other writes happen before the query
func (self *MongodbDatabaseFunctions) UpdateMany(ctx context.Context, p goke.UpdateParams, hook goke.TransformDocument) (goke.NodesMutationPayload, error) {
if p.Limit == 0 {
p.Limit = math.MaxInt16
}
db, err := self.Init(ctx)
payload := goke.NodesMutationPayload{
Returning: nil,
Returning: nil, // TODO maybe list should be allocated to not return null
AffectedCount: 0,
}
if err != nil {
Expand Down Expand Up @@ -191,7 +138,6 @@ func (self *MongodbDatabaseFunctions) UpdateMany(ctx context.Context, p goke.Upd

res := db.Collection(p.Collection).FindOneAndUpdate(ctx, match, bson.M{"$set": p.Set}, opts)
if res.Err() == mongo.ErrNoDocuments {
println("no docs to update")
return payload, nil
} else if res.Err() != nil {
return payload, err
Expand Down

0 comments on commit 529a06e

Please sign in to comment.