Skip to content

Commit

Permalink
Support index-related Rake tasks.
Browse files Browse the repository at this point in the history
Refactor if statements to be inside individual patch files for clarity.
  • Loading branch information
johnnyshields committed Mar 6, 2016
1 parent ea6a43c commit 39f7eeb
Show file tree
Hide file tree
Showing 21 changed files with 1,576 additions and 1,178 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@

#### 0.1.3

* Support index-related Rake tasks.
* Refactor if statements to be inside individual patch files for clarity.

#### 0.1.2

* More index support, port index-related tests from Mongoid lib.
Expand Down
18 changes: 5 additions & 13 deletions lib/mongoid_monkey.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
require 'version'

if Mongoid::VERSION =~ /\A3\./
require 'patches/atomic'
require 'patches/reorder'
end

if Mongoid::VERSION =~ /\A[345]\./
require 'patches/big_decimal'
end

if defined?(Moped)
require 'patches/instrument' if Moped::VERSION =~ /\A1\./
require 'patches/db_commands'
end
require 'patches/atomic'
require 'patches/big_decimal'
require 'patches/db_commands'
require 'patches/instrument'
require 'patches/reorder'
5 changes: 5 additions & 0 deletions lib/patches/atomic.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Backport Mongoid 4 hash-based atomic method syntax to Mongoid 3.

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

module Mongoid
module Contextual
module Atomic
Expand Down Expand Up @@ -107,3 +111,4 @@ def collect_operations(ops)
end
end
end
end
45 changes: 24 additions & 21 deletions lib/patches/big_decimal.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
# Fixes inconsistent behavior of BigDecimal. This can be removed after
# https://github.com/mongodb/mongoid/pull/4164 is merged, planned for Mongoid 6.

module MongoidMonkey
module Mongoid
module Extensions
module BigDecimal
if Mongoid::VERSION =~ /\A[345]\./

def numeric?
true
end

module ClassMethods
module MongoidMonkey
module Mongoid
module Extensions
module BigDecimal

def demongoize(object)
object && object.numeric? ? ::BigDecimal.new(object.to_s) : nil
def numeric?
true
end

def mongoize(object)
object && object.numeric? ? object.to_s : nil
module ClassMethods

def demongoize(object)
object && object.numeric? ? ::BigDecimal.new(object.to_s) : nil
end

def mongoize(object)
object && object.numeric? ? object.to_s : nil
end
end
end
end

module String
module String

def numeric?
true if Float(self) rescue (self =~ /^NaN|\-?Infinity$/)
def numeric?
true if Float(self) rescue (self =~ /^NaN|\-?Infinity$/)
end
end
end
end
end
end

::BigDecimal.__send__(:include, MongoidMonkey::Mongoid::Extensions::BigDecimal)
::BigDecimal.extend(MongoidMonkey::Mongoid::Extensions::BigDecimal::ClassMethods)
::BigDecimal.__send__(:include, MongoidMonkey::Mongoid::Extensions::BigDecimal)
::BigDecimal.extend(MongoidMonkey::Mongoid::Extensions::BigDecimal::ClassMethods)

::String.__send__(:include, MongoidMonkey::Mongoid::Extensions::String)
::String.__send__(:include, MongoidMonkey::Mongoid::Extensions::String)
end
126 changes: 98 additions & 28 deletions lib/patches/db_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,119 @@
# - listIndexes
# - createIndexes

module Moped
class Database
if defined?(Moped)

def collection_names
namespaces = command(listCollections: 1, filter: { name: { "$not" => /system\.|\$/ } })
namespaces["cursor"]["firstBatch"].map do |doc|
doc["name"]
module Moped
class Database

def collection_names
namespaces = command(listCollections: 1, filter: { name: { "$not" => /system\.|\$/ } })
namespaces["cursor"]["firstBatch"].map do |doc|
doc["name"]
end
end
end
end
end

module Moped
class Indexes
module Moped
class Indexes

def [](key)
list_indexes_command.detect do |index|
(index['name'] == key) || (index['key'] == normalize_keys(key))
def [](key)
list_indexes_command.detect do |index|
(index['name'] == key) || (index['key'] == normalize_keys(key))
end
end
end

def create(key, options = {})
spec = options.merge(ns: namespace, key: key)
spec[:name] ||= key.to_a.join("_")
database.command(createIndexes: collection_name, indexes: [spec])
end
def create(key, options = {})
spec = options.merge(ns: namespace, key: key)
spec[:name] ||= key.to_a.join("_")
database.command(createIndexes: collection_name, indexes: [spec])
end

def each(&block)
list_indexes_command.each(&block)
def each(&block)
list_indexes_command.each(&block)
end

protected

def list_indexes_command
database.command(listIndexes: collection_name)["cursor"]["firstBatch"]
end

def normalize_keys(spec)
return false if spec.is_a?(String)
spec.reduce({}) do |transformed, (key, value)|
transformed[key.to_s] = value
transformed
end
end
end
end
end

if Mongoid::VERSION =~ /\A3\./ && defined?(Rails::Mongoid)

protected
module Rails::Mongoid

def list_indexes_command
database.command(listIndexes: collection_name)["cursor"]["firstBatch"]
def remove_indexes(*globs)
models(*globs).each do |model|
next if model.embedded?
begin
indexes = model.collection.indexes.map{ |doc| doc["name"] }
indexes.delete_one("_id_")
model.remove_indexes
rescue Moped::Errors::OperationFailure
next
end
logger.info("MONGOID: Removing indexes on: #{model} for: #{indexes.join(', ')}.")
model
end.compact
end
end
end

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

def normalize_keys(spec)
return false if spec.is_a?(String)
spec.reduce({}) do |transformed, (key, value)|
transformed[key.to_s] = value
transformed
module Mongoid::Tasks::Database

def undefined_indexes(models = ::Mongoid.models)
undefined_by_model = {}

models.each do |model|
unless model.embedded?
begin
model.collection.indexes.each do |index|
# ignore default index
unless index['name'] == '_id_'
key = index['key'].symbolize_keys
spec = model.index_specification(key)
unless spec
# index not specified
undefined_by_model[model] ||= []
undefined_by_model[model] << index
end
end
end
rescue Moped::Errors::OperationFailure; end
end
end

undefined_by_model
end

def remove_indexes(models = ::Mongoid.models)
models.each do |model|
next if model.embedded?
begin
indexes = model.collection.indexes.map{ |doc| doc["name"] }
indexes.delete_one("_id_")
model.remove_indexes
rescue Moped::Errors::OperationFailure
next
end
logger.info("MONGOID: Removing indexes on: #{model} for: #{indexes.join(', ')}.")
model
end.compact
end
end
end
51 changes: 27 additions & 24 deletions lib/patches/instrument.rb
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
# Instrument Moped 1.x same as Moped 2.x.
# Useful for integration with third-party services.

module Moped
module Instrumentable
class Noop
if defined?(Moped) && Moped::VERSION =~ /\A1\./

class << self
module Moped
module Instrumentable
class Noop

# Do not instrument anything.
def instrument(name, payload = {})
yield payload if block_given?
class << self

# Do not instrument anything.
def instrument(name, payload = {})
yield payload if block_given?
end
end
end
end
end
end

module Moped
module Instrumentable
module Moped
module Instrumentable

TOPIC = "query.moped"
TOPIC = "query.moped"

def instrumenter
@instrumenter ||= Moped::Instrumentable::Noop
end
def instrumenter
@instrumenter ||= Moped::Instrumentable::Noop
end

def instrument(name, payload = {}, &block)
instrumenter.instrument(name, payload, &block)
def instrument(name, payload = {}, &block)
instrumenter.instrument(name, payload, &block)
end
end
end
end

module Moped
class Node
include Moped::Instrumentable
module Moped
class Node
include Moped::Instrumentable

def logging_with_instrument(operations, &block)
instrument(TOPIC, prefix: " MOPED: #{resolved_address}", ops: operations) do
logging_without_instrument(operations, &block)
def logging_with_instrument(operations, &block)
instrument(TOPIC, prefix: " MOPED: #{resolved_address}", ops: operations) do
logging_without_instrument(operations, &block)
end
end
alias_method_chain :logging, :instrument
end
alias_method_chain :logging, :instrument
end
end
13 changes: 8 additions & 5 deletions lib/patches/reorder.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Backport of Criteria#reorder method from Mongoid 4 to Mongoid 3.

module Origin
module Optional
if Mongoid::VERSION =~ /\A3\./

def reorder(*spec)
options.delete(:sort)
order_by(*spec)
module Origin
module Optional

def reorder(*spec)
options.delete(:sort)
order_by(*spec)
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.1.2'
VERSION = '0.1.3'
end
4 changes: 4 additions & 0 deletions spec/app/models/account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

class Account
include Mongoid::Document
end
7 changes: 7 additions & 0 deletions spec/app/models/address.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

class Address
include Mongoid::Document
field :street
field :name, localize: true
embedded_in :addressable, polymorphic: true
end
7 changes: 7 additions & 0 deletions spec/app/models/draft.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

class Draft
include Mongoid::Document
field :text
recursively_embeds_one
index text: 1
end
11 changes: 11 additions & 0 deletions spec/app/models/person.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

class Person
include Mongoid::Document

index age: 1
index addresses: 1
index dob: 1
index name: 1
index title: 1
index({ ssn: 1 }, { unique: true })
end
6 changes: 6 additions & 0 deletions spec/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

class User
include Mongoid::Document
field :name
index name: 1
end
Loading

0 comments on commit 39f7eeb

Please sign in to comment.