promiscuous 0.53.1 → 0.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. data/lib/promiscuous.rb +25 -28
  2. data/lib/promiscuous/amqp.rb +27 -8
  3. data/lib/promiscuous/amqp/bunny.rb +131 -16
  4. data/lib/promiscuous/amqp/fake.rb +52 -0
  5. data/lib/promiscuous/amqp/hot_bunnies.rb +56 -0
  6. data/lib/promiscuous/amqp/null.rb +6 -6
  7. data/lib/promiscuous/cli.rb +108 -24
  8. data/lib/promiscuous/config.rb +73 -12
  9. data/lib/promiscuous/convenience.rb +18 -0
  10. data/lib/promiscuous/dependency.rb +59 -0
  11. data/lib/promiscuous/dsl.rb +36 -0
  12. data/lib/promiscuous/error.rb +3 -1
  13. data/lib/promiscuous/error/already_processed.rb +5 -0
  14. data/lib/promiscuous/error/base.rb +1 -0
  15. data/lib/promiscuous/error/connection.rb +7 -5
  16. data/lib/promiscuous/error/dependency.rb +111 -0
  17. data/lib/promiscuous/error/lock_unavailable.rb +12 -0
  18. data/lib/promiscuous/error/lost_lock.rb +12 -0
  19. data/lib/promiscuous/error/missing_context.rb +29 -0
  20. data/lib/promiscuous/error/publisher.rb +5 -15
  21. data/lib/promiscuous/error/recovery.rb +7 -0
  22. data/lib/promiscuous/error/subscriber.rb +2 -4
  23. data/lib/promiscuous/key.rb +36 -0
  24. data/lib/promiscuous/loader.rb +12 -16
  25. data/lib/promiscuous/middleware.rb +112 -0
  26. data/lib/promiscuous/publisher.rb +7 -4
  27. data/lib/promiscuous/publisher/context.rb +92 -0
  28. data/lib/promiscuous/publisher/mock_generator.rb +72 -0
  29. data/lib/promiscuous/publisher/model.rb +3 -86
  30. data/lib/promiscuous/publisher/model/active_record.rb +8 -15
  31. data/lib/promiscuous/publisher/model/base.rb +136 -0
  32. data/lib/promiscuous/publisher/model/ephemeral.rb +69 -0
  33. data/lib/promiscuous/publisher/model/mock.rb +61 -0
  34. data/lib/promiscuous/publisher/model/mongoid.rb +57 -100
  35. data/lib/promiscuous/{common/lint.rb → publisher/operation.rb} +1 -1
  36. data/lib/promiscuous/publisher/operation/base.rb +707 -0
  37. data/lib/promiscuous/publisher/operation/mongoid.rb +370 -0
  38. data/lib/promiscuous/publisher/worker.rb +22 -0
  39. data/lib/promiscuous/railtie.rb +21 -3
  40. data/lib/promiscuous/redis.rb +132 -40
  41. data/lib/promiscuous/resque.rb +12 -0
  42. data/lib/promiscuous/sidekiq.rb +15 -0
  43. data/lib/promiscuous/subscriber.rb +9 -20
  44. data/lib/promiscuous/subscriber/model.rb +4 -104
  45. data/lib/promiscuous/subscriber/model/active_record.rb +10 -0
  46. data/lib/promiscuous/subscriber/model/base.rb +96 -0
  47. data/lib/promiscuous/subscriber/model/mongoid.rb +86 -0
  48. data/lib/promiscuous/subscriber/model/observer.rb +37 -0
  49. data/lib/promiscuous/subscriber/operation.rb +167 -0
  50. data/lib/promiscuous/subscriber/payload.rb +34 -0
  51. data/lib/promiscuous/subscriber/worker.rb +22 -18
  52. data/lib/promiscuous/subscriber/worker/message.rb +48 -25
  53. data/lib/promiscuous/subscriber/worker/message_synchronizer.rb +273 -181
  54. data/lib/promiscuous/subscriber/worker/pump.rb +17 -43
  55. data/lib/promiscuous/subscriber/worker/recorder.rb +24 -0
  56. data/lib/promiscuous/subscriber/worker/runner.rb +24 -3
  57. data/lib/promiscuous/subscriber/worker/stats.rb +62 -0
  58. data/lib/promiscuous/timer.rb +38 -0
  59. data/lib/promiscuous/version.rb +1 -1
  60. metadata +98 -143
  61. data/README.md +0 -33
  62. data/lib/promiscuous/amqp/ruby_amqp.rb +0 -140
  63. data/lib/promiscuous/common.rb +0 -4
  64. data/lib/promiscuous/common/class_helpers.rb +0 -12
  65. data/lib/promiscuous/common/lint/base.rb +0 -24
  66. data/lib/promiscuous/common/options.rb +0 -51
  67. data/lib/promiscuous/ephemeral.rb +0 -14
  68. data/lib/promiscuous/error/recover.rb +0 -1
  69. data/lib/promiscuous/observer.rb +0 -5
  70. data/lib/promiscuous/publisher/active_record.rb +0 -7
  71. data/lib/promiscuous/publisher/amqp.rb +0 -18
  72. data/lib/promiscuous/publisher/attributes.rb +0 -32
  73. data/lib/promiscuous/publisher/base.rb +0 -23
  74. data/lib/promiscuous/publisher/class.rb +0 -36
  75. data/lib/promiscuous/publisher/envelope.rb +0 -7
  76. data/lib/promiscuous/publisher/ephemeral.rb +0 -9
  77. data/lib/promiscuous/publisher/lint.rb +0 -35
  78. data/lib/promiscuous/publisher/lint/amqp.rb +0 -14
  79. data/lib/promiscuous/publisher/lint/attributes.rb +0 -12
  80. data/lib/promiscuous/publisher/lint/base.rb +0 -5
  81. data/lib/promiscuous/publisher/lint/class.rb +0 -15
  82. data/lib/promiscuous/publisher/lint/polymorphic.rb +0 -22
  83. data/lib/promiscuous/publisher/mock.rb +0 -79
  84. data/lib/promiscuous/publisher/mongoid.rb +0 -33
  85. data/lib/promiscuous/publisher/mongoid/embedded.rb +0 -27
  86. data/lib/promiscuous/publisher/mongoid/embedded_many.rb +0 -12
  87. data/lib/promiscuous/publisher/polymorphic.rb +0 -8
  88. data/lib/promiscuous/subscriber/active_record.rb +0 -11
  89. data/lib/promiscuous/subscriber/amqp.rb +0 -25
  90. data/lib/promiscuous/subscriber/attributes.rb +0 -35
  91. data/lib/promiscuous/subscriber/base.rb +0 -29
  92. data/lib/promiscuous/subscriber/class.rb +0 -29
  93. data/lib/promiscuous/subscriber/dummy.rb +0 -19
  94. data/lib/promiscuous/subscriber/envelope.rb +0 -18
  95. data/lib/promiscuous/subscriber/lint.rb +0 -30
  96. data/lib/promiscuous/subscriber/lint/amqp.rb +0 -21
  97. data/lib/promiscuous/subscriber/lint/attributes.rb +0 -21
  98. data/lib/promiscuous/subscriber/lint/base.rb +0 -14
  99. data/lib/promiscuous/subscriber/lint/class.rb +0 -13
  100. data/lib/promiscuous/subscriber/lint/polymorphic.rb +0 -39
  101. data/lib/promiscuous/subscriber/mongoid.rb +0 -27
  102. data/lib/promiscuous/subscriber/mongoid/embedded.rb +0 -17
  103. data/lib/promiscuous/subscriber/mongoid/embedded_many.rb +0 -44
  104. data/lib/promiscuous/subscriber/observer.rb +0 -26
  105. data/lib/promiscuous/subscriber/polymorphic.rb +0 -36
  106. data/lib/promiscuous/subscriber/upsert.rb +0 -12
@@ -1,25 +1,18 @@
1
1
  module Promiscuous::Publisher::Model::ActiveRecord
2
2
  extend ActiveSupport::Concern
3
+ include Promiscuous::Publisher::Model::Base
3
4
 
4
- module ModelInstanceMethods
5
- extend ActiveSupport::Concern
5
+ # TODO FIXME This needs some serious work. We need to hook deeper.
6
6
 
7
- def with_promiscuous(options={}, &block)
8
- fetch_proc = proc { self.class.find(self.id) }
9
- self.class.promiscuous_publisher.new(options.merge(:instance => self, :fetch_proc => fetch_proc)).commit(&block)
10
- end
11
-
12
- included do
13
- around_create { |&block| with_promiscuous(:operation => :create, &block) }
14
- around_update { |&block| with_promiscuous(:operation => :update, &block) }
15
- around_destroy { |&block| with_promiscuous(:operation => :destroy, &block) }
16
- end
7
+ included do
8
+ around_create { |&block| promiscuous.sync(:operation => :create, &block) }
9
+ around_update { |&block| promiscuous.sync(:operation => :update, &block) }
10
+ around_destroy { |&block| promiscuous.sync(:operation => :destroy, &block) }
17
11
  end
18
12
 
19
13
  module ClassMethods
20
- def setup_class_binding
21
- super
22
- klass.__send__(:include, ModelInstanceMethods) if klass
14
+ def __promiscuous_missing_record_exception
15
+ ActiveRecord::RecordNotFound
23
16
  end
24
17
  end
25
18
  end
@@ -0,0 +1,136 @@
1
+ module Promiscuous::Publisher::Model::Base
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ class_attribute :publish_to, :published_attrs, :tracked_attrs
6
+ cattr_accessor :published_db_fields # There is one on each root class, none on the subclasses
7
+ self.published_attrs = []
8
+ self.tracked_attrs = []
9
+ self.published_db_fields = []
10
+ track_dependencies_of :id
11
+ Promiscuous::Publisher::Model.publishers[self.promiscuous_collection_name] = self
12
+ end
13
+
14
+ module PromiscuousMethodsBase
15
+ def initialize(instance)
16
+ @instance = instance
17
+ end
18
+
19
+ def sync(options={}, &block)
20
+ options = {:instance => @instance, :operation => :update}.merge(options)
21
+ Promiscuous::Publisher::Operation::Base.new(options).execute(&block)
22
+ end
23
+
24
+ def payload(options={})
25
+ # It's nice to see the entire payload in one piece, not merged 36 times
26
+ # TODO migrate this format to something that makes more sense once the store is out
27
+ msg = {}
28
+ msg[:__amqp__] = @instance.class.publish_to
29
+ msg[:type] = @instance.class.publish_as # for backward compatibility
30
+ msg[:ancestors] = @instance.class.ancestors.select { |a| a < Promiscuous::Publisher::Model::Base }.map(&:publish_as)
31
+ msg[:id] = @instance.id.to_s
32
+ if @instance.respond_to?(:promiscuous_payload)
33
+ msg[:payload] = @instance.promiscuous_payload
34
+ else
35
+ msg[:payload] = self.attributes unless options[:with_attributes] == false
36
+ end
37
+ msg
38
+ end
39
+
40
+ def attributes
41
+ Hash[@instance.class.published_attrs.map { |attr| [attr, self.attribute(attr)] }]
42
+ end
43
+
44
+ def attribute(attr)
45
+ value = @instance.__send__(attr)
46
+ value = value.promiscuous.payload if value.respond_to?(:promiscuous)
47
+ value
48
+ end
49
+
50
+ def get_dependency(attr, value)
51
+ return nil unless value
52
+ @collection ||= @instance.class.promiscuous_collection_name
53
+ Promiscuous::Dependency.new(@collection, attr, value)
54
+ end
55
+
56
+ def tracked_dependencies(options={})
57
+ # FIXME This is not sufficient, we need to consider the previous and next
58
+ # values in case of an update.
59
+ # Note that the caller expect the id dependency to come first
60
+ @instance.class.tracked_attrs
61
+ .map { |attr| [attr, @instance.__send__(attr)] }
62
+ .map { |attr, value| get_dependency(attr, value) }
63
+ .compact
64
+ end
65
+ end
66
+
67
+ class PromiscuousMethods
68
+ include Promiscuous::Publisher::Model::Base::PromiscuousMethodsBase
69
+ end
70
+
71
+ def promiscuous
72
+ # XXX Not thread safe
73
+ @promiscuous ||= self.class.const_get(:PromiscuousMethods).new(self)
74
+ end
75
+
76
+ def valid?(*args)
77
+ # Validations are not dependencies
78
+ # TODO we should yell if the user is trying to write
79
+ without_promiscuous { super }
80
+ end
81
+
82
+ module ClassMethods
83
+ # all methods are virtual
84
+
85
+ def publish(*args, &block)
86
+ options = args.extract_options!
87
+ attributes = args.map(&:to_sym)
88
+
89
+ # TODO reject invalid options
90
+
91
+ if attributes.present? && self.publish_to && options[:to] && self.publish_to != options[:to]
92
+ raise 'versionned publishing is not supported yet'
93
+ end
94
+ self.publish_to ||= options[:to] || "#{Promiscuous::Config.app}/#{self.name.underscore}"
95
+ @publish_as = options[:as].to_s if options[:as]
96
+
97
+ ([self] + descendants).each do |klass|
98
+ # When the user passes :use => [:f1, :f2] for example, operation/mongoid.rb
99
+ # can track f1 and f2 as fields important for the publishing.
100
+ # It's important for virtual attributes. The published_db_fields is global
101
+ # for the entire subclass tree.
102
+ klass.published_db_fields |= [options[:use]].flatten.map(&:to_sym) if options[:use]
103
+ klass.published_db_fields |= attributes # aliased fields are resolved later
104
+ klass.published_attrs |= attributes
105
+ end
106
+ end
107
+
108
+ def track_dependencies_of(*attributes)
109
+ ([self] + descendants).each { |klass| klass.tracked_attrs |= attributes.map(&:to_sym) }
110
+ end
111
+
112
+ def promiscuous_collection_name
113
+ self.name.pluralize.underscore
114
+ end
115
+
116
+ def get_operation_class_for(operation)
117
+ Promiscuous::Publisher::Operation::Base
118
+ end
119
+
120
+ def publish_as
121
+ @publish_as || name
122
+ end
123
+
124
+ def inherited(subclass)
125
+ super
126
+ subclass.published_attrs = self.published_attrs.dup
127
+ subclass.tracked_attrs = self.tracked_attrs.dup
128
+ # no copy for published_db_fields
129
+ end
130
+
131
+ class None; end
132
+ def promiscuous_missing_record_exception
133
+ None
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,69 @@
1
+ module Promiscuous::Publisher::Model::Ephemeral
2
+ extend ActiveSupport::Concern
3
+ include Promiscuous::Publisher::Model::Base
4
+
5
+ attr_accessor :id, :new_record, :destroyed
6
+
7
+ module PromiscuousMethodsEphemeral
8
+ def attribute(attr)
9
+ value = super
10
+ if value.is_a?(Array) &&
11
+ value.first.is_a?(Promiscuous::Publisher::Model::Ephemeral)
12
+ value = {:__amqp__ => '__promiscuous__/embedded_many',
13
+ :payload => value.map(&:promiscuous).map(&:payload)}
14
+ end
15
+ value
16
+ end
17
+ end
18
+
19
+ class PromiscuousMethods
20
+ include Promiscuous::Publisher::Model::Base::PromiscuousMethodsBase
21
+ include Promiscuous::Publisher::Model::Ephemeral::PromiscuousMethodsEphemeral
22
+ end
23
+
24
+ def initialize(attrs={})
25
+ self.id ||= 'none'
26
+ self.new_record = true
27
+ self.destroyed = false
28
+ attrs.each { |attr, value| __send__("#{attr}=", value) }
29
+ end
30
+
31
+ def save
32
+ operation = :create
33
+ operation = :update unless self.new_record
34
+ operation = :destroy if self.destroyed
35
+ promiscuous.sync(:operation => operation)
36
+ self.new_record = false
37
+ true
38
+ end
39
+ alias :save! :save
40
+
41
+ def update_attributes(attrs)
42
+ attrs.each { |attr, value| __send__("#{attr}=", value) }
43
+ save
44
+ end
45
+ alias :update_attributes! :update_attributes
46
+
47
+ def destroy
48
+ self.destroyed = true
49
+ save
50
+ end
51
+
52
+ def attributes
53
+ Hash[self.class.published_attrs.map { |attr| [attr, __send__(attr)] }]
54
+ end
55
+
56
+ module ClassMethods
57
+ def publish(*args)
58
+ super
59
+ published_attrs.each do |attr|
60
+ # TODO do not overwrite existing methods
61
+ attr_accessor attr
62
+ end
63
+ end
64
+
65
+ def create(attributes)
66
+ new(attributes).tap { |m| m.save }
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,61 @@
1
+ module Promiscuous::Publisher::Model::Mock
2
+ extend ActiveSupport::Concern
3
+ include Promiscuous::Publisher::Model::Ephemeral
4
+
5
+ included { class_attribute :mock_options }
6
+
7
+ def initialize(attrs={})
8
+ self.id = __get_new_id
9
+ super
10
+ end
11
+
12
+ def __get_new_id
13
+ if self.class.mock_options.try(:[], :id) == :bson
14
+ BSON::ObjectId.new
15
+ else
16
+ # XXX Not thread safe
17
+ @@next_id ||= 1
18
+ @@next_id += 1
19
+ end
20
+ end
21
+
22
+ class PromiscuousMethods
23
+ include Promiscuous::Publisher::Model::Base::PromiscuousMethodsBase
24
+ include Promiscuous::Publisher::Model::Ephemeral::PromiscuousMethodsEphemeral
25
+
26
+ def sync(options={}, &block)
27
+ payload = self.payload
28
+ payload[:operation] = options[:operation] || :update
29
+ Promiscuous::Subscriber::Worker::Message.new(MultiJson.dump(payload)).process
30
+ end
31
+ end
32
+
33
+ module ClassMethods
34
+ def publish_as
35
+ # The mocks are in the publisher's namespace, so we need to remove that.
36
+ @publish_as ||= ($2 if self.name =~ /^(.+)::Publishers::(.+)$/)
37
+ end
38
+
39
+ def mock(options={})
40
+ self.mock_options = options
41
+ end
42
+
43
+ def publish(*args, &block)
44
+ super
45
+
46
+ args.extract_options!
47
+ attributes = args
48
+ attr_accessor(*attributes)
49
+
50
+ # Hacks for associations on the factory
51
+ associations = attributes.map { |attr| $1 if attr =~ /^(.*)_id$/ }.compact
52
+ associations.each do |attr|
53
+ attr_accessor(attr)
54
+ define_method("#{attr}=") do |value|
55
+ instance_variable_set("@#{attr}", value)
56
+ instance_variable_set("@#{attr}_id", value.nil? ? value : value.id)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,129 +1,86 @@
1
1
  module Promiscuous::Publisher::Model::Mongoid
2
2
  extend ActiveSupport::Concern
3
+ include Promiscuous::Publisher::Model::Base
3
4
 
4
- class Commit
5
- attr_accessor :collection, :selector, :document, :operation
6
- def initialize(options={})
7
- self.collection = options[:collection]
8
- self.selector = options[:selector]
9
- self.document = options[:document]
10
- self.operation = options[:operation]
11
- end
5
+ mattr_accessor :collection_mapping
6
+ self.collection_mapping = {}
12
7
 
13
- def klass
14
- @klass ||= document.try(:[], '_type').try(:constantize) ||
15
- collection.singularize.camelize.constantize
16
- rescue NameError
17
- end
8
+ # We hook at the database driver level
9
+ require 'promiscuous/publisher/operation/mongoid'
10
+ included do
11
+ # Important for the query hooks (see ../operation/mongoid.rb)
12
+ # We want the root class when we do a collection name lookup
18
13
 
19
- def fetch
20
- case operation
21
- when :create then klass.new(document, :without_protection => true)
22
- when :update then klass.with(:consistency => :strong).where(selector).first
23
- when :destroy then klass.with(:consistency => :strong).where(selector).first
24
- end
14
+ root_class = self.collection.name.singularize.camelize.constantize
15
+ unless self == root_class
16
+ raise "Please include Promiscuous::Publisher in #{root_class} first (the root class)"
25
17
  end
26
18
 
27
- def commit(&block)
28
- return block.call unless klass
29
-
30
- # We bypass the call if instance == nil, the destroy or the update would
31
- # have had no effect
32
- instance = fetch
33
- return if instance.nil?
34
-
35
- return block.call unless instance.class.respond_to?(:promiscuous_publisher)
36
-
37
- self.selector = {:id => instance.id}
38
-
39
- publisher = instance.class.promiscuous_publisher
40
- publisher.new(:operation => operation,
41
- :instance => instance,
42
- :fetch_proc => method(:fetch)).commit(&block)
43
- end
19
+ Promiscuous::Publisher::Model::Mongoid.collection_mapping[self.collection.name] = self
44
20
  end
45
21
 
46
- module ModelInstanceMethods
47
- extend ActiveSupport::Concern
48
-
49
- def promiscuous_sync
50
- publisher = self.class.promiscuous_publisher
22
+ class PromiscuousMethods
23
+ include Promiscuous::Publisher::Model::Base::PromiscuousMethodsBase
51
24
 
52
- fetch_proc = proc { self.class.with(:consistency => :strong).where(atomic_selector).first }
25
+ def sync(options={}, &block)
26
+ raise "Use promiscuous.sync on the parent instance" if @instance.embedded?
27
+ super
28
+ end
53
29
 
54
- publisher.new(:operation => :update,
55
- :instance => self,
56
- :fetch_proc => fetch_proc).commit
30
+ def attribute(attr)
31
+ value = super
32
+ if value.is_a?(Array) &&
33
+ value.respond_to?(:ancestors) &&
34
+ value.ancestors.any? { |a| a == Promiscuous::Publisher::Model::Mongoid }
35
+ value = {:__amqp__ => '__promiscuous__/embedded_many',
36
+ :payload => value.map(&:promiscuous).map(&:payload)}
37
+ end
38
+ value
57
39
  end
58
40
  end
59
41
 
60
42
  module ClassMethods
61
- def setup_class_binding
43
+ # TODO DRY this up with the publisher side
44
+ def publish(*args, &block)
62
45
  super
63
- klass.__send__(:include, ModelInstanceMethods) if klass
64
- end
65
- end
46
+ return unless block
66
47
 
67
- def self.hook_mongoid
68
- Moped::Collection.class_eval do
69
- alias_method :insert_orig, :insert
70
- def insert(documents, flags=nil)
71
- documents = [documents] unless documents.is_a?(Array)
72
- documents.each do |doc|
73
- Promiscuous::Publisher::Model::Mongoid::Commit.new(
74
- :collection => self.name,
75
- :document => doc,
76
- :operation => :create
77
- ).commit do
78
- insert_orig(doc, flags)
79
- end
80
- end
48
+ begin
49
+ @in_publish_block = true
50
+ block.call
51
+ ensure
52
+ @in_publish_block = false
81
53
  end
82
54
  end
83
55
 
84
- Moped::Query.class_eval do
85
- alias_method :update_orig, :update
86
- def update(change, flags=nil)
87
- if flags && flags.include?(:multi)
88
- raise "Promiscuous: Do not use multi updates, update each instance separately"
89
- end
90
-
91
- Promiscuous::Publisher::Model::Mongoid::Commit.new(
92
- :collection => collection.name,
93
- :selector => selector,
94
- :operation => :update
95
- ).commit do
96
- update_orig(change, flags)
56
+ def self.publish_on(method, options={})
57
+ define_method(method) do |name, *args, &block|
58
+ super(name, *args, &block)
59
+ if @in_publish_block
60
+ name = args.last[:as] if args.last.is_a?(Hash) && args.last[:as]
61
+ publish(name)
97
62
  end
98
63
  end
64
+ end
99
65
 
100
- alias_method :modify_orig, :modify
101
- def modify(change, options={})
102
- Promiscuous::Publisher::Model::Mongoid::Commit.new(
103
- :collection => collection.name,
104
- :selector => selector,
105
- :operation => :update
106
- ).commit do
107
- modify_orig(change, options)
108
- end
109
- end
66
+ publish_on :field
67
+ publish_on :embeds_one
68
+ publish_on :embeds_many
110
69
 
111
- alias_method :remove_orig, :remove
112
- def remove
113
- Promiscuous::Publisher::Model::Mongoid::Commit.new(
114
- :collection => collection.name,
115
- :selector => selector,
116
- :operation => :destroy
117
- ).commit do
118
- remove_orig
119
- end
120
- end
70
+ def promiscuous_collection_name
71
+ self.collection.name
72
+ end
121
73
 
122
- alias_method :remove_all_orig, :remove_all
123
- def remove_all
124
- raise "Promiscuous: Do not use delete_all, use destroy_all"
74
+ def get_operation_class_for(operation)
75
+ if operation == :create
76
+ Moped::PromiscuousCollectionWrapper::PromiscuousCollectionOperation
77
+ else
78
+ Moped::PromiscuousQueryWrapper::PromiscuousQueryOperation
125
79
  end
126
80
  end
81
+
82
+ def promiscuous_missing_record_exception
83
+ Mongoid::Errors::DocumentNotFound
84
+ end
127
85
  end
128
- hook_mongoid
129
86
  end