simply_stored 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  Changelog
2
2
  =============
3
3
 
4
+ 0.6.2
5
+
6
+ - Decorate conflict exceptions with information about the conflict
7
+
4
8
  0.6.1
5
9
 
6
10
  - Fix warning of dynamically created views to point to the correct called
@@ -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
- [:updated_at, :created_at, :id, :rev, :_id, :_rev].each do |skipped_attribute|
96
- our_attributes.delete(skipped_attribute)
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.all? do |attr_name, their_value|
118
- our_attributes[attr_name] == their_value || # same
119
- !self.send("#{attr_name}_changed?") || # we didn't change
120
- self.send("#{attr_name}_changed?") && their_value == self.send("#{attr_name}_was") # we changed and they kept the original
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.1'
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: 5
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 1
10
- version: 0.6.1
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-06 00:00:00 Z
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