acts_as_archive 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- metadata +130 -43
- data/MIT-LICENSE +0 -18
- data/README.markdown +0 -119
- data/Rakefile +0 -9
- data/bin/acts_as_archive +0 -2
- data/init.rb +0 -1
- data/lib/acts_as_archive.rb +0 -19
- data/lib/acts_as_archive/base.rb +0 -31
- data/lib/acts_as_archive/base/adapters/mysql.rb +0 -17
- data/lib/acts_as_archive/base/adapters/postgresql.rb +0 -40
- data/lib/acts_as_archive/base/destroy.rb +0 -71
- data/lib/acts_as_archive/base/restore.rb +0 -36
- data/lib/acts_as_archive/base/table.rb +0 -109
- data/lib/acts_as_archive/migration.rb +0 -49
- data/rails/init.rb +0 -5
- data/require.rb +0 -49
- data/spec/acts_as_archive/base/destroy_spec.rb +0 -117
- data/spec/acts_as_archive/base/restore_spec.rb +0 -58
- data/spec/acts_as_archive/base/table_spec.rb +0 -74
- data/spec/acts_as_archive/base_spec.rb +0 -24
- data/spec/acts_as_archive/migration_spec.rb +0 -37
- data/spec/db/config/database.mysql.yml +0 -6
- data/spec/db/config/database.postgresql.yml +0 -6
- data/spec/db/migrate/001_add_to_articles.rb +0 -9
- data/spec/db/migrate_2/001_add_to_articles.rb +0 -9
- data/spec/db/models/article.rb +0 -3
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -88
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_archive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Winton Welsh
|
@@ -9,55 +15,130 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-01-04 00:00:00 -08:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
22
|
+
name: also_migrate
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - "="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 19
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 2
|
33
|
+
- 2
|
34
|
+
version: 0.2.2
|
17
35
|
type: :runtime
|
18
|
-
|
19
|
-
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: mover
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - "="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 25
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 3
|
49
|
+
- 5
|
50
|
+
version: 0.3.5
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: active_wrapper-solo
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - "="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 13
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 4
|
65
|
+
- 1
|
66
|
+
version: 0.4.1
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: externals
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
20
74
|
requirements:
|
21
75
|
- - "="
|
22
76
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
25
|
-
|
77
|
+
hash: 19
|
78
|
+
segments:
|
79
|
+
- 1
|
80
|
+
- 0
|
81
|
+
- 2
|
82
|
+
version: 1.0.2
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: framework_fixture
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - "="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 29
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
- 1
|
97
|
+
- 3
|
98
|
+
version: 0.1.3
|
99
|
+
type: :development
|
100
|
+
version_requirements: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: rake
|
103
|
+
prerelease: false
|
104
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 49
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
- 8
|
113
|
+
- 7
|
114
|
+
version: 0.8.7
|
115
|
+
type: :development
|
116
|
+
version_requirements: *id006
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rspec
|
119
|
+
prerelease: false
|
120
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 15
|
126
|
+
segments:
|
127
|
+
- 1
|
128
|
+
- 0
|
129
|
+
version: "1.0"
|
130
|
+
type: :development
|
131
|
+
version_requirements: *id007
|
132
|
+
description: Don't delete your records, move them to a different table. Like acts_as_paranoid, but doesn't mess with your SQL queries.
|
26
133
|
email: mail@wintoni.us
|
27
|
-
executables:
|
28
|
-
|
134
|
+
executables: []
|
135
|
+
|
29
136
|
extensions: []
|
30
137
|
|
31
|
-
extra_rdoc_files:
|
32
|
-
|
33
|
-
files:
|
34
|
-
|
35
|
-
- init.rb
|
36
|
-
- lib/acts_as_archive/base/adapters/mysql.rb
|
37
|
-
- lib/acts_as_archive/base/adapters/postgresql.rb
|
38
|
-
- lib/acts_as_archive/base/destroy.rb
|
39
|
-
- lib/acts_as_archive/base/restore.rb
|
40
|
-
- lib/acts_as_archive/base/table.rb
|
41
|
-
- lib/acts_as_archive/base.rb
|
42
|
-
- lib/acts_as_archive/migration.rb
|
43
|
-
- lib/acts_as_archive.rb
|
44
|
-
- MIT-LICENSE
|
45
|
-
- rails/init.rb
|
46
|
-
- Rakefile
|
47
|
-
- README.markdown
|
48
|
-
- require.rb
|
49
|
-
- spec/acts_as_archive/base/destroy_spec.rb
|
50
|
-
- spec/acts_as_archive/base/restore_spec.rb
|
51
|
-
- spec/acts_as_archive/base/table_spec.rb
|
52
|
-
- spec/acts_as_archive/base_spec.rb
|
53
|
-
- spec/acts_as_archive/migration_spec.rb
|
54
|
-
- spec/db/config/database.mysql.yml
|
55
|
-
- spec/db/config/database.postgresql.yml
|
56
|
-
- spec/db/migrate/001_add_to_articles.rb
|
57
|
-
- spec/db/migrate_2/001_add_to_articles.rb
|
58
|
-
- spec/db/models/article.rb
|
59
|
-
- spec/spec.opts
|
60
|
-
- spec/spec_helper.rb
|
138
|
+
extra_rdoc_files: []
|
139
|
+
|
140
|
+
files: []
|
141
|
+
|
61
142
|
has_rdoc: true
|
62
143
|
homepage: http://github.com/winton/acts_as_archive
|
63
144
|
licenses: []
|
@@ -68,21 +149,27 @@ rdoc_options: []
|
|
68
149
|
require_paths:
|
69
150
|
- lib
|
70
151
|
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
71
153
|
requirements:
|
72
154
|
- - ">="
|
73
155
|
- !ruby/object:Gem::Version
|
156
|
+
hash: 3
|
157
|
+
segments:
|
158
|
+
- 0
|
74
159
|
version: "0"
|
75
|
-
version:
|
76
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
77
162
|
requirements:
|
78
163
|
- - ">="
|
79
164
|
- !ruby/object:Gem::Version
|
165
|
+
hash: 3
|
166
|
+
segments:
|
167
|
+
- 0
|
80
168
|
version: "0"
|
81
|
-
version:
|
82
169
|
requirements: []
|
83
170
|
|
84
171
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.3.
|
172
|
+
rubygems_version: 1.3.7
|
86
173
|
signing_key:
|
87
174
|
specification_version: 3
|
88
175
|
summary: Don't delete your records, move them to a different table
|
data/MIT-LICENSE
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
Copyright (c) 2009 Winton Welsh
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
-
this software and associated documentation files (the "Software"), to deal in
|
5
|
-
the Software without restriction, including without limitation the rights to
|
6
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
-
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
-
subject to the following conditions:
|
9
|
-
|
10
|
-
The above copyright notice and this permission notice shall be included in all
|
11
|
-
copies or substantial portions of the Software.
|
12
|
-
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
ActsAsArchive
|
2
|
-
=============
|
3
|
-
|
4
|
-
Don't delete your records, move them to a different table.
|
5
|
-
|
6
|
-
Like <code>acts\_as\_paranoid</code>, but doesn't mess with your SQL queries.
|
7
|
-
|
8
|
-
Install
|
9
|
-
-------
|
10
|
-
|
11
|
-
<pre>
|
12
|
-
sudo gem install acts_as_archive
|
13
|
-
</pre>
|
14
|
-
|
15
|
-
**environment.rb**:
|
16
|
-
|
17
|
-
<pre>
|
18
|
-
config.gem 'acts_as_archive'
|
19
|
-
</pre>
|
20
|
-
|
21
|
-
Update models
|
22
|
-
-------------
|
23
|
-
|
24
|
-
Add <code>acts\_as\_archive</code> to your models:
|
25
|
-
|
26
|
-
<pre>
|
27
|
-
class Article < ActiveRecord::Base
|
28
|
-
acts_as_archive
|
29
|
-
end
|
30
|
-
</pre>
|
31
|
-
|
32
|
-
<a name="create_archive_tables"></a>
|
33
|
-
|
34
|
-
Create archive tables
|
35
|
-
---------------------
|
36
|
-
|
37
|
-
Add this line to a migration:
|
38
|
-
|
39
|
-
<pre>
|
40
|
-
ActsAsArchive.update Article, Comment
|
41
|
-
</pre>
|
42
|
-
|
43
|
-
Replace <code>Article, Comment</code> with your own models that use <code>acts_as_archive</code>.
|
44
|
-
|
45
|
-
Archive tables mirror your table's structure, but with an additional <code>deleted_at</code> column.
|
46
|
-
|
47
|
-
There is an [alternate way to create archive tables](http://wiki.github.com/winton/acts_as_archive/alternatives-to-migrations) if you don't like migrations.
|
48
|
-
|
49
|
-
That's it!
|
50
|
-
----------
|
51
|
-
|
52
|
-
Use <code>destroy</code>, <code>delete</code>, and <code>delete_all</code> like you normally would.
|
53
|
-
|
54
|
-
Records move into the archive table instead of being destroyed.
|
55
|
-
|
56
|
-
What if my schema changes?
|
57
|
-
--------------------------
|
58
|
-
|
59
|
-
New migrations are automatically applied to the archive table.
|
60
|
-
|
61
|
-
No action is necessary on your part.
|
62
|
-
|
63
|
-
Query the archive
|
64
|
-
-----------------
|
65
|
-
|
66
|
-
Add <code>::Archive</code> to your ActiveRecord class:
|
67
|
-
|
68
|
-
<pre>
|
69
|
-
Article::Archive.find(:first)
|
70
|
-
</pre>
|
71
|
-
|
72
|
-
Restore from the archive
|
73
|
-
------------------------
|
74
|
-
|
75
|
-
Use <code>restore\_all</code> to copy archived records back to your table:
|
76
|
-
|
77
|
-
<pre>
|
78
|
-
Article.restore_all([ 'id = ?', 1 ])
|
79
|
-
</pre>
|
80
|
-
|
81
|
-
Auto-migrate from acts\_as\_paranoid
|
82
|
-
------------------------------------
|
83
|
-
|
84
|
-
If you previously used <code>acts\_as\_paranoid</code>, the <code>ActsAsArchive.update</code>
|
85
|
-
call will automatically move your deleted records to the archive table
|
86
|
-
(see <a href="#create_archive_tables">_Create archive tables_</a>).
|
87
|
-
|
88
|
-
Original <code>deleted_at</code> values are preserved.
|
89
|
-
|
90
|
-
Add indexes to the archive table
|
91
|
-
--------------------------------
|
92
|
-
|
93
|
-
To keep insertions fast, there are no indexes on your archive table by default.
|
94
|
-
|
95
|
-
If you are querying your archive a lot, you will want to add indexes:
|
96
|
-
|
97
|
-
<pre>
|
98
|
-
class Article < ActiveRecord::Base
|
99
|
-
acts_as_archive :indexes => [ :id, :created_at, :deleted_at ]
|
100
|
-
end
|
101
|
-
</pre>
|
102
|
-
|
103
|
-
Call <code>ActsAsArchive.update</code> upon adding new indexes
|
104
|
-
(see <a href="#create_archive_tables">_Create archive tables_</a>).
|
105
|
-
|
106
|
-
Delete records without archiving
|
107
|
-
--------------------------------
|
108
|
-
|
109
|
-
To destroy a record without archiving:
|
110
|
-
|
111
|
-
<pre>
|
112
|
-
article.destroy!
|
113
|
-
</pre>
|
114
|
-
|
115
|
-
To delete multiple records without archiving:
|
116
|
-
|
117
|
-
<pre>
|
118
|
-
Article.delete_all!(["id in (?)", [1,2,3]])
|
119
|
-
</pre>
|
data/Rakefile
DELETED
data/bin/acts_as_archive
DELETED
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + "/rails/init"
|
data/lib/acts_as_archive.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require File.expand_path("#{File.dirname(__FILE__)}/../require")
|
2
|
-
Require.lib!
|
3
|
-
|
4
|
-
module ActsAsArchive
|
5
|
-
|
6
|
-
def self.update(*models)
|
7
|
-
models.each do |klass|
|
8
|
-
if klass.respond_to?(:acts_as_archive?) && klass.acts_as_archive?
|
9
|
-
time = Benchmark.measure do
|
10
|
-
klass.create_archive_table
|
11
|
-
klass.migrate_from_acts_as_paranoid
|
12
|
-
klass.create_archive_indexes
|
13
|
-
end
|
14
|
-
$stdout.puts "-- ActsAsArchive.update(#{models.join(', ')})"
|
15
|
-
$stdout.puts " -> #{"%.4fs" % time.real}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/lib/acts_as_archive/base.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
|
3
|
-
module Base
|
4
|
-
def self.included(base)
|
5
|
-
base.extend ActMethods
|
6
|
-
end
|
7
|
-
|
8
|
-
module ActMethods
|
9
|
-
def acts_as_archive(options={})
|
10
|
-
class_eval <<-end_eval
|
11
|
-
|
12
|
-
def self.acts_as_archive?
|
13
|
-
self.to_s == #{self.to_s.inspect}
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.archive_indexes
|
17
|
-
#{Array(options[:indexes]).collect(&:to_s).inspect}
|
18
|
-
end
|
19
|
-
|
20
|
-
class Archive < ActiveRecord::Base
|
21
|
-
self.record_timestamps = false
|
22
|
-
self.table_name = "archived_#{self.table_name}"
|
23
|
-
end
|
24
|
-
end_eval
|
25
|
-
include Destroy
|
26
|
-
include Restore
|
27
|
-
include Table
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
module Base
|
3
|
-
module Adapters
|
4
|
-
module MySQL
|
5
|
-
|
6
|
-
private
|
7
|
-
|
8
|
-
def archive_table_indexed_columns
|
9
|
-
index_query = "SHOW INDEX FROM archived_#{table_name}"
|
10
|
-
indexes = connection.select_all(index_query).collect do |r|
|
11
|
-
r["Column_name"]
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
module Base
|
3
|
-
module Adapters
|
4
|
-
module PostgreSQL
|
5
|
-
|
6
|
-
private
|
7
|
-
|
8
|
-
def archive_table_indexed_columns
|
9
|
-
# This query comes courtesy of cope360:
|
10
|
-
# http://stackoverflow.com/questions/2204058/show-which-columns-an-index-is-on-in-postgresql/2213199#2213199
|
11
|
-
index_query = <<-SQL
|
12
|
-
select
|
13
|
-
t.relname as table_name,
|
14
|
-
i.relname as index_name,
|
15
|
-
a.attname as column_name
|
16
|
-
from
|
17
|
-
pg_class t,
|
18
|
-
pg_class i,
|
19
|
-
pg_index ix,
|
20
|
-
pg_attribute a
|
21
|
-
where
|
22
|
-
t.oid = ix.indrelid
|
23
|
-
and i.oid = ix.indexrelid
|
24
|
-
and a.attrelid = t.oid
|
25
|
-
and a.attnum = ANY(ix.indkey)
|
26
|
-
and t.relkind = 'r'
|
27
|
-
and t.relname = 'archived_#{table_name}'
|
28
|
-
order by
|
29
|
-
t.relname,
|
30
|
-
i.relname
|
31
|
-
SQL
|
32
|
-
|
33
|
-
indexes = connection.select_all(index_query).collect do |r|
|
34
|
-
r["column_name"]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
module Base
|
3
|
-
module Destroy
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
unless base.included_modules.include?(InstanceMethods)
|
7
|
-
base.class_eval do
|
8
|
-
alias_method :destroy_without_callbacks!, :destroy_without_callbacks
|
9
|
-
class <<self
|
10
|
-
alias_method :delete_all!, :delete_all
|
11
|
-
end
|
12
|
-
end
|
13
|
-
base.send :extend, ClassMethods
|
14
|
-
base.send :include, InstanceMethods
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
module ClassMethods
|
19
|
-
def copy_to_archive(conditions, import=false)
|
20
|
-
add_conditions!(where = '', conditions)
|
21
|
-
insert_cols = column_names.clone
|
22
|
-
select_cols = column_names.clone
|
23
|
-
if insert_cols.include?('deleted_at')
|
24
|
-
unless import
|
25
|
-
select_cols[select_cols.index('deleted_at')] = "'#{Time.now.utc.to_s(:db)}'"
|
26
|
-
end
|
27
|
-
else
|
28
|
-
insert_cols << 'deleted_at'
|
29
|
-
select_cols << "'#{Time.now.utc.to_s(:db)}'"
|
30
|
-
end
|
31
|
-
|
32
|
-
insert_cols.map! { |col| connection.quote_column_name(col) }
|
33
|
-
select_cols.map! { |col| col =~ /^\'/ ? col : connection.quote_column_name(col) }
|
34
|
-
|
35
|
-
connection.execute(%{
|
36
|
-
INSERT INTO archived_#{table_name} (#{insert_cols.join(', ')})
|
37
|
-
SELECT #{select_cols.join(', ')}
|
38
|
-
FROM #{table_name}
|
39
|
-
#{where}
|
40
|
-
})
|
41
|
-
connection.execute("DELETE FROM #{table_name} #{where}")
|
42
|
-
end
|
43
|
-
|
44
|
-
def delete_all(conditions=nil)
|
45
|
-
copy_to_archive(conditions)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
module InstanceMethods
|
50
|
-
def destroy_without_callbacks
|
51
|
-
unless new_record?
|
52
|
-
self.class.copy_to_archive("#{self.class.primary_key} = #{id}")
|
53
|
-
end
|
54
|
-
@destroyed = true
|
55
|
-
freeze
|
56
|
-
end
|
57
|
-
|
58
|
-
def destroy!
|
59
|
-
transaction { destroy_with_callbacks! }
|
60
|
-
end
|
61
|
-
|
62
|
-
def destroy_with_callbacks!
|
63
|
-
return false if callback(:before_destroy) == false
|
64
|
-
result = destroy_without_callbacks!
|
65
|
-
callback(:after_destroy)
|
66
|
-
result
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
module Base
|
3
|
-
module Restore
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
unless base.included_modules.include?(InstanceMethods)
|
7
|
-
base.send :extend, ClassMethods
|
8
|
-
base.send :include, InstanceMethods
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
|
14
|
-
def copy_from_archive(conditions)
|
15
|
-
add_conditions!(where = '', conditions)
|
16
|
-
col_names = column_names - [ 'deleted_at' ]
|
17
|
-
col_names.map! { |col| connection.quote_column_name(col) }
|
18
|
-
connection.execute(%{
|
19
|
-
INSERT INTO #{table_name} (#{col_names.join(', ')})
|
20
|
-
SELECT #{col_names.join(', ')}
|
21
|
-
FROM archived_#{table_name}
|
22
|
-
#{where}
|
23
|
-
})
|
24
|
-
connection.execute("DELETE FROM archived_#{table_name} #{where}")
|
25
|
-
end
|
26
|
-
|
27
|
-
def restore_all(conditions=nil)
|
28
|
-
copy_from_archive(conditions)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module InstanceMethods
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
module Base
|
3
|
-
module Table
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
unless base.included_modules.include?(InstanceMethods)
|
7
|
-
base.send :extend, ClassMethods
|
8
|
-
base.send :include, InstanceMethods
|
9
|
-
|
10
|
-
if base.connection.class.to_s.include?('Mysql')
|
11
|
-
base.send :extend, ActsAsArchive::Base::Adapters::MySQL
|
12
|
-
elsif base.connection.class.to_s.include?('PostgreSQL')
|
13
|
-
base.send :extend, ActsAsArchive::Base::Adapters::PostgreSQL
|
14
|
-
else
|
15
|
-
raise 'acts_as_archive does not support this database adapter'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module ClassMethods
|
21
|
-
|
22
|
-
def archive_table_exists?
|
23
|
-
connection.table_exists?("archived_#{table_name}")
|
24
|
-
end
|
25
|
-
|
26
|
-
def create_archive_table
|
27
|
-
if table_exists? && !archive_table_exists?
|
28
|
-
connection.execute(%{
|
29
|
-
CREATE TABLE archived_#{table_name}
|
30
|
-
#{"ENGINE=InnoDB" if connection.class.to_s.include?('Mysql')}
|
31
|
-
AS SELECT * from #{table_name}
|
32
|
-
WHERE false;
|
33
|
-
})
|
34
|
-
columns = connection.columns("archived_#{table_name}").collect(&:name)
|
35
|
-
unless columns.include?('deleted_at')
|
36
|
-
connection.add_column("archived_#{table_name}", :deleted_at, :datetime)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def create_archive_indexes
|
42
|
-
if archive_table_exists?
|
43
|
-
indexes = archive_table_indexed_columns
|
44
|
-
|
45
|
-
(archive_indexes - indexes).each do |index|
|
46
|
-
connection.add_index("archived_#{table_name}", index)
|
47
|
-
end
|
48
|
-
(indexes - archive_indexes).each do |index|
|
49
|
-
connection.remove_index("archived_#{table_name}", index)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
def migrate_from_acts_as_paranoid
|
56
|
-
if column_names.include?('deleted_at')
|
57
|
-
if table_exists? && archive_table_exists?
|
58
|
-
condition = "deleted_at IS NOT NULL"
|
59
|
-
if self.count_by_sql("SELECT COUNT(*) FROM #{table_name} WHERE #{condition}") > 0
|
60
|
-
# Base::Destroy.copy_to_archive
|
61
|
-
copy_to_archive(condition, true)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def archive_table_indexed_columns
|
70
|
-
case connection.class.to_s
|
71
|
-
when "ActiveRecord::ConnectionAdapters::MysqlAdapter"
|
72
|
-
index_query = "SHOW INDEX FROM archived_#{table_name}"
|
73
|
-
indexes = connection.select_all(index_query).collect do |r|
|
74
|
-
r["Column_name"]
|
75
|
-
end
|
76
|
-
when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
|
77
|
-
#postgresql is...slightly...more complicated
|
78
|
-
index_query = <<EOS
|
79
|
-
SELECT c2.relname as index_name
|
80
|
-
FROM pg_catalog.pg_class c,
|
81
|
-
pg_catalog.pg_class c2,
|
82
|
-
pg_catalog.pg_index i
|
83
|
-
WHERE c.oid = (SELECT c.oid
|
84
|
-
FROM pg_catalog.pg_class c
|
85
|
-
WHERE c.relname ~ '^(archived_#{table_name})$')
|
86
|
-
AND c.oid = i.indrelid
|
87
|
-
AND i.indexrelid = c2.oid
|
88
|
-
EOS
|
89
|
-
indexes = connection.select_all(index_query).collect do |r|
|
90
|
-
r["index_name"]
|
91
|
-
end
|
92
|
-
|
93
|
-
# HACK: reverse engineer the column name
|
94
|
-
# This sucks, but acts_as_archive only adds indexes on single columns anyway so it should work OK
|
95
|
-
# and getting the columns indexed is INCREDIBLY complicated in PostgreSQL.
|
96
|
-
indexes.map do |index|
|
97
|
-
index.split("_on_").last
|
98
|
-
end
|
99
|
-
else
|
100
|
-
raise "Unsupported Database"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
module InstanceMethods
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module ActsAsArchive
|
2
|
-
module Migration
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
unless base.included_modules.include?(InstanceMethods)
|
6
|
-
base.send :extend, ClassMethods
|
7
|
-
base.class_eval do
|
8
|
-
class <<self
|
9
|
-
unless method_defined?(:method_missing_without_archive)
|
10
|
-
alias_method :method_missing_without_archive, :method_missing
|
11
|
-
alias_method :method_missing, :method_missing_with_archive
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
module ClassMethods
|
19
|
-
|
20
|
-
def method_missing_with_archive(method, *arguments, &block)
|
21
|
-
args = Marshal.load(Marshal.dump(arguments))
|
22
|
-
method_missing_without_archive(method, *arguments, &block)
|
23
|
-
supported = [
|
24
|
-
:add_column, :add_timestamps, :change_column,
|
25
|
-
:change_column_default, :change_table,
|
26
|
-
:drop_table, :remove_column, :remove_columns,
|
27
|
-
:remove_timestamps, :rename_column, :rename_table
|
28
|
-
]
|
29
|
-
if args.include?(:deleted_at) || args.include?('deleted_at')
|
30
|
-
# Don't change the archive's deleted_at column
|
31
|
-
return
|
32
|
-
end
|
33
|
-
if !args.empty? && supported.include?(method)
|
34
|
-
connection = ActiveRecord::Base.connection
|
35
|
-
args[0] = "archived_" + ActiveRecord::Migrator.proper_table_name(args[0])
|
36
|
-
if method == :rename_table
|
37
|
-
args[1] = "archived_" + args[1].to_s
|
38
|
-
end
|
39
|
-
if connection.table_exists?(args[0])
|
40
|
-
connection.send(method, *args, &block)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
module InstanceMethods
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
data/rails/init.rb
DELETED
data/require.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
gem 'require'
|
3
|
-
require 'require'
|
4
|
-
|
5
|
-
Require do
|
6
|
-
gem(:activerecord) { require 'active_record' }
|
7
|
-
gem :require, '=0.2.1'
|
8
|
-
gem(:rake, '=0.8.7') { require 'rake' }
|
9
|
-
gem :rspec, '=1.3.0'
|
10
|
-
|
11
|
-
gemspec do
|
12
|
-
author 'Winton Welsh'
|
13
|
-
dependencies do
|
14
|
-
gem :require
|
15
|
-
end
|
16
|
-
email 'mail@wintoni.us'
|
17
|
-
name 'acts_as_archive'
|
18
|
-
homepage "http://github.com/winton/#{name}"
|
19
|
-
summary "Don't delete your records, move them to a different table"
|
20
|
-
version '0.2.5'
|
21
|
-
end
|
22
|
-
|
23
|
-
lib do
|
24
|
-
require "lib/acts_as_archive/base"
|
25
|
-
require "lib/acts_as_archive/base/adapters/mysql"
|
26
|
-
require "lib/acts_as_archive/base/adapters/postgresql"
|
27
|
-
require "lib/acts_as_archive/base/destroy"
|
28
|
-
require "lib/acts_as_archive/base/restore"
|
29
|
-
require "lib/acts_as_archive/base/table"
|
30
|
-
require "lib/acts_as_archive/migration"
|
31
|
-
end
|
32
|
-
|
33
|
-
rails_init { require 'lib/acts_as_archive' }
|
34
|
-
|
35
|
-
rakefile do
|
36
|
-
gem(:rake) { require 'rake/gempackagetask' }
|
37
|
-
gem(:rspec) { require 'spec/rake/spectask' }
|
38
|
-
require 'require/tasks'
|
39
|
-
end
|
40
|
-
|
41
|
-
spec_helper do
|
42
|
-
require 'require/spec_helper'
|
43
|
-
gem :activerecord
|
44
|
-
require 'logger'
|
45
|
-
require 'yaml'
|
46
|
-
require 'pp'
|
47
|
-
require 'rails/init'
|
48
|
-
end
|
49
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
-
|
3
|
-
describe ActsAsArchive::Base::Destroy do
|
4
|
-
|
5
|
-
before(:all) do
|
6
|
-
establish_test_db
|
7
|
-
Article.create_archive_table
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'delete_all!' do
|
11
|
-
|
12
|
-
before(:all) do
|
13
|
-
create_records
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should really delete all records" do
|
17
|
-
Article.delete_all!
|
18
|
-
Article.count.should == 0
|
19
|
-
Article::Archive.count.should == 0
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
describe 'destroy!' do
|
25
|
-
|
26
|
-
before(:all) do
|
27
|
-
create_records
|
28
|
-
@article = Article.first
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should really destroy a records" do
|
32
|
-
@article.destroy!
|
33
|
-
Article::Archive.count.should == 0
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
describe 'delete_all' do
|
39
|
-
|
40
|
-
before(:all) do
|
41
|
-
@articles = create_records
|
42
|
-
end
|
43
|
-
|
44
|
-
describe 'with conditions' do
|
45
|
-
|
46
|
-
before(:all) do
|
47
|
-
# Mini delete_all parameter test
|
48
|
-
Article.delete_all [ 'id = ?', @articles[0].id ]
|
49
|
-
Article.delete_all "id = #{@articles[1].id}"
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should move some records to the archive table" do
|
53
|
-
Article.count.should == 3
|
54
|
-
Article::Archive.count.should == 2
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should preserve record attributes" do
|
58
|
-
2.times do |x|
|
59
|
-
original = @articles[x]
|
60
|
-
copy = Article::Archive.find(original.id)
|
61
|
-
article_match?(original, copy)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe 'without conditions' do
|
67
|
-
|
68
|
-
before(:all) do
|
69
|
-
Article.delete_all
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should move all records to the archive table" do
|
73
|
-
Article.count.should == 0
|
74
|
-
Article::Archive.count.should == 5
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should preserve record attributes" do
|
78
|
-
5.times do |x|
|
79
|
-
original = @articles[x]
|
80
|
-
copy = Article::Archive.find(original.id)
|
81
|
-
article_match?(original, copy)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
[ :destroy, :delete ].each do |d|
|
88
|
-
|
89
|
-
describe d do
|
90
|
-
|
91
|
-
before(:all) do
|
92
|
-
@articles = create_records
|
93
|
-
Article.find(@articles[0..1].collect(&:id)).each do |a|
|
94
|
-
a.send(d)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should move some records to the archive table" do
|
99
|
-
Article.count.should == 3
|
100
|
-
Article::Archive.count.should == 2
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should preserve record attributes" do
|
104
|
-
2.times do |x|
|
105
|
-
original = @articles[x]
|
106
|
-
copy = Article::Archive.find(original.id)
|
107
|
-
article_match?(original, copy)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should mark the object as destroyed" do
|
112
|
-
@articles[3].send(d)
|
113
|
-
@articles[3].destroyed?.should == true
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
-
|
3
|
-
describe ActsAsArchive::Base::Restore do
|
4
|
-
|
5
|
-
before(:all) do
|
6
|
-
establish_test_db
|
7
|
-
Article.create_archive_table
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'restore_all' do
|
11
|
-
|
12
|
-
before(:all) do
|
13
|
-
@articles = create_records(Article::Archive)
|
14
|
-
end
|
15
|
-
|
16
|
-
describe 'with conditions' do
|
17
|
-
|
18
|
-
before(:all) do
|
19
|
-
# Mini restore parameter test
|
20
|
-
Article.restore_all [ 'id = ?', @articles[0].id ]
|
21
|
-
Article.restore_all "id = #{@articles[1].id}"
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should move some records to the article table" do
|
25
|
-
Article::Archive.count.should == 3
|
26
|
-
Article.count.should == 2
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should preserve record attributes" do
|
30
|
-
2.times do |x|
|
31
|
-
original = @articles[x]
|
32
|
-
copy = Article.find(original.id)
|
33
|
-
article_match?(original, copy)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe 'without conditions' do
|
39
|
-
|
40
|
-
before(:all) do
|
41
|
-
Article.restore_all
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should move all records to the archive table" do
|
45
|
-
Article::Archive.count.should == 0
|
46
|
-
Article.count.should == 5
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should preserve record attributes" do
|
50
|
-
5.times do |x|
|
51
|
-
original = @articles[x]
|
52
|
-
copy = Article.find(original.id)
|
53
|
-
article_match?(original, copy)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
-
|
3
|
-
describe ActsAsArchive::Base::Table do
|
4
|
-
|
5
|
-
before(:all) do
|
6
|
-
establish_test_db
|
7
|
-
Article.create_archive_table
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'create_archive_table' do
|
11
|
-
|
12
|
-
before(:all) do
|
13
|
-
@article_columns = connection.columns("articles").collect(&:name)
|
14
|
-
@archive_columns = connection.columns("archived_articles").collect(&:name)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should create an archive table" do
|
18
|
-
connection.table_exists?("archived_articles").should == true
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should create an archive table with the same structure as the original table" do
|
22
|
-
@article_columns.each do |col|
|
23
|
-
@archive_columns.include?(col).should == true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should add a deleted_at column to the archive table" do
|
28
|
-
(@archive_columns - @article_columns).should == [ 'deleted_at' ]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe 'create_archive_indexes' do
|
33
|
-
|
34
|
-
before(:all) do
|
35
|
-
Article.create_archive_indexes
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should create archive indexes" do
|
39
|
-
indexes.to_set.should == [ "id", "deleted_at" ].to_set
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should destroy archive indexes" do
|
43
|
-
Article.class_eval { acts_as_archive }
|
44
|
-
Article.create_archive_indexes
|
45
|
-
indexes.should == []
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'migrate_from_acts_as_paranoid' do
|
50
|
-
|
51
|
-
before(:all) do
|
52
|
-
connection.add_column(:articles, :deleted_at, :datetime)
|
53
|
-
Article.reset_column_information
|
54
|
-
end
|
55
|
-
|
56
|
-
before(:each) do
|
57
|
-
connection.execute("DELETE FROM #{Article::Archive.table_name}")
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should move deleted records to the archive" do
|
61
|
-
create_records(Article, :deleted_at => Time.now.utc)
|
62
|
-
Article.migrate_from_acts_as_paranoid
|
63
|
-
Article.count.should == 0
|
64
|
-
Article::Archive.count.should == 5
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should not move non-deleted records to the archive" do
|
68
|
-
create_records
|
69
|
-
Article.migrate_from_acts_as_paranoid
|
70
|
-
Article.count.should == 5
|
71
|
-
Article::Archive.count.should == 0
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
-
|
3
|
-
describe ActsAsArchive::Base do
|
4
|
-
|
5
|
-
before(:all) do
|
6
|
-
establish_test_db
|
7
|
-
end
|
8
|
-
|
9
|
-
describe 'acts_as_archive' do
|
10
|
-
|
11
|
-
it "should add self.acts_as_archive? to the model" do
|
12
|
-
Article.respond_to?(:acts_as_archive?).should == true
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should add self.archive_indexes to the model" do
|
16
|
-
Article.respond_to?(:archive_indexes).should == true
|
17
|
-
Article.archive_indexes.should == [ 'id', 'deleted_at' ]
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should add Archive class to the model" do
|
21
|
-
defined?(Article::Archive).should == "constant"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
|
3
|
-
describe ActsAsArchive::Migration do
|
4
|
-
|
5
|
-
before(:each) do
|
6
|
-
establish_test_db
|
7
|
-
Article.create_archive_table
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'method_missing_with_archive' do
|
11
|
-
|
12
|
-
it 'should migrate both tables up' do
|
13
|
-
migrate_up
|
14
|
-
(@new_article_columns - @old_article_columns).should == [ 'permalink' ]
|
15
|
-
(@new_archive_columns - @old_archive_columns).should == [ 'permalink' ]
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should migrate both tables down' do
|
19
|
-
migrate_up
|
20
|
-
@old_article_columns = @new_article_columns
|
21
|
-
@old_archive_columns = @new_archive_columns
|
22
|
-
ActiveRecord::Migrator.migrate("#{SPEC}/db/migrate", 0)
|
23
|
-
@new_article_columns = columns("articles")
|
24
|
-
@new_archive_columns = columns("archived_articles")
|
25
|
-
(@old_article_columns - @new_article_columns).should == [ 'permalink' ]
|
26
|
-
(@old_archive_columns - @new_archive_columns).should == [ 'permalink' ]
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should not touch the archive's deleted_at column" do
|
30
|
-
connection.add_column(:articles, :deleted_at, :datetime)
|
31
|
-
Article.reset_column_information
|
32
|
-
migrate_up("migrate_2")
|
33
|
-
(@old_article_columns - @new_article_columns).should == [ 'deleted_at' ]
|
34
|
-
(@old_archive_columns - @new_archive_columns).should == []
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/spec/db/models/article.rb
DELETED
data/spec/spec.opts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|
data/spec/spec_helper.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
require File.expand_path("#{File.dirname(__FILE__)}/../require")
|
2
|
-
Require.spec_helper!
|
3
|
-
|
4
|
-
Spec::Runner.configure do |config|
|
5
|
-
end
|
6
|
-
|
7
|
-
def db_type
|
8
|
-
ENV['DB_TYPE'] ? ENV['DB_TYPE'] : 'mysql'
|
9
|
-
end
|
10
|
-
|
11
|
-
def article_match?(original, copy)
|
12
|
-
copy.id.should == original.id
|
13
|
-
copy.title.should == original.title
|
14
|
-
copy.body.should == original.body
|
15
|
-
if copy.respond_to?(:deleted_at)
|
16
|
-
copy.deleted_at.strftime('%j%H%M').should == Time.now.utc.strftime('%j%H%M')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def columns(table)
|
21
|
-
connection.columns(table).collect(&:name)
|
22
|
-
end
|
23
|
-
|
24
|
-
def connection
|
25
|
-
ActiveRecord::Base.connection
|
26
|
-
end
|
27
|
-
|
28
|
-
def create_records(klass=Article, values={})
|
29
|
-
articles = []
|
30
|
-
table = klass.table_name
|
31
|
-
cols = columns(table)
|
32
|
-
connection.execute("DELETE FROM #{table}")
|
33
|
-
(1..5).collect do |x|
|
34
|
-
vals = cols.collect do |c|
|
35
|
-
if values.keys.include?(c.intern)
|
36
|
-
values[c.intern] ? "'#{values[c.intern]}'" : "NULL"
|
37
|
-
else
|
38
|
-
case c.intern
|
39
|
-
when :id; x
|
40
|
-
when :deleted_at; 'NULL'
|
41
|
-
else "'#{c.capitalize} #{x}'"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
connection.execute(%{
|
46
|
-
INSERT INTO #{table} (#{cols.collect { |c| "#{connection.quote_column_name(c)}" }.join(', ')})
|
47
|
-
VALUES (#{vals.join(', ')})
|
48
|
-
})
|
49
|
-
klass.find(x)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def establish_test_db
|
54
|
-
# Establish connection
|
55
|
-
unless ActiveRecord::Base.connected?
|
56
|
-
config = YAML::load(File.open("#{SPEC}/db/config/database.#{db_type}.yml"))
|
57
|
-
ActiveRecord::Base.configurations = config
|
58
|
-
ActiveRecord::Base.establish_connection(config['test'])
|
59
|
-
end
|
60
|
-
# Establish logger
|
61
|
-
logger_file = File.open("#{SPEC}/db/log/test.log", 'a')
|
62
|
-
logger_file.sync = true
|
63
|
-
@logger = Logger.new(logger_file)
|
64
|
-
ActiveRecord::Base.logger = @logger
|
65
|
-
# The database should have only a simple articles table
|
66
|
-
connection.execute("DROP TABLE IF EXISTS articles")
|
67
|
-
connection.execute("DROP TABLE IF EXISTS archived_articles")
|
68
|
-
connection.execute("DROP TABLE IF EXISTS schema_migrations")
|
69
|
-
connection.create_table(:articles) do |t|
|
70
|
-
t.string :title
|
71
|
-
t.string :body
|
72
|
-
t.boolean :read # break mysql w/o quotation
|
73
|
-
end
|
74
|
-
# Load the model
|
75
|
-
load "#{SPEC}/db/models/article.rb"
|
76
|
-
end
|
77
|
-
|
78
|
-
def indexes
|
79
|
-
Article.send(:archive_table_indexed_columns)
|
80
|
-
end
|
81
|
-
|
82
|
-
def migrate_up(directory='migrate')
|
83
|
-
@old_article_columns = columns("articles")
|
84
|
-
@old_archive_columns = columns("archived_articles")
|
85
|
-
ActiveRecord::Migrator.migrate("#{SPEC}/db/#{directory}")
|
86
|
-
@new_article_columns = columns("articles")
|
87
|
-
@new_archive_columns = columns("archived_articles")
|
88
|
-
end
|