Skip to content

Commit

Permalink
Backport push each patch (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyshields authored Jan 8, 2018
1 parent 98bdf06 commit 9ccc394
Show file tree
Hide file tree
Showing 6 changed files with 886 additions and 32 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ If you would only like some of the patches, please copy and paste the code to yo
| `instrument.rb` | Backport instrumentation change to Moped 1. ||||
| `reorder.rb` | Backport `Criteria#reorder` method from Mongoid 4. ||||
| `only_pluck_localized.rb` | Backport [PR #4299](https://github.com/mongodb/mongoid/pull/4299) from Mongoid 6 which fixes `#only`, `#without`, and `#pluck` with localized fields. || × | × |
| `push_each.rb` | Backport [PR #4460](https://github.com/mongodb/mongoid/pull/4460) to replace usage of $pushAll with $push + $each for MongoDB 3.6 support. || × | × |
| `embedded_touch.rb` (1) | Backport [Issue #3310](https://github.com/mongodb/mongoid/commit/a94c2f43573e58f973913c881ad9d11d62bf857c) from Mongoid 4 to add `:touch` option to `embedded_in`. ||||
| `embedded_touch.rb` (2) | Backport [PR #4392](https://github.com/mongodb/mongoid/pull/4392) from Mongoid 6 to fix an infinite loop issue related to `:touch` callbacks. ||||
| `index_options.rb` | Backport latest index valid index options from Mongoid 6. ||||
Expand Down
1 change: 1 addition & 0 deletions lib/mongoid_monkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'patches/aggregate_cursor'
require 'patches/atomic'
require 'patches/push_each'
require 'patches/big_decimal'
require 'patches/db_commands'
require 'patches/index_options'
Expand Down
41 changes: 10 additions & 31 deletions lib/patches/atomic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def push_with_mongoid4(*args)
# Uses $push + $each rather than $pushAll
def push_all(*args)
if args.length == 1 && args.first.is_a?(Hash)
query.update_all("$push" => collect_operations(args.first, true))
query.update_all("$push" => collect_each_operations(args.first))
else
query.update_all("$push" => { database_field_name(args[0]) => { "$each" => Array.wrap(args[1]) } })
end
Expand Down Expand Up @@ -102,10 +102,15 @@ def set_with_mongoid4(*args)

private

def collect_operations(ops, use_each = false)
ops.inject({}) do |operations, (field, value)|
operations[database_field_name(field)] = use_each ? { '$each' => Array.wrap(value.mongoize) } : value.mongoize
operations
def collect_operations(ops)
ops.each_with_object({}) do |(field, value), operations|
operations[database_field_name(field)] = value.mongoize
end
end

def collect_each_operations(ops)
ops.each_with_object({}) do |(field, value), operations|
operations[database_field_name(field)] = { "$each" => Array.wrap(value).mongoize }
end
end
end
Expand Down Expand Up @@ -344,30 +349,4 @@ def persist_atomic_operations(operations)
end
end

# Replace usage of $pushAll with $push + $each
module Mongoid
module Relations
module Embedded
module Batchable

def batch_insert(docs)
execute_batch_insert(docs, "$push", true)
end

def execute_batch_insert(docs, operation, use_each = false)
self.inserts_valid = true
inserts = pre_process_batch_insert(docs)
if insertable?
collection.find(selector).update(
positionally(selector, operation => { path => use_each ? { '$each' => Array.wrap(inserts) } : inserts })
)
post_process_batch_insert(docs)
end
inserts
end
end
end
end
end

end
63 changes: 63 additions & 0 deletions lib/patches/push_each.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Replace usage of $pushAll with $push + $each for MongoDB 3.6 support.
# Note that some of this is done in the `atomic.rb` patch as well.

if Mongoid::VERSION =~ /\A3\./

module Mongoid
module Relations
module Embedded
module Batchable
def batch_insert(docs)
execute_batch_insert(docs, "$push", true)
end

def execute_batch_insert(docs, operation, use_each = false)
self.inserts_valid = true
inserts = pre_process_batch_insert(docs)
if insertable?
collection.find(selector).update(
positionally(selector, operation => { path => use_each ? { '$each' => inserts } : inserts })
)
post_process_batch_insert(docs)
end
inserts
end
end
end
end
end

module Mongoid
module Atomic
class Modifiers < Hash
def push(modifications)
modifications.each_pair do |field, value|
push_fields[field] = field
mods = push_conflict?(field) ? conflicting_pushes : pushes
add_each_operation(mods, field, value)
end
end

def add_each_operation(mods, field, value)
value = Array.wrap(value)
if mods.has_key?(field)
value.each do |val|
mods[field]["$each"].push(val)
end
else
mods[field] = { "$each" => value }
end
end

def conflicting_pushes
conflicts["$push"] ||= {}
end

def pushes
self["$push"] ||= {}
end
end
end
end

end
2 changes: 1 addition & 1 deletion lib/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module MongoidMonkey
VERSION = '0.3.1'
VERSION = '0.3.2'
end
Loading

0 comments on commit 9ccc394

Please sign in to comment.