ripple 0.9.5 → 1.0.0.beta
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.
- data/.gitignore +32 -0
- data/Gemfile +10 -9
- data/Guardfile +15 -0
- data/Rakefile +11 -40
- data/lib/rails/generators/ripple/configuration/configuration_generator.rb +0 -13
- data/lib/rails/generators/ripple/configuration/templates/ripple.yml +4 -4
- data/lib/rails/generators/ripple/js/js_generator.rb +0 -13
- data/lib/rails/generators/ripple/js/templates/js/contrib.js +0 -17
- data/lib/rails/generators/ripple/js/templates/js/ripple.js +0 -13
- data/lib/rails/generators/ripple/model/model_generator.rb +0 -14
- data/lib/rails/generators/ripple/model/templates/model.rb +1 -1
- data/lib/rails/generators/ripple/observer/observer_generator.rb +0 -14
- data/lib/rails/generators/ripple/test/test_generator.rb +7 -19
- data/lib/rails/generators/ripple_generator.rb +1 -14
- data/lib/ripple.rb +7 -14
- data/lib/ripple/associations.rb +129 -26
- data/lib/ripple/associations/embedded.rb +1 -15
- data/lib/ripple/associations/instantiators.rb +0 -13
- data/lib/ripple/associations/linked.rb +41 -19
- data/lib/ripple/associations/many.rb +0 -14
- data/lib/ripple/associations/many_embedded_proxy.rb +0 -14
- data/lib/ripple/associations/many_linked_proxy.rb +39 -18
- data/lib/ripple/associations/many_reference_proxy.rb +93 -0
- data/lib/ripple/associations/many_stored_key_proxy.rb +76 -0
- data/lib/ripple/associations/one.rb +1 -15
- data/lib/ripple/associations/one_embedded_proxy.rb +0 -14
- data/lib/ripple/associations/one_key_proxy.rb +58 -0
- data/lib/ripple/associations/one_linked_proxy.rb +4 -14
- data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
- data/lib/ripple/associations/proxy.rb +8 -14
- data/lib/ripple/attribute_methods.rb +19 -17
- data/lib/ripple/attribute_methods/dirty.rb +19 -15
- data/lib/ripple/attribute_methods/query.rb +0 -14
- data/lib/ripple/attribute_methods/read.rb +0 -14
- data/lib/ripple/attribute_methods/write.rb +0 -14
- data/lib/ripple/callbacks.rb +10 -16
- data/lib/ripple/conflict/basic_resolver.rb +82 -0
- data/lib/ripple/conflict/document_hooks.rb +20 -0
- data/lib/ripple/conflict/resolver.rb +71 -0
- data/lib/ripple/conflict/test_helper.rb +33 -0
- data/lib/ripple/conversion.rb +0 -14
- data/lib/ripple/core_ext.rb +1 -14
- data/lib/ripple/core_ext/casting.rb +19 -19
- data/lib/ripple/core_ext/object.rb +8 -0
- data/lib/ripple/document.rb +21 -16
- data/lib/ripple/document/bucket_access.rb +0 -14
- data/lib/ripple/document/finders.rb +17 -23
- data/lib/ripple/document/key.rb +8 -28
- data/lib/ripple/document/link.rb +30 -0
- data/lib/ripple/document/persistence.rb +12 -20
- data/lib/ripple/embedded_document.rb +10 -15
- data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
- data/lib/ripple/embedded_document/finders.rb +7 -18
- data/lib/ripple/embedded_document/persistence.rb +5 -17
- data/lib/ripple/i18n.rb +0 -14
- data/lib/ripple/inspection.rb +21 -15
- data/lib/ripple/locale/en.yml +9 -13
- data/lib/ripple/nested_attributes.rb +33 -39
- data/lib/ripple/observable.rb +0 -13
- data/lib/ripple/properties.rb +1 -14
- data/lib/ripple/property_type_mismatch.rb +0 -14
- data/lib/ripple/railtie.rb +4 -14
- data/lib/ripple/railties/ripple.rake +86 -0
- data/lib/ripple/serialization.rb +11 -11
- data/lib/ripple/test_server.rb +36 -0
- data/lib/ripple/timestamps.rb +0 -13
- data/lib/ripple/translation.rb +4 -14
- data/lib/ripple/validations.rb +1 -15
- data/lib/ripple/validations/associated_validator.rb +26 -17
- data/lib/ripple/version.rb +3 -0
- data/ripple.gemspec +24 -35
- data/spec/integration/ripple/associations_spec.rb +89 -58
- data/spec/integration/ripple/conflict_resolution_spec.rb +298 -0
- data/spec/integration/ripple/nested_attributes_spec.rb +19 -19
- data/spec/integration/ripple/persistence_spec.rb +15 -34
- data/spec/integration/ripple/search_associations_spec.rb +31 -0
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +23 -36
- data/spec/ripple/associations/many_linked_proxy_spec.rb +133 -45
- data/spec/ripple/associations/many_reference_proxy_spec.rb +170 -0
- data/spec/ripple/associations/many_stored_key_proxy_spec.rb +158 -0
- data/spec/ripple/associations/one_embedded_proxy_spec.rb +24 -37
- data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
- data/spec/ripple/associations/one_linked_proxy_spec.rb +22 -23
- data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
- data/spec/ripple/associations/proxy_spec.rb +21 -15
- data/spec/ripple/associations_spec.rb +54 -23
- data/spec/ripple/attribute_methods/dirty_spec.rb +56 -5
- data/spec/ripple/attribute_methods_spec.rb +47 -21
- data/spec/ripple/bucket_access_spec.rb +4 -17
- data/spec/ripple/callbacks_spec.rb +52 -15
- data/spec/ripple/conflict/resolver_spec.rb +42 -0
- data/spec/ripple/conversion_spec.rb +2 -15
- data/spec/ripple/core_ext_spec.rb +12 -15
- data/spec/ripple/document/link_spec.rb +67 -0
- data/spec/ripple/document_spec.rb +34 -19
- data/spec/ripple/embedded_document/finders_spec.rb +12 -19
- data/spec/ripple/embedded_document/persistence_spec.rb +20 -26
- data/spec/ripple/embedded_document_spec.rb +44 -34
- data/spec/ripple/finders_spec.rb +58 -29
- data/spec/ripple/inspection_spec.rb +40 -37
- data/spec/ripple/key_spec.rb +5 -17
- data/spec/ripple/observable_spec.rb +3 -16
- data/spec/ripple/persistence_spec.rb +134 -18
- data/spec/ripple/properties_spec.rb +21 -15
- data/spec/ripple/ripple_spec.rb +1 -14
- data/spec/ripple/serialization_spec.rb +16 -17
- data/spec/ripple/timestamps_spec.rb +73 -52
- data/spec/ripple/validations/associated_validator_spec.rb +69 -25
- data/spec/ripple/validations_spec.rb +3 -16
- data/spec/spec_helper.rb +17 -18
- data/spec/support/associations.rb +1 -1
- data/spec/support/associations/proxies.rb +0 -13
- data/spec/support/integration_setup.rb +11 -0
- data/spec/support/mocks.rb +0 -13
- data/spec/support/models.rb +33 -2
- data/spec/support/models/address.rb +1 -16
- data/spec/support/models/box.rb +7 -14
- data/spec/support/models/car.rb +27 -1
- data/spec/support/models/cardboard_box.rb +0 -14
- data/spec/support/models/clock.rb +6 -15
- data/spec/support/models/clock_observer.rb +0 -14
- data/spec/support/models/credit_card.rb +5 -0
- data/spec/support/models/customer.rb +0 -14
- data/spec/support/models/email.rb +0 -14
- data/spec/support/models/family.rb +1 -13
- data/spec/support/models/favorite.rb +0 -14
- data/spec/support/models/invoice.rb +0 -14
- data/spec/support/models/late_invoice.rb +0 -14
- data/spec/support/models/nested.rb +12 -0
- data/spec/support/models/ninja.rb +7 -0
- data/spec/support/models/note.rb +0 -14
- data/spec/support/models/page.rb +1 -15
- data/spec/support/models/paid_invoice.rb +0 -14
- data/spec/support/models/post.rb +12 -0
- data/spec/support/models/profile.rb +7 -0
- data/spec/support/models/subscription.rb +26 -0
- data/spec/support/models/tasks.rb +0 -18
- data/spec/support/models/team.rb +11 -0
- data/spec/support/models/transactions.rb +17 -0
- data/spec/support/models/tree.rb +2 -16
- data/spec/support/models/user.rb +14 -16
- data/spec/support/models/widget.rb +8 -14
- data/spec/support/search.rb +14 -0
- data/spec/support/test_server.rb +22 -12
- data/spec/support/test_server.yml.example +14 -2
- metadata +223 -59
- data/lib/rails/generators/ripple/test/templates/test_server.rb +0 -46
- data/spec/support/models/driver.rb +0 -5
- data/spec/support/models/engine.rb +0 -4
- data/spec/support/models/passenger.rb +0 -5
- data/spec/support/models/seat.rb +0 -4
- data/spec/support/models/wheel.rb +0 -5
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'ripple/associations/proxy'
|
|
2
|
+
require 'ripple/associations/one'
|
|
3
|
+
|
|
4
|
+
module Ripple
|
|
5
|
+
module Associations
|
|
6
|
+
class OneKeyProxy < Proxy
|
|
7
|
+
include One
|
|
8
|
+
|
|
9
|
+
def replace(doc)
|
|
10
|
+
@reflection.verify_type!(doc, owner)
|
|
11
|
+
|
|
12
|
+
reset_previous_target_key_delegate
|
|
13
|
+
assign_new_target_key_delegate(doc)
|
|
14
|
+
|
|
15
|
+
loaded
|
|
16
|
+
@target = doc
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def find_target
|
|
20
|
+
klass.find(owner.key)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
def instantiate_target(instantiator, attrs={})
|
|
25
|
+
@target = super
|
|
26
|
+
@target.key = owner.key
|
|
27
|
+
@target
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
def reset_previous_target_key_delegate
|
|
32
|
+
@target.key_delegate = @target if @target
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def assign_new_target_key_delegate(doc)
|
|
36
|
+
doc.class.send(:include, Ripple::Associations::KeyDelegator) unless doc.class.include?(Ripple::Associations::KeyDelegator)
|
|
37
|
+
owner.key_delegate = doc.key_delegate = owner
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module KeyDelegator
|
|
43
|
+
attr_accessor :key_delegate
|
|
44
|
+
|
|
45
|
+
def key_delegate
|
|
46
|
+
@key_delegate || self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def key
|
|
50
|
+
self === key_delegate ? super : key_delegate.key
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def key=(value)
|
|
54
|
+
self === key_delegate ? super(value) : key_delegate.key = value
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'ripple/associations/proxy'
|
|
16
2
|
require 'ripple/associations/one'
|
|
17
3
|
require 'ripple/associations/linked'
|
|
@@ -22,6 +8,10 @@ module Ripple
|
|
|
22
8
|
include One
|
|
23
9
|
include Linked
|
|
24
10
|
|
|
11
|
+
def key
|
|
12
|
+
keys.first
|
|
13
|
+
end
|
|
14
|
+
|
|
25
15
|
protected
|
|
26
16
|
def find_target
|
|
27
17
|
return nil if links.blank?
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'ripple/associations/proxy'
|
|
2
|
+
require 'ripple/associations/one'
|
|
3
|
+
|
|
4
|
+
module Ripple
|
|
5
|
+
module Associations
|
|
6
|
+
class OneStoredKeyProxy < Proxy
|
|
7
|
+
include One
|
|
8
|
+
|
|
9
|
+
def replace(value)
|
|
10
|
+
@reflection.verify_type!(value, owner)
|
|
11
|
+
|
|
12
|
+
if value
|
|
13
|
+
assign_key(value.key)
|
|
14
|
+
else
|
|
15
|
+
assign_key(nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@target = value
|
|
19
|
+
loaded
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
def key
|
|
25
|
+
@owner.send(key_name)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def assign_key(value)
|
|
29
|
+
@owner.send("#{key_name}=", value)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def key_name
|
|
33
|
+
"#{@reflection.name}_key"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def find_target
|
|
37
|
+
return nil if key.blank?
|
|
38
|
+
|
|
39
|
+
klass.find(key)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'ripple/associations'
|
|
16
2
|
|
|
17
3
|
module Ripple
|
|
@@ -99,6 +85,14 @@ module Ripple
|
|
|
99
85
|
other === target
|
|
100
86
|
end
|
|
101
87
|
|
|
88
|
+
def loaded_documents
|
|
89
|
+
loaded? ? Array(target) : []
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def has_changed_documents?
|
|
93
|
+
loaded_documents.any? { |doc| doc.changed? }
|
|
94
|
+
end
|
|
95
|
+
|
|
102
96
|
protected
|
|
103
97
|
def method_missing(method, *args, &block)
|
|
104
98
|
load_target
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'ripple/translation'
|
|
16
2
|
require 'active_support/concern'
|
|
17
3
|
require 'active_model/attribute_methods'
|
|
@@ -35,7 +21,7 @@ module Ripple
|
|
|
35
21
|
include Query
|
|
36
22
|
include Dirty
|
|
37
23
|
include ActiveModel::MassAssignmentSecurity
|
|
38
|
-
|
|
24
|
+
|
|
39
25
|
attr_protected :key
|
|
40
26
|
end
|
|
41
27
|
|
|
@@ -59,6 +45,10 @@ module Ripple
|
|
|
59
45
|
# nor embedded documents.
|
|
60
46
|
# @return [Hash] all document attributes, by key
|
|
61
47
|
def attributes
|
|
48
|
+
raw_attributes.reject { |k, v| !respond_to?(k) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def raw_attributes
|
|
62
52
|
self.class.properties.values.inject(@attributes.with_indifferent_access) do |hash, prop|
|
|
63
53
|
hash[prop.key] = attribute(prop.key)
|
|
64
54
|
hash
|
|
@@ -67,9 +57,21 @@ module Ripple
|
|
|
67
57
|
|
|
68
58
|
# Mass assign the document's attributes.
|
|
69
59
|
# @param [Hash] attrs the attributes to assign
|
|
70
|
-
def attributes=(attrs
|
|
60
|
+
def attributes=(attrs)
|
|
61
|
+
raise ArgumentError, t('attribute_hash') unless Hash === attrs
|
|
62
|
+
sanitize_for_mass_assignment(attrs).each do |k,v|
|
|
63
|
+
if respond_to?("#{k}=")
|
|
64
|
+
__send__("#{k}=",v)
|
|
65
|
+
else
|
|
66
|
+
raise ArgumentError, t('undefined_property', :prop => k, :class => self.class.name)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @private
|
|
72
|
+
def raw_attributes=(attrs)
|
|
71
73
|
raise ArgumentError, t('attribute_hash') unless Hash === attrs
|
|
72
|
-
|
|
74
|
+
attrs.each do |k,v|
|
|
73
75
|
next if k.to_sym == :key
|
|
74
76
|
if respond_to?("#{k}=")
|
|
75
77
|
__send__("#{k}=",v)
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'active_support/concern'
|
|
16
2
|
require 'active_model/dirty'
|
|
17
3
|
|
|
@@ -21,6 +7,15 @@ module Ripple
|
|
|
21
7
|
extend ActiveSupport::Concern
|
|
22
8
|
include ActiveModel::Dirty
|
|
23
9
|
|
|
10
|
+
module ClassMethods
|
|
11
|
+
# @private
|
|
12
|
+
def instantiate(robject)
|
|
13
|
+
super(robject).tap do |o|
|
|
14
|
+
o.changed_attributes.clear
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
24
19
|
# @private
|
|
25
20
|
def really_save(*args)
|
|
26
21
|
if result = super
|
|
@@ -43,9 +38,18 @@ module Ripple
|
|
|
43
38
|
changed_attributes.clear
|
|
44
39
|
end
|
|
45
40
|
|
|
41
|
+
# Determines if the document has any chnages.
|
|
42
|
+
# @return [Boolean] true if this document, or any of its embedded
|
|
43
|
+
# documents at any level, have changed.
|
|
44
|
+
def changed?
|
|
45
|
+
super || self.class.embedded_associations.any? do |association|
|
|
46
|
+
send(association.name).has_changed_documents?
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
46
50
|
private
|
|
47
51
|
def attribute=(attr_name, value)
|
|
48
|
-
if self.class.properties.include?(attr_name.
|
|
52
|
+
if self.class.properties.include?(attr_name.to_sym) && @attributes[attr_name] != value
|
|
49
53
|
attribute_will_change!(attr_name)
|
|
50
54
|
end
|
|
51
55
|
super
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'active_support/concern'
|
|
16
2
|
|
|
17
3
|
module Ripple
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'active_support/concern'
|
|
16
2
|
|
|
17
3
|
module Ripple
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'active_support/concern'
|
|
16
2
|
|
|
17
3
|
module Ripple
|
data/lib/ripple/callbacks.rb
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
require 'active_support/concern'
|
|
16
2
|
require 'active_model/callbacks'
|
|
17
3
|
|
|
@@ -21,9 +7,11 @@ module Ripple
|
|
|
21
7
|
module Callbacks
|
|
22
8
|
extend ActiveSupport::Concern
|
|
23
9
|
|
|
10
|
+
CALLBACK_TYPES = [:create, :update, :save, :destroy, :validation]
|
|
11
|
+
|
|
24
12
|
included do
|
|
25
13
|
extend ActiveModel::Callbacks
|
|
26
|
-
define_model_callbacks
|
|
14
|
+
define_model_callbacks *(CALLBACK_TYPES - [:validation])
|
|
27
15
|
define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name]
|
|
28
16
|
end
|
|
29
17
|
|
|
@@ -53,10 +41,16 @@ module Ripple
|
|
|
53
41
|
module InstanceMethods
|
|
54
42
|
# @private
|
|
55
43
|
def really_save(*args, &block)
|
|
44
|
+
run_save_callbacks do
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def run_save_callbacks
|
|
56
50
|
state = new? ? :create : :update
|
|
57
51
|
run_callbacks(:save) do
|
|
58
52
|
run_callbacks(state) do
|
|
59
|
-
|
|
53
|
+
yield
|
|
60
54
|
end
|
|
61
55
|
end
|
|
62
56
|
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module Ripple
|
|
2
|
+
module Conflict
|
|
3
|
+
class BasicResolver
|
|
4
|
+
delegate :model_class, :document, :siblings, :to => :@main_resolver
|
|
5
|
+
|
|
6
|
+
def initialize(main_resolver)
|
|
7
|
+
@main_resolver = main_resolver
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def remaining_conflicts
|
|
11
|
+
@remaining_conflicts ||= []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def unexpected_conflicts
|
|
15
|
+
# if the user didn't specify the conflict they expect,
|
|
16
|
+
# then don't consider any conflicts unexpected
|
|
17
|
+
return [] if model_class.expected_conflicts.blank?
|
|
18
|
+
|
|
19
|
+
remaining_conflicts - model_class.expected_conflicts
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def perform
|
|
23
|
+
process_properties
|
|
24
|
+
process_embedded_associations
|
|
25
|
+
process_linked_associations
|
|
26
|
+
process_stored_key_associations
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def process_properties
|
|
32
|
+
model_class.properties.each do |name, property|
|
|
33
|
+
document.send(:"#{name}=", resolved_property_value_for(property))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def process_embedded_associations
|
|
38
|
+
model_class.embedded_associations.each do |assoc|
|
|
39
|
+
document.send(:"#{assoc.name}=", resolved_association_value_for(assoc, :load_target))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def process_linked_associations
|
|
44
|
+
model_class.linked_associations.each do |assoc|
|
|
45
|
+
document.send(assoc.name).replace_links(resolved_association_value_for(assoc, :links))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def process_stored_key_associations
|
|
50
|
+
model_class.stored_key_associations.each do |assoc|
|
|
51
|
+
document.send(assoc.name).reset_owner_keys if (assoc.type == :many)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def resolved_property_value_for(property)
|
|
56
|
+
uniq_values = siblings.map(&property.key).uniq
|
|
57
|
+
|
|
58
|
+
value = if uniq_values.size == 1
|
|
59
|
+
uniq_values.first
|
|
60
|
+
elsif property.key == :updated_at
|
|
61
|
+
uniq_values.compact.max
|
|
62
|
+
elsif property.key == :created_at
|
|
63
|
+
uniq_values.compact.min
|
|
64
|
+
else
|
|
65
|
+
remaining_conflicts << property.key
|
|
66
|
+
property.default
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def resolved_association_value_for(association, proxy_value_method)
|
|
71
|
+
# the association proxy doesn't uniquify well, so we have to use the target or links directly
|
|
72
|
+
uniq_values = siblings.map { |s| s.send(association.name).__send__(proxy_value_method) }.uniq
|
|
73
|
+
|
|
74
|
+
return uniq_values.first if uniq_values.size == 1
|
|
75
|
+
remaining_conflicts << association.name
|
|
76
|
+
|
|
77
|
+
association.many? ? [] : nil # default value
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|