rtiss_acts_as_versioned 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,96 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ ## This is the rakegem gemspec template. Make sure you read and understand
4
+ ## all of the comments. Some sections require modification, and others can
5
+ ## be deleted if you don't need them. Once you understand the contents of
6
+ ## this file, feel free to delete any comments that begin with two hash marks.
7
+ ## You can find comprehensive Gem::Specification documentation, at
8
+ ## http://docs.rubygems.org/read/chapter/20
9
+ Gem::Specification.new do |s|
10
+ s.specification_version = 2 if s.respond_to? :specification_version=
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.rubygems_version = '1.3.5'
13
+
14
+ ## Leave these as is they will be modified for you by the rake gemspec task.
15
+ ## If your rubyforge_project name is different, then edit it and comment out
16
+ ## the sub! line in the Rakefile
17
+ s.name = 'rtiss_acts_as_versioned'
18
+ s.version = '0.6.2'
19
+ s.date = '2014-02-03'
20
+ s.rubyforge_project = 'rtiss_acts_as_versioned'
21
+
22
+ ## Make sure your summary is short. The description may be as long
23
+ ## as you like.
24
+ s.summary = "Add simple versioning to ActiveRecord models (TISS version)."
25
+ s.description = "Add simple versioning to ActiveRecord models (TISS version).
26
+
27
+ Each model has a to-many model named mymodel_h which records all changes
28
+ (including destroys but not deletes) made to the model. This is the version
29
+ used by http://tiss.tuwien.ac.at and substantially differs from the original
30
+ version. If you want to use acts_as_versioned in your project we recommend
31
+ to use technoweenie's version (can be found also on github)"
32
+
33
+ ## List the primary authors. If there are a bunch of authors, it's probably
34
+ ## better to set the email to an email list or something. If you don't have
35
+ ## a custom homepage, consider using your GitHub URL or the like.
36
+ s.authors = ["Rick Olson", "Johannes Thoma", "Igor Jancev"]
37
+ s.email = 'igor.jancev@tuwien.ac.at'
38
+ s.homepage = 'http://github.com/rtiss/rtiss_acts_as_versioned'
39
+
40
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
41
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
42
+ s.require_paths = %w[lib]
43
+
44
+ ## Specify any RDoc options here. You'll want to add your README and
45
+ ## LICENSE files to the extra_rdoc_files list.
46
+ s.rdoc_options = ["--charset=UTF-8"]
47
+ s.extra_rdoc_files = %w[README MIT-LICENSE CHANGELOG]
48
+
49
+ ## List your runtime dependencies here. Runtime dependencies are those
50
+ ## that are needed for an end user to actually USE your code.
51
+ s.add_dependency('activerecord', ["~> 2.3.16"])
52
+
53
+ ## List your development dependencies here. Development dependencies are
54
+ ## those that are only needed during development
55
+ s.add_development_dependency('sqlite3-ruby', ["~> 1.3.1"])
56
+
57
+ ## Leave this section as-is. It will be automatically generated from the
58
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
59
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
60
+ # = MANIFEST =
61
+ s.files = %w[
62
+ CHANGELOG
63
+ Gemfile
64
+ MIT-LICENSE
65
+ README
66
+ RUNNING_UNIT_TESTS
67
+ Rakefile
68
+ init.rb
69
+ lib/rtiss_acts_as_versioned.rb
70
+ rtiss_acts_as_versioned.gemspec
71
+ test/abstract_unit.rb
72
+ test/database.yml
73
+ test/fixtures/authors.yml
74
+ test/fixtures/landmark.rb
75
+ test/fixtures/landmark_h.yml
76
+ test/fixtures/landmarks.yml
77
+ test/fixtures/locked_pages.yml
78
+ test/fixtures/locked_pages_revisions.yml
79
+ test/fixtures/locked_rolle.rb
80
+ test/fixtures/migrations/1_add_versioned_tables.rb
81
+ test/fixtures/page.rb
82
+ test/fixtures/pages.yml
83
+ test/fixtures/pages_h.yml
84
+ test/fixtures/rolle.rb
85
+ test/fixtures/widget.rb
86
+ test/migration_test.rb
87
+ test/schema.rb
88
+ test/tiss_test.rb
89
+ test/versioned_test.rb
90
+ ]
91
+ # = MANIFEST =
92
+
93
+ ## Test files will be grabbed from the file list. Make sure the path glob
94
+ ## matches what you actually use.
95
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
96
+ end
@@ -0,0 +1,49 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup(:default, :development)
4
+
5
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
6
+ require 'test/unit'
7
+ require 'active_support'
8
+ require 'active_record'
9
+ require 'active_record/fixtures'
10
+ require 'active_record/test_case'
11
+
12
+ begin
13
+ require 'ruby-debug'
14
+ Debugger.start
15
+ rescue LoadError
16
+ end
17
+
18
+ require 'rtiss_acts_as_versioned'
19
+
20
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
21
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
22
+ ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
23
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
24
+
25
+ load(File.dirname(__FILE__) + "/schema.rb")
26
+
27
+ # set up custom sequence on widget_versions for DBs that support sequences
28
+ if ENV['DB'] == 'postgresql'
29
+ ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil
30
+ ActiveRecord::Base.connection.remove_column :widget_versions, :id
31
+ ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;"
32
+ ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');"
33
+ end
34
+
35
+ class ActiveSupport::TestCase #:nodoc:
36
+ include ActiveRecord::TestFixtures
37
+
38
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
39
+
40
+ # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
41
+ self.use_transactional_fixtures = true
42
+
43
+ # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
44
+ self.use_instantiated_fixtures = false
45
+
46
+ # Add more helper methods to be used by all tests here...
47
+ end
48
+
49
+ $:.unshift(ActiveSupport::TestCase.fixture_path)
data/test/database.yml ADDED
@@ -0,0 +1,18 @@
1
+ sqlite:
2
+ adapter: sqlite
3
+ dbfile: acts_as_versioned_plugin.sqlite.db
4
+ sqlite3:
5
+ adapter: sqlite3
6
+ database: acts_as_versioned_plugin.sqlite3.db
7
+ postgresql:
8
+ adapter: postgresql
9
+ username: postgres
10
+ password: postgres
11
+ database: acts_as_versioned_plugin_test
12
+ min_messages: ERROR
13
+ mysql:
14
+ adapter: mysql
15
+ host: localhost
16
+ username: rails
17
+ password:
18
+ database: acts_as_versioned_plugin_test
@@ -0,0 +1,6 @@
1
+ caged:
2
+ id: 1
3
+ name: caged
4
+ mly:
5
+ id: 2
6
+ name: mly
@@ -0,0 +1,3 @@
1
+ class Landmark < ActiveRecord::Base
2
+ acts_as_versioned :if_changed => [ :name, :longitude, :latitude ]
3
+ end
@@ -0,0 +1,7 @@
1
+ washington:
2
+ id: 1
3
+ landmark_id: 1
4
+ version: 1
5
+ name: Washington, D.C.
6
+ latitude: 38.895
7
+ longitude: -77.036667
@@ -0,0 +1,7 @@
1
+ washington:
2
+ id: 1
3
+ name: Washington, D.C.
4
+ latitude: 38.895
5
+ longitude: -77.036667
6
+ doesnt_trigger_version: This is not important
7
+ version: 1
@@ -0,0 +1,10 @@
1
+ welcome:
2
+ id: 1
3
+ title: Welcome to the weblog
4
+ lock_version: 24
5
+ type: LockedPage
6
+ thinking:
7
+ id: 2
8
+ title: So I was thinking
9
+ lock_version: 24
10
+ type: SpecialLockedPage
@@ -0,0 +1,27 @@
1
+ welcome_1:
2
+ id: 1
3
+ page_id: 1
4
+ title: Welcome to the weblg
5
+ lock_version: 23
6
+ version_type: LockedPage
7
+
8
+ welcome_2:
9
+ id: 2
10
+ page_id: 1
11
+ title: Welcome to the weblog
12
+ lock_version: 24
13
+ version_type: LockedPage
14
+
15
+ thinking_1:
16
+ id: 3
17
+ page_id: 2
18
+ title: So I was thinking!!!
19
+ lock_version: 23
20
+ version_type: SpecialLockedPage
21
+
22
+ thinking_2:
23
+ id: 4
24
+ page_id: 2
25
+ title: So I was thinking
26
+ lock_version: 24
27
+ version_type: SpecialLockedPage
@@ -0,0 +1,8 @@
1
+ # Same as Rolle except for the presence of the lock_version field
2
+ class LockedRolle < ActiveRecord::Base
3
+ set_table_name 'locked_rolle'
4
+ acts_as_versioned
5
+
6
+ validates_presence_of :name
7
+ validates_uniqueness_of :name
8
+ end
@@ -0,0 +1,15 @@
1
+ class AddVersionedTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table("things") do |t|
4
+ t.column :title, :text
5
+ t.column :price, :decimal, :precision => 7, :scale => 2
6
+ t.column :type, :string
7
+ end
8
+ Thing.create_versioned_table
9
+ end
10
+
11
+ def self.down
12
+ Thing.drop_versioned_table
13
+ drop_table "things" rescue nil
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ class Page < ActiveRecord::Base
2
+ belongs_to :author
3
+ has_many :authors, :through => :versions, :order => 'name'
4
+ belongs_to :revisor, :class_name => 'Author'
5
+ has_many :revisors, :class_name => 'Author', :through => :versions, :order => 'name'
6
+ acts_as_versioned :if => :feeling_good? do
7
+ def self.included(base)
8
+ base.cattr_accessor :feeling_good
9
+ base.feeling_good = true
10
+ base.belongs_to :author
11
+ base.belongs_to :revisor, :class_name => 'Author'
12
+ end
13
+
14
+ def feeling_good?
15
+ @@feeling_good == true
16
+ end
17
+ end
18
+ end
19
+
20
+ module LockedPageExtension
21
+ def hello_world
22
+ 'hello_world'
23
+ end
24
+ end
25
+
26
+ class LockedPage < ActiveRecord::Base
27
+ acts_as_versioned \
28
+ :inheritance_column => :version_type,
29
+ :foreign_key => :page_id,
30
+ :table_name => :locked_pages_revisions,
31
+ :class_name => 'LockedPageRevision',
32
+ :version_column => :lock_version,
33
+ :limit => 2,
34
+ :if_changed => :title,
35
+ :extend => LockedPageExtension
36
+ end
37
+
38
+ class SpecialLockedPage < LockedPage
39
+ end
40
+
41
+ class Author < ActiveRecord::Base
42
+ has_many :pages
43
+ end
@@ -0,0 +1,8 @@
1
+ welcome:
2
+ id: 1
3
+ title: Welcome to the weblog
4
+ body: Such a lovely day
5
+ version: 24
6
+ author_id: 1
7
+ revisor_id: 1
8
+ created_on: "2008-01-01 00:00:00"
@@ -0,0 +1,18 @@
1
+ welcome_2:
2
+ id: 1
3
+ page_id: 1
4
+ title: Welcome to the weblog
5
+ body: Such a lovely day
6
+ version: 24
7
+ author_id: 1
8
+ revisor_id: 1
9
+ deleted_in_original_table: 0
10
+ welcome_1:
11
+ id: 2
12
+ page_id: 1
13
+ title: Welcome to the weblg
14
+ body: Such a lovely day
15
+ version: 23
16
+ author_id: 2
17
+ revisor_id: 2
18
+ deleted_in_original_table: 0
@@ -0,0 +1,7 @@
1
+ class Rolle < ActiveRecord::Base
2
+ set_table_name 'rolle'
3
+ acts_as_versioned
4
+
5
+ validates_presence_of :name
6
+ validates_uniqueness_of :name
7
+ end
@@ -0,0 +1,6 @@
1
+ class Widget < ActiveRecord::Base
2
+ acts_as_versioned :sequence_name => 'widgets_seq', :association_options => {
3
+ :dependent => :nullify, :order => 'version desc'
4
+ }
5
+ non_versioned_columns << 'foo'
6
+ end
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), 'abstract_unit')
2
+
3
+ if ActiveRecord::Base.connection.supports_migrations?
4
+ class Thing < ActiveRecord::Base
5
+ attr_accessor :version
6
+ acts_as_versioned
7
+ end
8
+
9
+ class MigrationTest < ActiveSupport::TestCase
10
+ self.use_transactional_fixtures = false
11
+ def teardown
12
+ if ActiveRecord::Base.connection.respond_to?(:initialize_schema_information)
13
+ ActiveRecord::Base.connection.initialize_schema_information
14
+ ActiveRecord::Base.connection.update "UPDATE schema_info SET version = 0"
15
+ else
16
+ ActiveRecord::Base.connection.initialize_schema_migrations_table
17
+ ActiveRecord::Base.connection.assume_migrated_upto_version(0)
18
+ end
19
+
20
+ Thing.connection.drop_table "things" rescue nil
21
+ Thing.connection.drop_table "thing_versions" rescue nil
22
+ Thing.reset_column_information
23
+ end
24
+
25
+ def test_versioned_migration
26
+ assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
27
+ # take 'er up
28
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
29
+ t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
30
+ assert_equal 1, t.versions.size
31
+
32
+ # check that the price column has remembered its value correctly
33
+ assert_equal t.price, t.versions.first.price
34
+ assert_equal t.title, t.versions.first.title
35
+ assert_equal t[:type], t.versions.first[:type]
36
+
37
+ # make sure that the precision of the price column has been preserved
38
+ assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
39
+ assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale
40
+
41
+ # now lets take 'er back down
42
+ ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
43
+ assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
44
+ end
45
+ end
46
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,154 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :pages, :force => true do |t|
3
+ t.column :version, :integer
4
+ t.column :title, :string, :limit => 255
5
+ t.column :body, :text
6
+ t.column :created_on, :datetime
7
+ t.column :updated_on, :datetime
8
+ t.column :author_id, :integer
9
+ t.column :revisor_id, :integer
10
+ end
11
+
12
+ create_table :pages_h, :force => true do |t|
13
+ t.column :page_id, :integer
14
+ t.column :version, :integer
15
+ t.column :title, :string, :limit => 255
16
+ t.column :body, :text
17
+ t.column :created_on, :datetime
18
+ t.column :updated_on, :datetime
19
+ t.column :author_id, :integer
20
+ t.column :revisor_id, :integer
21
+ t.column :deleted_in_original_table, :boolean
22
+ t.column :record_restored, :boolean
23
+ end
24
+
25
+ add_index :pages_h, [:page_id, :version], :unique => true
26
+
27
+ create_table :authors, :force => true do |t|
28
+ t.column :page_id, :integer
29
+ t.column :name, :string
30
+ end
31
+
32
+ create_table :locked_pages, :force => true do |t|
33
+ t.column :lock_version, :integer
34
+ t.column :title, :string, :limit => 255
35
+ t.column :body, :text
36
+ t.column :type, :string, :limit => 255
37
+ end
38
+
39
+ create_table :locked_pages_revisions, :force => true do |t|
40
+ t.column :page_id, :integer
41
+ t.column :lock_version, :integer
42
+ t.column :title, :string, :limit => 255
43
+ t.column :body, :text
44
+ t.column :version_type, :string, :limit => 255
45
+ t.column :updated_at, :datetime
46
+ t.column :deleted_in_original_table, :boolean
47
+ t.column :record_restored, :boolean
48
+ end
49
+
50
+ add_index :locked_pages_revisions, [:page_id, :lock_version], :unique => true
51
+
52
+ create_table :widgets, :force => true do |t|
53
+ t.column :name, :string, :limit => 50
54
+ t.column :foo, :string
55
+ t.column :version, :integer
56
+ t.column :updated_at, :datetime
57
+ end
58
+
59
+ create_table :widgets_h, :force => true do |t|
60
+ t.column :widget_id, :integer
61
+ t.column :name, :string, :limit => 50
62
+ t.column :version, :integer
63
+ t.column :updated_at, :datetime
64
+ t.column :deleted_in_original_table, :boolean
65
+ t.column :record_restored, :boolean
66
+ end
67
+
68
+ add_index :widgets_h, [:widget_id, :version], :unique => true
69
+
70
+ create_table :landmarks, :force => true do |t|
71
+ t.column :name, :string
72
+ t.column :latitude, :float
73
+ t.column :longitude, :float
74
+ t.column :doesnt_trigger_version,:string
75
+ t.column :version, :integer
76
+ end
77
+
78
+ create_table :landmark_h, :force => true do |t|
79
+ t.column :landmark_id, :integer
80
+ t.column :name, :string
81
+ t.column :latitude, :float
82
+ t.column :longitude, :float
83
+ t.column :doesnt_trigger_version,:string
84
+ t.column :version, :integer
85
+ t.column :deleted_in_original_table, :boolean
86
+ t.column :record_restored, :boolean
87
+ end
88
+
89
+ add_index :landmark_h, [:landmark_id, :version], :unique => true
90
+
91
+ create_table "rolle", :force => true do |t|
92
+ t.datetime "created_at"
93
+ t.datetime "updated_at"
94
+ t.integer "version", :precision => 38, :scale => 0, :default => 1
95
+ t.integer "mutator_id", :precision => 38, :scale => 0, :default => 0
96
+ t.string "name", :limit => 50, :null => false
97
+ t.string "beschreibung", :limit => 250
98
+ t.integer "parent_id", :precision => 38, :scale => 0
99
+ t.string "beschreibung_intern", :limit => 4000
100
+ t.string "geltungsbereich", :limit => 1000
101
+ t.string "vergaberichtlinien", :limit => 4000
102
+ t.boolean "ist_delegierbar", :precision => 1, :scale => 0, :default => true
103
+ end
104
+
105
+ create_table "rolle_h", :force => true do |t|
106
+ t.integer "rolle_id", :precision => 38, :scale => 0
107
+ t.integer "version", :precision => 38, :scale => 0
108
+ t.datetime "created_at"
109
+ t.datetime "updated_at"
110
+ t.integer "mutator_id", :precision => 38, :scale => 0
111
+ t.string "name", :limit => 50
112
+ t.string "beschreibung", :limit => 250
113
+ t.boolean "deleted_in_original_table", :precision => 1, :scale => 0
114
+ t.boolean "record_restored", :precision => 1, :scale => 0
115
+ t.integer "parent_id", :precision => 38, :scale => 0
116
+ t.string "beschreibung_intern", :limit => 4000
117
+ t.string "geltungsbereich", :limit => 1000
118
+ t.string "vergaberichtlinien", :limit => 4000
119
+ t.boolean "ist_delegierbar", :precision => 1, :scale => 0, :default => true
120
+ end
121
+
122
+ create_table "locked_rolle", :force => true do |t|
123
+ t.datetime "created_at"
124
+ t.datetime "updated_at"
125
+ t.integer "version", :precision => 38, :scale => 0, :default => 1
126
+ t.integer "lock_version", :precision => 38, :scale => 0, :default => 0
127
+ t.integer "mutator_id", :precision => 38, :scale => 0, :default => 0
128
+ t.string "name", :limit => 50, :null => false
129
+ t.string "beschreibung", :limit => 250
130
+ t.integer "parent_id", :precision => 38, :scale => 0
131
+ t.string "beschreibung_intern", :limit => 4000
132
+ t.string "geltungsbereich", :limit => 1000
133
+ t.string "vergaberichtlinien", :limit => 4000
134
+ t.boolean "ist_delegierbar", :precision => 1, :scale => 0, :default => true
135
+ end
136
+
137
+ create_table "locked_rolle_h", :force => true do |t|
138
+ t.integer "locked_rolle_id", :precision => 38, :scale => 0
139
+ t.integer "version", :precision => 38, :scale => 0
140
+ t.integer "lock_version", :precision => 38, :scale => 0, :default => 0
141
+ t.datetime "created_at"
142
+ t.datetime "updated_at"
143
+ t.integer "mutator_id", :precision => 38, :scale => 0
144
+ t.string "name", :limit => 50
145
+ t.string "beschreibung", :limit => 250
146
+ t.boolean "deleted_in_original_table", :precision => 1, :scale => 0
147
+ t.boolean "record_restored", :precision => 1, :scale => 0
148
+ t.integer "parent_id", :precision => 38, :scale => 0
149
+ t.string "beschreibung_intern", :limit => 4000
150
+ t.string "geltungsbereich", :limit => 1000
151
+ t.string "vergaberichtlinien", :limit => 4000
152
+ t.boolean "ist_delegierbar", :precision => 1, :scale => 0, :default => true
153
+ end
154
+ end