promiscuous 0.53.1 → 0.90.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/promiscuous.rb +25 -28
- data/lib/promiscuous/amqp.rb +27 -8
- data/lib/promiscuous/amqp/bunny.rb +131 -16
- data/lib/promiscuous/amqp/fake.rb +52 -0
- data/lib/promiscuous/amqp/hot_bunnies.rb +56 -0
- data/lib/promiscuous/amqp/null.rb +6 -6
- data/lib/promiscuous/cli.rb +108 -24
- data/lib/promiscuous/config.rb +73 -12
- data/lib/promiscuous/convenience.rb +18 -0
- data/lib/promiscuous/dependency.rb +59 -0
- data/lib/promiscuous/dsl.rb +36 -0
- data/lib/promiscuous/error.rb +3 -1
- data/lib/promiscuous/error/already_processed.rb +5 -0
- data/lib/promiscuous/error/base.rb +1 -0
- data/lib/promiscuous/error/connection.rb +7 -5
- data/lib/promiscuous/error/dependency.rb +111 -0
- data/lib/promiscuous/error/lock_unavailable.rb +12 -0
- data/lib/promiscuous/error/lost_lock.rb +12 -0
- data/lib/promiscuous/error/missing_context.rb +29 -0
- data/lib/promiscuous/error/publisher.rb +5 -15
- data/lib/promiscuous/error/recovery.rb +7 -0
- data/lib/promiscuous/error/subscriber.rb +2 -4
- data/lib/promiscuous/key.rb +36 -0
- data/lib/promiscuous/loader.rb +12 -16
- data/lib/promiscuous/middleware.rb +112 -0
- data/lib/promiscuous/publisher.rb +7 -4
- data/lib/promiscuous/publisher/context.rb +92 -0
- data/lib/promiscuous/publisher/mock_generator.rb +72 -0
- data/lib/promiscuous/publisher/model.rb +3 -86
- data/lib/promiscuous/publisher/model/active_record.rb +8 -15
- data/lib/promiscuous/publisher/model/base.rb +136 -0
- data/lib/promiscuous/publisher/model/ephemeral.rb +69 -0
- data/lib/promiscuous/publisher/model/mock.rb +61 -0
- data/lib/promiscuous/publisher/model/mongoid.rb +57 -100
- data/lib/promiscuous/{common/lint.rb → publisher/operation.rb} +1 -1
- data/lib/promiscuous/publisher/operation/base.rb +707 -0
- data/lib/promiscuous/publisher/operation/mongoid.rb +370 -0
- data/lib/promiscuous/publisher/worker.rb +22 -0
- data/lib/promiscuous/railtie.rb +21 -3
- data/lib/promiscuous/redis.rb +132 -40
- data/lib/promiscuous/resque.rb +12 -0
- data/lib/promiscuous/sidekiq.rb +15 -0
- data/lib/promiscuous/subscriber.rb +9 -20
- data/lib/promiscuous/subscriber/model.rb +4 -104
- data/lib/promiscuous/subscriber/model/active_record.rb +10 -0
- data/lib/promiscuous/subscriber/model/base.rb +96 -0
- data/lib/promiscuous/subscriber/model/mongoid.rb +86 -0
- data/lib/promiscuous/subscriber/model/observer.rb +37 -0
- data/lib/promiscuous/subscriber/operation.rb +167 -0
- data/lib/promiscuous/subscriber/payload.rb +34 -0
- data/lib/promiscuous/subscriber/worker.rb +22 -18
- data/lib/promiscuous/subscriber/worker/message.rb +48 -25
- data/lib/promiscuous/subscriber/worker/message_synchronizer.rb +273 -181
- data/lib/promiscuous/subscriber/worker/pump.rb +17 -43
- data/lib/promiscuous/subscriber/worker/recorder.rb +24 -0
- data/lib/promiscuous/subscriber/worker/runner.rb +24 -3
- data/lib/promiscuous/subscriber/worker/stats.rb +62 -0
- data/lib/promiscuous/timer.rb +38 -0
- data/lib/promiscuous/version.rb +1 -1
- metadata +98 -143
- data/README.md +0 -33
- data/lib/promiscuous/amqp/ruby_amqp.rb +0 -140
- data/lib/promiscuous/common.rb +0 -4
- data/lib/promiscuous/common/class_helpers.rb +0 -12
- data/lib/promiscuous/common/lint/base.rb +0 -24
- data/lib/promiscuous/common/options.rb +0 -51
- data/lib/promiscuous/ephemeral.rb +0 -14
- data/lib/promiscuous/error/recover.rb +0 -1
- data/lib/promiscuous/observer.rb +0 -5
- data/lib/promiscuous/publisher/active_record.rb +0 -7
- data/lib/promiscuous/publisher/amqp.rb +0 -18
- data/lib/promiscuous/publisher/attributes.rb +0 -32
- data/lib/promiscuous/publisher/base.rb +0 -23
- data/lib/promiscuous/publisher/class.rb +0 -36
- data/lib/promiscuous/publisher/envelope.rb +0 -7
- data/lib/promiscuous/publisher/ephemeral.rb +0 -9
- data/lib/promiscuous/publisher/lint.rb +0 -35
- data/lib/promiscuous/publisher/lint/amqp.rb +0 -14
- data/lib/promiscuous/publisher/lint/attributes.rb +0 -12
- data/lib/promiscuous/publisher/lint/base.rb +0 -5
- data/lib/promiscuous/publisher/lint/class.rb +0 -15
- data/lib/promiscuous/publisher/lint/polymorphic.rb +0 -22
- data/lib/promiscuous/publisher/mock.rb +0 -79
- data/lib/promiscuous/publisher/mongoid.rb +0 -33
- data/lib/promiscuous/publisher/mongoid/embedded.rb +0 -27
- data/lib/promiscuous/publisher/mongoid/embedded_many.rb +0 -12
- data/lib/promiscuous/publisher/polymorphic.rb +0 -8
- data/lib/promiscuous/subscriber/active_record.rb +0 -11
- data/lib/promiscuous/subscriber/amqp.rb +0 -25
- data/lib/promiscuous/subscriber/attributes.rb +0 -35
- data/lib/promiscuous/subscriber/base.rb +0 -29
- data/lib/promiscuous/subscriber/class.rb +0 -29
- data/lib/promiscuous/subscriber/dummy.rb +0 -19
- data/lib/promiscuous/subscriber/envelope.rb +0 -18
- data/lib/promiscuous/subscriber/lint.rb +0 -30
- data/lib/promiscuous/subscriber/lint/amqp.rb +0 -21
- data/lib/promiscuous/subscriber/lint/attributes.rb +0 -21
- data/lib/promiscuous/subscriber/lint/base.rb +0 -14
- data/lib/promiscuous/subscriber/lint/class.rb +0 -13
- data/lib/promiscuous/subscriber/lint/polymorphic.rb +0 -39
- data/lib/promiscuous/subscriber/mongoid.rb +0 -27
- data/lib/promiscuous/subscriber/mongoid/embedded.rb +0 -17
- data/lib/promiscuous/subscriber/mongoid/embedded_many.rb +0 -44
- data/lib/promiscuous/subscriber/observer.rb +0 -26
- data/lib/promiscuous/subscriber/polymorphic.rb +0 -36
- 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
|
-
|
5
|
-
extend ActiveSupport::Concern
|
5
|
+
# TODO FIXME This needs some serious work. We need to hook deeper.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
21
|
-
|
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
|
-
|
5
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
def promiscuous_sync
|
50
|
-
publisher = self.class.promiscuous_publisher
|
22
|
+
class PromiscuousMethods
|
23
|
+
include Promiscuous::Publisher::Model::Base::PromiscuousMethodsBase
|
51
24
|
|
52
|
-
|
25
|
+
def sync(options={}, &block)
|
26
|
+
raise "Use promiscuous.sync on the parent instance" if @instance.embedded?
|
27
|
+
super
|
28
|
+
end
|
53
29
|
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
43
|
+
# TODO DRY this up with the publisher side
|
44
|
+
def publish(*args, &block)
|
62
45
|
super
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
46
|
+
return unless block
|
66
47
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
if
|
88
|
-
|
89
|
-
|
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
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
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
|