sequel_bitemporal 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,6 +20,9 @@ module Sequel
20
20
  valid_from.to_time<=now &&
21
21
  valid_to.to_time>now
22
22
  end
23
+ def destroy
24
+ master.destroy_version self
25
+ end
23
26
  end
24
27
  master.instance_eval do
25
28
  @version_class = version
@@ -77,6 +80,30 @@ module Sequel
77
80
  super
78
81
  end
79
82
 
83
+ def destroy
84
+ versions_dataset.where(expired_at: nil).where("valid_to>valid_from").update expired_at: Time.now
85
+ end
86
+
87
+ def destroy_version(version)
88
+ point_in_time = Time.now
89
+ return false if version.valid_to.to_time<=point_in_time
90
+ model.db.transaction do
91
+ success = true
92
+ previous = versions_dataset.where({
93
+ expired_at: nil,
94
+ valid_to: version.valid_from,
95
+ }).where("valid_to>valid_from").first
96
+ if previous
97
+ success &&= save_fossil previous, created_at: point_in_time, valid_to: version.valid_to
98
+ success &&= previous.update expired_at: point_in_time
99
+ end
100
+ success &&= save_fossil version, created_at: point_in_time, valid_to: point_in_time if point_in_time>=version.valid_from.to_time
101
+ success &&= version.update expired_at: point_in_time
102
+ raise Sequel::Rollback unless success
103
+ success
104
+ end
105
+ end
106
+
80
107
  private
81
108
 
82
109
  def prepare_pending_version
@@ -96,7 +123,7 @@ module Sequel
96
123
  expired = versions_dataset.where expired_at: nil
97
124
  expired = expired.exclude "valid_from=valid_to"
98
125
  expired = expired.exclude "valid_to<=?", pending_version.valid_from
99
- pending_version.valid_to ||= expired.where("valid_from>?", pending_version.valid_from).select("MIN(valid_from)").first
126
+ pending_version.valid_to ||= expired.where("valid_from>?", pending_version.valid_from).min(:valid_from)
100
127
  pending_version.valid_to ||= Time.utc 9999
101
128
  expired = expired.exclude "valid_from>=?", pending_version.valid_to
102
129
  expired = expired.all
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "sequel_bitemporal"
6
- s.version = "0.1.1"
6
+ s.version = "0.1.2"
7
7
  s.authors = ["Joseph HALTER"]
8
8
  s.email = ["joseph.halter@thetalentbox.com"]
9
9
  s.homepage = "https://github.com/TalentBox/sequel_bitemporal"
@@ -168,14 +168,126 @@ describe "Sequel::Plugins::Bitemporal" do
168
168
  # | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
169
169
  # | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | | true |
170
170
  end
171
+ it "overrides no future versions" do
172
+ master = @master_class.new
173
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
174
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2, valid_to: Date.today+4
175
+ master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+4, valid_to: Date.today+6
176
+ Timecop.freeze Date.today+1
177
+ master.update_attributes name: "King Size", valid_to: nil, partial_update: true
178
+ master.should have_versions %Q{
179
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
180
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
181
+ | Single Standard | 94 | 2009-11-28 | | 2009-11-30 | 2009-12-02 | |
182
+ | Single Standard | 95 | 2009-11-28 | | 2009-12-02 | 2009-12-04 | |
183
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
184
+ | King Size | 98 | 2009-11-29 | | 2009-11-29 | 2009-11-30 | true |
185
+ }
186
+ end
187
+ it "overrides multiple future versions" do
188
+ master = @master_class.new
189
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
190
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2, valid_to: Date.today+4
191
+ master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+4, valid_to: Date.today+6
192
+ Timecop.freeze Date.today+1
193
+ master.update_attributes name: "King Size", valid_to: Date.today+4, partial_update: true
194
+ master.should have_versions %Q{
195
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
196
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
197
+ | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | 2009-12-02 | |
198
+ | Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-12-02 | 2009-12-04 | |
199
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
200
+ | Single Standard | 95 | 2009-11-29 | | 2009-12-03 | 2009-12-04 | |
201
+ | King Size | 98 | 2009-11-29 | | 2009-11-29 | 2009-12-03 | true |
202
+ }
203
+ end
204
+ it "overrides all future versions" do
205
+ master = @master_class.new
206
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
207
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2, valid_to: Date.today+4
208
+ master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+4, valid_to: Date.today+6
209
+ Timecop.freeze Date.today+1
210
+ master.update_attributes name: "King Size", valid_to: Time.utc(9999), partial_update: true
211
+ master.should have_versions %Q{
212
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
213
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
214
+ | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | 2009-12-02 | |
215
+ | Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-12-02 | 2009-12-04 | |
216
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
217
+ | King Size | 98 | 2009-11-29 | | 2009-11-29 | | true |
218
+ }
219
+ end
171
220
  xit "doesn't do anything if unchanged" do
172
221
  end
173
- xit "allows deleting current version" do
222
+ it "allows deleting current version" do
223
+ master = @master_class.new
224
+ master.update_attributes name: "Single Standard", price: 98
225
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
226
+ Timecop.freeze Date.today+1
227
+ master.current_version.destroy.should be_true
228
+ master.should have_versions %Q{
229
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
230
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
231
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
232
+ | Single Standard | 94 | 2009-11-28 | | 2009-11-30 | | |
233
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
234
+ }
235
+ end
236
+ it "allows deleting a future version" do
237
+ master = @master_class.new
238
+ master.update_attributes name: "Single Standard", price: 98
239
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
240
+ Timecop.freeze Date.today+1
241
+ master.versions.last.destroy.should be_true
242
+ master.should have_versions %Q{
243
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
244
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
245
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
246
+ | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | | |
247
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | | true |
248
+ }
174
249
  end
175
- xit "allows deleting a future version" do
250
+ it "allows deleting all versions" do
251
+ master = @master_class.new
252
+ master.update_attributes name: "Single Standard", price: 98
253
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
254
+ Timecop.freeze Date.today+1
255
+ master.destroy.should be_true
256
+ master.should have_versions %Q{
257
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
258
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
259
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
260
+ | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | | |
261
+ }
176
262
  end
177
- xit "allows deleting all versions" do
263
+ it "allows simultaneous updates without information loss" do
264
+ master = @master_class.new
265
+ master.update_attributes name: "Single Standard", price: 98
266
+ Timecop.freeze Date.today+1
267
+ master2 = @master_class.find id: master.id
268
+ master.update_attributes name: "Single Standard", price: 94
269
+ master2.update_attributes name: "Single Standard", price: 95
270
+ master.should have_versions %Q{
271
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
272
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | | |
273
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
274
+ | Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | | |
275
+ | Single Standard | 95 | 2009-11-29 | | 2009-11-29 | | true |
276
+ }
178
277
  end
179
- xit "allows simultaneous updates" do
278
+ it "allows simultaneous cumulative updates" do
279
+ master = @master_class.new
280
+ master.update_attributes name: "Single Standard", price: 98
281
+ Timecop.freeze Date.today+1
282
+ master2 = @master_class.find id: master.id
283
+ master.update_attributes price: 94, partial_update: true
284
+ master2.update_attributes name: "King Size", partial_update: true
285
+ master.should have_versions %Q{
286
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
287
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | | |
288
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
289
+ | Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | | |
290
+ | King Size | 94 | 2009-11-29 | | 2009-11-29 | | true |
291
+ }
180
292
  end
181
293
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_bitemporal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-01 00:00:00.000000000Z
12
+ date: 2011-11-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3
16
- requirement: &2153760860 !ruby/object:Gem::Requirement
16
+ requirement: &2154275980 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2153760860
24
+ version_requirements: *2154275980
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2153760420 !ruby/object:Gem::Requirement
27
+ requirement: &2154275540 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2153760420
35
+ version_requirements: *2154275540
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: timecop
38
- requirement: &2153760000 !ruby/object:Gem::Requirement
38
+ requirement: &2154302740 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2153760000
46
+ version_requirements: *2154302740
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sequel
49
- requirement: &2156552020 !ruby/object:Gem::Requirement
49
+ requirement: &2154302320 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2156552020
57
+ version_requirements: *2154302320
58
58
  description: Bitemporal versioning for sequel, fully tested.
59
59
  email:
60
60
  - joseph.halter@thetalentbox.com