simply_stored 0.6.1 → 0.6.2
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/CHANGELOG.md +4 -0
- data/lib/simply_stored/instance_methods.rb +42 -11
- data/lib/simply_stored.rb +1 -1
- metadata +4 -4
data/CHANGELOG.md
CHANGED
@@ -77,34 +77,57 @@ module SimplyStored
|
|
77
77
|
def retry_on_conflict(max_retries = 2, &blk)
|
78
78
|
retry_count = 0
|
79
79
|
begin
|
80
|
+
_reset_conflict_information
|
80
81
|
blk.call
|
81
82
|
rescue RestClient::Exception, RestClient::Conflict => e
|
82
83
|
if (e.http_code == 409 || e.is_a?(RestClient::Conflict)) && self.class.auto_conflict_resolution_on_save && retry_count < max_retries && try_to_merge_conflict
|
83
84
|
retry_count += 1
|
84
85
|
retry
|
85
86
|
else
|
87
|
+
_decorate_with_conflict_details(e) if e.is_a?(RestClient::Conflict)
|
86
88
|
raise e
|
87
89
|
end
|
88
90
|
end
|
89
91
|
end
|
90
|
-
|
92
|
+
|
93
|
+
def _decorate_with_conflict_details(exception)
|
94
|
+
if @_conflict_information.present?
|
95
|
+
def exception.metaclass
|
96
|
+
class << self
|
97
|
+
self
|
98
|
+
end
|
99
|
+
end
|
100
|
+
local_conflict_information = @_conflict_information
|
101
|
+
exception.metaclass.send(:define_method, :message){ "409 Conflict - conflict on attributes: #{local_conflict_information.inspect}" }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
91
105
|
def try_to_merge_conflict
|
92
106
|
original = self.class.find(id)
|
93
107
|
our_attributes = self.attributes.dup
|
94
108
|
their_attributes = original.attributes.dup
|
95
|
-
|
96
|
-
|
97
|
-
their_attributes.delete(skipped_attribute)
|
98
|
-
end
|
109
|
+
_clear_non_relevant_attributes(our_attributes)
|
110
|
+
_clear_non_relevant_attributes(their_attributes)
|
99
111
|
if _merge_possible?(our_attributes, their_attributes)
|
100
112
|
_copy_non_conflicting_attributes(our_attributes, their_attributes)
|
101
113
|
self._rev = original._rev
|
102
114
|
true
|
103
115
|
else
|
116
|
+
@_conflict_information = _conflicting_attributes(our_attributes, their_attributes)
|
104
117
|
false
|
105
118
|
end
|
106
119
|
end
|
107
|
-
|
120
|
+
|
121
|
+
def _reset_conflict_information
|
122
|
+
@_conflict_information = nil
|
123
|
+
end
|
124
|
+
|
125
|
+
def _clear_non_relevant_attributes(attr_list)
|
126
|
+
[:updated_at, :created_at, :id, :rev, :_id, :_rev].each do |skipped_attribute|
|
127
|
+
attr_list.delete(skipped_attribute)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
108
131
|
def _copy_non_conflicting_attributes(our_attributes, their_attributes)
|
109
132
|
their_attributes.each do |attr_name, their_value|
|
110
133
|
if !self.send("#{attr_name}_changed?") && our_attributes[attr_name] != their_value
|
@@ -114,13 +137,21 @@ module SimplyStored
|
|
114
137
|
end
|
115
138
|
|
116
139
|
def _merge_possible?(our_attributes, their_attributes)
|
117
|
-
their_attributes.
|
118
|
-
|
119
|
-
|
120
|
-
|
140
|
+
_conflicting_attributes(our_attributes, their_attributes).empty?
|
141
|
+
end
|
142
|
+
|
143
|
+
def _conflicting_attributes(our_attributes, their_attributes)
|
144
|
+
their_attributes.keys.delete_if do |attr_name|
|
145
|
+
_attribute_not_in_conflict?(attr_name, our_attributes[attr_name], their_attributes[attr_name])
|
121
146
|
end
|
122
147
|
end
|
123
|
-
|
148
|
+
|
149
|
+
def _attribute_not_in_conflict?(attr_name, our_value, their_value)
|
150
|
+
our_value == their_value || # same
|
151
|
+
!self.send("#{attr_name}_changed?") || # we didn't change
|
152
|
+
self.send("#{attr_name}_changed?") && their_value == self.send("#{attr_name}_was") # we changed and they kept the original
|
153
|
+
end
|
154
|
+
|
124
155
|
def reset_association_caches
|
125
156
|
self.class.properties.each do |property|
|
126
157
|
if property.respond_to?(:association?) && property.association?
|
data/lib/simply_stored.rb
CHANGED
@@ -5,7 +5,7 @@ unless defined?(SimplyStored)
|
|
5
5
|
require File.expand_path(File.dirname(__FILE__) + '/simply_stored/class_methods_base')
|
6
6
|
|
7
7
|
module SimplyStored
|
8
|
-
VERSION = '0.6.
|
8
|
+
VERSION = '0.6.2'
|
9
9
|
class Error < RuntimeError; end
|
10
10
|
class RecordNotFound < RuntimeError; end
|
11
11
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simply_stored
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 2
|
10
|
+
version: 0.6.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mathias Meyer, Jonathan Weiss
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-07 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|