mongo_mapper_versioned 0.1
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/README.rdoc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
WORK IN PROGRESS
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module Versioned
|
4
|
+
class Version
|
5
|
+
|
6
|
+
include MongoMapper::Document
|
7
|
+
|
8
|
+
# stores id of versioned document
|
9
|
+
key :versioned_id, ObjectId
|
10
|
+
|
11
|
+
# stores version number
|
12
|
+
key :version_number, Integer
|
13
|
+
|
14
|
+
# stores versioned attributes
|
15
|
+
key :data, Hash
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module Versioned
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def versioned(options={})
|
7
|
+
configuration = { :ignored_keys => %w(_id version_number created_at updated_at creator_id updater_id) }
|
8
|
+
configuration.update(options) if options.is_a?(Hash)
|
9
|
+
|
10
|
+
key :version_number, Integer, :default => 1, :index => true
|
11
|
+
many :versions, :class => MongoMapper::Plugins::Versioned::Version, :foreign_key => :versioned_id, :dependent => :destroy, :order => :version_number.asc
|
12
|
+
|
13
|
+
after_create :create_version
|
14
|
+
before_update :create_version, :if => Proc.new{ |doc| doc.should_create_version? }
|
15
|
+
|
16
|
+
define_method "ignored_keys" do
|
17
|
+
configuration[:ignored_keys]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
module InstanceMethods
|
25
|
+
|
26
|
+
def create_version
|
27
|
+
self.version_number = version_count + 1 if (version_count > 0)
|
28
|
+
self.versions << current_version
|
29
|
+
end
|
30
|
+
|
31
|
+
def revert_to(target_version_number)
|
32
|
+
if target_version = version_at(target_version_number)
|
33
|
+
self.attributes = target_version.data
|
34
|
+
self.version_number = target_version.version_number
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def version_count
|
39
|
+
self.versions.count
|
40
|
+
end
|
41
|
+
|
42
|
+
def current_version
|
43
|
+
Version.new(:data => self.attributes.slice!(*ignored_keys), :versioned_id => self.id, :version_number => self.version_number)
|
44
|
+
end
|
45
|
+
|
46
|
+
def version_at(target_version_number)
|
47
|
+
versions.where(:version_number => target_version_number).first
|
48
|
+
end
|
49
|
+
|
50
|
+
# this method might be overwritten
|
51
|
+
# by something more sophisticated (esp. in case of EmbeddedDocuments)
|
52
|
+
def should_create_version?
|
53
|
+
changes.slice!(*ignored_keys).size > 0
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
# CLASS SETUP
|
6
|
+
|
7
|
+
class VersionedDoc
|
8
|
+
include MongoMapper::Document
|
9
|
+
plugin MongoMapper::Plugins::Versioned
|
10
|
+
|
11
|
+
key :title, String
|
12
|
+
key :body, String
|
13
|
+
|
14
|
+
versioned :ignored_keys => ['body']
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# TESTS
|
19
|
+
|
20
|
+
class VersionedTest < ActiveSupport::TestCase
|
21
|
+
|
22
|
+
context "by default" do
|
23
|
+
setup do
|
24
|
+
@doc = VersionedDoc.new
|
25
|
+
end
|
26
|
+
should "be on version 1" do
|
27
|
+
assert_equal 1, @doc.version_number
|
28
|
+
end
|
29
|
+
should "have 0 versions" do
|
30
|
+
assert_equal 0, @doc.version_count
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when created" do
|
35
|
+
setup do
|
36
|
+
@doc = VersionedDoc.create(:title => "Famfula")
|
37
|
+
end
|
38
|
+
should "be on version 1" do
|
39
|
+
assert_equal 1, @doc.version_number
|
40
|
+
end
|
41
|
+
should "have 1 (initial) version" do
|
42
|
+
assert_equal 1, @doc.version_count
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when saved with no changes" do
|
46
|
+
setup do
|
47
|
+
@version_count = @doc.version_count
|
48
|
+
@version_number = @doc.version_number
|
49
|
+
@doc.save
|
50
|
+
end
|
51
|
+
should "still be at version 1" do
|
52
|
+
assert_equal @version_number, @doc.version_number
|
53
|
+
end
|
54
|
+
should "not create new version" do
|
55
|
+
assert_equal @version_count, @doc.version_count
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "after a change" do
|
60
|
+
setup do
|
61
|
+
@version_count = @doc.version_count
|
62
|
+
@version_number = @doc.version_number
|
63
|
+
@title = @doc.title
|
64
|
+
@doc.update_attributes(:title => "Krabaty")
|
65
|
+
end
|
66
|
+
should "increase number of versions" do
|
67
|
+
assert_equal @version_count+1, @doc.version_count
|
68
|
+
end
|
69
|
+
should "increase version number" do
|
70
|
+
assert_equal @version_number+1, @doc.version_number
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when reverting" do
|
77
|
+
setup do
|
78
|
+
@doc = VersionedDoc.create(:title => "Vaclav", :body => "Kroupa")
|
79
|
+
@doc.update_attributes(:title => "Slavoj", :body => "Zizek")
|
80
|
+
@doc.update_attributes(:title => "Karel", :body => "Martens")
|
81
|
+
@doc.update_attributes(:title => "Keren", :body => "Cytter")
|
82
|
+
@doc.update_attributes(:title => "Jon", :body => "Arnett")
|
83
|
+
end
|
84
|
+
|
85
|
+
context "to first version" do
|
86
|
+
setup do
|
87
|
+
@doc.revert_to(1)
|
88
|
+
end
|
89
|
+
should "be at version 1" do
|
90
|
+
assert_equal 1, @doc.version_number
|
91
|
+
end
|
92
|
+
should "have correct attributes" do
|
93
|
+
assert_equal "Vaclav", @doc.title
|
94
|
+
end
|
95
|
+
should "not revert ignored attributes" do
|
96
|
+
assert_equal "Arnett", @doc.body
|
97
|
+
end
|
98
|
+
should "not create new version" do
|
99
|
+
assert_equal 5, @doc.version_count
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "to version 2" do
|
104
|
+
setup do
|
105
|
+
@doc.revert_to(2)
|
106
|
+
end
|
107
|
+
should "be at version 2" do
|
108
|
+
assert_equal 2, @doc.version_number
|
109
|
+
end
|
110
|
+
should "have correct attributes" do
|
111
|
+
assert_equal "Slavoj", @doc.title
|
112
|
+
end
|
113
|
+
should "not revert ignored attributes" do
|
114
|
+
assert_equal "Arnett", @doc.body
|
115
|
+
end
|
116
|
+
should "not create new version" do
|
117
|
+
assert_equal 5, @doc.version_count
|
118
|
+
end
|
119
|
+
context "after save" do
|
120
|
+
setup do
|
121
|
+
@doc.save
|
122
|
+
end
|
123
|
+
should "be at version 6" do
|
124
|
+
assert_equal 6, @doc.version_number
|
125
|
+
end
|
126
|
+
should "have 6 versions" do
|
127
|
+
assert_equal 6, @doc.version_count
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
context "to version 5" do
|
134
|
+
setup do
|
135
|
+
@doc.revert_to(5)
|
136
|
+
end
|
137
|
+
should "be at version 5" do
|
138
|
+
assert_equal 5, @doc.version_number
|
139
|
+
end
|
140
|
+
should "have correct attributes" do
|
141
|
+
assert_equal "Jon", @doc.title
|
142
|
+
end
|
143
|
+
should "not revert ignored attributes" do
|
144
|
+
assert_equal "Arnett", @doc.body
|
145
|
+
end
|
146
|
+
should "not create new version" do
|
147
|
+
assert_equal 5, @doc.version_count
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
3
|
+
|
4
|
+
require 'mongo_mapper'
|
5
|
+
require 'mongo_mapper/plugins/versioned'
|
6
|
+
require 'mongo_mapper/plugins/models/version'
|
7
|
+
require 'test/unit'
|
8
|
+
require 'shoulda'
|
9
|
+
require 'ruby-debug'
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
class ActiveSupport::TestCase
|
14
|
+
|
15
|
+
# Drop all collections after each test case.
|
16
|
+
def teardown
|
17
|
+
MongoMapper.database.collections.each { |coll| coll.remove }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Make sure that each test case has a teardown
|
21
|
+
# method to clear the db after each test.
|
22
|
+
def inherited(base)
|
23
|
+
base.define_method teardown do
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017)
|
33
|
+
MongoMapper.database = "mongo_mapper_versioned"
|
34
|
+
MongoMapper.database.collections.each { |c| c.drop_indexes }
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongo_mapper_versioned
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Tomas Celizna
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-22 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
requirement: *id001
|
32
|
+
name: mongo_mapper
|
33
|
+
type: :runtime
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 3
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
requirement: *id002
|
46
|
+
name: rake
|
47
|
+
type: :development
|
48
|
+
description:
|
49
|
+
email:
|
50
|
+
- tomas.celizna@gmail.com
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
extra_rdoc_files: []
|
56
|
+
|
57
|
+
files:
|
58
|
+
- lib/mongo_mapper/plugins/models/version.rb
|
59
|
+
- lib/mongo_mapper/plugins/version.rb
|
60
|
+
- lib/mongo_mapper/plugins/versioned.rb
|
61
|
+
- test/mongo_mapper_versioned_test.rb
|
62
|
+
- test/test_helper.rb
|
63
|
+
- README.rdoc
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://github.com/tomasc/mongo_mapper_versioned
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.7
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Versioned plugin for MongoMapper
|
98
|
+
test_files: []
|
99
|
+
|