fast_change_table 0.0.6 → 1.0.0

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/Gemfile.lock CHANGED
@@ -1,18 +1,43 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fast_change_table (0.0.2)
5
- activerecord (~> 2.3)
4
+ fast_change_table (1.0.0)
5
+ activerecord (>= 2.3)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- activerecord (2.3.14)
11
- activesupport (= 2.3.14)
12
- activesupport (2.3.14)
10
+ activemodel (3.2.0)
11
+ activesupport (= 3.2.0)
12
+ builder (~> 3.0.0)
13
+ activerecord (3.2.0)
14
+ activemodel (= 3.2.0)
15
+ activesupport (= 3.2.0)
16
+ arel (~> 3.0.0)
17
+ tzinfo (~> 0.3.29)
18
+ activesupport (3.2.0)
19
+ i18n (~> 0.6)
20
+ multi_json (~> 1.0)
21
+ arel (3.0.0)
22
+ builder (3.0.0)
23
+ diff-lcs (1.1.3)
24
+ i18n (0.6.0)
25
+ multi_json (1.0.4)
26
+ mysql2 (0.3.11)
27
+ rspec (2.8.0)
28
+ rspec-core (~> 2.8.0)
29
+ rspec-expectations (~> 2.8.0)
30
+ rspec-mocks (~> 2.8.0)
31
+ rspec-core (2.8.0)
32
+ rspec-expectations (2.8.0)
33
+ diff-lcs (~> 1.1.2)
34
+ rspec-mocks (2.8.0)
35
+ tzinfo (0.3.31)
13
36
 
14
37
  PLATFORMS
15
38
  ruby
16
39
 
17
40
  DEPENDENCIES
18
41
  fast_change_table!
42
+ mysql2
43
+ rspec
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ #Fast Change Table
2
+
3
+ Use fast\_change\_table instead of change_table in your migrations on large tables of data. Uses a duplication pattern to speed things up.
4
+
5
+
6
+ uses ordinary change_table syntax but adds two options
7
+
8
+ * "replace\_keys" to remove all indexes; new indexes will be specified
9
+ - "disable\_keys" to remove indexes and apply them after data load; this is a tremendous performance enhancement for a dbms with fast index creation
10
+
11
+ __Example:__
12
+
13
+ fast_change_table :table_name, :disable_keys => true do |t|
14
+ t.change :old_string, :string, :limit => 64
15
+ t.rename :old_string, :new_string
16
+ t.integer :an_integer
17
+ end
18
+
19
+
20
+ __other methods:__
21
+
22
+ create\_table\_like(orignal\_table, table\_to\_copy\_to)
23
+ creates a table with the same structure
24
+
25
+ disable\_indexes(table)
26
+ removes all indexes from a table, returns a list of index objects removed
27
+
28
+ enable\_indexes(table, list\_of\_indexes)
29
+ restores a list of indexes to a table
30
+
31
+ fast\_add\_indexes(table, &block)
32
+ allows you to pass a block to add indexes. For mysql creates specified indexes in one statement; allows the data to be scanned once.
33
+
34
+ __Example:__
35
+
36
+
37
+ fast_add_indexes :sometable do |t|
38
+ t.index :some_column
39
+ t.index [:some_other_column, :column_three], :name => "a_multicolumn_index"
40
+ end
41
+
42
+ copy\_table(from\_table, to\_table, remaps = [])
43
+
44
+ * copies rows from one table into another. this probably only works with Mysql.
45
+ by default copies data from column of from_table to to_table of same name.
46
+ will not copy data where there is no corresponding column.
47
+ the remaps argument can be supplied to tell copy table how to handle unmatched columns or override this behavior
48
+
49
+ __Examples:__
50
+
51
+
52
+ copy_table(old_users_without_email_hash, new_table, ['MD5(email)', 'email_hash'])
53
+
54
+ copy_table(old_users_without_total, new_table, ['sum(payments)', 'total_payments'])
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task :default => :spec
@@ -21,7 +21,11 @@ Gem::Specification.new do |s|
21
21
  # specify any dependencies here; for example:
22
22
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
23
23
  s.add_runtime_dependency('activerecord', '>= 2.3')
24
+ s.add_development_dependency("rspec")
25
+ s.add_development_dependency("mysql2")
24
26
  else
25
27
  s.add_dependency('activerecord', '>= 2.3')
28
+ s.add_development_dependency("rspec")
29
+ s.add_development_dependency("mysql2")
26
30
  end
27
31
  end
@@ -1,164 +1,12 @@
1
- module ActiveRecord
2
- module ConnectionAdapters #:nodoc:
3
-
4
- module SchemaStatements
5
- def change_table_with_remaps(table_name)
6
- t = Table.new(table_name, self)
7
- yield t
8
- return t.renamed_columns
9
- end
10
- end
11
-
12
- class Table
13
-
14
- def initialize(table_name, base)
15
- @table_name = table_name
16
- @base = base
17
- @renamed_columns = []
18
- end
19
-
20
- def renamed_columns
21
- @renamed_columns
22
- end
23
-
24
- def rename(column_name, new_column_name)
25
- @renamed_columns << [column_name, new_column_name]
26
- @base.rename_column(@table_name, column_name, new_column_name)
27
- end
28
-
29
- end
30
- end
31
- end
1
+ require 'active_record'
2
+ require 'fast_change_table/connection_adapters'
3
+ require 'fast_change_table/fast_change_table'
4
+ require 'fast_change_table/version'
32
5
 
33
6
  module FastChangeTable
34
7
  def self.included(base)
35
8
  base.extend ClassMethods
36
9
  end
37
-
38
- module ClassMethods
39
- def fast_change_table(table_name, options = {}, &block)
40
- options.symbolize_keys!
41
- old_table_name = "old_#{table_name}"
42
- rename_table(table_name, old_table_name)
43
- begin
44
- create_table_like(old_table_name, table_name, options)
45
- renamed_columns = change_table_with_remaps(table_name, &block)
46
- index_list = options[:disable_keys] ? disable_indexes(table_name) : []
47
- #prepare the columns names for the insert statements
48
- copy_table(old_table_name, table_name, renamed_columns)
49
- enable_indexes(table_name, index_list) if options[:disable_keys]
50
- drop_table(old_table_name)
51
- rescue Exception => e
52
- puts "#{e}\n#{e.backtrace}"
53
- drop_table(table_name) if table_exists?(table_name)
54
- rename_table(old_table_name, table_name)
55
- raise e
56
- end
57
- end
58
-
59
- def fast_add_indexes(table, &blk)
60
- phoney = PhoneyTable.new(table.to_s)
61
- yield phoney
62
- enable_indexes(table, phoney.indexes)
63
- end
64
-
65
- #create_table_like( :sometable, :newtable, :remove_keys => true)
66
- def create_table_like(like_table, table, options = {})
67
- options.symbolize_keys!
68
- code = table_schema_code(like_table)
69
- code.gsub!(/create_table\s+"#{like_table}"/, "create_table :#{table}")
70
- if options[:replace_keys] or options[:remove_keys]
71
- code.gsub!(/add_index\s+"#{like_table}"/, "#add_index :#{table}")
72
- else
73
- code.gsub!(/add_index\s+"#{like_table}"/, "add_index :#{table}")
74
- end
75
- class_eval(code)
76
- true
77
- end
78
-
79
- #copy_table( :sometable, :newtable, [[:old_column, :new_column]])
80
- def copy_table(from, to, remaps = [])
81
- old = connection.columns(from).collect(&:name)
82
- current = connection.columns(to).collect(&:name)
83
- remapped_columns = remaps.collect {|c| c.first.to_s}.compact
84
- common = (current & old).sort - remapped_columns
85
- from_columns = common.collect {|c| "`#{c}`"}
86
- to_columns = common.collect {|c| "`#{c}`"}
87
- remaps.each do |remap|
88
- remap = [remap].flatten
89
- next if remap.length != 2
90
- from_columns << remap.first
91
- to_columns << remap.last
92
- end
93
- from_columns_to_s = from_columns.join(', ')
94
- to_columns_to_s = to_columns.join(', ')
95
- execute "INSERT INTO #{to}(#{to_columns_to_s}) SELECT #{from_columns_to_s} FROM #{from}"
96
- end
97
-
98
- def table_schema_code(table)
99
- dumper = ActiveRecord::SchemaDumper.send(:new, connection)
100
- stream = StringIO.new
101
- dumper.send(:table, table.to_s, stream)
102
- stream.rewind
103
- code = stream.read
104
- end
105
-
106
- #removes all the indexes
107
- def disable_indexes(table)
108
- list = connection.indexes(table)
109
- list.each do |i|
110
- remove_index table, :name => i.name
111
- end
112
- list
113
- end
114
-
115
- #
116
- def enable_indexes(table, list)
117
- list.each do |i|
118
- options = {}
119
- options[:name] = i.name if i.name
120
- options[:length] = i.lengths if i.lengths
121
- options[:unique] = i.unique if i.unique
122
- add_index table, i.columns, options
123
- end
124
- true
125
- end
126
-
127
- class PhoneyTable
128
-
129
- attr_accessor :indexes
130
-
131
- def initialize(tablename)
132
- @table = tablename
133
- @indexes = []
134
- end
135
-
136
- def index(columns, options = {})
137
- new_index = PhoneyIndex.new(@table, columns, options)
138
- @indexes << new_index unless @indexes.to_a.any? {|i| i == new_index}
139
- end
140
-
141
- def indexes; @indexes.to_a.uniq end
142
- end
143
-
144
- class PhoneyIndex
145
-
146
- attr_accessor :columns, :lengths, :name, :unique
147
-
148
- def initialize(table, cols, options)
149
- cols = [cols].flatten
150
- self.columns = cols.collect(&:to_s)
151
- self.lengths = options[:length]
152
- self.unique = !!options[:unique]
153
- self.name = options[:name] || "index_#{table}_on_#{columns.join('_and_')}"
154
- self.name = "#{columns.join('_')}_idx" if name.length > 64
155
- end
156
-
157
- def ==(val)
158
- columns == val.columns rescue false
159
- end
160
- end
161
- end
162
10
  end
163
11
 
164
12
  ::ActiveRecord::Migration.send :include, FastChangeTable
@@ -0,0 +1,31 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters #:nodoc:
3
+
4
+ module SchemaStatements
5
+ def change_table_with_remaps(table_name)
6
+ t = Table.new(table_name, self)
7
+ yield t
8
+ return t.renamed_columns
9
+ end
10
+ end
11
+
12
+ class Table
13
+
14
+ def initialize(table_name, base)
15
+ @table_name = table_name
16
+ @base = base
17
+ @renamed_columns = []
18
+ end
19
+
20
+ def renamed_columns
21
+ @renamed_columns
22
+ end
23
+
24
+ def rename(column_name, new_column_name)
25
+ @renamed_columns << [column_name, new_column_name]
26
+ @base.rename_column(@table_name, column_name, new_column_name)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,132 @@
1
+
2
+
3
+ module FastChangeTable
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def fast_change_table(table_name, options = {}, &block)
10
+ options.symbolize_keys!
11
+ old_table_name = "old_#{table_name}"
12
+ rename_table(table_name, old_table_name)
13
+ begin
14
+ create_table_like(old_table_name, table_name, options)
15
+ renamed_columns = change_table_with_remaps(table_name, &block)
16
+ index_list = options[:disable_keys] ? disable_indexes(table_name) : []
17
+ #prepare the columns names for the insert statements
18
+ copy_table(old_table_name, table_name, renamed_columns)
19
+ enable_indexes(table_name, index_list) if options[:disable_keys]
20
+ drop_table(old_table_name)
21
+ rescue Exception => e
22
+ puts "#{e}\n#{e.backtrace}"
23
+ drop_table(table_name) if table_exists?(table_name)
24
+ rename_table(old_table_name, table_name)
25
+ raise e
26
+ end
27
+ end
28
+
29
+ def fast_add_indexes(table, &blk)
30
+ phoney = PhoneyTable.new(table.to_s)
31
+ yield phoney
32
+ enable_indexes(table, phoney.indexes)
33
+ end
34
+
35
+ #create_table_like( :sometable, :newtable, :remove_keys => true)
36
+ def create_table_like(like_table, table, options = {})
37
+ options.symbolize_keys!
38
+ code = table_schema_code(like_table)
39
+ code.gsub!(/create_table\s+"#{like_table}"/, "create_table :#{table}")
40
+ if options[:replace_keys] or options[:remove_keys]
41
+ code.gsub!(/add_index\s+"#{like_table}"/, "#add_index :#{table}")
42
+ else
43
+ code.gsub!(/add_index\s+"#{like_table}"/, "add_index :#{table}")
44
+ end
45
+ class_eval(code)
46
+ true
47
+ end
48
+
49
+ #copy_table( :sometable, :newtable, [[:old_column, :new_column]])
50
+ def copy_table(from, to, remaps = [])
51
+ old = connection.columns(from).collect(&:name)
52
+ current = connection.columns(to).collect(&:name)
53
+ remapped_columns = remaps.collect {|c| c.first.to_s}.compact
54
+ common = (current & old).sort - remapped_columns
55
+ from_columns = common.collect {|c| "`#{c}`"}
56
+ to_columns = common.collect {|c| "`#{c}`"}
57
+ remaps.each do |remap|
58
+ remap = [remap].flatten
59
+ next if remap.length != 2
60
+ from_columns << remap.first
61
+ to_columns << remap.last
62
+ end
63
+ from_columns_to_s = from_columns.join(', ')
64
+ to_columns_to_s = to_columns.join(', ')
65
+ execute "INSERT INTO #{to}(#{to_columns_to_s}) SELECT #{from_columns_to_s} FROM #{from}"
66
+ end
67
+
68
+ def table_schema_code(table)
69
+ dumper = ActiveRecord::SchemaDumper.send(:new, connection)
70
+ stream = StringIO.new
71
+ dumper.send(:table, table.to_s, stream)
72
+ stream.rewind
73
+ code = stream.read
74
+ end
75
+
76
+ #removes all the indexes
77
+ def disable_indexes(table)
78
+ list = connection.indexes(table)
79
+ list.each do |i|
80
+ remove_index table, :name => i.name
81
+ end
82
+ list
83
+ end
84
+
85
+ #
86
+ def enable_indexes(table, list)
87
+ list.each do |i|
88
+ options = {}
89
+ options[:name] = i.name if i.name
90
+ options[:length] = i.lengths if i.lengths
91
+ options[:unique] = i.unique if i.unique
92
+ add_index table, i.columns, options
93
+ end
94
+ true
95
+ end
96
+
97
+ class PhoneyTable
98
+
99
+ attr_accessor :indexes
100
+
101
+ def initialize(tablename)
102
+ @table = tablename
103
+ @indexes = []
104
+ end
105
+
106
+ def index(columns, options = {})
107
+ new_index = PhoneyIndex.new(@table, columns, options)
108
+ @indexes << new_index unless @indexes.to_a.any? {|i| i == new_index}
109
+ end
110
+
111
+ def indexes; @indexes.to_a.uniq end
112
+ end
113
+
114
+ class PhoneyIndex
115
+
116
+ attr_accessor :columns, :lengths, :name, :unique
117
+
118
+ def initialize(table, cols, options)
119
+ cols = [cols].flatten
120
+ self.columns = cols.collect(&:to_s)
121
+ self.lengths = options[:length]
122
+ self.unique = !!options[:unique]
123
+ self.name = options[:name] || "index_#{table}_on_#{columns.join('_and_')}"
124
+ self.name = "#{columns.join('_')}_idx" if name.length > 64
125
+ end
126
+
127
+ def ==(val)
128
+ columns == val.columns rescue false
129
+ end
130
+ end
131
+ end
132
+ end
@@ -1,3 +1,3 @@
1
1
  module FastChangeTable
2
- VERSION = "0.0.6"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Migration do
4
+ before(:each) do
5
+ ActiveRecord::Migration.create_table :my_table, :force => true do |t|
6
+ t.integer :an_integer
7
+ t.string :a_string
8
+ t.string :a_name
9
+ end
10
+ @connection = ActiveRecord::Migration.connection
11
+ end
12
+
13
+ after(:each) do
14
+ ActiveRecord::Migration.drop_table(:my_copied_table) rescue nil
15
+ end
16
+
17
+ describe "initialize table" do
18
+ it "should have expected starting table" do
19
+ @connection.columns("my_table").all? do |c|
20
+ ["id", "an_integer", "a_string", "a_name"].include?(c.name)
21
+ end.should eq(true)
22
+ end
23
+ end
24
+
25
+ describe "#create_table_like" do
26
+ it "should create an identical table" do
27
+ ActiveRecord::Migration.create_table_like(:my_table, :my_copied_table)
28
+
29
+ @connection.columns("my_copied_table").all? do |c|
30
+ ["id", "an_integer", "a_string", "a_name"].include?(c.name.to_s)
31
+ end.should eq(true)
32
+ end
33
+ end
34
+
35
+ describe "#fast_add_indexes, #disable_indexes, #enable_indexes" do
36
+ it "should add index, remove it then put it back" do
37
+ ActiveRecord::Migration.fast_add_indexes :my_table do |t|
38
+ t.index :an_integer, :name => "an_index"
39
+ end
40
+ @connection.indexes("my_table").collect(&:name).include?("an_index").should eq(true)
41
+
42
+ indexes = ActiveRecord::Migration.disable_indexes("my_table")
43
+ @connection.indexes("my_table").collect(&:name).include?("an_index").should eq(false)
44
+
45
+ ActiveRecord::Migration.enable_indexes("my_table", indexes)
46
+ @connection.indexes("my_table").collect(&:name).include?("an_index").should eq(true)
47
+ end
48
+ end
49
+
50
+ describe "#copy_table" do
51
+ it "should copy the records from one table to another" do
52
+ @connection.execute "INSERT my_table (an_integer, a_string, a_name) VALUES (1,'String','Name')"
53
+ ActiveRecord::Migration.create_table_like(:my_table, :my_copied_table)
54
+ ActiveRecord::Migration.add_column(:my_copied_table, :new_column, :string)
55
+ ActiveRecord::Migration.copy_table(:my_table, :my_copied_table, [["'Nothing'", "new_column"]])
56
+ record = @connection.select_all("select * from my_copied_table").first
57
+ record['an_integer'].should eq(1)
58
+ record['a_string'].should eq('String')
59
+ record['a_name'].should eq('Name')
60
+ record['new_column'].should eq('Nothing')
61
+ end
62
+ end
63
+
64
+ describe "#fast_change_table" do
65
+ it "should bring it all together" do
66
+ @connection.execute "INSERT my_table (an_integer, a_string, a_name) VALUES (1,'String','Name')"
67
+ ActiveRecord::Migration.add_index :my_table, :an_integer, :name => "an_index"
68
+ ActiveRecord::Migration.fast_change_table :my_table, :remove_keys => true do |t|
69
+ t.change :an_integer, :integer
70
+ t.change :a_string, :string
71
+ t.change :a_name, :string
72
+ t.string :new_column
73
+ end
74
+ record = @connection.select_all("select * from my_table").first
75
+ record['an_integer'].should eq(1)
76
+ record['a_string'].should eq('String')
77
+ record['a_name'].should eq('Name')
78
+ record['new_column'].should eq(nil)
79
+ @connection.indexes("my_table").empty?.should eq(true)
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'fast_change_table'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
9
+
10
+ ActiveRecord::Base.establish_connection(
11
+ :adapter => "mysql2",
12
+ :database => "fast_change_table_test"
13
+ )
14
+
15
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_change_table
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
9
  - 0
9
- - 6
10
- version: 0.0.6
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Grady Griffin
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-23 00:00:00 Z
18
+ date: 2012-02-02 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activerecord
@@ -32,6 +32,34 @@ dependencies:
32
32
  version: "2.3"
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: mysql2
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
35
63
  description: Uses table duplication to speed up migrations on large tables
36
64
  email:
37
65
  - gradyg@izea.com
@@ -45,12 +73,15 @@ files:
45
73
  - .gitignore
46
74
  - Gemfile
47
75
  - Gemfile.lock
48
- - README
76
+ - README.md
49
77
  - Rakefile
50
78
  - fast_change_table.gemspec
51
79
  - lib/fast_change_table.rb
80
+ - lib/fast_change_table/connection_adapters.rb
81
+ - lib/fast_change_table/fast_change_table.rb
52
82
  - lib/fast_change_table/version.rb
53
- - test/fast_change_table_test.rb
83
+ - spec/fast_change_table_spec.rb
84
+ - spec/spec_helper.rb
54
85
  homepage: https://github.com/moxie/fast_change_table
55
86
  licenses: []
56
87
 
@@ -85,4 +116,5 @@ signing_key:
85
116
  specification_version: 3
86
117
  summary: Faster table changes
87
118
  test_files:
88
- - test/fast_change_table_test.rb
119
+ - spec/fast_change_table_spec.rb
120
+ - spec/spec_helper.rb
data/README DELETED
@@ -1,39 +0,0 @@
1
- Use fast_change_table instead of change_table in your migrations on large tables of data. Uses a duplication pattern to speed things up.
2
-
3
- # Known issues
4
- - Not tested
5
-
6
- uses ordinary change_table syntax but adds two options
7
- - "replace_keys" to remove all indexes; new indexes will be specified
8
- - "disable_keys" to remove indexes and apply them after data load; this is a tremendous performance enhancement for a dbms with fast index creation
9
-
10
- other methods:
11
-
12
- create_table_like(orignal_table, table_to_copy_to)
13
- creates a table with the same structure
14
-
15
- disable_indexes(table)
16
- removes all indexes from a table, returns a list of index objects removed
17
-
18
- enable_indexes(table, list_of_indexes)
19
- restores a list of indexes to a table
20
-
21
- fast_add_indexes(table, &block)
22
- allows you to pass a block to add indexes. For mysql creates specified indexes in one statement; allows the data to be scanned once.
23
- example
24
-
25
- fast_add_indexes :sometable do |t|
26
- t.index :some_column
27
- t.index [:some_other_column, :column_three], :name => "a_multicolumn_index"
28
- end
29
-
30
- copy_table(from_table, to_table, remaps = [])
31
- copies rows from one table into another. this probably only works with Mysql.
32
- by default copies data from column of from_table to to_table of same name.
33
- will not copy data where there is no corresponding column.
34
- the remaps argument can be supplied to tell copy table how to handle unmatched columns or override this behavior
35
- examples
36
-
37
- copy_table(old_users_without_email_hash, new_table, ['MD5(email)', 'email_hash'])
38
-
39
- copy_table(old_users_without_total, new_table, ['sum(payments)', 'total_payments'])
@@ -1 +0,0 @@
1
- require 'test/unit'