jdunphy-sequel_revisioned 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-01-02
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,5 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ lib/sequel_revisioned.rb
5
+ lib/sequel_revisioned/sequel_revisioned.rb
data/README.rdoc ADDED
@@ -0,0 +1,62 @@
1
+ = sequel_revisioned
2
+
3
+ == DESCRIPTION:
4
+
5
+ Sequel plugin designed to maintain a revision history of an object.
6
+
7
+ Sequel_revisioned will create a revision table and model specific to the class that calls
8
+ `is :revisioned`. It's set up this way to allow multiple tables to maintain revisions
9
+ without interfering with each other.
10
+
11
+ == USAGE
12
+
13
+ class Post < Sequel::Model
14
+ is :revisioned, :watch => [:title, :body, :synopsis]
15
+
16
+ end
17
+
18
+ $ p = Post[n]
19
+ $ p.revisions
20
+ => Array of post's revisions
21
+ $ p.roll_back(x)
22
+ => Rolls watched fields back to the sate of revision x
23
+
24
+ $ revision = p.revisions.first
25
+ $ revision.class.name
26
+ => PostRevision
27
+ $ revision.table_name
28
+ => post_revisions
29
+
30
+
31
+ == REQUIREMENTS:
32
+
33
+ Sequel >= 2.9.0
34
+
35
+ == INSTALL:
36
+
37
+ sudo gem install jdunphy-sequel_revisioned --source http://gems.github.com
38
+
39
+ == LICENSE:
40
+
41
+ (The MIT License)
42
+
43
+ Copyright (c) 2009 Jacob Dunphy
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining
46
+ a copy of this software and associated documentation files (the
47
+ 'Software'), to deal in the Software without restriction, including
48
+ without limitation the rights to use, copy, modify, merge, publish,
49
+ distribute, sublicense, and/or sell copies of the Software, and to
50
+ permit persons to whom the Software is furnished to do so, subject to
51
+ the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be
54
+ included in all copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
57
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
58
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
59
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
60
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
61
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
62
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module SequelRevisioned
5
+ VERSION = '0.0.1'
6
+ end
7
+
8
+ module Sequel
9
+ class InvalidRevisionError < StandardError; end
10
+ end
11
+
12
+ require 'sequel_revisioned/sequel_revisioned'
@@ -0,0 +1,116 @@
1
+ module Sequel
2
+ module Plugins
3
+ module Revisioned
4
+
5
+ def self.apply(model, options = {})
6
+ revision_model_name = "::#{model.name}Revision"
7
+ eval "
8
+ class #{revision_model_name} < Sequel::Model
9
+ before_create :set_created_at
10
+ before_create :set_version
11
+ many_to_one :#{model.name.underscore}
12
+
13
+ def next_revision
14
+ if version && post_id
15
+ self.class.find(:post_id => post_id, :version => version + 1)
16
+ end
17
+ end
18
+
19
+ def previous_revision
20
+ if version && post_id && version > 1
21
+ self.class.find(:post_id => post_id, :version => version - 1)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def set_version
28
+ if last_revision = #{model.name.underscore}.revisions.first
29
+ self.version = last_revision.version + 1
30
+ else
31
+ self.version = 1
32
+ end
33
+ end
34
+
35
+ def set_created_at
36
+ self.created_at ||= Time.now
37
+ end
38
+ end
39
+ "
40
+ revision_model = revision_model_name.constantize
41
+ unless revision_model.table_exists?
42
+ migration = "
43
+ class CreateRevisions < Sequel::Migration
44
+ def up
45
+ create_table :#{revision_model.table_name} do
46
+ primary_key :id
47
+ integer :#{model.name.underscore}_id
48
+ integer :version
49
+ timestamp :created_at
50
+ #{additional_migration_columns(model, options)}
51
+ end
52
+ end
53
+ end
54
+ CreateRevisions.apply(DB, :up)
55
+ #{revision_model_name}.columns"
56
+ # TODO - This last line feels really hacky.
57
+ # The #generate_revision code below doesn't work without it.
58
+ # It seems like I have to load the schema into the model
59
+ eval migration
60
+ end
61
+
62
+ model.class_eval "
63
+ one_to_many :revisions, :class => '#{revision_model}', :order => :version.desc
64
+ after_save :generate_revision
65
+ @@watched_columns = [#{Array(options[:watch]).map {|w| ":#{w.to_s}"}.join(",")}]
66
+
67
+ def self.revision_class; #{revision_model}; end
68
+ "
69
+ end
70
+
71
+ def self.additional_migration_columns(model, options = {})
72
+ if options[:watch]
73
+ Array(options[:watch]).map do |column|
74
+ "#{model.db_schema[column.to_sym][:type]} :#{column}"
75
+ end.join("\n")
76
+ end
77
+ end
78
+
79
+ module InstanceMethods
80
+
81
+ def roll_back(version)
82
+ revision = revisions.detect {|rev| rev.version == version.to_i }
83
+ raise Sequel::InvalidRevisionError unless revision
84
+ self.class.watched_columns.each do |col|
85
+ send("#{col}=", revision.send(col))
86
+ end
87
+ end
88
+
89
+ def watched_data
90
+ data = {}
91
+ self.class.watched_columns.each do |col|
92
+ data[col] = send(col)
93
+ end
94
+ data
95
+ end
96
+ private :watched_data
97
+
98
+ def generate_revision
99
+ revision = self.class.revision_class.new(watched_data)
100
+ add_revision(revision)
101
+ revision.save
102
+ end
103
+ private :generate_revision
104
+ end
105
+
106
+ module ClassMethods
107
+
108
+ def watched_columns
109
+ class_variable_get(:@@watched_columns)
110
+ end
111
+ end
112
+
113
+ end
114
+ end
115
+ end
116
+
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jdunphy-sequel_revisioned
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jacob Dunphy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-19 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sequel
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.9.0
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: newgem
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.2.3
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: hoe
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.0
41
+ version:
42
+ description: Sequel plugin designed to maintain a revision history of an object. Sequel_revisioned will create a revision table and model specific to the class that calls `is :revisioned`. It's set up this way to allow multiple tables to maintain revisions without interfering with each other.
43
+ email:
44
+ - jacob.dunphy@gmail.com
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ extra_rdoc_files:
50
+ - History.txt
51
+ - Manifest.txt
52
+ - README.rdoc
53
+ files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - README.rdoc
57
+ - lib/sequel_revisioned.rb
58
+ - lib/sequel_revisioned/sequel_revisioned.rb
59
+ has_rdoc: true
60
+ homepage:
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --main
64
+ - README.rdoc
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project: sequel_revisioned
82
+ rubygems_version: 1.2.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: Sequel plugin designed to maintain a revision history of an object
86
+ test_files: []
87
+