memories 0.2.0 → 0.2.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.markdown +84 -0
- data/lib/memories/base.rb +51 -11
- metadata +7 -6
data/README.markdown
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#Introduction
|
2
|
+
|
3
|
+
A simple gem for adding versioning to your CouchRest::Model::Base documents. When you update a document, the previous version gets
|
4
|
+
stored as an attachment on the document. This versioning strategy was originally created here: http://blog.couch.io/post/632718824/simple-document-versioning-with-couchdb
|
5
|
+
|
6
|
+
##Installation
|
7
|
+
|
8
|
+
$ gem install memories
|
9
|
+
|
10
|
+
##How does it work?
|
11
|
+
|
12
|
+
Just "include Memories" in your "CouchRest::Model::Base" classes and let the auto-versioning begin.
|
13
|
+
|
14
|
+
###Basic Versioning
|
15
|
+
|
16
|
+
Here's how basic versioning works. Every time you save your document, you get a new version. You have the ability to roll back to a previous version.
|
17
|
+
|
18
|
+
class Book < CouchRest::Model::Base
|
19
|
+
include Memories
|
20
|
+
use_database SOME_DATABASE
|
21
|
+
|
22
|
+
property :name
|
23
|
+
view_by :name
|
24
|
+
end
|
25
|
+
|
26
|
+
b = Book.create :name => "2001"
|
27
|
+
b.current_version #==> 1
|
28
|
+
b.name = "2001: A Space Odyssey"
|
29
|
+
b.save
|
30
|
+
b.current_version #==> 2
|
31
|
+
b.previous_version #==> 1
|
32
|
+
b.name #==> "2001: A Space Odyssey"
|
33
|
+
b.revert_to! 1
|
34
|
+
b.name #==> "2001"
|
35
|
+
b.current_version #==> 3
|
36
|
+
|
37
|
+
###Milestones
|
38
|
+
|
39
|
+
As of version 0.2.0, Memories also supports milestones. Milestones are special versions that you want to flag in some way.
|
40
|
+
For example, suppose you were creating a content management system, and every time someone publishes an article to the website, you want to flag the version
|
41
|
+
they published as a milestone.
|
42
|
+
|
43
|
+
class Article < CouchRest::Model::Base
|
44
|
+
include Memories
|
45
|
+
use_database SOME_DATABASE
|
46
|
+
|
47
|
+
property :title
|
48
|
+
property :author
|
49
|
+
property :body
|
50
|
+
|
51
|
+
def publish!
|
52
|
+
# .... publishing logic
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
a = Article.create(
|
57
|
+
:title => "Memories gem makes versioning simple",
|
58
|
+
:author => "moonmaster9000",
|
59
|
+
:body => <<-ARTICLE
|
60
|
+
Check it out at http://github.com/moonmaster9000/memories
|
61
|
+
ARTICLE
|
62
|
+
)
|
63
|
+
a.save
|
64
|
+
a.publish!
|
65
|
+
a.current_version #==> 1
|
66
|
+
a.milestone! do
|
67
|
+
name "First publish."
|
68
|
+
notes "Passed all relevant editing. Signed off by moonmaster10000"
|
69
|
+
end
|
70
|
+
|
71
|
+
Notice that we annotated our milestone; we gave it a name, and some notes. You can annotate with whatever properties you desire. The annotation do block is entirely optional.
|
72
|
+
Now that we've created a milestone, let's inspect it:
|
73
|
+
|
74
|
+
a.milestones.count #==> 1
|
75
|
+
a.latest_milestone.version # ==> 1
|
76
|
+
a.latest_milestone.annotations.name ==> "First publish."
|
77
|
+
a.latest_milestone.annotations.notes ==> "Passed all relevant editing. Signed off by moonmaster 10000"
|
78
|
+
|
79
|
+
Now, let's imagine that we've made some more edits / saves to the document, but they don't get approved. Now we want to revert to the version the document was
|
80
|
+
at at the first milestone. How do we do that? Simple!
|
81
|
+
|
82
|
+
a.revert_to_milestone! 1
|
83
|
+
|
84
|
+
And now our document properties are back to the where they were when we first published the document.
|
data/lib/memories/base.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Memories
|
2
2
|
def self.included(base)
|
3
3
|
base.property(:milestone_memories) do |milestone_memory|
|
4
|
-
milestone_memory.property :version
|
4
|
+
milestone_memory.property :version
|
5
5
|
milestone_memory.property :annotations, Memories::Annotation
|
6
6
|
end
|
7
7
|
|
@@ -11,21 +11,40 @@ module Memories
|
|
11
11
|
|
12
12
|
VERSION_REGEX = /(?:rev-)?(\d+)-[a-zA-Z0-9]+/
|
13
13
|
|
14
|
-
def revert_to!(version
|
15
|
-
version
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
def revert_to!(version)
|
15
|
+
revert version, :hard
|
16
|
+
end
|
17
|
+
|
18
|
+
def revert_to(version)
|
19
|
+
revert version
|
20
|
+
end
|
21
|
+
|
22
|
+
def rollback
|
23
|
+
self.revert_to self.previous_version
|
24
|
+
end
|
25
|
+
|
26
|
+
def rollback!
|
27
|
+
self.revert_to! self.previous_version
|
23
28
|
end
|
24
29
|
|
25
30
|
def revert_to_milestone!(n)
|
31
|
+
verify_milestone_exists n
|
26
32
|
self.revert_to! self.milestones[n.to_i-1].version
|
27
33
|
end
|
28
34
|
|
35
|
+
def revert_to_milestone(n)
|
36
|
+
verify_milestone_exists n
|
37
|
+
self.revert_to self.milestones[n.to_i-1].version
|
38
|
+
end
|
39
|
+
|
40
|
+
def rollback_to_latest_milestone
|
41
|
+
self.revert_to_milestone self.milestones.count
|
42
|
+
end
|
43
|
+
|
44
|
+
def rollback_to_latest_milestone!
|
45
|
+
self.revert_to_milestone! self.milestones.count
|
46
|
+
end
|
47
|
+
|
29
48
|
def version_id(version_num)
|
30
49
|
self["_attachments"].keys.sort {|a,b| version_number(a) <=> version_number(b)}[version_num - 1] if self["_attachments"]
|
31
50
|
end
|
@@ -45,7 +64,7 @@ module Memories
|
|
45
64
|
def milestone!(&block)
|
46
65
|
annotations = Memories::Annotation.new
|
47
66
|
annotations.instance_eval(&block) if block
|
48
|
-
self.milestone_memories << {:version => self.
|
67
|
+
self.milestone_memories << {:version => self.rev, :annotations => annotations}
|
49
68
|
self.save
|
50
69
|
end
|
51
70
|
|
@@ -58,6 +77,27 @@ module Memories
|
|
58
77
|
end
|
59
78
|
|
60
79
|
private
|
80
|
+
def verify_milestone_exists(n)
|
81
|
+
raise StandardError, "This document does not have any milestones." if self.milestones.empty?
|
82
|
+
raise StandardError, "Unknown milestone" if n > self.milestones.count
|
83
|
+
end
|
84
|
+
|
85
|
+
def revert(version, revert_type = :soft)
|
86
|
+
raise StandardError, "Unknown revert type passed to 'revert' method. Allowed types: :soft, :hard." if revert_type != :soft && revert_type != :hard
|
87
|
+
|
88
|
+
if (match = version.to_s.match(VERSION_REGEX)) && match[1]
|
89
|
+
version = match[1].to_i
|
90
|
+
end
|
91
|
+
|
92
|
+
if properties = JSON.parse(read_attachment(version_id version))
|
93
|
+
if revert_type == :soft
|
94
|
+
self.update_attributes_without_saving properties
|
95
|
+
elsif revert_type == :hard
|
96
|
+
self.update_attributes properties
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
61
101
|
def add_version_attachment
|
62
102
|
current_document_version = Attachment.new prep_for_versioning(self.database.get(self.id, :rev => self.rev)).to_json
|
63
103
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memories
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt Parker
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-29 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -41,13 +41,14 @@ executables: []
|
|
41
41
|
|
42
42
|
extensions: []
|
43
43
|
|
44
|
-
extra_rdoc_files:
|
45
|
-
|
44
|
+
extra_rdoc_files:
|
45
|
+
- README.markdown
|
46
46
|
files:
|
47
47
|
- lib/memories.rb
|
48
48
|
- lib/memories/annotation.rb
|
49
49
|
- lib/memories/attachment.rb
|
50
50
|
- lib/memories/base.rb
|
51
|
+
- README.markdown
|
51
52
|
has_rdoc: true
|
52
53
|
homepage: http://github.com/moonmaster9000/memories
|
53
54
|
licenses: []
|