sequel_bitemporal 0.1.6 → 0.1.7
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/sequel_bitemporal.gemspec
CHANGED
@@ -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.
|
6
|
+
s.version = "0.1.7"
|
7
7
|
s.authors = ["Joseph HALTER"]
|
8
8
|
s.email = ["joseph.halter@thetalentbox.com"]
|
9
9
|
s.homepage = "https://github.com/TalentBox/sequel_bitemporal"
|
@@ -67,7 +67,7 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
67
67
|
master.should_not be_new
|
68
68
|
master.should have_versions %Q{
|
69
69
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
70
|
-
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 |
|
70
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
71
71
|
}
|
72
72
|
end
|
73
73
|
it "allows creating a new version in the past" do
|
@@ -75,7 +75,7 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
75
75
|
master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today-1
|
76
76
|
master.should have_versions %Q{
|
77
77
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
78
|
-
| Single Standard | 98 | 2009-11-28 | | 2009-11-27 |
|
78
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-27 | MAX DATE | true |
|
79
79
|
}
|
80
80
|
end
|
81
81
|
it "allows creating a new version in the future" do
|
@@ -83,7 +83,7 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
83
83
|
master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today+1
|
84
84
|
master.should have_versions %Q{
|
85
85
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
86
|
-
| Single Standard | 98 | 2009-11-28 | | 2009-11-29 |
|
86
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-29 | MAX DATE | |
|
87
87
|
}
|
88
88
|
end
|
89
89
|
it "doesn't loose previous version in same-day update" do
|
@@ -92,8 +92,8 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
92
92
|
master.update_attributes name: "Single Standard", price: 94
|
93
93
|
master.should have_versions %Q{
|
94
94
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
95
|
-
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 |
|
96
|
-
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 |
|
95
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
96
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
97
97
|
}
|
98
98
|
end
|
99
99
|
it "allows partial updating based on current version" do
|
@@ -103,9 +103,9 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
103
103
|
master.update_attributes name: "King Size", partial_update: true
|
104
104
|
master.should have_versions %Q{
|
105
105
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
106
|
-
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 |
|
107
|
-
| Single Standard | 94 | 2009-11-28 | 2009-11-28 | 2009-11-28 |
|
108
|
-
| King Size | 94 | 2009-11-28 | | 2009-11-28 |
|
106
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
107
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
108
|
+
| King Size | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
109
109
|
}
|
110
110
|
end
|
111
111
|
it "expires previous version but keep it in history" do
|
@@ -115,9 +115,9 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
115
115
|
master.update_attributes price: 94, partial_update: true
|
116
116
|
master.should have_versions %Q{
|
117
117
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
118
|
-
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 |
|
118
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
119
119
|
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
120
|
-
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 |
|
120
|
+
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
121
121
|
}
|
122
122
|
end
|
123
123
|
it "doesn't expire no longer valid versions" do
|
@@ -129,7 +129,7 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
129
129
|
master.should have_versions %Q{
|
130
130
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
131
131
|
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | 2009-11-29 | |
|
132
|
-
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 |
|
132
|
+
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
133
133
|
}
|
134
134
|
end
|
135
135
|
it "allows shortening validity (SEE COMMENTS FOR IMPROVEMENTS)" do
|
@@ -139,7 +139,7 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
139
139
|
master.update_attributes valid_to: Date.today+10, partial_update: true
|
140
140
|
master.should have_versions %Q{
|
141
141
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
142
|
-
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 |
|
142
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
143
143
|
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
144
144
|
| Single Standard | 98 | 2009-11-29 | | 2009-11-29 | 2009-12-09 | true |
|
145
145
|
}
|
@@ -161,12 +161,12 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
161
161
|
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
162
162
|
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
163
163
|
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
164
|
-
| Single Standard | 98 | 2009-11-29 | | 2009-11-29 |
|
164
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
165
165
|
}
|
166
166
|
# would be even better if it could be:
|
167
167
|
# | name | price | created_at | expired_at | valid_from | valid_to | current |
|
168
168
|
# | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
169
|
-
# | Single Standard | 98 | 2009-11-29 | | 2009-11-28 |
|
169
|
+
# | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | true |
|
170
170
|
end
|
171
171
|
xit "doesn't do anything if unchanged" do
|
172
172
|
end
|
@@ -216,7 +216,7 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
216
216
|
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | 2009-12-02 | |
|
217
217
|
| Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-12-02 | 2009-12-04 | |
|
218
218
|
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
219
|
-
| King Size | 98 | 2009-11-29 | | 2009-11-29 |
|
219
|
+
| King Size | 98 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
220
220
|
}
|
221
221
|
end
|
222
222
|
it "allows deleting current version" do
|
@@ -227,9 +227,9 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
227
227
|
master.current_version.destroy.should be_true
|
228
228
|
master.should have_versions %Q{
|
229
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 |
|
230
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
231
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 |
|
232
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-30 | MAX DATE | |
|
233
233
|
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
234
234
|
}
|
235
235
|
end
|
@@ -241,10 +241,10 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
241
241
|
master.versions.last.destroy.should be_true
|
242
242
|
master.should have_versions %Q{
|
243
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 |
|
244
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
245
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 |
|
246
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
|
247
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | true |
|
248
248
|
}
|
249
249
|
end
|
250
250
|
it "allows deleting all versions" do
|
@@ -255,9 +255,9 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
255
255
|
master.destroy.should be_true
|
256
256
|
master.should have_versions %Q{
|
257
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 |
|
258
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
259
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 |
|
260
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
|
261
261
|
}
|
262
262
|
end
|
263
263
|
it "allows simultaneous updates without information loss" do
|
@@ -269,10 +269,10 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
269
269
|
master2.update_attributes name: "Single Standard", price: 95
|
270
270
|
master.should have_versions %Q{
|
271
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 |
|
272
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
273
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 |
|
274
|
+
| Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | MAX DATE | |
|
275
|
+
| Single Standard | 95 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
276
276
|
}
|
277
277
|
end
|
278
278
|
it "allows simultaneous cumulative updates" do
|
@@ -284,10 +284,10 @@ describe "Sequel::Plugins::Bitemporal" do
|
|
284
284
|
master2.update_attributes name: "King Size", partial_update: true
|
285
285
|
master.should have_versions %Q{
|
286
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 |
|
287
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
288
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 |
|
289
|
+
| Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | MAX DATE | |
|
290
|
+
| King Size | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
291
291
|
}
|
292
292
|
end
|
293
293
|
it "allows eager loading with conditions on current version" do
|
@@ -0,0 +1,317 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Sequel::Plugins::Bitemporal" do
|
4
|
+
let(:hour){ 3600 }
|
5
|
+
before :all do
|
6
|
+
DB.create_table! :rooms do
|
7
|
+
primary_key :id
|
8
|
+
end
|
9
|
+
DB.create_table! :room_versions do
|
10
|
+
primary_key :id
|
11
|
+
foreign_key :master_id, :rooms
|
12
|
+
String :name
|
13
|
+
Fixnum :price
|
14
|
+
Time :created_at
|
15
|
+
Time :expired_at
|
16
|
+
Time :valid_from
|
17
|
+
Time :valid_to
|
18
|
+
end
|
19
|
+
@version_class = Class.new Sequel::Model do
|
20
|
+
set_dataset :room_versions
|
21
|
+
def validate
|
22
|
+
super
|
23
|
+
errors.add(:name, "is required") unless name
|
24
|
+
errors.add(:price, "is required") unless price
|
25
|
+
end
|
26
|
+
end
|
27
|
+
closure = @version_class
|
28
|
+
@master_class = Class.new Sequel::Model do
|
29
|
+
set_dataset :rooms
|
30
|
+
plugin :bitemporal, version_class: closure
|
31
|
+
end
|
32
|
+
end
|
33
|
+
before do
|
34
|
+
Timecop.freeze 2009, 11, 28, 10
|
35
|
+
end
|
36
|
+
after do
|
37
|
+
Timecop.return
|
38
|
+
@master_class.truncate
|
39
|
+
@version_class.truncate
|
40
|
+
end
|
41
|
+
it "checks version class is given" do
|
42
|
+
lambda{
|
43
|
+
@version_class.plugin :bitemporal
|
44
|
+
}.should raise_error Sequel::Error, "please specify version class to use for bitemporal plugin"
|
45
|
+
end
|
46
|
+
it "checks required columns are present" do
|
47
|
+
lambda{
|
48
|
+
@version_class.plugin :bitemporal, :version_class => @master_class
|
49
|
+
}.should raise_error Sequel::Error, "bitemporal plugin requires the following missing columns on version class: master_id, valid_from, valid_to, created_at, expired_at"
|
50
|
+
end
|
51
|
+
it "propagates errors from version to master" do
|
52
|
+
master = @master_class.new
|
53
|
+
master.should be_valid
|
54
|
+
master.attributes = {name: "Single Standard"}
|
55
|
+
master.should_not be_valid
|
56
|
+
master.errors.should == {price: ["is required"]}
|
57
|
+
end
|
58
|
+
it "#update_attributes returns false instead of raising errors" do
|
59
|
+
master = @master_class.new
|
60
|
+
master.update_attributes(name: "Single Standard").should be_false
|
61
|
+
master.should be_new
|
62
|
+
master.errors.should == {price: ["is required"]}
|
63
|
+
master.update_attributes(price: 98).should be_true
|
64
|
+
end
|
65
|
+
it "allows creating a master and its first version in one step" do
|
66
|
+
master = @master_class.new
|
67
|
+
master.update_attributes(name: "Single Standard", price: 98).should be_true
|
68
|
+
master.should_not be_new
|
69
|
+
master.should have_versions %Q{
|
70
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
71
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
|
72
|
+
}
|
73
|
+
end
|
74
|
+
it "allows creating a new version in the past" do
|
75
|
+
master = @master_class.new
|
76
|
+
master.update_attributes name: "Single Standard", price: 98, valid_from: Time.now-hour
|
77
|
+
master.should have_versions %Q{
|
78
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
79
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 09:00:00 +0100 | MAX TIME | true |
|
80
|
+
}
|
81
|
+
end
|
82
|
+
it "allows creating a new version in the future" do
|
83
|
+
master = @master_class.new
|
84
|
+
master.update_attributes name: "Single Standard", price: 98, valid_from: Time.now+hour
|
85
|
+
master.should have_versions %Q{
|
86
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
87
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | |
|
88
|
+
}
|
89
|
+
end
|
90
|
+
it "doesn't loose previous version in same-day update" do
|
91
|
+
master = @master_class.new
|
92
|
+
master.update_attributes name: "Single Standard", price: 98
|
93
|
+
master.update_attributes name: "Single Standard", price: 94
|
94
|
+
master.should have_versions %Q{
|
95
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
96
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
97
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
|
98
|
+
}
|
99
|
+
end
|
100
|
+
it "allows partial updating based on current version" do
|
101
|
+
master = @master_class.new
|
102
|
+
master.update_attributes name: "Single Standard", price: 98
|
103
|
+
master.update_attributes price: 94, partial_update: true
|
104
|
+
master.update_attributes name: "King Size", partial_update: true
|
105
|
+
master.should have_versions %Q{
|
106
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
107
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
108
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
109
|
+
| King Size | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
|
110
|
+
}
|
111
|
+
end
|
112
|
+
it "expires previous version but keep it in history" do
|
113
|
+
master = @master_class.new
|
114
|
+
master.update_attributes name: "Single Standard", price: 98
|
115
|
+
Timecop.freeze Time.now+hour
|
116
|
+
master.update_attributes price: 94, partial_update: true
|
117
|
+
master.should have_versions %Q{
|
118
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
119
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
120
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
121
|
+
| Single Standard | 94 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
|
122
|
+
}
|
123
|
+
end
|
124
|
+
it "doesn't expire no longer valid versions" do
|
125
|
+
master = @master_class.new
|
126
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+hour
|
127
|
+
Timecop.freeze Time.now+hour
|
128
|
+
master.update_attributes(price: 94, partial_update: true).should be_false
|
129
|
+
master.update_attributes name: "Single Standard", price: 94
|
130
|
+
master.should have_versions %Q{
|
131
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
132
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
133
|
+
| Single Standard | 94 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
|
134
|
+
}
|
135
|
+
end
|
136
|
+
it "allows shortening validity (SEE COMMENTS FOR IMPROVEMENTS)" do
|
137
|
+
master = @master_class.new
|
138
|
+
master.update_attributes name: "Single Standard", price: 98
|
139
|
+
Timecop.freeze Time.now+hour
|
140
|
+
master.update_attributes valid_to: Time.now+10*hour, partial_update: true
|
141
|
+
master.should have_versions %Q{
|
142
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
143
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
144
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
145
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | 2009-11-28 21:00:00 +0100 | true |
|
146
|
+
}
|
147
|
+
# would be even better if it could be:
|
148
|
+
# | name | price | created_at | expired_at | valid_from | valid_to | current |
|
149
|
+
# | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
150
|
+
# | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 21:00:00 +0100 | true |
|
151
|
+
end
|
152
|
+
it "allows extending validity (SEE COMMENTS FOR IMPROVEMENTS)" do
|
153
|
+
master = @master_class.new
|
154
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
|
155
|
+
Timecop.freeze Time.now+hour
|
156
|
+
master.should have_versions %Q{
|
157
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
158
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | true |
|
159
|
+
}
|
160
|
+
master.update_attributes valid_to: nil, partial_update: true
|
161
|
+
master.should have_versions %Q{
|
162
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
163
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
164
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
165
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
|
166
|
+
}
|
167
|
+
# would be even better if it could be:
|
168
|
+
# | name | price | created_at | expired_at | valid_from | valid_to | current |
|
169
|
+
# | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
170
|
+
# | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
|
171
|
+
end
|
172
|
+
xit "doesn't do anything if unchanged" do
|
173
|
+
end
|
174
|
+
it "overrides no future versions" do
|
175
|
+
master = @master_class.new
|
176
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
|
177
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour, valid_to: Time.now+4*hour
|
178
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Time.now+4*hour, valid_to: Time.now+6*hour
|
179
|
+
Timecop.freeze Time.now+hour
|
180
|
+
master.update_attributes name: "King Size", valid_to: nil, partial_update: true
|
181
|
+
master.should have_versions %Q{
|
182
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
183
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
184
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 12:00:00 +0100 | 2009-11-28 14:00:00 +0100 | |
|
185
|
+
| Single Standard | 95 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 14:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
|
186
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
187
|
+
| King Size | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | true |
|
188
|
+
}
|
189
|
+
end
|
190
|
+
it "overrides multiple future versions" do
|
191
|
+
master = @master_class.new
|
192
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
|
193
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour, valid_to: Time.now+4*hour
|
194
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Time.now+4*hour, valid_to: Time.now+6*hour
|
195
|
+
Timecop.freeze Time.now+hour
|
196
|
+
master.update_attributes name: "King Size", valid_to: Time.now+4*hour, partial_update: true
|
197
|
+
master.should have_versions %Q{
|
198
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
199
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
200
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | 2009-11-28 14:00:00 +0100 | |
|
201
|
+
| Single Standard | 95 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 14:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
|
202
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
203
|
+
| Single Standard | 95 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 15:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
|
204
|
+
| King Size | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | 2009-11-28 15:00:00 +0100 | true |
|
205
|
+
}
|
206
|
+
end
|
207
|
+
it "overrides all future versions" do
|
208
|
+
master = @master_class.new
|
209
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
|
210
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour, valid_to: Time.now+4*hour
|
211
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Time.now+4*hour, valid_to: Time.now+6*hour
|
212
|
+
Timecop.freeze Time.now+hour
|
213
|
+
master.update_attributes name: "King Size", valid_to: Time.utc(9999), partial_update: true
|
214
|
+
master.should have_versions %Q{
|
215
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
216
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
217
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | 2009-11-28 14:00:00 +0100 | |
|
218
|
+
| Single Standard | 95 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 14:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
|
219
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
220
|
+
| King Size | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
|
221
|
+
}
|
222
|
+
end
|
223
|
+
it "allows deleting current version" do
|
224
|
+
master = @master_class.new
|
225
|
+
master.update_attributes name: "Single Standard", price: 98
|
226
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
|
227
|
+
Timecop.freeze Time.now+hour
|
228
|
+
master.current_version.destroy.should be_true
|
229
|
+
master.should have_versions %Q{
|
230
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
231
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
232
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
233
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 12:00:00 +0100 | MAX TIME | |
|
234
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
235
|
+
}
|
236
|
+
end
|
237
|
+
it "allows deleting a future version" do
|
238
|
+
master = @master_class.new
|
239
|
+
master.update_attributes name: "Single Standard", price: 98
|
240
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
|
241
|
+
Timecop.freeze Time.now+hour
|
242
|
+
master.versions.last.destroy.should be_true
|
243
|
+
master.should have_versions %Q{
|
244
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
245
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
246
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
247
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | MAX TIME | |
|
248
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
|
249
|
+
}
|
250
|
+
end
|
251
|
+
it "allows deleting all versions" do
|
252
|
+
master = @master_class.new
|
253
|
+
master.update_attributes name: "Single Standard", price: 98
|
254
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
|
255
|
+
Timecop.freeze Time.now+hour
|
256
|
+
master.destroy.should be_true
|
257
|
+
master.should have_versions %Q{
|
258
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
259
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
260
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
|
261
|
+
| Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | MAX TIME | |
|
262
|
+
}
|
263
|
+
end
|
264
|
+
it "allows simultaneous updates without information loss" do
|
265
|
+
master = @master_class.new
|
266
|
+
master.update_attributes name: "Single Standard", price: 98
|
267
|
+
Timecop.freeze Time.now+hour
|
268
|
+
master2 = @master_class.find id: master.id
|
269
|
+
master.update_attributes name: "Single Standard", price: 94
|
270
|
+
master2.update_attributes name: "Single Standard", price: 95
|
271
|
+
master.should have_versions %Q{
|
272
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
273
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
274
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
275
|
+
| Single Standard | 94 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | MAX TIME | |
|
276
|
+
| Single Standard | 95 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
|
277
|
+
}
|
278
|
+
end
|
279
|
+
it "allows simultaneous cumulative updates" do
|
280
|
+
master = @master_class.new
|
281
|
+
master.update_attributes name: "Single Standard", price: 98
|
282
|
+
Timecop.freeze Time.now+hour
|
283
|
+
master2 = @master_class.find id: master.id
|
284
|
+
master.update_attributes price: 94, partial_update: true
|
285
|
+
master2.update_attributes name: "King Size", partial_update: true
|
286
|
+
master.should have_versions %Q{
|
287
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
288
|
+
| Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
|
289
|
+
| Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
|
290
|
+
| Single Standard | 94 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | MAX TIME | |
|
291
|
+
| King Size | 94 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
|
292
|
+
}
|
293
|
+
end
|
294
|
+
it "allows eager loading with conditions on current version" do
|
295
|
+
master = @master_class.new
|
296
|
+
master.update_attributes name: "Single Standard", price: 98
|
297
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
|
298
|
+
@master_class.eager_graph(:current_version).where("current_version.id IS NOT NULL").first.should be
|
299
|
+
Timecop.freeze Time.now+hour
|
300
|
+
master.destroy
|
301
|
+
@master_class.eager_graph(:current_version).where("current_version.id IS NOT NULL").first.should be_nil
|
302
|
+
end
|
303
|
+
it "gets pending or current version attributes" do
|
304
|
+
master = @master_class.new
|
305
|
+
master.attributes.should == {}
|
306
|
+
master.pending_version.should be_nil
|
307
|
+
master.pending_or_current_version.should be_nil
|
308
|
+
master.update_attributes name: "Single Standard", price: 98
|
309
|
+
master.attributes[:name].should == "Single Standard"
|
310
|
+
master.pending_version.should be_nil
|
311
|
+
master.pending_or_current_version.name.should == "Single Standard"
|
312
|
+
master.attributes = {name: "King Size"}
|
313
|
+
master.attributes[:name].should == "King Size"
|
314
|
+
master.pending_version.should be
|
315
|
+
master.pending_or_current_version.name.should == "King Size"
|
316
|
+
end
|
317
|
+
end
|
@@ -9,15 +9,20 @@ RSpec::Matchers.define :have_versions do |versions_str|
|
|
9
9
|
@last_version = version
|
10
10
|
master_version = versions[index]
|
11
11
|
[:name, :price, :valid_from, :valid_to, :created_at, :expired_at, :current].all? do |column|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
expected =
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
if column==:current
|
13
|
+
found = master_version.current?
|
14
|
+
expected = (version[column.to_s]=="true").to_s
|
15
|
+
else
|
16
|
+
found = master_version.send column
|
17
|
+
expected = version[column.to_s]
|
18
|
+
case expected
|
19
|
+
when "MAX DATE"
|
20
|
+
expected = "9999-01-01"
|
21
|
+
when "MAX TIME"
|
22
|
+
expected = "9999-01-01 01:00:00 +0100"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
equal = found.to_s == expected
|
21
26
|
puts "#{column}: #{found} != #{expected}" unless equal
|
22
27
|
equal
|
23
28
|
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.
|
4
|
+
version: 0.1.7
|
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-
|
12
|
+
date: 2011-11-07 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sqlite3
|
16
|
-
requirement: &
|
16
|
+
requirement: &2157615300 !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: *
|
24
|
+
version_requirements: *2157615300
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &2157614860 !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: *
|
35
|
+
version_requirements: *2157614860
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: timecop
|
38
|
-
requirement: &
|
38
|
+
requirement: &2157614440 !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: *
|
46
|
+
version_requirements: *2157614440
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sequel
|
49
|
-
requirement: &
|
49
|
+
requirement: &2157614020 !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: *
|
57
|
+
version_requirements: *2157614020
|
58
58
|
description: Bitemporal versioning for sequel, fully tested.
|
59
59
|
email:
|
60
60
|
- joseph.halter@thetalentbox.com
|
@@ -69,7 +69,8 @@ files:
|
|
69
69
|
- lib/sequel/plugins/bitemporal.rb
|
70
70
|
- lib/sequel_bitemporal.rb
|
71
71
|
- sequel_bitemporal.gemspec
|
72
|
-
- spec/
|
72
|
+
- spec/bitemporal_date_spec.rb
|
73
|
+
- spec/bitemporal_time_spec.rb
|
73
74
|
- spec/spec_helper.rb
|
74
75
|
- spec/support/bitemporal_matchers.rb
|
75
76
|
homepage: https://github.com/TalentBox/sequel_bitemporal
|
@@ -97,6 +98,7 @@ signing_key:
|
|
97
98
|
specification_version: 3
|
98
99
|
summary: Bitemporal versioning for sequel.
|
99
100
|
test_files:
|
100
|
-
- spec/
|
101
|
+
- spec/bitemporal_date_spec.rb
|
102
|
+
- spec/bitemporal_time_spec.rb
|
101
103
|
- spec/spec_helper.rb
|
102
104
|
- spec/support/bitemporal_matchers.rb
|