rtiss_acts_as_versioned 0.8.2 → 0.8.3
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.
- checksums.yaml +4 -4
- data/Rakefile +0 -8
- data/lib/rtiss_acts_as_versioned.rb +61 -43
- data/rtiss_acts_as_versioned.gemspec +7 -6
- data/test/abstract_unit.rb +4 -9
- data/test/fixtures/locked_pages.yml +4 -2
- data/test/fixtures/locked_pages_revisions.yml +4 -4
- data/test/fixtures/locked_rolle.rb +1 -1
- data/test/fixtures/migrations/{1_add_versioned_tables.rb → 2_add_versioned_tables.rb} +1 -1
- data/test/fixtures/page.rb +3 -3
- data/test/fixtures/rolle.rb +1 -1
- data/test/fixtures/widget.rb +1 -1
- data/test/migration_test.rb +5 -22
- data/test/schema.rb +11 -9
- data/test/tiss_test.rb +49 -8
- data/test/versioned_test.rb +18 -12
- metadata +36 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9f5a6e965b68027705381bc7f298c863c4a72f1
|
4
|
+
data.tar.gz: d604439b36e5bd52fe5480dcf5e96a1a74c6f213
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59bcc2984591245b9dcfafde7e80330388fdff93ca952ba582b3759941dc5c575bc64ea13f7ceff5b6685ae5dcba10273d24bad8839e63ff8afb409b372bb1ea
|
7
|
+
data.tar.gz: e180bd6b6234db9488ce3e9beb9f40b2c4521e57161ab89346cd96b786208822c7340d64f6c9751fce5743f6cfa516b8920b2b8669b37867dfeaf183cd2fc71a
|
data/Rakefile
CHANGED
@@ -73,14 +73,6 @@ task :console do
|
|
73
73
|
sh "irb -rubygems -r ./lib//#{name}.rb"
|
74
74
|
end
|
75
75
|
|
76
|
-
#############################################################################
|
77
|
-
#
|
78
|
-
# Custom tasks (add your own tasks here)
|
79
|
-
#
|
80
|
-
#############################################################################
|
81
|
-
|
82
|
-
|
83
|
-
|
84
76
|
#############################################################################
|
85
77
|
#
|
86
78
|
# Packaging tasks
|
@@ -20,7 +20,7 @@
|
|
20
20
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
|
23
|
-
VERSION = '0.8.
|
23
|
+
VERSION = '0.8.3'
|
24
24
|
|
25
25
|
module ActiveRecord #:nodoc:
|
26
26
|
module Acts #:nodoc:
|
@@ -173,7 +173,7 @@ module ActiveRecord #:nodoc:
|
|
173
173
|
|
174
174
|
cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
|
175
175
|
:version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
|
176
|
-
:version_association_options, :version_if_changed, :deleted_in_original_table_flag, :
|
176
|
+
:version_association_options, :version_if_changed, :deleted_in_original_table_flag, :record_restored_column
|
177
177
|
|
178
178
|
self.versioned_class_name = options[:class_name] || "Version"
|
179
179
|
self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
|
@@ -182,11 +182,14 @@ module ActiveRecord #:nodoc:
|
|
182
182
|
self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
|
183
183
|
self.version_column = options[:version_column] || 'version'
|
184
184
|
self.deleted_in_original_table_flag = options[:deleted_in_original_table_flag] || 'deleted_in_original_table'
|
185
|
-
self.
|
185
|
+
self.record_restored_column = options[:record_restored_column] || 'record_restored'
|
186
186
|
self.version_sequence_name = options[:sequence_name]
|
187
187
|
self.max_version_limit = options[:limit].to_i
|
188
188
|
self.version_condition = options[:if] || true
|
189
189
|
self.non_versioned_columns = [self.primary_key, inheritance_column, self.version_column, 'lock_version', versioned_inheritance_column] + options[:non_versioned_columns].to_a.map(&:to_s)
|
190
|
+
if options[:association_options].is_a?(Hash) && options[:association_options][:dependent] == :nullify
|
191
|
+
raise "Illegal option :dependent => :nullify - this would produce orphans in version model"
|
192
|
+
end
|
190
193
|
self.version_association_options = {
|
191
194
|
:class_name => "#{self.to_s}::#{versioned_class_name}",
|
192
195
|
:foreign_key => versioned_foreign_key
|
@@ -205,12 +208,12 @@ module ActiveRecord #:nodoc:
|
|
205
208
|
has_many :versions, version_association_options do
|
206
209
|
# finds earliest version of this record
|
207
210
|
def earliest
|
208
|
-
@earliest ||=
|
211
|
+
@earliest ||= order('#{version_column}').first
|
209
212
|
end
|
210
213
|
|
211
214
|
# find latest version of this record
|
212
215
|
def latest
|
213
|
-
@latest ||=
|
216
|
+
@latest ||= order('#{version_column} desc').first
|
214
217
|
end
|
215
218
|
end
|
216
219
|
before_save :set_new_version
|
@@ -231,15 +234,14 @@ module ActiveRecord #:nodoc:
|
|
231
234
|
const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
|
232
235
|
def self.reloadable? ; false ; end
|
233
236
|
# find first version before the given version
|
237
|
+
# TODO: replace "version" in selects with version_column, use select-method instead of find
|
234
238
|
def self.before(version)
|
235
|
-
|
236
|
-
:conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
|
239
|
+
where("#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version).order('version desc').first
|
237
240
|
end
|
238
241
|
|
239
242
|
# find first version after the given version.
|
240
243
|
def self.after(version)
|
241
|
-
|
242
|
-
:conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
|
244
|
+
where("#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version).order('version').first
|
243
245
|
end
|
244
246
|
|
245
247
|
def previous
|
@@ -263,7 +265,7 @@ module ActiveRecord #:nodoc:
|
|
263
265
|
version_hash = self.attributes
|
264
266
|
version_hash.delete "id"
|
265
267
|
version_hash.delete self.original_class.deleted_in_original_table_flag.to_s
|
266
|
-
version_hash.delete self.original_class.
|
268
|
+
version_hash.delete self.original_class.record_restored_column.to_s
|
267
269
|
version_hash.delete self.original_class.versioned_foreign_key.to_s
|
268
270
|
|
269
271
|
restored_record = self.original_class.new(version_hash)
|
@@ -271,18 +273,26 @@ module ActiveRecord #:nodoc:
|
|
271
273
|
if restored_record.respond_to? :updated_at=
|
272
274
|
restored_record.updated_at = Time.now
|
273
275
|
end
|
276
|
+
# DON'T EVEN THINK ABOUT CALCULATING THE VERSION NUMBER USING THE VERSIONS ASSOCIATION HERE:
|
277
|
+
# There is a problem in ActiveRecord. An association Relation will be converted to an Array internally, when the SQL-select is
|
278
|
+
# executed.
|
279
|
+
# Some ActiveRecord-Methods (for example #ActiveRecord::Base::AutosaveAssociation#save_collection_association) try to use ActiveRecord methods
|
280
|
+
# with these Relations, and if these Relations have been converted to Arrays, these calls fail with an Exception
|
281
|
+
new_version_number = self.class.where(self.original_class.versioned_foreign_key => id).order('id desc').first.send(restored_record.version_column).to_i + 1
|
282
|
+
restored_record.send("#{restored_record.version_column}=", new_version_number)
|
274
283
|
unless restored_record.save_without_revision(perform_validation)
|
275
284
|
raise RuntimeError.new("Couldn't restore the record, id = #{id} class = #{self.class.name}")
|
276
285
|
end
|
286
|
+
restored_record.save_version(true, false, self.send(self.original_class.version_column))
|
287
|
+
end
|
277
288
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
new_version.save!
|
289
|
+
def record_restored?
|
290
|
+
self.read_attribute(self.original_class.record_restored_column) != nil
|
291
|
+
end
|
292
|
+
alias :record_restored :record_restored?
|
293
|
+
|
294
|
+
def record_restored_from_version
|
295
|
+
self.read_attribute(self.original_class.record_restored_column)
|
286
296
|
end
|
287
297
|
|
288
298
|
def original_record_exists?
|
@@ -307,15 +317,15 @@ module ActiveRecord #:nodoc:
|
|
307
317
|
end
|
308
318
|
|
309
319
|
# Saves a version of the model in the versioned table. This is called in the after_save callback by default
|
310
|
-
def save_version
|
311
|
-
if @saving_version
|
320
|
+
def save_version(save_this=false, deleted_flag=false, restored_from_version=nil)
|
321
|
+
if @saving_version || save_this
|
312
322
|
@saving_version = nil
|
313
323
|
rev = self.class.versioned_class.new
|
314
324
|
clone_versioned_model(self, rev)
|
315
325
|
rev.send("#{self.class.version_column}=", send(self.class.version_column))
|
316
326
|
rev.send("#{self.class.versioned_foreign_key}=", id)
|
317
|
-
rev.send("#{self.class.deleted_in_original_table_flag}=",
|
318
|
-
rev.send("#{self.class.
|
327
|
+
rev.send("#{self.class.deleted_in_original_table_flag}=", deleted_flag)
|
328
|
+
rev.send("#{self.class.record_restored_column}=", restored_from_version)
|
319
329
|
if rev.respond_to? :updated_at=
|
320
330
|
rev.updated_at = Time.now
|
321
331
|
end
|
@@ -331,7 +341,7 @@ module ActiveRecord #:nodoc:
|
|
331
341
|
rev.send("#{self.class.version_column}=", highest_version+1)
|
332
342
|
rev.send("#{self.class.versioned_foreign_key}=", id)
|
333
343
|
rev.send("#{self.class.deleted_in_original_table_flag}=", true)
|
334
|
-
rev.send("#{self.class.
|
344
|
+
rev.send("#{self.class.record_restored_column}=", nil)
|
335
345
|
if rev.respond_to? :updated_at=
|
336
346
|
rev.updated_at = Time.now
|
337
347
|
end
|
@@ -351,9 +361,12 @@ module ActiveRecord #:nodoc:
|
|
351
361
|
# Reverts a model to a given version. Takes either a version number or an instance of the versioned model
|
352
362
|
def revert_to(version)
|
353
363
|
if version.is_a?(self.class.versioned_class)
|
364
|
+
@reverted_from = version.send(self.class.version_column)
|
354
365
|
return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
|
355
366
|
else
|
356
|
-
|
367
|
+
@reverted_from = version
|
368
|
+
version = versions.where(self.class.version_column => version).first
|
369
|
+
return false unless version
|
357
370
|
end
|
358
371
|
self.clone_versioned_model(version, self)
|
359
372
|
send("#{self.class.version_column}=", version.send(self.class.version_column))
|
@@ -363,7 +376,13 @@ module ActiveRecord #:nodoc:
|
|
363
376
|
# Reverts a model to a given version and saves the model.
|
364
377
|
# Takes either a version number or an instance of the versioned model
|
365
378
|
def revert_to!(version)
|
366
|
-
revert_to(version)
|
379
|
+
if revert_to(version)
|
380
|
+
set_new_version
|
381
|
+
save_without_revision
|
382
|
+
save_version(true, false, @reverted_from)
|
383
|
+
else
|
384
|
+
false
|
385
|
+
end
|
367
386
|
end
|
368
387
|
|
369
388
|
# Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
|
@@ -451,7 +470,7 @@ module ActiveRecord #:nodoc:
|
|
451
470
|
|
452
471
|
options = args.extract_options!
|
453
472
|
version_condition = "#{self.class.versioned_foreign_key} = #{self.id}"
|
454
|
-
if options[:conditions]
|
473
|
+
if options[:conditions]
|
455
474
|
options[:conditions] += " and #{version_condition}"
|
456
475
|
else
|
457
476
|
options[:conditions] = version_condition
|
@@ -466,7 +485,7 @@ module ActiveRecord #:nodoc:
|
|
466
485
|
def find_newest_version
|
467
486
|
return nil if self.id.nil?
|
468
487
|
|
469
|
-
self.class.versioned_class.
|
488
|
+
self.class.versioned_class.where("#{self.class.versioned_foreign_key} = #{self.id}").order("version DESC").first
|
470
489
|
end
|
471
490
|
|
472
491
|
def highest_version
|
@@ -481,22 +500,22 @@ module ActiveRecord #:nodoc:
|
|
481
500
|
def find_version(version)
|
482
501
|
return nil if self.id.nil?
|
483
502
|
|
484
|
-
ret = self.class.versioned_class.
|
503
|
+
ret = self.class.versioned_class.where("#{self.class.versioned_foreign_key} = #{self.id} and #{self.class.version_column}=#{version}").first
|
485
504
|
raise "find_version: version #{version} not found in database" unless ret
|
486
505
|
ret
|
487
506
|
end
|
488
507
|
|
489
508
|
protected
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
509
|
+
# sets the new version before saving
|
510
|
+
def set_new_version
|
511
|
+
@saving_version = new_record? || save_version?
|
512
|
+
self.send("#{self.class.version_column}=", next_version) if new_record? || save_version?
|
513
|
+
end
|
495
514
|
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
515
|
+
# Gets the next available version for the current record, or 1 for a new record
|
516
|
+
def next_version
|
517
|
+
(new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
|
518
|
+
end
|
500
519
|
|
501
520
|
module ClassMethods
|
502
521
|
# Returns an array of columns that are versioned. See non_versioned_columns
|
@@ -523,13 +542,13 @@ module ActiveRecord #:nodoc:
|
|
523
542
|
t.column versioned_foreign_key, :integer
|
524
543
|
t.column version_column, :integer
|
525
544
|
t.column deleted_in_original_table_flag, :boolean, :default => false
|
526
|
-
t.column
|
545
|
+
t.column record_restored_column, :integer, :default => nil
|
527
546
|
end
|
528
547
|
|
529
548
|
self.versioned_columns.each do |col|
|
530
549
|
self.connection.add_column versioned_table_name, col.name, col.type,
|
531
550
|
:limit => col.limit,
|
532
|
-
:default => col.default,
|
551
|
+
:default => col.cast_type.type_cast_from_database(col.default), # convert strings to ruby types
|
533
552
|
:scale => col.scale,
|
534
553
|
:precision => col.precision
|
535
554
|
end
|
@@ -537,7 +556,7 @@ module ActiveRecord #:nodoc:
|
|
537
556
|
if type_col = self.columns_hash[inheritance_column]
|
538
557
|
self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
|
539
558
|
:limit => type_col.limit,
|
540
|
-
:default => type_col.default,
|
559
|
+
:default => type_col.cast_type.type_cast_from_database(type_col.default), # convert strings to ruby types
|
541
560
|
:scale => type_col.scale,
|
542
561
|
:precision => type_col.precision
|
543
562
|
end
|
@@ -551,12 +570,12 @@ module ActiveRecord #:nodoc:
|
|
551
570
|
end
|
552
571
|
|
553
572
|
def restore_deleted(id)
|
554
|
-
version_record = versioned_class.
|
573
|
+
version_record = versioned_class.where("#{versioned_foreign_key} = #{id}").order("version DESC").first
|
555
574
|
version_record.restore
|
556
575
|
end
|
557
576
|
|
558
577
|
def restore_deleted_version(id, version)
|
559
|
-
version_record = versioned_class.
|
578
|
+
version_record = versioned_class.where("#{versioned_foreign_key} = #{id} and version = #{version}").first
|
560
579
|
version_record.restore
|
561
580
|
end
|
562
581
|
|
@@ -604,7 +623,6 @@ module ActiveRecord #:nodoc:
|
|
604
623
|
end
|
605
624
|
|
606
625
|
# TISS extension: do not pull this.
|
607
|
-
# TODO: Move to TISS app (initializer)
|
608
626
|
module ActiveRecord #:nodoc:
|
609
627
|
module ConnectionAdapters #:nodoc:
|
610
628
|
class TableDefinition
|
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
|
|
12
12
|
## If your rubyforge_project name is different, then edit it and comment out
|
13
13
|
## the sub! line in the Rakefile
|
14
14
|
s.name = 'rtiss_acts_as_versioned'
|
15
|
-
s.version = '0.8.
|
16
|
-
s.date = '
|
15
|
+
s.version = '0.8.3'
|
16
|
+
s.date = '2016-01-25'
|
17
17
|
s.rubyforge_project = 'rtiss_acts_as_versioned'
|
18
18
|
s.summary = "Add simple versioning to ActiveRecord models (TISS version)."
|
19
19
|
s.description = "Add simple versioning to ActiveRecord models (TISS version).
|
@@ -31,10 +31,11 @@ to use technoweenie's version (can be found also on github)"
|
|
31
31
|
s.rdoc_options = ["--charset=UTF-8"]
|
32
32
|
s.extra_rdoc_files = %w[README MIT-LICENSE CHANGELOG]
|
33
33
|
|
34
|
-
s.add_dependency 'activerecord', ">=
|
34
|
+
s.add_dependency 'activerecord', ">= 4.2.5"
|
35
35
|
s.add_development_dependency 'sqlite3-ruby', "~> 1.3.1"
|
36
|
-
s.add_development_dependency 'rails', "~>
|
37
|
-
s.add_development_dependency '
|
36
|
+
s.add_development_dependency 'rails', "~> 4.2.5"
|
37
|
+
s.add_development_dependency 'activerecord-testcase'
|
38
|
+
s.add_development_dependency 'activerecord-deprecated_finders' # todo alte, hash-basierte finders auf die neue AR Query-API migrieren
|
38
39
|
|
39
40
|
## Leave this section as-is. It will be automatically generated from the
|
40
41
|
## contents of your Git repository via the gemspec task. DO NOT REMOVE
|
@@ -59,7 +60,7 @@ to use technoweenie's version (can be found also on github)"
|
|
59
60
|
test/fixtures/locked_pages.yml
|
60
61
|
test/fixtures/locked_pages_revisions.yml
|
61
62
|
test/fixtures/locked_rolle.rb
|
62
|
-
test/fixtures/migrations/
|
63
|
+
test/fixtures/migrations/2_add_versioned_tables.rb
|
63
64
|
test/fixtures/page.rb
|
64
65
|
test/fixtures/pages.yml
|
65
66
|
test/fixtures/pages_h.yml
|
data/test/abstract_unit.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
|
-
require "rubygems"
|
2
1
|
require "bundler"
|
3
2
|
Bundler.setup(:default, :development)
|
4
3
|
|
5
4
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
6
|
-
require '
|
5
|
+
require 'minitest/autorun'
|
7
6
|
require 'active_support'
|
8
7
|
require 'active_record'
|
9
8
|
require 'active_record/fixtures'
|
10
9
|
require 'active_record/test_case'
|
11
|
-
|
12
|
-
begin
|
13
|
-
require 'ruby-debug'
|
14
|
-
Debugger.start
|
15
|
-
rescue LoadError
|
16
|
-
end
|
17
|
-
|
10
|
+
require 'active_record/deprecated_finders'
|
18
11
|
require 'rtiss_acts_as_versioned'
|
19
12
|
|
13
|
+
ActiveSupport::TestCase.test_order = :sorted
|
14
|
+
|
20
15
|
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
21
16
|
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
22
17
|
ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
|
@@ -2,26 +2,26 @@ welcome_1:
|
|
2
2
|
id: 1
|
3
3
|
page_id: 1
|
4
4
|
title: Welcome to the weblg
|
5
|
-
|
5
|
+
version: 23
|
6
6
|
version_type: LockedPage
|
7
7
|
|
8
8
|
welcome_2:
|
9
9
|
id: 2
|
10
10
|
page_id: 1
|
11
11
|
title: Welcome to the weblog
|
12
|
-
|
12
|
+
version: 24
|
13
13
|
version_type: LockedPage
|
14
14
|
|
15
15
|
thinking_1:
|
16
16
|
id: 3
|
17
17
|
page_id: 2
|
18
18
|
title: So I was thinking!!!
|
19
|
-
|
19
|
+
version: 23
|
20
20
|
version_type: SpecialLockedPage
|
21
21
|
|
22
22
|
thinking_2:
|
23
23
|
id: 4
|
24
24
|
page_id: 2
|
25
25
|
title: So I was thinking
|
26
|
-
|
26
|
+
version: 24
|
27
27
|
version_type: SpecialLockedPage
|
data/test/fixtures/page.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
class Page < ActiveRecord::Base
|
2
2
|
belongs_to :author
|
3
|
-
has_many :authors,
|
3
|
+
has_many :authors, -> { order(:name)}, :through => :versions
|
4
4
|
belongs_to :revisor, :class_name => 'Author'
|
5
|
-
has_many :revisors, :class_name => 'Author', :through => :versions
|
5
|
+
has_many :revisors, -> { order(:name)}, :class_name => 'Author', :through => :versions
|
6
|
+
|
6
7
|
acts_as_versioned :if => :feeling_good? do
|
7
8
|
def self.included(base)
|
8
9
|
base.cattr_accessor :feeling_good
|
@@ -29,7 +30,6 @@ class LockedPage < ActiveRecord::Base
|
|
29
30
|
:foreign_key => :page_id,
|
30
31
|
:table_name => :locked_pages_revisions,
|
31
32
|
:class_name => 'LockedPageRevision',
|
32
|
-
:version_column => :lock_version,
|
33
33
|
:limit => 2,
|
34
34
|
:if_changed => :title,
|
35
35
|
:extend => LockedPageExtension
|
data/test/fixtures/rolle.rb
CHANGED
data/test/fixtures/widget.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Widget < ActiveRecord::Base
|
2
2
|
acts_as_versioned :sequence_name => 'widgets_seq', :association_options => {
|
3
|
-
:
|
3
|
+
:order => 'version desc' # Don't nullify the foreign key column when deleting the original record! :dependent => :nullify option removed
|
4
4
|
}
|
5
5
|
non_versioned_columns << 'foo'
|
6
6
|
end
|
data/test/migration_test.rb
CHANGED
@@ -8,39 +8,22 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
8
8
|
|
9
9
|
class MigrationTest < ActiveSupport::TestCase
|
10
10
|
self.use_transactional_fixtures = false
|
11
|
-
|
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
|
-
|
11
|
+
|
25
12
|
def test_versioned_migration
|
26
|
-
assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
|
27
13
|
# take 'er up
|
28
|
-
|
14
|
+
migrations_path = File.expand_path(File.dirname(__FILE__)) + '/fixtures/migrations'
|
15
|
+
require migrations_path + '/2_add_versioned_tables'
|
16
|
+
ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations(migrations_path), 2).run
|
29
17
|
t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
|
30
18
|
assert_equal 1, t.versions.size
|
31
19
|
|
32
20
|
# check that the price column has remembered its value correctly
|
33
21
|
assert_equal t.price, t.versions.first.price
|
34
22
|
assert_equal t.title, t.versions.first.title
|
35
|
-
|
36
|
-
|
23
|
+
|
37
24
|
# make sure that the precision of the price column has been preserved
|
38
25
|
assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
|
39
26
|
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
27
|
end
|
45
28
|
end
|
46
29
|
end
|
data/test/schema.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
ActiveRecord::Schema.define(:version =>
|
1
|
+
ActiveRecord::Schema.define(:version => 1) do
|
2
2
|
create_table :pages, :force => true do |t|
|
3
3
|
t.column :version, :integer
|
4
4
|
t.column :title, :string, :limit => 255
|
@@ -19,7 +19,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
19
19
|
t.column :author_id, :integer
|
20
20
|
t.column :revisor_id, :integer
|
21
21
|
t.column :deleted_in_original_table, :boolean
|
22
|
-
t.column :record_restored, :
|
22
|
+
t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
|
23
23
|
end
|
24
24
|
|
25
25
|
add_index :pages_h, [:page_id, :version], :unique => true
|
@@ -31,6 +31,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
31
31
|
|
32
32
|
create_table :locked_pages, :force => true do |t|
|
33
33
|
t.column :lock_version, :integer
|
34
|
+
t.column :version, :integer
|
34
35
|
t.column :title, :string, :limit => 255
|
35
36
|
t.column :body, :text
|
36
37
|
t.column :type, :string, :limit => 255
|
@@ -38,16 +39,17 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
38
39
|
|
39
40
|
create_table :locked_pages_revisions, :force => true do |t|
|
40
41
|
t.column :page_id, :integer
|
41
|
-
t.column :
|
42
|
+
t.column :version, :integer
|
43
|
+
#t.column :lock_version, :integer
|
42
44
|
t.column :title, :string, :limit => 255
|
43
45
|
t.column :body, :text
|
44
46
|
t.column :version_type, :string, :limit => 255
|
45
47
|
t.column :updated_at, :datetime
|
46
48
|
t.column :deleted_in_original_table, :boolean
|
47
|
-
t.column :record_restored, :
|
49
|
+
t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
|
48
50
|
end
|
49
51
|
|
50
|
-
add_index :locked_pages_revisions, [:page_id, :
|
52
|
+
add_index :locked_pages_revisions, [:page_id, :version], :unique => true
|
51
53
|
|
52
54
|
create_table :widgets, :force => true do |t|
|
53
55
|
t.column :name, :string, :limit => 50
|
@@ -62,7 +64,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
62
64
|
t.column :version, :integer
|
63
65
|
t.column :updated_at, :datetime
|
64
66
|
t.column :deleted_in_original_table, :boolean
|
65
|
-
t.column :record_restored, :
|
67
|
+
t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
|
66
68
|
end
|
67
69
|
|
68
70
|
add_index :widgets_h, [:widget_id, :version], :unique => true
|
@@ -83,7 +85,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
83
85
|
t.column :doesnt_trigger_version,:string
|
84
86
|
t.column :version, :integer
|
85
87
|
t.column :deleted_in_original_table, :boolean
|
86
|
-
t.column :record_restored, :
|
88
|
+
t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
|
87
89
|
end
|
88
90
|
|
89
91
|
add_index :landmark_h, [:landmark_id, :version], :unique => true
|
@@ -111,7 +113,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
111
113
|
t.string "name", :limit => 50
|
112
114
|
t.string "beschreibung", :limit => 250
|
113
115
|
t.boolean "deleted_in_original_table", :precision => 1, :scale => 0
|
114
|
-
t.
|
116
|
+
t.integer "record_restored", :precision => 38, :scale => 0, :default => nil
|
115
117
|
t.integer "parent_id", :precision => 38, :scale => 0
|
116
118
|
t.string "beschreibung_intern", :limit => 4000
|
117
119
|
t.string "geltungsbereich", :limit => 1000
|
@@ -144,7 +146,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
144
146
|
t.string "name", :limit => 50
|
145
147
|
t.string "beschreibung", :limit => 250
|
146
148
|
t.boolean "deleted_in_original_table", :precision => 1, :scale => 0
|
147
|
-
t.
|
149
|
+
t.integer "record_restored", :precision => 38, :scale => 0, :default => nil
|
148
150
|
t.integer "parent_id", :precision => 38, :scale => 0
|
149
151
|
t.string "beschreibung_intern", :limit => 4000
|
150
152
|
t.string "geltungsbereich", :limit => 1000
|
data/test/tiss_test.rb
CHANGED
@@ -45,7 +45,7 @@ class TissTest < ActiveSupport::TestCase
|
|
45
45
|
|
46
46
|
def test_deleted_in_original_table
|
47
47
|
record = create_object('test deleted_in_orginal_table')
|
48
|
-
version_record = record.versions.
|
48
|
+
version_record = record.versions.first
|
49
49
|
assert version_record != nil
|
50
50
|
|
51
51
|
assert !version_record.deleted_in_original_table
|
@@ -106,23 +106,63 @@ class TissTest < ActiveSupport::TestCase
|
|
106
106
|
oid = o.id
|
107
107
|
v = o.find_version(1)
|
108
108
|
assert v!=nil
|
109
|
-
|
109
|
+
|
110
110
|
assert_raises(RuntimeError) { v.restore }
|
111
111
|
assert !v.deleted_in_original_table
|
112
112
|
assert !v.record_restored, "Record_restored shows that the record was undeleted (should be false) for a newly created record"
|
113
113
|
|
114
|
+
old_version = o.version
|
114
115
|
o.destroy
|
115
116
|
v = o.find_newest_version
|
116
|
-
|
117
|
+
first_delete_version = v.version
|
118
|
+
assert v.deleted_in_original_table, "Deleted-Flag in versioned record is not set"
|
119
|
+
assert_equal old_version + 1, v.version, "Destroy did not increment version number in history record"
|
117
120
|
|
118
121
|
v.restore
|
122
|
+
restored_version = v.version
|
119
123
|
assert !v.record_restored, "Record_restored shows that the record was undeleted (should be false) for the restored version record (but should be in the newly created record)"
|
120
124
|
o = Rolle.find oid
|
121
|
-
assert v.version == o.version, "Version field not restored correctly"
|
122
|
-
|
123
125
|
v = o.find_newest_version
|
126
|
+
v_old = v
|
127
|
+
assert_equal v.version, o.version
|
128
|
+
assert_equal old_version + 2, v.version, "Version field not restored correctly"
|
124
129
|
assert !v.deleted_in_original_table, "Deleted_in_original_table doesn't show that the record was undeleted (should be false)"
|
125
130
|
assert v.record_restored, "Record_restored doesn't show that the record was undeleted (should be true) for the version record created upon restore"
|
131
|
+
assert_equal restored_version, v.record_restored_from_version
|
132
|
+
|
133
|
+
o.name = 'kaputt'
|
134
|
+
assert o.save
|
135
|
+
o.destroy
|
136
|
+
v = o.find_newest_version
|
137
|
+
v.restore
|
138
|
+
o = Rolle.find oid
|
139
|
+
assert_equal v.version + 1, o.version
|
140
|
+
assert_equal 'kaputt', o.name
|
141
|
+
assert_equal v.version, o.find_newest_version.record_restored_from_version
|
142
|
+
o.destroy
|
143
|
+
v_old.restore
|
144
|
+
o = Rolle.find oid
|
145
|
+
assert_equal 'lebt', o.name
|
146
|
+
assert_equal v_old.version, o.find_newest_version.record_restored_from_version
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_restore_and_destroy_with_revision_on_every_change
|
150
|
+
r = Rolle.new(:name => 'karin')
|
151
|
+
assert r.save
|
152
|
+
r.name = 'zak'
|
153
|
+
assert r.save
|
154
|
+
assert_equal 2, Rolle::Version.count
|
155
|
+
r.destroy
|
156
|
+
assert_equal 0, Rolle.count
|
157
|
+
assert_equal 3, Rolle::Version.count
|
158
|
+
assert version = r.find_version(3)
|
159
|
+
assert version.deleted_in_original_table?
|
160
|
+
assert version = r.find_version(2)
|
161
|
+
version.restore
|
162
|
+
assert r = Rolle.first
|
163
|
+
assert r.find_newest_version.record_restored?
|
164
|
+
assert_equal 4, Rolle::Version.count
|
165
|
+
assert_equal 4, r.version
|
126
166
|
end
|
127
167
|
|
128
168
|
def test_original_record_exists
|
@@ -193,7 +233,8 @@ class TissTest < ActiveSupport::TestCase
|
|
193
233
|
assert r.save
|
194
234
|
r.name = 'zak'
|
195
235
|
assert r.save
|
196
|
-
|
236
|
+
r.reload
|
237
|
+
assert_equal 2, r.versions.size
|
197
238
|
assert_equal 2, r.versions.count
|
198
239
|
end
|
199
240
|
|
@@ -205,9 +246,9 @@ class TissTest < ActiveSupport::TestCase
|
|
205
246
|
|
206
247
|
r = Rolle.new(:name => 'karin')
|
207
248
|
assert r.save
|
208
|
-
|
209
249
|
assert_raises RuntimeError do version.restore end
|
210
|
-
assert_nothing_raised do
|
250
|
+
#assert_nothing_raised do
|
251
|
+
version.restore(perform_validations = false) #end
|
211
252
|
end
|
212
253
|
|
213
254
|
def test_save_without_revision
|
data/test/versioned_test.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'abstract_unit')
|
2
2
|
require File.join(File.dirname(__FILE__), 'fixtures/page')
|
3
|
+
require File.join(File.dirname(__FILE__), 'fixtures/landmark')
|
3
4
|
require File.join(File.dirname(__FILE__), 'fixtures/widget')
|
4
5
|
|
5
6
|
class VersionedTest < ActiveSupport::TestCase
|
@@ -29,11 +30,14 @@ class VersionedTest < ActiveSupport::TestCase
|
|
29
30
|
|
30
31
|
def test_rollback_with_version_number
|
31
32
|
p = pages(:welcome)
|
33
|
+
versioncount = p.versions.count
|
32
34
|
assert_equal 24, p.version
|
33
35
|
assert_equal 'Welcome to the weblog', p.title
|
34
36
|
|
35
37
|
assert p.revert_to!(23), "Couldn't revert to 23"
|
36
|
-
|
38
|
+
assert p.reload
|
39
|
+
assert_equal versioncount + 1, p.versions.count
|
40
|
+
assert_equal 25, p.version
|
37
41
|
assert_equal 'Welcome to the weblg', p.title
|
38
42
|
end
|
39
43
|
|
@@ -56,11 +60,14 @@ class VersionedTest < ActiveSupport::TestCase
|
|
56
60
|
|
57
61
|
def test_rollback_with_version_class
|
58
62
|
p = pages(:welcome)
|
63
|
+
versioncount = p.versions.count
|
59
64
|
assert_equal 24, p.version
|
60
65
|
assert_equal 'Welcome to the weblog', p.title
|
61
66
|
|
62
67
|
assert p.revert_to!(p.versions.find_by_version(23)), "Couldn't revert to 23"
|
63
|
-
|
68
|
+
assert p.reload
|
69
|
+
assert_equal versioncount + 1, p.versions.count
|
70
|
+
assert_equal 25, p.version
|
64
71
|
assert_equal 'Welcome to the weblg', p.title
|
65
72
|
end
|
66
73
|
|
@@ -81,7 +88,7 @@ class VersionedTest < ActiveSupport::TestCase
|
|
81
88
|
assert_equal 'Welcome to the weblog', p.title
|
82
89
|
assert_equal 'LockedPage', p.versions.first.version_type
|
83
90
|
|
84
|
-
assert p.revert_to!(p.versions.first.
|
91
|
+
assert p.revert_to!(p.versions.first.version), "Couldn't revert to 23"
|
85
92
|
assert_equal 'Welcome to the weblg', p.title
|
86
93
|
assert_equal 'LockedPage', p.versions.first.version_type
|
87
94
|
end
|
@@ -108,7 +115,7 @@ class VersionedTest < ActiveSupport::TestCase
|
|
108
115
|
p = locked_pages(:thinking)
|
109
116
|
assert_equal 'So I was thinking', p.title
|
110
117
|
|
111
|
-
assert p.revert_to!(p.versions.first.
|
118
|
+
assert p.revert_to!(p.versions.first.version), "Couldn't revert to 1"
|
112
119
|
assert_equal 'So I was thinking!!!', p.title
|
113
120
|
assert_equal 'SpecialLockedPage', p.versions.first.version_type
|
114
121
|
end
|
@@ -202,7 +209,7 @@ class VersionedTest < ActiveSupport::TestCase
|
|
202
209
|
p.title = "title#{i}"
|
203
210
|
p.save
|
204
211
|
assert_equal "title#{i}", p.title
|
205
|
-
assert_equal (i+4), p.
|
212
|
+
assert_equal (i+4), p.version
|
206
213
|
assert p.versions(true).size <= 2, "locked version can only store 2 versions"
|
207
214
|
end
|
208
215
|
end
|
@@ -215,25 +222,25 @@ class VersionedTest < ActiveSupport::TestCase
|
|
215
222
|
|
216
223
|
def test_track_altered_attributes
|
217
224
|
p = LockedPage.create! :title => "title"
|
218
|
-
assert_equal 1, p.
|
225
|
+
assert_equal 1, p.version
|
219
226
|
assert_equal 1, p.versions(true).size
|
220
227
|
|
221
228
|
p.body = 'whoa'
|
222
229
|
assert !p.save_version?
|
223
230
|
p.save
|
224
|
-
assert_equal
|
231
|
+
assert_equal 1, p.version # no increment, because we're not using lock_version column
|
225
232
|
assert_equal 1, p.versions(true).size
|
226
233
|
|
227
234
|
p.title = 'updated title'
|
228
235
|
assert p.save_version?
|
229
236
|
p.save
|
230
|
-
assert_equal
|
231
|
-
assert_equal
|
237
|
+
assert_equal 2, p.version
|
238
|
+
assert_equal 2, p.versions(true).size
|
232
239
|
|
233
240
|
p.title = 'updated title!'
|
234
241
|
assert p.save_version?
|
235
242
|
p.save
|
236
|
-
assert_equal
|
243
|
+
assert_equal 3, p.version
|
237
244
|
assert_equal 2, p.versions(true).size # version 1 deleted
|
238
245
|
end
|
239
246
|
|
@@ -273,8 +280,7 @@ class VersionedTest < ActiveSupport::TestCase
|
|
273
280
|
|
274
281
|
association = Widget.reflect_on_association(:versions)
|
275
282
|
options = association.options
|
276
|
-
assert_equal :nullify, options[:dependent]
|
277
|
-
assert_equal 'version desc', options[:order]
|
283
|
+
#assert_equal :nullify, options[:dependent] #Removed! we do not nullify the foreign key, because on restore we want to set the correct original ID
|
278
284
|
assert_equal 'widget_id', options[:foreign_key]
|
279
285
|
|
280
286
|
widget = Widget.create! :name => 'new widget'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtiss_acts_as_versioned
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Olson
|
@@ -10,64 +10,78 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-01-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 4.2.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version:
|
28
|
+
version: 4.2.5
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: sqlite3-ruby
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- - ~>
|
33
|
+
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
35
|
version: 1.3.1
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- - ~>
|
40
|
+
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: 1.3.1
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: rails
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - ~>
|
47
|
+
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 4.2.5
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- - ~>
|
54
|
+
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 4.2.5
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
|
-
name:
|
58
|
+
name: activerecord-testcase
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
|
-
- -
|
61
|
+
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: '0'
|
64
64
|
type: :development
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- -
|
68
|
+
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: activerecord-deprecated_finders
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
71
85
|
description: "Add simple versioning to ActiveRecord models (TISS version).\n\nEach
|
72
86
|
model has a to-many model named mymodel_h which records all changes \n(including
|
73
87
|
destroys but not deletes) made to the model. This is the version\nused by http://tiss.tuwien.ac.at
|
@@ -100,7 +114,7 @@ files:
|
|
100
114
|
- test/fixtures/locked_pages.yml
|
101
115
|
- test/fixtures/locked_pages_revisions.yml
|
102
116
|
- test/fixtures/locked_rolle.rb
|
103
|
-
- test/fixtures/migrations/
|
117
|
+
- test/fixtures/migrations/2_add_versioned_tables.rb
|
104
118
|
- test/fixtures/page.rb
|
105
119
|
- test/fixtures/pages.yml
|
106
120
|
- test/fixtures/pages_h.yml
|
@@ -115,17 +129,17 @@ licenses: []
|
|
115
129
|
metadata: {}
|
116
130
|
post_install_message:
|
117
131
|
rdoc_options:
|
118
|
-
- --charset=UTF-8
|
132
|
+
- "--charset=UTF-8"
|
119
133
|
require_paths:
|
120
134
|
- lib
|
121
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|
122
136
|
requirements:
|
123
|
-
- -
|
137
|
+
- - ">="
|
124
138
|
- !ruby/object:Gem::Version
|
125
139
|
version: '0'
|
126
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
141
|
requirements:
|
128
|
-
- -
|
142
|
+
- - ">="
|
129
143
|
- !ruby/object:Gem::Version
|
130
144
|
version: '0'
|
131
145
|
requirements: []
|
@@ -135,3 +149,4 @@ signing_key:
|
|
135
149
|
specification_version: 4
|
136
150
|
summary: Add simple versioning to ActiveRecord models (TISS version).
|
137
151
|
test_files: []
|
152
|
+
has_rdoc:
|