Skip to content

Commit f8241de

Browse files
committed
Initial version for the recreate_table plugin
0 parents  commit f8241de

10 files changed

+1675
-0
lines changed

README

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
RecreateTable
2+
=============
3+
4+
Introduction goes here.
5+
6+
7+
Example
8+
=======
9+
10+
Example goes here.
11+
12+
13+
Copyright (c) 2009 [name of plugin creator], released under the MIT license

Rakefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
require 'rake'
2+
require 'spec/rake/spectask'
3+
4+
desc 'Default: run specs.'
5+
task :default => :spec
6+
7+
desc 'Run the specs'
8+
Spec::Rake::SpecTask.new(:spec) do |t|
9+
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
10+
t.spec_files = FileList['spec/**/*_spec.rb']
11+
end

init.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Include hook code here
2+
require 'recreate_table'

install.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Install hook code here

lib/recreate_table.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# RecreateTable
2+
3+
ActiveRecord::ConnectionAdapters::SchemaStatements.module_eval do
4+
5+
def recreate_table(table, options={})
6+
old_table = "#{table}_old"
7+
as = options[:as] || "SELECT * FROM #{old_table}"
8+
9+
model = table.to_s.titleize.singularize.constantize
10+
columns = model.columns.dup
11+
id_sequence = "#{table}_id_seq"
12+
13+
transaction do
14+
15+
rename_table table, old_table
16+
17+
execute "CREATE TABLE #{table} AS (#{as})"
18+
19+
columns.each do |column|
20+
if column.primary
21+
execute "ALTER TABLE #{table} ADD PRIMARY KEY (#{column.name})"
22+
execute "ALTER TABLE #{table} ALTER COLUMN #{column.name} SET DEFAULT nextval('#{id_sequence}'::regclass)"
23+
execute "ALTER SEQUENCE #{id_sequence} OWNED BY #{table}.id"
24+
else
25+
change_column table, column.name, column.type, { :null => column.null , :default => column.default }
26+
end
27+
end
28+
29+
indexes(old_table).each do |index|
30+
execute "DROP INDEX #{index.name}"
31+
add_index table, index.columns, :name => index.name, :unique => index.unique
32+
end
33+
34+
drop_table old_table
35+
end
36+
end
37+
end
38+

spec/debug.log

Lines changed: 1471 additions & 0 deletions
Large diffs are not rendered by default.

spec/recreate_table_spec.rb

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
require File.dirname(__FILE__) + '/spec_helper'
2+
3+
describe "The RecreateTable plugin" do
4+
5+
it "should add a command to schema commands" do
6+
ActiveRecord::Base.connection.should respond_to(:recreate_table)
7+
end
8+
end
9+
10+
11+
describe "recreate_table" do
12+
class Foo < ActiveRecord::Base; end
13+
14+
before(:each) do
15+
Foo.connection.create_table(:foos) do |t|
16+
t.integer :bar
17+
t.integer :baz, :null => false, :default => 0
18+
end
19+
20+
Foo.create!(:bar => 123)
21+
end
22+
23+
it "should have Foos" do
24+
Foo.count.should == 1
25+
end
26+
27+
it "should keep the contents of the table" do
28+
Foo.connection.recreate_table :foos
29+
30+
Foo.count.should == 1
31+
end
32+
33+
it "should keep the primary key" do
34+
Foo.connection.recreate_table :foos
35+
36+
new = Foo.create!
37+
new.id.should_not be_nil
38+
end
39+
40+
it "should allow to insert further rows" do
41+
Foo.connection.recreate_table :foos
42+
43+
lambda {
44+
Foo.create!
45+
Foo.create!
46+
Foo.create!
47+
}.should_not raise_error
48+
end
49+
50+
it "should keep defaults" do
51+
Foo.connection.recreate_table :foos
52+
Foo.reset_column_information
53+
54+
baz = Foo.columns.find { |c| c.name == 'baz' }
55+
56+
baz.default.should == 0
57+
end
58+
59+
it "should allow to create with default" do
60+
Foo.connection.recreate_table :foos
61+
Foo.reset_column_information
62+
63+
new = Foo.create!
64+
new.baz.should == 0
65+
end
66+
67+
it "should keep NOT NULL constraint" do
68+
Foo.connection.recreate_table :foos
69+
Foo.reset_column_information
70+
71+
baz = Foo.columns.find { |c| c.name == 'baz' }
72+
73+
baz.null.should be_false
74+
end
75+
end
76+
77+
78+
describe "recreate_table with new columns" do
79+
class Foo < ActiveRecord::Base; end
80+
81+
before(:each) do
82+
Foo.connection.create_table(:foos) do |t|
83+
t.integer :bar
84+
end
85+
Foo.create!
86+
end
87+
88+
it "should allow to add new columns" do
89+
Foo.connection.recreate_table :foos, :as => "SELECT *, 123 AS baz FROM foos_old"
90+
Foo.reset_column_information
91+
92+
Foo.first.baz.should == 123
93+
end
94+
end
95+
96+
97+
describe "recreate_table with indices" do
98+
class Foo < ActiveRecord::Base; end
99+
100+
before(:each) do
101+
Foo.connection.create_table(:foos) do |t|
102+
t.integer :bar
103+
t.integer :baz
104+
end
105+
Foo.connection.add_index :foos, :bar
106+
Foo.connection.add_index :foos, :baz, :unique => true
107+
end
108+
109+
it "should recreate the indices" do
110+
Foo.connection.recreate_table :foos
111+
Foo.reset_column_information
112+
113+
index = Foo.connection.indexes(:foos).find { |i| i.name == 'index_foos_on_bar' }
114+
index.should_not be_nil
115+
end
116+
117+
it "should retain uniqueness of indices" do
118+
Foo.connection.recreate_table :foos
119+
Foo.reset_column_information
120+
121+
index = Foo.connection.indexes(:foos).find { |i| i.name == 'index_foos_on_baz' }
122+
index.unique.should be_true
123+
end
124+
end

spec/spec_helper.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
begin
2+
require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
3+
rescue LoadError
4+
puts "You need to install rspec in your base app"
5+
exit
6+
end
7+
8+
plugin_spec_dir = File.dirname(__FILE__)
9+
ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
10+

tasks/recreate_table_tasks.rake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# desc "Explaining what the task does"
2+
# task :recreate_table do
3+
# # Task goes here
4+
# end

uninstall.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Uninstall hook code here

0 commit comments

Comments
 (0)