dm-is-versioned 0.9.11 → 0.10.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/{History.txt → History.rdoc} +4 -0
- data/Manifest.txt +2 -2
- data/{README.txt → README.rdoc} +0 -0
- data/Rakefile +2 -3
- data/lib/dm-is-versioned.rb +4 -9
- data/lib/dm-is-versioned/is/version.rb +1 -1
- data/lib/dm-is-versioned/is/versioned.rb +45 -39
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +8 -4
- data/spec/versioned_spec.rb +51 -112
- data/tasks/install.rb +1 -1
- data/tasks/spec.rb +4 -4
- metadata +14 -21
data/Manifest.txt
CHANGED
data/{README.txt → README.rdoc}
RENAMED
File without changes
|
data/Rakefile
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'pathname'
|
2
|
-
require 'rubygems'
|
3
2
|
|
4
3
|
ROOT = Pathname(__FILE__).dirname.expand_path
|
5
4
|
JRUBY = RUBY_PLATFORM =~ /java/
|
@@ -14,10 +13,10 @@ GEM_NAME = 'dm-is-versioned'
|
|
14
13
|
GEM_VERSION = DataMapper::Is::Versioned::VERSION
|
15
14
|
GEM_DEPENDENCIES = [['dm-core', GEM_VERSION]]
|
16
15
|
GEM_CLEAN = %w[ log pkg coverage ]
|
17
|
-
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.
|
16
|
+
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.rdoc LICENSE TODO History.rdoc ] }
|
18
17
|
|
19
18
|
PROJECT_NAME = 'datamapper'
|
20
|
-
PROJECT_URL = "http://github.com/
|
19
|
+
PROJECT_URL = "http://github.com/datamapper/dm-more/tree/master/#{GEM_NAME}"
|
21
20
|
PROJECT_DESCRIPTION = PROJECT_SUMMARY = 'DataMapper plugin enabling simple versioning of models'
|
22
21
|
|
23
22
|
[ ROOT, ROOT.parent ].each do |dir|
|
data/lib/dm-is-versioned.rb
CHANGED
@@ -1,14 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
gem 'dm-core', '0.9.11'
|
5
|
-
require 'dm-core'
|
6
|
-
|
7
|
-
require Pathname(__FILE__).dirname.expand_path / 'dm-is-versioned' / 'is' / 'versioned.rb'
|
1
|
+
require 'dm-is-versioned/is/versioned'
|
2
|
+
require 'dm-is-versioned/is/version'
|
8
3
|
|
9
4
|
# Include the plugin in Resource
|
10
5
|
module DataMapper
|
11
6
|
module Model
|
12
7
|
include DataMapper::Is::Versioned
|
13
|
-
end
|
14
|
-
end
|
8
|
+
end
|
9
|
+
end
|
@@ -45,54 +45,62 @@ module DataMapper
|
|
45
45
|
#
|
46
46
|
# TODO: enable replacing a current version with an old version.
|
47
47
|
module Versioned
|
48
|
-
|
49
48
|
def is_versioned(options = {})
|
50
|
-
on = options[:on]
|
51
|
-
|
52
|
-
class << self; self end.class_eval do
|
53
|
-
define_method :const_missing do |name|
|
54
|
-
storage_name = Extlib::Inflection.tableize(self.name + "Version")
|
55
|
-
model = DataMapper::Model.new(storage_name)
|
56
|
-
|
57
|
-
if name == :Version
|
58
|
-
properties.each do |property|
|
59
|
-
options = property.options
|
60
|
-
options[:key] = true if property.name == on || options[:serial] == true
|
61
|
-
options[:serial] = false
|
62
|
-
model.property property.name, property.type, options
|
63
|
-
end
|
49
|
+
@on = on = options[:on]
|
64
50
|
|
65
|
-
|
66
|
-
else
|
67
|
-
super(name)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
self.after_class_method :auto_migrate! do
|
51
|
+
after_class_method :auto_migrate! do |retval|
|
73
52
|
self::Version.auto_migrate!
|
74
53
|
end
|
75
54
|
|
76
|
-
|
55
|
+
after_class_method :auto_upgrade! do |retval|
|
77
56
|
self::Version.auto_upgrade!
|
78
57
|
end
|
79
58
|
|
80
|
-
|
81
|
-
|
59
|
+
properties.each do |property|
|
60
|
+
name = property.name
|
61
|
+
before "#{name}=".to_sym do
|
62
|
+
unless (value = property.get(self)).nil? || pending_version_attributes.key?(name)
|
63
|
+
pending_version_attributes[name] = value
|
64
|
+
end
|
65
|
+
end
|
82
66
|
end
|
83
67
|
|
84
|
-
|
85
|
-
if
|
86
|
-
|
87
|
-
|
68
|
+
after :update do |retval|
|
69
|
+
if retval && pending_version_attributes.key?(on)
|
70
|
+
model::Version.create(attributes.merge(pending_version_attributes))
|
71
|
+
pending_version_attributes.clear
|
88
72
|
end
|
89
73
|
|
90
|
-
|
74
|
+
retval
|
91
75
|
end
|
92
76
|
|
93
|
-
|
77
|
+
extend ClassMethods
|
78
|
+
include InstanceMethods
|
94
79
|
end
|
95
80
|
|
81
|
+
module ClassMethods
|
82
|
+
def const_missing(name)
|
83
|
+
if name == :Version
|
84
|
+
model = DataMapper::Model.new
|
85
|
+
|
86
|
+
properties.each do |property|
|
87
|
+
type = property.type
|
88
|
+
type = Class if type == DataMapper::Types::Discriminator
|
89
|
+
|
90
|
+
options = property.options.merge(
|
91
|
+
:key => property.name == @on,
|
92
|
+
:serial => false
|
93
|
+
)
|
94
|
+
|
95
|
+
model.property(property.name, type, options)
|
96
|
+
end
|
97
|
+
|
98
|
+
const_set(name, model)
|
99
|
+
else
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end # ClassMethods
|
96
104
|
|
97
105
|
module InstanceMethods
|
98
106
|
##
|
@@ -114,14 +122,12 @@ module DataMapper
|
|
114
122
|
# --
|
115
123
|
# @return <Collection>
|
116
124
|
def versions
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
version.all(query)
|
125
|
+
version_model = model.const_get(:Version)
|
126
|
+
query = model.key.zip(key).map { |p, v| [ p.name, v ] }.to_hash
|
127
|
+
query.merge(:order => version_model.key.map { |k| k.name.desc })
|
128
|
+
version_model.all(query)
|
122
129
|
end
|
123
|
-
end
|
124
|
-
|
130
|
+
end # InstanceMethods
|
125
131
|
end # Versioned
|
126
132
|
end # Is
|
127
133
|
end # DataMapper
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
require 'pathname'
|
2
1
|
require 'rubygems'
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
# Use local dm-core if running from a typical dev checkout.
|
4
|
+
lib = File.join('..', '..', 'dm-core', 'lib')
|
5
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
6
|
+
require 'dm-core'
|
6
7
|
|
7
|
-
|
8
|
+
# Support running specs with 'rake spec' and 'spec'
|
9
|
+
$LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
|
10
|
+
|
11
|
+
require 'dm-is-versioned'
|
8
12
|
|
9
13
|
def load_driver(name, default_uri)
|
10
14
|
return false if ENV['ADAPTER'] != name.to_s
|
data/spec/versioned_spec.rb
CHANGED
@@ -1,184 +1,123 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
class Story
|
4
4
|
include DataMapper::Resource
|
5
5
|
|
6
|
-
property :id,
|
7
|
-
property :title,
|
6
|
+
property :id, Serial
|
7
|
+
property :title, String
|
8
8
|
property :updated_at, DateTime
|
9
|
+
property :type, Discriminator
|
9
10
|
|
10
11
|
before :save do
|
11
12
|
# For the sake of testing, make sure the updated_at is always unique
|
12
|
-
|
13
|
-
|
13
|
+
if dirty?
|
14
|
+
time = self.updated_at ? self.updated_at + 1 : Time.now
|
15
|
+
self.updated_at = time
|
16
|
+
end
|
14
17
|
end
|
15
18
|
|
16
19
|
is_versioned :on => :updated_at
|
17
|
-
|
18
20
|
end
|
19
21
|
|
20
22
|
if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
21
|
-
describe 'DataMapper' do
|
22
|
-
describe "#auto_migrate!" do
|
23
|
-
before do
|
24
|
-
# I *think* AutoMigrator breaks toplevel auto_migrate
|
25
|
-
# into two calls to reduce redundancy, so auto_migrate!
|
26
|
-
# never actually gets called on decendents after a
|
27
|
-
# DataMapper.auto_migrate! call.
|
28
|
-
Story::Version.should_receive(:auto_migrate_down!)
|
29
|
-
Story::Version.should_receive(:auto_migrate_up!)
|
30
|
-
end
|
31
|
-
it "should get called on a versioned inner class" do
|
32
|
-
DataMapper.auto_migrate!
|
33
|
-
end
|
34
|
-
end # #auto_migrate!
|
35
|
-
|
36
|
-
describe "#auto_upgrade!" do
|
37
|
-
before do
|
38
|
-
# AutoMigrator collects all descendents, triggering once
|
39
|
-
# but triggers a second time after Story gets upgraded.
|
40
|
-
# Since it's non-destructive, shouldn't matter that it
|
41
|
-
# gets called twice though.
|
42
|
-
Story::Version.should_receive(:auto_upgrade!).twice
|
43
|
-
end
|
44
|
-
it "should get called on a versioned inner class" do
|
45
|
-
DataMapper.auto_upgrade!
|
46
|
-
end
|
47
|
-
end # #auto_upgrade!
|
48
|
-
end
|
49
|
-
|
50
23
|
describe 'DataMapper::Is::Versioned' do
|
51
|
-
describe
|
52
|
-
it
|
53
|
-
Story::Version.should be_a_kind_of(
|
24
|
+
describe 'inner class' do
|
25
|
+
it 'should be present' do
|
26
|
+
Story::Version.should be_a_kind_of(DataMapper::Model)
|
54
27
|
end
|
55
28
|
|
56
|
-
it
|
57
|
-
Story::Version.storage_name.should ==
|
29
|
+
it 'should have a default storage name' do
|
30
|
+
Story::Version.storage_name.should == 'story_versions'
|
58
31
|
end
|
59
32
|
|
60
|
-
|
61
|
-
|
62
|
-
Story::Version.properties.should
|
33
|
+
Story.properties.each do |property|
|
34
|
+
it "should have its parent's property #{property.name}" do
|
35
|
+
Story::Version.properties.should include(property)
|
63
36
|
end
|
64
37
|
end
|
65
|
-
end
|
38
|
+
end
|
66
39
|
|
67
|
-
describe
|
68
|
-
before do
|
69
|
-
Story::Version.should_receive(:auto_migrate!)
|
70
|
-
end
|
71
|
-
it "should get called on the inner class" do
|
40
|
+
describe '#create' do
|
41
|
+
before :all do
|
72
42
|
Story.auto_migrate!
|
43
|
+
Story.create(:title => 'A Very Interesting Article')
|
73
44
|
end
|
74
|
-
end # #auto_migrate!
|
75
|
-
|
76
|
-
describe "#auto_upgrade!" do
|
77
|
-
before do
|
78
|
-
Story::Version.should_receive(:auto_upgrade!)
|
79
|
-
end
|
80
|
-
it "should get called on the inner class" do
|
81
|
-
Story.auto_upgrade!
|
82
|
-
end
|
83
|
-
end # #auto_upgrade!
|
84
45
|
|
85
|
-
|
86
|
-
before do
|
87
|
-
Story.auto_migrate!
|
88
|
-
Story.create(:title => "A Very Interesting Article")
|
89
|
-
end
|
90
|
-
it "should not create a versioned copy" do
|
46
|
+
it 'should not create a versioned copy' do
|
91
47
|
Story::Version.all.size.should == 0
|
92
48
|
end
|
93
|
-
end
|
49
|
+
end
|
94
50
|
|
95
|
-
describe
|
96
|
-
before do
|
51
|
+
describe '#save' do
|
52
|
+
before :all do
|
97
53
|
Story.auto_migrate!
|
98
54
|
end
|
99
55
|
|
100
|
-
describe
|
101
|
-
before do
|
102
|
-
@story = Story.new(:title =>
|
56
|
+
describe '(with new resource)' do
|
57
|
+
before :all do
|
58
|
+
@story = Story.new(:title => 'A Story')
|
103
59
|
@story.save
|
104
60
|
end
|
105
|
-
|
61
|
+
|
62
|
+
it 'should not create a versioned copy' do
|
106
63
|
Story::Version.all.size.should == 0
|
107
64
|
end
|
108
65
|
end
|
109
66
|
|
110
|
-
describe
|
111
|
-
before do
|
112
|
-
@story = Story.create(:title =>
|
67
|
+
describe '(with a clean existing resource)' do
|
68
|
+
before :all do
|
69
|
+
@story = Story.create(:title => 'A Story')
|
113
70
|
@story.save
|
114
71
|
end
|
115
72
|
|
116
|
-
it
|
73
|
+
it 'should not create a versioned copy' do
|
117
74
|
Story::Version.all.size.should == 0
|
118
75
|
end
|
119
76
|
end
|
120
77
|
|
121
|
-
describe
|
122
|
-
before do
|
123
|
-
@story = Story.create(:title =>
|
124
|
-
@story.title =
|
125
|
-
@story.title =
|
78
|
+
describe '(with a dirty existing resource)' do
|
79
|
+
before :all do
|
80
|
+
@story = Story.create(:title => 'A Story')
|
81
|
+
@story.title = 'An Inner Update'
|
82
|
+
@story.title = 'An Updated Story'
|
126
83
|
@story.save
|
127
84
|
end
|
128
85
|
|
129
|
-
it
|
86
|
+
it 'should create a versioned copy' do
|
130
87
|
Story::Version.all.size.should == 1
|
131
88
|
end
|
132
89
|
|
133
|
-
it
|
90
|
+
it 'should not have the same value for the versioned field' do
|
134
91
|
@story.updated_at.should_not == Story::Version.first.updated_at
|
135
92
|
end
|
136
93
|
|
137
|
-
it
|
94
|
+
it 'should save the original value, not the inner update' do
|
138
95
|
# changes to the story between saves shouldn't be updated.
|
139
|
-
@story.versions.last.title.should ==
|
96
|
+
@story.versions.last.title.should == 'A Story'
|
140
97
|
end
|
141
98
|
end
|
99
|
+
end
|
142
100
|
|
143
|
-
|
144
|
-
|
145
|
-
describe "#pending_version_attributes" do
|
146
|
-
before do
|
147
|
-
@story = Story.create(:title => "A Story")
|
148
|
-
end
|
149
|
-
|
150
|
-
it "should be updated when a property changes" do
|
151
|
-
@story.title = "A New Title"
|
152
|
-
@story.pending_version_attributes[:title].should == "A Story"
|
153
|
-
end
|
154
|
-
|
155
|
-
it "should be cleared when a resource is saved" do
|
156
|
-
@story.title = "A New Title"
|
157
|
-
@story.save
|
158
|
-
@story.pending_version_attributes.should be_empty
|
159
|
-
end
|
160
|
-
end # #pending_version_attributes
|
161
|
-
|
162
|
-
describe "#versions" do
|
163
|
-
before do
|
101
|
+
describe '#versions' do
|
102
|
+
before :all do
|
164
103
|
Story.auto_migrate!
|
165
|
-
@story = Story.create(:title =>
|
104
|
+
@story = Story.create(:title => 'A Story')
|
166
105
|
end
|
167
106
|
|
168
|
-
it
|
107
|
+
it 'should return an empty array when there are no versions' do
|
169
108
|
@story.versions.should == []
|
170
109
|
end
|
171
110
|
|
172
|
-
it
|
111
|
+
it 'should return a collection when there are versions' do
|
173
112
|
@story.versions.should == Story::Version.all(:id => @story.id)
|
174
113
|
end
|
175
114
|
|
176
115
|
it "should not return another object's versions" do
|
177
|
-
@story2 = Story.create(:title =>
|
178
|
-
@story2.title =
|
116
|
+
@story2 = Story.create(:title => 'A Different Story')
|
117
|
+
@story2.title = 'A Different Title'
|
179
118
|
@story2.save
|
180
119
|
@story.versions.should == Story::Version.all(:id => @story.id)
|
181
120
|
end
|
182
|
-
end
|
121
|
+
end
|
183
122
|
end
|
184
123
|
end
|
data/tasks/install.rb
CHANGED
@@ -4,7 +4,7 @@ end
|
|
4
4
|
|
5
5
|
desc "Install #{GEM_NAME} #{GEM_VERSION}"
|
6
6
|
task :install => [ :package ] do
|
7
|
-
sudo_gem "install
|
7
|
+
sudo_gem "install pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
|
data/tasks/spec.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
begin
|
2
|
-
gem 'rspec', '~>1.2'
|
3
|
-
require 'spec'
|
4
2
|
require 'spec/rake/spectask'
|
5
3
|
|
6
4
|
task :default => [ :spec ]
|
@@ -8,16 +6,18 @@ begin
|
|
8
6
|
desc 'Run specifications'
|
9
7
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
10
8
|
t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
|
11
|
-
t.
|
9
|
+
t.libs << 'lib' << 'spec' # needed for CI rake spec task, duplicated in spec_helper
|
12
10
|
|
13
11
|
begin
|
14
|
-
|
12
|
+
require 'rcov'
|
15
13
|
t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
|
16
14
|
t.rcov_opts << '--exclude' << 'spec'
|
17
15
|
t.rcov_opts << '--text-summary'
|
18
16
|
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
19
17
|
rescue LoadError
|
20
18
|
# rcov not installed
|
19
|
+
rescue SyntaxError
|
20
|
+
# rcov syntax invalid
|
21
21
|
end
|
22
22
|
end
|
23
23
|
rescue LoadError
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-is-versioned
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernerd Schaefer
|
@@ -9,19 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: dm-core
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - "="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.11
|
24
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
25
16
|
description: DataMapper plugin enabling simple versioning of models
|
26
17
|
email:
|
27
18
|
- bernerd [a] wieck [d] com
|
@@ -30,15 +21,15 @@ executables: []
|
|
30
21
|
extensions: []
|
31
22
|
|
32
23
|
extra_rdoc_files:
|
33
|
-
- README.
|
24
|
+
- README.rdoc
|
34
25
|
- LICENSE
|
35
26
|
- TODO
|
36
|
-
- History.
|
27
|
+
- History.rdoc
|
37
28
|
files:
|
38
|
-
- History.
|
29
|
+
- History.rdoc
|
39
30
|
- LICENSE
|
40
31
|
- Manifest.txt
|
41
|
-
- README.
|
32
|
+
- README.rdoc
|
42
33
|
- Rakefile
|
43
34
|
- TODO
|
44
35
|
- lib/dm-is-versioned.rb
|
@@ -50,11 +41,13 @@ files:
|
|
50
41
|
- tasks/install.rb
|
51
42
|
- tasks/spec.rb
|
52
43
|
has_rdoc: true
|
53
|
-
homepage: http://github.com/
|
44
|
+
homepage: http://github.com/datamapper/dm-more/tree/master/dm-is-versioned
|
45
|
+
licenses: []
|
46
|
+
|
54
47
|
post_install_message:
|
55
48
|
rdoc_options:
|
56
49
|
- --main
|
57
|
-
- README.
|
50
|
+
- README.rdoc
|
58
51
|
require_paths:
|
59
52
|
- lib
|
60
53
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -72,9 +65,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
65
|
requirements: []
|
73
66
|
|
74
67
|
rubyforge_project: datamapper
|
75
|
-
rubygems_version: 1.3.
|
68
|
+
rubygems_version: 1.3.5
|
76
69
|
signing_key:
|
77
|
-
specification_version:
|
70
|
+
specification_version: 3
|
78
71
|
summary: DataMapper plugin enabling simple versioning of models
|
79
72
|
test_files: []
|
80
73
|
|