acts_as_archival 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -2
- data/CHANGELOG.md +8 -2
- data/Gemfile.lock +30 -21
- data/README.md +83 -47
- data/acts_as_archival.gemspec +2 -0
- data/lib/acts_as_archival/version.rb +1 -1
- data/test/ambiguous_table_test.rb +3 -1
- data/test/associations_test.rb +1 -1
- data/test/basic_test.rb +14 -14
- data/test/database.yml +26 -8
- data/test/deep_nesting_test.rb +6 -6
- data/test/fixtures/archival_grandkid.rb +3 -0
- data/test/fixtures/archival_kid.rb +3 -0
- data/test/fixtures/exploder.rb +3 -1
- data/test/fixtures/independent_archival.rb +0 -1
- data/test/fixtures/mass_attribute_protected.rb +3 -0
- data/test/fixtures/missing_archive_number.rb +2 -0
- data/test/fixtures/missing_archived_at.rb +2 -0
- data/test/fixtures/mysql_archival.rb +10 -0
- data/test/fixtures/mysql_exploder.rb +9 -0
- data/test/fixtures/pg_archival.rb +10 -0
- data/test/fixtures/pg_exploder.rb +9 -0
- data/test/fixtures/poly.rb +0 -1
- data/test/fixtures/readonly_when_archived.rb +3 -0
- data/test/schema.rb +50 -49
- data/test/scope_test.rb +8 -4
- data/test/script/db_setup +1 -1
- data/test/test_helper.rb +13 -6
- data/test/transaction_test.rb +53 -2
- metadata +42 -3
- data/.rvmrc +0 -1
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
# Changes!
|
2
2
|
|
3
|
+
## 0.6.0
|
4
|
+
* **BREAKING CHANGE** (possibly): Some refactoring to modern gem module idioms instead of old school plugins
|
5
|
+
* Officially support PostgreSQL
|
6
|
+
* Switch default testing to use sqlite, mysql, and postgres instead of just mysql
|
7
|
+
* Major upgrades to test suite
|
8
|
+
|
3
9
|
## 0.5.3
|
4
10
|
* Major refactoring of archiving/unarchiving logic into nice command classes instead of big ball of ARec voodoo. Thanks, Marten Claes!
|
5
11
|
|
6
12
|
## 0.5.2
|
13
|
+
* **BREAKING CHANGE** (possibly): removed the scope constants, so if you were using them, you should stop
|
14
|
+
* **BUGFIX** fix scoping combinations with relations for Rails 4
|
7
15
|
* More changes to support Rails 4
|
8
|
-
* fix scoping combinations with relations for Rails 4
|
9
|
-
* BREAKING CHANGE (possibly): removed the scope constants, so if you were using them, you should stop
|
10
16
|
|
11
17
|
## 0.5.1
|
12
18
|
* update to use .table_name for archived scope
|
data/Gemfile.lock
CHANGED
@@ -7,28 +7,35 @@ PATH
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (
|
11
|
-
activesupport (=
|
12
|
-
builder (~> 3.
|
13
|
-
activerecord (
|
14
|
-
activemodel (=
|
15
|
-
activesupport (=
|
16
|
-
arel (~>
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
activemodel (4.1.0)
|
11
|
+
activesupport (= 4.1.0)
|
12
|
+
builder (~> 3.1)
|
13
|
+
activerecord (4.1.0)
|
14
|
+
activemodel (= 4.1.0)
|
15
|
+
activesupport (= 4.1.0)
|
16
|
+
arel (~> 5.0.0)
|
17
|
+
activesupport (4.1.0)
|
18
|
+
i18n (~> 0.6, >= 0.6.9)
|
19
|
+
json (~> 1.7, >= 1.7.7)
|
20
|
+
minitest (~> 5.1)
|
21
|
+
thread_safe (~> 0.1)
|
22
|
+
tzinfo (~> 1.1)
|
23
|
+
arel (5.0.0)
|
22
24
|
assertions-eb (1.7.3)
|
23
|
-
builder (3.
|
24
|
-
database_cleaner (1.0
|
25
|
-
highline (1.6.
|
26
|
-
i18n (0.6.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
builder (3.2.2)
|
26
|
+
database_cleaner (1.2.0)
|
27
|
+
highline (1.6.21)
|
28
|
+
i18n (0.6.9)
|
29
|
+
json (1.8.1)
|
30
|
+
minitest (5.3.2)
|
31
|
+
mysql2 (0.3.15)
|
32
|
+
pg (0.17.1)
|
33
|
+
rake (10.2.2)
|
34
|
+
rr (1.1.2)
|
35
|
+
sqlite3 (1.3.9)
|
36
|
+
thread_safe (0.3.3)
|
37
|
+
tzinfo (1.1.0)
|
38
|
+
thread_safe (~> 0.1)
|
32
39
|
|
33
40
|
PLATFORMS
|
34
41
|
ruby
|
@@ -39,5 +46,7 @@ DEPENDENCIES
|
|
39
46
|
database_cleaner
|
40
47
|
highline
|
41
48
|
mysql2
|
49
|
+
pg
|
42
50
|
rake
|
43
51
|
rr
|
52
|
+
sqlite3
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Atomically archive object trees in your activerecord models.
|
4
4
|
|
5
5
|
We had the problem that acts_as_paranoid and similar plugins/gems
|
6
|
-
always work on a record
|
6
|
+
always work on a record-by-record basis and made it very difficult to
|
7
7
|
restore records atomically (or archive them, for that matter).
|
8
8
|
|
9
9
|
Because the archive and unarchive methods are in transactions, and
|
@@ -16,60 +16,97 @@ Additionally, other plugins generally screw with how
|
|
16
16
|
to destroy records.
|
17
17
|
|
18
18
|
## Install
|
19
|
-
Rails 3.2 and up
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
or in your Gemfile
|
20
|
+
Gemfile:
|
24
21
|
|
25
22
|
`gem "acts_as_archival"`
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
`rails plugin install http://github.com/expectedbehavior/acts_as_archival.git -r rails3.0x`
|
30
|
-
|
31
|
-
Rails 2:
|
32
|
-
|
33
|
-
`script/plugin install http://github.com/expectedbehavior/acts_as_archival.git -r rails2`
|
24
|
+
Any models you want to be archival should have the columns `archive_number` (String) and `archived_at` (DateTime).
|
34
25
|
|
35
|
-
|
36
|
-
`archive_number`(String) and `archived_at` (DateTime).
|
26
|
+
i.e. `rails g migration AddAAAToPost archive_number archived_at:datetime`
|
37
27
|
|
38
|
-
|
28
|
+
Any dependent-destroy AAA model associated to an AAA model will be archived with its parent.
|
39
29
|
|
40
|
-
|
41
|
-
archived with its parent.
|
30
|
+
_If you're stuck on Rails 3.0x/2, check out the available branches._
|
42
31
|
|
43
32
|
## Example
|
44
33
|
|
45
34
|
``` ruby
|
46
35
|
class Hole < ActiveRecord::Base
|
47
36
|
acts_as_archival
|
48
|
-
has_many :
|
37
|
+
has_many :rats, :dependent => :destroy
|
49
38
|
end
|
50
39
|
|
51
|
-
class
|
40
|
+
class Rat < ActiveRecord::Base
|
52
41
|
acts_as_archival
|
53
42
|
end
|
54
43
|
```
|
55
44
|
|
45
|
+
### Simple interactions & scopes
|
46
|
+
|
47
|
+
``` ruby
|
48
|
+
h = Hole.create #
|
49
|
+
h.archived? # => false
|
50
|
+
h.archive # => true
|
51
|
+
h.archived? # => "b56876de48a5dcfe71b2c13eec15e4a2"
|
52
|
+
h.archive_number # => "b56876de48a5dcfe71b2c13eec15e4a2"
|
53
|
+
h.archived_at # => Thu, 01 Jan 2012 01:49:21 -0400
|
54
|
+
h.unarchive # => true
|
55
|
+
h.archived? # => false
|
56
|
+
h.archive_number # => nil
|
57
|
+
h.archived_at # => nil
|
58
|
+
```
|
59
|
+
|
60
|
+
### Associations
|
61
|
+
|
62
|
+
``` ruby
|
63
|
+
h = Hole.create #
|
64
|
+
r = h.rats.create #
|
65
|
+
h.archive # => true
|
66
|
+
h.archive_number # => "b56876de48a5dcfe71b2c13eec15e4a2"
|
67
|
+
r.archive_number # => "b56876de48a5dcfe71b2c13eec15e4a2"
|
68
|
+
r.archived? # => "b56876de48a5dcfe71b2c13eec15e4a2"
|
69
|
+
h.unarchive # => true
|
70
|
+
h.archive_number # => nil
|
71
|
+
r.archive_number # => nil
|
72
|
+
r.archived? # => false
|
73
|
+
```
|
74
|
+
|
75
|
+
### Scopes
|
76
|
+
|
56
77
|
``` ruby
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
h = Hole.create
|
79
|
+
Hole.archived.size # => 0
|
80
|
+
Hole.unarchived.size # => 1
|
81
|
+
h.archive
|
82
|
+
Hole.archived.size # => 1
|
83
|
+
Hole.unarchived.size # => 0
|
84
|
+
```
|
85
|
+
|
86
|
+
### Utility methods
|
87
|
+
|
88
|
+
``` ruby
|
89
|
+
h = Hole.create #
|
90
|
+
h.is_archival? # => true
|
91
|
+
Hole.is_archival? # => true
|
92
|
+
```
|
93
|
+
|
94
|
+
### Options
|
95
|
+
|
96
|
+
When defining an AAA model, it is is possible to make it unmodifiable
|
97
|
+
when it is archived by passing `:readonly_when_archived => true` to the
|
98
|
+
`acts_as_archival` call in your model.
|
99
|
+
|
100
|
+
``` ruby
|
101
|
+
class CantTouchThis < ActiveRecord::Base
|
102
|
+
acts_as_archival :readonly_when_archived => true
|
103
|
+
end
|
104
|
+
|
105
|
+
record = CantTouchThis.create(:foo => "bar")
|
106
|
+
record.archive # => true
|
107
|
+
record.foo = "I want this to work"
|
108
|
+
record.save # => false
|
109
|
+
record.errors.full_messages.first # => "Cannot modify an archived record."
|
73
110
|
```
|
74
111
|
|
75
112
|
## Caveats
|
@@ -77,33 +114,32 @@ end
|
|
77
114
|
1. This will only work on associations that are dependent destroy. It
|
78
115
|
should be trival to change that or make it optional.
|
79
116
|
1. It will only work for Rails 2.2 and up, because we are using
|
80
|
-
`named_scope`/`scope`. You can check out permanent records for a way
|
117
|
+
`named_scope`/`scope`. You can check out [permanent records](http://github.com/fastestforward/permanent_records) for a way
|
81
118
|
to conditionally add the functionality to older Rails installations.
|
82
|
-
1.
|
83
|
-
postgres, etc.).
|
119
|
+
1. If you would like to work on this, you will need to setup sqlite, postgres, and mysql on your development machine. Alternately, you can disable specific dev dependencies in the gemspec and test_helper and ask for help.
|
84
120
|
|
85
121
|
## Testing
|
86
122
|
|
87
|
-
Because this plugin makes use of transactions we're testing it on
|
88
|
-
MySQL instead of the more convenient sqlite. Running the tests should
|
89
|
-
be as easy as:
|
123
|
+
Because this plugin makes use of transactions we're testing it (mostly) on sqlite. Running the tests should be as easy as:
|
90
124
|
|
91
125
|
``` bash
|
92
|
-
bundle
|
93
|
-
test/script/db_setup
|
126
|
+
bundle # if this fails you might need to install/configure some databases
|
127
|
+
test/script/db_setup # makes the databases with the correct permissions (for mySQL)
|
128
|
+
createuser -D -A -P archival_tester # makes user for PostgreSQL; answer the password prompt with "perspicacious"
|
129
|
+
createdb -O archival_tester aaa_test # makes db for PostgreSQL and sets owner to our test user
|
94
130
|
rake
|
95
131
|
```
|
96
132
|
|
97
133
|
## Help Wanted
|
98
134
|
|
99
|
-
|
100
|
-
postgres and if not, submit a patch / let us know about it!
|
135
|
+
We'd love to have your help making this better! If you have ideas for features this should implement or you think the code sucks, let us know. And PRs are greatly appreciated. :+1:
|
101
136
|
|
102
137
|
## Thanks
|
103
138
|
|
104
139
|
ActsAsParanoid and PermanentRecords were both inspirations for this:
|
105
|
-
|
106
|
-
http://github.com/
|
140
|
+
|
141
|
+
* http://github.com/technoweenie/acts_as_paranoid
|
142
|
+
* http://github.com/fastestforward/permanent_records
|
107
143
|
|
108
144
|
## Contributors
|
109
145
|
|
data/acts_as_archival.gemspec
CHANGED
@@ -32,6 +32,8 @@ Gem::Specification.new do |gem|
|
|
32
32
|
gem.add_development_dependency "assertions-eb"
|
33
33
|
gem.add_development_dependency "rake"
|
34
34
|
gem.add_development_dependency "mysql2"
|
35
|
+
gem.add_development_dependency "sqlite3"
|
36
|
+
gem.add_development_dependency "pg"
|
35
37
|
gem.add_development_dependency "highline"
|
36
38
|
gem.add_development_dependency "rr"
|
37
39
|
gem.add_development_dependency "database_cleaner"
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require_relative "test_helper"
|
2
2
|
|
3
3
|
class AmbiguousTableTest < ActiveSupport::TestCase
|
4
|
-
# test against the problem fixed in http://github.com/DarkTatka/acts_as_archival/commit/63d0a2532a15d7a6ab41d081e1591108a5ea9b37
|
5
4
|
test "no ambiguous table problem" do
|
6
5
|
archival = Archival.create!
|
7
6
|
child = archival.archivals.create!
|
8
7
|
child.archive
|
9
8
|
|
9
|
+
# this is a bug fix for a problem wherein table names weren't being
|
10
|
+
# namespaced, so if a table joined against itself, incorrect SQL was
|
11
|
+
# generated
|
10
12
|
assert_equal 1, Archival.unarchived.joins(:archivals).count
|
11
13
|
end
|
12
14
|
end
|
data/test/associations_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative "test_helper"
|
2
2
|
|
3
|
-
class
|
3
|
+
class AssociationsTest < ActiveSupport::TestCase
|
4
4
|
test "archive archives 'has_' associated archival objects that are dependent destroy" do
|
5
5
|
archival = Archival.create!
|
6
6
|
child = archival.archivals.create!
|
data/test/basic_test.rb
CHANGED
@@ -3,33 +3,35 @@ require_relative "test_helper"
|
|
3
3
|
class BasicTest < ActiveSupport::TestCase
|
4
4
|
test "archive archives the record" do
|
5
5
|
archival = Archival.create!
|
6
|
-
|
7
6
|
archival.archive
|
8
|
-
assert archival.archived?
|
7
|
+
assert archival.reload.archived?
|
9
8
|
end
|
10
9
|
|
11
10
|
test "unarchive unarchives archival records" do
|
12
11
|
archival = Archival.create!(:archived_at => Time.now, :archive_number => 1)
|
13
12
|
archival.unarchive
|
13
|
+
assert_not archival.reload.archived?
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
+
test "archive returns true on success" do
|
17
|
+
normal = Archival.create!
|
18
|
+
assert_equal true, normal.archive
|
16
19
|
end
|
17
20
|
|
18
|
-
test "archive returns
|
19
|
-
archival = Archival.create!
|
21
|
+
test "archive returns false on failure" do
|
20
22
|
readonly = Archival.create!
|
21
23
|
readonly.readonly!
|
22
|
-
|
23
|
-
assert_equal true, archival.archive
|
24
24
|
assert_equal false, readonly.archive
|
25
25
|
end
|
26
26
|
|
27
|
-
test "unarchive returns true on success
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
test "unarchive returns true on success" do
|
28
|
+
normal = Archival.create!(:archived_at => Time.now, :archive_number => "1")
|
29
|
+
assert_equal true, normal.unarchive
|
30
|
+
end
|
31
31
|
|
32
|
-
|
32
|
+
test "unarchive returns false on failure" do
|
33
|
+
readonly = Archival.create!(:archived_at => Time.now, :archive_number => "1")
|
34
|
+
readonly.readonly!
|
33
35
|
assert_equal false, readonly.unarchive
|
34
36
|
end
|
35
37
|
|
@@ -47,7 +49,6 @@ class BasicTest < ActiveSupport::TestCase
|
|
47
49
|
test "archive sets the archive number to the md5 hexdigest for the model and id that is archived" do
|
48
50
|
archival = Archival.create!
|
49
51
|
archival.archive
|
50
|
-
|
51
52
|
expected_digest = Digest::MD5.hexdigest("#{archival.class.name}#{archival.id}")
|
52
53
|
assert_equal expected_digest, archival.archive_number
|
53
54
|
end
|
@@ -58,7 +59,6 @@ class BasicTest < ActiveSupport::TestCase
|
|
58
59
|
initial_number = archived.archive_number
|
59
60
|
archived.reload.archive
|
60
61
|
second_number = archived.archive_number
|
61
|
-
|
62
62
|
assert_equal initial_number, second_number
|
63
63
|
end
|
64
64
|
end
|
data/test/database.yml
CHANGED
@@ -1,8 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
sqlite:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: aaa_test.sqlite3
|
4
|
+
pool: 5
|
5
|
+
timeout: 5000
|
6
|
+
|
7
|
+
mysql:
|
8
|
+
adapter: mysql2
|
9
|
+
pool: 5
|
10
|
+
timeout: 5000
|
11
|
+
encoding: utf8
|
12
|
+
reconnect: false
|
13
|
+
database: aaa_test
|
14
|
+
username: archival_tester
|
15
|
+
password: perspicacious
|
16
|
+
socket: /tmp/mysql.sock
|
17
|
+
|
18
|
+
pg:
|
19
|
+
adapter: postgresql
|
20
|
+
pool: 5
|
21
|
+
timeout: 5000
|
22
|
+
encoding: utf8
|
23
|
+
database: aaa_test
|
24
|
+
username: archival_tester
|
25
|
+
password: perspicacious
|
26
|
+
min_messages: WARNING
|
data/test/deep_nesting_test.rb
CHANGED
@@ -2,14 +2,15 @@ require_relative "test_helper"
|
|
2
2
|
|
3
3
|
class DeepNestingTest < ActiveSupport::TestCase
|
4
4
|
test "archiving deeply nested items" do
|
5
|
-
archival
|
6
|
-
child
|
5
|
+
archival = Archival.create!
|
6
|
+
child = archival.archivals.create!
|
7
7
|
grandchild = child.archivals.create!
|
8
8
|
archival.archive
|
9
|
-
|
10
9
|
assert archival.reload.archived?
|
11
10
|
assert child.reload.archived?
|
12
11
|
assert grandchild.reload.archived?
|
12
|
+
assert_equal archival.archive_number, child.archive_number
|
13
|
+
assert_equal archival.archive_number, grandchild.archive_number
|
13
14
|
end
|
14
15
|
|
15
16
|
test "unarchiving deeply nested items doesn't blow up" do
|
@@ -17,11 +18,10 @@ class DeepNestingTest < ActiveSupport::TestCase
|
|
17
18
|
:archived_at => Time.now,
|
18
19
|
:archive_number => "test"
|
19
20
|
}
|
20
|
-
archival
|
21
|
-
child
|
21
|
+
archival = Archival.create!(archival_attributes)
|
22
|
+
child = archival.archivals.create!(archival_attributes)
|
22
23
|
grandchild = child.archivals.create!(archival_attributes)
|
23
24
|
archival.unarchive
|
24
|
-
|
25
25
|
assert_not archival.reload.archived?
|
26
26
|
assert_not child.reload.archived?
|
27
27
|
assert_not grandchild.reload.archived?
|
data/test/fixtures/exploder.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
# name - string
|
2
|
+
# archival_id - integer
|
3
|
+
# archive_number - string
|
4
|
+
# archived_at - datetime
|
5
|
+
class MysqlArchival < ActiveRecord::Base
|
6
|
+
establish_connection $dbconfig["mysql"]
|
7
|
+
self.table_name = "archivals"
|
8
|
+
acts_as_archival
|
9
|
+
has_many :exploders, :dependent => :destroy, :foreign_key => :archival_id, :class_name => "MysqlExploder"
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# archival_id - integer
|
2
|
+
# archive_number - string
|
3
|
+
# archived_at - datetime
|
4
|
+
class MysqlExploder < ActiveRecord::Base
|
5
|
+
establish_connection $dbconfig["mysql"]
|
6
|
+
self.table_name = "exploders"
|
7
|
+
acts_as_archival
|
8
|
+
belongs_to :mysql_archival, :foreign_key => :archival_id
|
9
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# name - string
|
2
|
+
# archival_id - integer
|
3
|
+
# archive_number - string
|
4
|
+
# archived_at - datetime
|
5
|
+
class PgArchival < ActiveRecord::Base
|
6
|
+
establish_connection $dbconfig["pg"]
|
7
|
+
self.table_name = "archivals"
|
8
|
+
acts_as_archival
|
9
|
+
has_many :exploders, :dependent => :destroy, :foreign_key => :archival_id, :class_name => "PgExploder"
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# archival_id - integer
|
2
|
+
# archive_number - string
|
3
|
+
# archived_at - datetime
|
4
|
+
class PgExploder < ActiveRecord::Base
|
5
|
+
establish_connection $dbconfig["pg"]
|
6
|
+
self.table_name = "exploders"
|
7
|
+
acts_as_archival
|
8
|
+
belongs_to :pg_archival, :foreign_key => :archival_id
|
9
|
+
end
|
data/test/fixtures/poly.rb
CHANGED
data/test/schema.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
ActiveRecord::Schema.define(:version => 1) do
|
2
|
-
|
3
2
|
create_table :archivals, :force => true do |t|
|
4
3
|
t.column :name, :string
|
5
4
|
t.column :archival_id, :integer
|
@@ -7,67 +6,69 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
7
6
|
t.column :archived_at, :datetime
|
8
7
|
end
|
9
8
|
|
10
|
-
create_table :
|
9
|
+
create_table :exploders, :force => true do |t|
|
11
10
|
t.column :archival_id, :integer
|
12
11
|
t.column :archive_number, :string
|
13
12
|
t.column :archived_at, :datetime
|
14
13
|
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
if "SQLite" == ActiveRecord::Base.connection.adapter_name
|
16
|
+
create_table :archival_kids, :force => true do |t|
|
17
|
+
t.column :archival_id, :integer
|
18
|
+
t.column :archive_number, :string
|
19
|
+
t.column :archived_at, :datetime
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
create_table :archival_grandkids, :force => true do |t|
|
23
|
+
t.column :archival_kid_id, :integer
|
24
|
+
t.column :archive_number, :string
|
25
|
+
t.column :archived_at, :datetime
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
create_table :independent_archivals, :force => true do |t|
|
29
|
+
t.column :name, :string
|
30
|
+
t.column :archival_id, :integer
|
31
|
+
t.column :archive_number, :string
|
32
|
+
t.column :archived_at, :datetime
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
create_table :plains, :force => true do |t|
|
36
|
+
t.column :name, :string
|
37
|
+
t.column :archival_id, :integer
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
create_table :mass_attribute_protecteds, :force => true do |t|
|
41
|
+
t.column :name, :string
|
42
|
+
t.column :archive_number, :string
|
43
|
+
t.column :archived_at, :datetime
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
create_table :readonly_when_archiveds, :force => true do |t|
|
47
|
+
t.column :name, :string
|
48
|
+
t.column :archive_number, :string
|
49
|
+
t.column :archived_at, :datetime
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
create_table :missing_archived_ats, :force => true do |t|
|
53
|
+
t.column :name, :string
|
54
|
+
t.column :archive_number, :string
|
55
|
+
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
create_table :missing_archive_numbers, :force => true do |t|
|
58
|
+
t.column :name, :string
|
59
|
+
t.column :archived_at, :datetime
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
create_table :polys, :force => true do |t|
|
63
|
+
t.references :archiveable, :polymorphic => true
|
64
|
+
t.column :archive_number, :string
|
65
|
+
t.column :archived_at, :datetime
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
create_table :legacy, :force => true do |t|
|
69
|
+
t.column :name, :string
|
70
|
+
t.column :archive_number, :string
|
71
|
+
t.column :archived_at, :datetime
|
72
|
+
end
|
72
73
|
end
|
73
74
|
end
|
data/test/scope_test.rb
CHANGED
@@ -49,15 +49,18 @@ class ScopeTest < ActiveSupport::TestCase
|
|
49
49
|
end
|
50
50
|
|
51
51
|
test "table_name is set to 'legacy'" do
|
52
|
-
|
53
|
-
|
52
|
+
archived_sql = %Q{SELECT "legacy".* FROM "legacy" WHERE (legacy.archived_at IS NOT NULL AND legacy.archive_number IS NOT NULL)}
|
53
|
+
unarchived_sql = %Q{SELECT "legacy".* FROM "legacy" WHERE "legacy"."archived_at" IS NULL AND "legacy"."archive_number" IS NULL}
|
54
|
+
assert_equal archived_sql, ArchivalTableName.archived.to_sql
|
55
|
+
assert_equal unarchived_sql, ArchivalTableName.unarchived.to_sql
|
54
56
|
end
|
55
57
|
|
56
58
|
test "combines with other scope properly" do
|
57
59
|
Archival.create!(:name => "Robert")
|
58
60
|
Archival.create!(:name => "Bobby")
|
59
61
|
Archival.create!(:name => "Sue")
|
60
|
-
Archival.create!(:name => "Bob")
|
62
|
+
bob = Archival.create!(:name => "Bob")
|
63
|
+
bob.archive
|
61
64
|
assert_equal 3, Archival.bobs.count
|
62
65
|
assert_equal 3, Archival.unarchived.count
|
63
66
|
assert_equal 2, Archival.bobs.unarchived.count
|
@@ -70,7 +73,8 @@ class ScopeTest < ActiveSupport::TestCase
|
|
70
73
|
parent = Archival.create!
|
71
74
|
parent.archivals.create!
|
72
75
|
parent.archivals.create!
|
73
|
-
parent.archivals.create
|
76
|
+
child = parent.archivals.create!
|
77
|
+
child.archive
|
74
78
|
assert_equal 3, parent.archivals.count
|
75
79
|
assert_equal 1, parent.archivals.archived.count
|
76
80
|
assert_equal 2, parent.archivals.unarchived.count
|
data/test/script/db_setup
CHANGED
@@ -5,7 +5,7 @@ require 'highline/import'
|
|
5
5
|
|
6
6
|
def read_database_config
|
7
7
|
database_file = File.join(File.dirname(__FILE__), "/../", "database.yml")
|
8
|
-
$DB_CONFIG = YAML.load(File.read(database_file))
|
8
|
+
$DB_CONFIG = YAML.load(File.read(database_file))["mysql"]
|
9
9
|
end
|
10
10
|
|
11
11
|
def get_root_password
|
data/test/test_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
2
|
require "bundler/setup"
|
3
|
-
require "
|
3
|
+
require "minitest/autorun"
|
4
4
|
|
5
5
|
require "active_record"
|
6
6
|
require "assertions"
|
@@ -9,7 +9,7 @@ require "database_cleaner"
|
|
9
9
|
require "acts_as_archival"
|
10
10
|
|
11
11
|
def prepare_for_tests
|
12
|
-
setup_logging if ENV["LOGGING_ENABLED"]
|
12
|
+
setup_logging# if ENV["LOGGING_ENABLED"]
|
13
13
|
setup_active_record
|
14
14
|
setup_database_cleaner
|
15
15
|
create_test_tables
|
@@ -24,8 +24,7 @@ end
|
|
24
24
|
|
25
25
|
def setup_active_record
|
26
26
|
dbconfig_file = File.dirname(__FILE__) + "/database.yml"
|
27
|
-
dbconfig = YAML.load
|
28
|
-
ActiveRecord::Base.establish_connection(dbconfig)
|
27
|
+
$dbconfig = YAML.load(File.read(dbconfig_file))
|
29
28
|
end
|
30
29
|
|
31
30
|
def setup_database_cleaner
|
@@ -36,8 +35,12 @@ def setup_database_cleaner
|
|
36
35
|
end
|
37
36
|
|
38
37
|
def create_test_tables
|
39
|
-
schema_file
|
40
|
-
|
38
|
+
schema_file = File.dirname(__FILE__) + "/schema.rb"
|
39
|
+
["pg", "mysql", "sqlite"].each do |db|
|
40
|
+
puts "** Loading schema for #{db}"
|
41
|
+
ActiveRecord::Base.establish_connection($dbconfig[db])
|
42
|
+
load(schema_file) if File.exist?(schema_file)
|
43
|
+
end
|
41
44
|
end
|
42
45
|
|
43
46
|
def require_test_classes
|
@@ -54,8 +57,12 @@ def require_test_classes
|
|
54
57
|
:plain,
|
55
58
|
:missing_archived_at,
|
56
59
|
:missing_archive_number,
|
60
|
+
:mysql_archival,
|
61
|
+
:mysql_exploder,
|
57
62
|
:plain,
|
58
63
|
:poly,
|
64
|
+
:pg_archival,
|
65
|
+
:pg_exploder,
|
59
66
|
:readonly_when_archived]
|
60
67
|
$require_mass_protection = ActiveModel.constants.include?(:MassAssignmentSecurity)
|
61
68
|
fixtures << :mass_attribute_protected if $require_mass_protection
|
data/test/transaction_test.rb
CHANGED
@@ -4,7 +4,7 @@ require "rr"
|
|
4
4
|
class TransactionTest < ActiveSupport::TestCase
|
5
5
|
include RR::Adapters::TestUnit
|
6
6
|
|
7
|
-
test "archiving is transactional" do
|
7
|
+
test "sqlite archiving is transactional" do
|
8
8
|
archival = Archival.create!
|
9
9
|
exploder = archival.exploders.create!
|
10
10
|
any_instance_of(Exploder) do |exploder|
|
@@ -16,7 +16,7 @@ class TransactionTest < ActiveSupport::TestCase
|
|
16
16
|
assert_not exploder.reload.archived?
|
17
17
|
end
|
18
18
|
|
19
|
-
test "unarchiving is transactional" do
|
19
|
+
test "sqlite unarchiving is transactional" do
|
20
20
|
archival = Archival.create!
|
21
21
|
exploder = archival.exploders.create!
|
22
22
|
any_instance_of(Exploder) do |exploder|
|
@@ -29,4 +29,55 @@ class TransactionTest < ActiveSupport::TestCase
|
|
29
29
|
assert exploder.reload.archived?
|
30
30
|
end
|
31
31
|
|
32
|
+
test "mysql archiving is transactional" do
|
33
|
+
archival = MysqlArchival.create!
|
34
|
+
exploder = archival.exploders.create!
|
35
|
+
any_instance_of(MysqlExploder) do |exploder|
|
36
|
+
stub(exploder).unarchive { raise "Rollback Imminent" }
|
37
|
+
end
|
38
|
+
archival.archive
|
39
|
+
archival.unarchive
|
40
|
+
|
41
|
+
assert archival.reload.archived?
|
42
|
+
assert exploder.reload.archived?
|
43
|
+
end
|
44
|
+
|
45
|
+
test "mysql unarchiving is transactional" do
|
46
|
+
archival = MysqlArchival.create!
|
47
|
+
exploder = archival.exploders.create!
|
48
|
+
any_instance_of(MysqlExploder) do |exploder|
|
49
|
+
stub(exploder).unarchive { raise "Rollback Imminent" }
|
50
|
+
end
|
51
|
+
archival.archive
|
52
|
+
archival.unarchive
|
53
|
+
|
54
|
+
assert archival.reload.archived?
|
55
|
+
assert exploder.reload.archived?
|
56
|
+
end
|
57
|
+
|
58
|
+
test "postgres archiving is transactional" do
|
59
|
+
archival = MysqlArchival.create!
|
60
|
+
exploder = archival.exploders.create!
|
61
|
+
any_instance_of(MysqlExploder) do |exploder|
|
62
|
+
stub(exploder).unarchive { raise "Rollback Imminent" }
|
63
|
+
end
|
64
|
+
archival.archive
|
65
|
+
archival.unarchive
|
66
|
+
|
67
|
+
assert archival.reload.archived?
|
68
|
+
assert exploder.reload.archived?
|
69
|
+
end
|
70
|
+
|
71
|
+
test "postgres unarchiving is transactional" do
|
72
|
+
archival = MysqlArchival.create!
|
73
|
+
exploder = archival.exploders.create!
|
74
|
+
any_instance_of(MysqlExploder) do |exploder|
|
75
|
+
stub(exploder).unarchive { raise "Rollback Imminent" }
|
76
|
+
end
|
77
|
+
archival.archive
|
78
|
+
archival.unarchive
|
79
|
+
|
80
|
+
assert archival.reload.archived?
|
81
|
+
assert exploder.reload.archived?
|
82
|
+
end
|
32
83
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_archival
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -17,7 +17,7 @@ authors:
|
|
17
17
|
autorequire:
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
|
-
date:
|
20
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: activerecord
|
@@ -83,6 +83,38 @@ dependencies:
|
|
83
83
|
- - ! '>='
|
84
84
|
- !ruby/object:Gem::Version
|
85
85
|
version: '0'
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: sqlite3
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: pg
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
86
118
|
- !ruby/object:Gem::Dependency
|
87
119
|
name: highline
|
88
120
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,7 +199,6 @@ extensions: []
|
|
167
199
|
extra_rdoc_files: []
|
168
200
|
files:
|
169
201
|
- .gitignore
|
170
|
-
- .rvmrc
|
171
202
|
- CHANGELOG.md
|
172
203
|
- Gemfile
|
173
204
|
- Gemfile.lock
|
@@ -198,6 +229,10 @@ files:
|
|
198
229
|
- test/fixtures/mass_attribute_protected.rb
|
199
230
|
- test/fixtures/missing_archive_number.rb
|
200
231
|
- test/fixtures/missing_archived_at.rb
|
232
|
+
- test/fixtures/mysql_archival.rb
|
233
|
+
- test/fixtures/mysql_exploder.rb
|
234
|
+
- test/fixtures/pg_archival.rb
|
235
|
+
- test/fixtures/pg_exploder.rb
|
201
236
|
- test/fixtures/plain.rb
|
202
237
|
- test/fixtures/poly.rb
|
203
238
|
- test/fixtures/readonly_when_archived.rb
|
@@ -251,6 +286,10 @@ test_files:
|
|
251
286
|
- test/fixtures/mass_attribute_protected.rb
|
252
287
|
- test/fixtures/missing_archive_number.rb
|
253
288
|
- test/fixtures/missing_archived_at.rb
|
289
|
+
- test/fixtures/mysql_archival.rb
|
290
|
+
- test/fixtures/mysql_exploder.rb
|
291
|
+
- test/fixtures/pg_archival.rb
|
292
|
+
- test/fixtures/pg_exploder.rb
|
254
293
|
- test/fixtures/plain.rb
|
255
294
|
- test/fixtures/poly.rb
|
256
295
|
- test/fixtures/readonly_when_archived.rb
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm ruby-1.9.3-p125@aaa --create
|