genki-dm-has-versions 0.1.1 → 0.2.0
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/Rakefile +1 -1
- data/lib/dm-has-versions/has/versions.rb +39 -6
- data/spec/dm-has-versions_spec.rb +43 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +1 -1
- metadata +5 -4
- data/spec/merb_test.log +0 -108
data/Rakefile
CHANGED
@@ -4,13 +4,16 @@ module DataMapper
|
|
4
4
|
class RevertError < StandardError; end
|
5
5
|
|
6
6
|
def has_versions(options = {})
|
7
|
+
original_class = self
|
8
|
+
original_name = name.snake_case
|
9
|
+
storage_name = Extlib::Inflection.tableize(name + "Version")
|
10
|
+
|
7
11
|
ignores = [options[:ignore]].flatten.compact.map do |ignore|
|
8
12
|
properties[ignore.to_s.intern]
|
9
13
|
end
|
10
14
|
|
11
15
|
class << self; self end.class_eval do
|
12
16
|
define_method :const_missing do |name|
|
13
|
-
storage_name = Extlib::Inflection.tableize(self.name + "Version")
|
14
17
|
model = DataMapper::Model.new(storage_name)
|
15
18
|
|
16
19
|
if name == :Version
|
@@ -20,6 +23,12 @@ module DataMapper
|
|
20
23
|
end
|
21
24
|
model.belongs_to self.storage_name.singular.intern
|
22
25
|
|
26
|
+
model.class_eval do
|
27
|
+
define_method("to_#{original_name}") do
|
28
|
+
original_class.new.tap{|object| object.send :copy, self}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
23
32
|
self.const_set("Version", model)
|
24
33
|
else
|
25
34
|
super(name)
|
@@ -27,6 +36,10 @@ module DataMapper
|
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
39
|
+
if options[:revision] != false
|
40
|
+
ignores << property(:revision, Integer, :unique_index => true)
|
41
|
+
end
|
42
|
+
|
30
43
|
self.after_class_method :auto_migrate! do
|
31
44
|
self::Version.auto_migrate!
|
32
45
|
end
|
@@ -66,6 +79,17 @@ module DataMapper
|
|
66
79
|
end
|
67
80
|
|
68
81
|
module InstanceMethods
|
82
|
+
def self.included(base)
|
83
|
+
base.class_eval do
|
84
|
+
def revision=(revision)
|
85
|
+
if target = versions.get(revision)
|
86
|
+
copy(target)
|
87
|
+
self.attribute_set :revision, revision
|
88
|
+
end
|
89
|
+
!!target
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
69
93
|
##
|
70
94
|
# Returns a hash of original values to be stored in the
|
71
95
|
# versions table when a new version is created. It is
|
@@ -100,16 +124,16 @@ module DataMapper
|
|
100
124
|
|
101
125
|
def version=(version)
|
102
126
|
if target = versions.first(:offset => version)
|
103
|
-
|
104
|
-
next if property.key?
|
105
|
-
name = property.name
|
106
|
-
self.attribute_set(name, target.attribute_get(name))
|
107
|
-
end
|
127
|
+
copy(target)
|
108
128
|
@version = version
|
109
129
|
end
|
110
130
|
!!target
|
111
131
|
end
|
112
132
|
|
133
|
+
def revisions
|
134
|
+
versions.all(:order => [:id.asc]).map(&:id)
|
135
|
+
end
|
136
|
+
|
113
137
|
def revert_to!(version)
|
114
138
|
self.version = version
|
115
139
|
pending_version_attributes.clear
|
@@ -128,6 +152,15 @@ module DataMapper
|
|
128
152
|
def revert
|
129
153
|
revert_to(version) or raise RevertError
|
130
154
|
end
|
155
|
+
|
156
|
+
private
|
157
|
+
def copy(target)
|
158
|
+
self.properties.each do |property|
|
159
|
+
next if property.key?
|
160
|
+
name = property.name
|
161
|
+
self.attribute_set(name, target.attribute_get(name))
|
162
|
+
end
|
163
|
+
end
|
131
164
|
end
|
132
165
|
end
|
133
166
|
end
|
@@ -109,6 +109,49 @@ describe "dm-has-versions" do
|
|
109
109
|
story.comments.should_not be_empty
|
110
110
|
story.comments.last.body.should == "Hey, maiha!"
|
111
111
|
end
|
112
|
+
|
113
|
+
it "should have revision methods" do
|
114
|
+
@story.should be_respond_to(:revision)
|
115
|
+
@story.revision.should be_nil
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return revision numbers" do
|
119
|
+
@story.should be_respond_to(:revisions)
|
120
|
+
revisions = @story.revisions
|
121
|
+
revisions.should be_a(Array)
|
122
|
+
revisions.should_not be_empty
|
123
|
+
revisions.first.should be_a(Integer)
|
124
|
+
revisions.should == revisions.sort
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should be able to set revision" do
|
128
|
+
revisions = @story.revisions
|
129
|
+
last_title = @story.title
|
130
|
+
proc do
|
131
|
+
@story.save.should be_true
|
132
|
+
end.should_not change(Story::Version, :count)
|
133
|
+
proc do
|
134
|
+
@story.title = "foo01"
|
135
|
+
@story.save.should be_true
|
136
|
+
end.should change(Story::Version, :count)
|
137
|
+
@story.should_not be_dirty
|
138
|
+
@story.revision = @story.revisions.last
|
139
|
+
@story.should be_dirty
|
140
|
+
@story.title.should_not == "foo01"
|
141
|
+
@story.title.should == last_title
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should be converted from version object" do
|
145
|
+
version = @story.versions.last
|
146
|
+
version.should be_a(Story::Version)
|
147
|
+
version.should be_respond_to(:to_story)
|
148
|
+
story = version.to_story
|
149
|
+
story.should be_a(Story)
|
150
|
+
story.attributes.each do |key, value|
|
151
|
+
next if key == :id
|
152
|
+
version.attributes[key].should == value
|
153
|
+
end
|
154
|
+
end
|
112
155
|
end
|
113
156
|
end
|
114
157
|
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
CHANGED
@@ -16,7 +16,7 @@ Merb.start_environment(
|
|
16
16
|
:adapter => 'runner',
|
17
17
|
:environment => ENV['MERB_ENV'] || 'test',
|
18
18
|
:merb_root => File.dirname(__FILE__) / 'fixture',
|
19
|
-
:log_file => File.dirname(__FILE__) / "merb_test.log"
|
19
|
+
:log_file => File.dirname(__FILE__) / "../merb_test.log"
|
20
20
|
)
|
21
21
|
DataMapper.setup(:default, "sqlite3::memory:")
|
22
22
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: genki-dm-has-versions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Genki Takiuchi
|
@@ -9,11 +9,12 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-15 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: merb
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
@@ -47,7 +48,7 @@ files:
|
|
47
48
|
- spec/fixture/app/models
|
48
49
|
- spec/fixture/app/models/comment.rb
|
49
50
|
- spec/fixture/app/models/story.rb
|
50
|
-
- spec/
|
51
|
+
- spec/spec.opts
|
51
52
|
- spec/spec_helper.rb
|
52
53
|
has_rdoc: true
|
53
54
|
homepage: http://blog.s21g.com/genki
|
@@ -73,7 +74,7 @@ requirements: []
|
|
73
74
|
rubyforge_project: merb
|
74
75
|
rubygems_version: 1.2.0
|
75
76
|
signing_key:
|
76
|
-
specification_version:
|
77
|
+
specification_version: 3
|
77
78
|
summary: Merb plugin that provides version control for DataMapper models.
|
78
79
|
test_files: []
|
79
80
|
|
data/spec/merb_test.log
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
Thu, 15 Jan 2009 12:52:48 GMT ~ info ~ Logfile created
|
2
|
-
~ Could not load /Users/takiuchi/project/dm-has-versions/spec/fixture/app/models/story.rb:
|
3
|
-
|
4
|
-
uninitialized constant DataMapper::Has::Versioned - (NameError)
|
5
|
-
|
6
|
-
/Users/takiuchi/project/dm-has-versions/spec/../lib/dm-has-versions/has/versions.rb:50:in `has_versions'
|
7
|
-
/Users/takiuchi/project/dm-has-versions/spec/fixture/app/models/story.rb:8
|
8
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
|
9
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
|
10
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:863:in `load_file'
|
11
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1018:in `load_classes_with_requirements'
|
12
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1015:in `each'
|
13
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1015:in `load_classes_with_requirements'
|
14
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:903:in `load_classes'
|
15
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:641:in `run'
|
16
|
-
/opt/local/lib/ruby/gems/1.8/gems/extlib-0.9.9/lib/extlib/dictionary.rb:268:in `each'
|
17
|
-
/opt/local/lib/ruby/gems/1.8/gems/extlib-0.9.9/lib/extlib/dictionary.rb:268:in `each'
|
18
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:639:in `run'
|
19
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:99:in `run'
|
20
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/server.rb:172:in `bootup'
|
21
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/server.rb:42:in `start'
|
22
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core.rb:170:in `start'
|
23
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core.rb:183:in `start_environment'
|
24
|
-
/Users/takiuchi/project/dm-has-versions/spec/spec_helper.rb:13
|
25
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
|
26
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
|
27
|
-
/Users/takiuchi/project/dm-has-versions/spec/dm-has-versions_spec.rb:1
|
28
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load'
|
29
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load_files'
|
30
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `each'
|
31
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `load_files'
|
32
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/options.rb:98:in `run_examples'
|
33
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/command_line.rb:10:in `run'
|
34
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/bin/spec:4
|
35
|
-
/opt/local/bin/spec:19:in `load'
|
36
|
-
/opt/local/bin/spec:19
|
37
|
-
~ Could not load /Users/takiuchi/project/dm-has-versions/spec/fixture/app/models/story.rb:
|
38
|
-
|
39
|
-
uninitialized constant DataMapper::Has::Versioned - (NameError)
|
40
|
-
|
41
|
-
/Users/takiuchi/project/dm-has-versions/spec/../lib/dm-has-versions/has/versions.rb:50:in `has_versions'
|
42
|
-
/Users/takiuchi/project/dm-has-versions/spec/fixture/app/models/story.rb:8
|
43
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
|
44
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
|
45
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:863:in `load_file'
|
46
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1018:in `load_classes_with_requirements'
|
47
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1015:in `each'
|
48
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1015:in `load_classes_with_requirements'
|
49
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:903:in `load_classes'
|
50
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:641:in `run'
|
51
|
-
/opt/local/lib/ruby/gems/1.8/gems/extlib-0.9.9/lib/extlib/dictionary.rb:268:in `each'
|
52
|
-
/opt/local/lib/ruby/gems/1.8/gems/extlib-0.9.9/lib/extlib/dictionary.rb:268:in `each'
|
53
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:639:in `run'
|
54
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:99:in `run'
|
55
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/server.rb:172:in `bootup'
|
56
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/server.rb:42:in `start'
|
57
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core.rb:170:in `start'
|
58
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core.rb:183:in `start_environment'
|
59
|
-
/Users/takiuchi/project/dm-has-versions/spec/spec_helper.rb:13
|
60
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
|
61
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
|
62
|
-
/Users/takiuchi/project/dm-has-versions/spec/dm-has-versions_spec.rb:1
|
63
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load'
|
64
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load_files'
|
65
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `each'
|
66
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `load_files'
|
67
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/options.rb:98:in `run_examples'
|
68
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/command_line.rb:10:in `run'
|
69
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/bin/spec:4
|
70
|
-
/opt/local/bin/spec:19:in `load'
|
71
|
-
/opt/local/bin/spec:19
|
72
|
-
~ Could not load /Users/takiuchi/project/dm-has-versions/spec/fixture/app/models/story.rb:
|
73
|
-
|
74
|
-
undefined local variable or method `n' for #<Class:Story> - (NameError)
|
75
|
-
|
76
|
-
/Users/takiuchi/project/dm-has-versions/spec/../lib/dm-has-versions/has/versions.rb:25:in `has_versions'
|
77
|
-
/Users/takiuchi/project/dm-has-versions/spec/../lib/dm-has-versions/has/versions.rb:7:in `class_eval'
|
78
|
-
/Users/takiuchi/project/dm-has-versions/spec/../lib/dm-has-versions/has/versions.rb:7:in `has_versions'
|
79
|
-
/Users/takiuchi/project/dm-has-versions/spec/fixture/app/models/story.rb:8
|
80
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
|
81
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
|
82
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:863:in `load_file'
|
83
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1018:in `load_classes_with_requirements'
|
84
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1015:in `each'
|
85
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:1015:in `load_classes_with_requirements'
|
86
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:903:in `load_classes'
|
87
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:641:in `run'
|
88
|
-
/opt/local/lib/ruby/gems/1.8/gems/extlib-0.9.9/lib/extlib/dictionary.rb:268:in `each'
|
89
|
-
/opt/local/lib/ruby/gems/1.8/gems/extlib-0.9.9/lib/extlib/dictionary.rb:268:in `each'
|
90
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:639:in `run'
|
91
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/bootloader.rb:99:in `run'
|
92
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/server.rb:172:in `bootup'
|
93
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core/server.rb:42:in `start'
|
94
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core.rb:170:in `start'
|
95
|
-
/opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0.7.1/lib/merb-core.rb:183:in `start_environment'
|
96
|
-
/Users/takiuchi/project/dm-has-versions/spec/spec_helper.rb:14
|
97
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
|
98
|
-
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
|
99
|
-
/Users/takiuchi/project/dm-has-versions/spec/dm-has-versions_spec.rb:1
|
100
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load'
|
101
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load_files'
|
102
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `each'
|
103
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `load_files'
|
104
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/options.rb:98:in `run_examples'
|
105
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/command_line.rb:10:in `run'
|
106
|
-
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/bin/spec:4
|
107
|
-
/opt/local/bin/spec:19:in `load'
|
108
|
-
/opt/local/bin/spec:19
|