joshbuddy-has_many_versions 0.0.4 → 0.0.6

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/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "has_many_versions"
8
+ gem.summary = %Q{Versioning for has_many relationships}
9
+ gem.email = "joshbuddy@gmail.com"
10
+ gem.homepage = "http://github.com/joshbuddy/has_many_versions"
11
+ gem.authors = ["Joshua Hull"]
12
+ gem.files = FileList["[A-Z]*", "{lib,spec,rails,bin}/**/*.rb", 'spec/database.yml', 'spec/spec.opts']
13
+ end
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
16
+ end
17
+
18
+ require 'rake/rdoctask'
19
+ Rake::RDocTask.new do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'has_many_versions'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README*')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ require 'spec/rake/spectask'
28
+ Spec::Rake::SpecTask.new(:spec) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.spec_opts << "--options" << "spec/spec.opts"
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ desc "Run all examples with RCov"
35
+ Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
36
+ t.spec_files = FileList['spec/**/*.rb']
37
+ t.rcov = true
38
+ t.rcov_opts = ['--exclude', 'spec']
39
+ end
40
+
41
+ task :default => :spec
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 4
2
+ :patch: 6
3
3
  :major: 0
4
4
  :minor: 0
@@ -8,6 +8,8 @@ end
8
8
 
9
9
  module HasManyVersions
10
10
 
11
+ HistoryItem = Struct.new(:version, :state)
12
+
11
13
  def upgrade_proxy_object
12
14
  proxy_owner.transaction do
13
15
  new_version = proxy_owner.version + 1
@@ -28,21 +30,25 @@ module HasManyVersions
28
30
 
29
31
  upgrade_proxy_object do |new_version|
30
32
  delete_records_without_versioning_transaction(new_version, @target.select { |v| !other.include?(v) })
31
- add_records_without_versioning_transaction(new_version, *other_array.select { |v| !current.include?(v) })
33
+ add_records_without_versioning_transaction(new_version, other_array.select { |v| !current.include?(v) }, @target.select { |v| !other.include?(v) }.collect(&:id))
32
34
  end
33
35
  end
34
36
 
35
- def add_records_without_versioning_transaction(new_version, *records)
36
- changing_records = flatten_deeper(records).select{|r| !r.new_record? && r.changed?}
37
- changing_records.empty? ? proxy_reflection.klass.update_all(
38
- ['version = ?', new_version],
39
- ["#{proxy_reflection.primary_key_name} = ? and version = ?", proxy_owner.id, new_version - 1]
40
- ) : proxy_reflection.klass.update_all(
41
- ['version = ?', new_version],
42
- ["#{proxy_reflection.primary_key_name} = ? and version = ? and #{proxy_reflection.klass.primary_key} not in (?)", proxy_owner.id, new_version - 1, changing_records.collect(&:id)]
43
- )
37
+ def add_records_without_versioning_transaction(new_version, records, excluded_ids = [])
38
+ changing_records = flatten_deeper(records).select{ |r|
39
+ (!r.new_record? && (r.changed? || (r.version != (new_version - 1))))
40
+ }
41
+ excluded_ids.concat(changing_records.collect(&:id)) unless changing_records.empty?
42
+ excluded_ids.empty? ?
43
+ proxy_reflection.klass.update_all(
44
+ ['version = ?', new_version],
45
+ ["#{proxy_reflection.primary_key_name} = ? and version = ?", proxy_owner.id, new_version - 1]
46
+ ) : proxy_reflection.klass.update_all(
47
+ ['version = ?', new_version],
48
+ ["#{proxy_reflection.primary_key_name} = ? and version = ? and #{proxy_reflection.klass.primary_key} not in (?)", proxy_owner.id, new_version - 1, excluded_ids]
49
+ )
44
50
  records = flatten_deeper(records).collect do |r|
45
- if !r.new_record? && r.changed?
51
+ if changing_records.include?(r)
46
52
  new_r = r.clone
47
53
  new_r.from_version = r.id if new_r.respond_to?(:from_version=)
48
54
  new_r
@@ -51,7 +57,7 @@ module HasManyVersions
51
57
  end
52
58
  end
53
59
  flatten_deeper(records).each do |record|
54
- record.initial_version = proxy_owner.version if record.new_record?
60
+ record.initial_version = proxy_owner.version if record.initial_version.nil? or record.new_record?
55
61
  record.version = proxy_owner.version
56
62
  end
57
63
  __concat__(*records)
@@ -60,7 +66,7 @@ module HasManyVersions
60
66
 
61
67
  def <<(*records)
62
68
  upgrade_proxy_object do |new_version|
63
- add_records_without_versioning_transaction(new_version, *records)
69
+ add_records_without_versioning_transaction(new_version, records)
64
70
  end
65
71
  end
66
72
 
@@ -83,9 +89,21 @@ module HasManyVersions
83
89
  '%s.version = #{version}' % [proxy_reflection.quoted_table_name])
84
90
  end
85
91
 
92
+ def history(from = [proxy_owner.version - 10, 1].max, to = proxy_owner.version)
93
+ history_items = proxy_reflection.klass.find(:all, :conditions => ["#{proxy_reflection.primary_key_name} = ? and version >= ? and initial_version <= ?", proxy_owner.id, from, to])
94
+ to = proxy_owner.version if to > proxy_owner.version
95
+ from = 1 if from < 1
96
+ (from..to).collect do |version|
97
+ HistoryItem.new(version, history_items.select { |item|
98
+ item.initial_version <= version && item.version >= version
99
+ })
100
+ end
101
+ end
102
+
86
103
  def rollback(target_version = proxy_owner.version - 1)
104
+ return if target_version == proxy_owner.version
87
105
  upgrade_proxy_object do |new_version|
88
- proxy_reflection.klass.find(:all, :conditions => ['initial_version <= ? and version >= ?', target_version, target_version]).each do |new_record|
106
+ proxy_reflection.klass.find(:all, :conditions => ["#{proxy_reflection.primary_key_name} = ? and initial_version <= ? and version >= ?", proxy_owner.id, target_version, target_version]).each do |new_record|
89
107
  new_record = new_record.clone
90
108
  new_record.initial_version = new_version
91
109
  new_record.version = new_version
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ autoload :HasManyVersions, 'lib/has_many_versions'
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "HasManyVersions history" do
4
+
5
+ before(:each) do
6
+ Database.reset!
7
+ end
8
+
9
+ it "should give you a history" do
10
+ Database.reset!(true)
11
+ jasper = Author.new(:name => 'Jasper Fforde')
12
+
13
+ books = (1..100).collect do |i|
14
+ book = Book.new(:name => "Book #{i}", :id => i)
15
+ book.save!
16
+ book
17
+ end
18
+ jasper.save!
19
+ titles = [[]]
20
+ jasper.books = [Book.find(1), Book.find(10), Book.find(11), Book.find(23), Book.find(99)]
21
+ titles << jasper.books.collect(&:name)
22
+ jasper.books = [Book.find(1), Book.find(10), Book.find(12), Book.find(25), Book.find(94)]
23
+ titles << jasper.books.collect(&:name)
24
+ jasper.books = [Book.find(1), Book.find(10), Book.find(12), Book.find(25), Book.find(94), Book.find(87)]
25
+ titles << jasper.books.collect(&:name)
26
+ jasper.books = [Book.find(2), Book.find(4), Book.find(5)]
27
+ titles << jasper.books.collect(&:name)
28
+ jasper.books = [Book.find(1), Book.find(10), Book.find(11), Book.find(23), Book.find(99)]
29
+ titles << jasper.books.collect(&:name)
30
+
31
+ jasper.books.history.each do |history|
32
+ history.state.collect(&:name).should == titles.shift
33
+ end
34
+
35
+ end
36
+
37
+ end
data/spec/update_spec.rb CHANGED
@@ -51,7 +51,7 @@ describe "HasManyVersions updating" do
51
51
 
52
52
  jasper.books = [shades_of_grey2, eyre_affair]
53
53
  jasper.version.should == 3
54
-
54
+ jasper.books.collect(&:name).should == ['The Eyre Affair', 'Shades of Grey 2']
55
55
  jasper.books.rollback
56
56
  jasper.books.collect(&:name).should == ['The Eyre Affair', 'Shades of Grey']
57
57
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joshbuddy-has_many_versions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Hull
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-15 00:00:00 -07:00
12
+ date: 2009-04-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -23,17 +23,20 @@ extra_rdoc_files:
23
23
  - README.rdoc
24
24
  - LICENSE
25
25
  files:
26
+ - LICENSE
27
+ - Rakefile
26
28
  - README.rdoc
27
29
  - VERSION.yml
28
30
  - lib/has_many_versions.rb
29
31
  - spec/add_spec.rb
30
- - spec/database.yml
31
32
  - spec/delete_spec.rb
33
+ - spec/history_spec.rb
32
34
  - spec/rollback_spec.rb
33
- - spec/spec.opts
34
35
  - spec/spec_helper.rb
35
36
  - spec/update_spec.rb
36
- - LICENSE
37
+ - rails/init.rb
38
+ - spec/database.yml
39
+ - spec/spec.opts
37
40
  has_rdoc: true
38
41
  homepage: http://github.com/joshbuddy/has_many_versions
39
42
  post_install_message: