Module: FastChangeTable::InstanceMethods

Defined in:
lib/fast_change_table/fast_change_table.rb

Defined Under Namespace

Classes: PhoneyIndex, PhoneyTable

Instance Method Summary collapse

Instance Method Details

#change_table_with_remaps(table_name, options = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/fast_change_table/fast_change_table.rb', line 24

def change_table_with_remaps(table_name, options = {})
  options.reverse_merge!(:bulk => true)
  if respond_to?('supports_bulk_alter?') && supports_bulk_alter? && options[:bulk]
    recorder = ActiveRecord::Migration::CommandRecorder.new(self)
    t = ActiveRecord::ConnectionAdapters::Table.new(table_name, recorder)
    yield t
    bulk_change_table(table_name, recorder.commands)
  else
    t = ActiveRecord::ConnectionAdapters::Table.new(table_name, self)
    yield t
  end
  return t.renamed_columns
end

#copy_table_data(from, to, remaps = []) ⇒ Object

copy_table_data( :sometable, :newtable, [[:old_column, :new_column]])



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fast_change_table/fast_change_table.rb', line 60

def copy_table_data(from, to, remaps = [])
  old = columns(from).collect(&:name)
  current = columns(to).collect(&:name)
  remapped_columns = remaps.collect {|c| c.first.to_s}.compact
  common = (current & old).sort - remapped_columns
  from_columns = common.collect {|c| "`#{c}`"}
  to_columns = common.collect {|c| "`#{c}`"}
  remaps.each do |remap|
    remap = [remap].flatten
    next if remap.length != 2
    from_columns << remap.first
    to_columns << remap.last
  end
  from_columns_to_s = from_columns.join(', ')
  to_columns_to_s   = to_columns.join(', ')
  execute "INSERT INTO #{to}(#{to_columns_to_s}) SELECT #{from_columns_to_s} FROM #{from}"
end

#create_table_like(like_table, table, options = {}, &blk) ⇒ Object

create_table_like( :sometable, :newtable, :remove_keys => true)



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fast_change_table/fast_change_table.rb', line 45

def create_table_like(like_table, table, options = {}, &blk)
  options.symbolize_keys!
  code = table_schema_code(like_table)
  code.gsub!(/create_table\s+"#{like_table}"/, "create_table :#{table}")
  if options[:replace_keys] or options[:remove_keys]
    code.gsub!(/add_index\s+"#{like_table}"/, "#add_index :#{table}")
  else
    code.gsub!(/add_index\s+"#{like_table}"/, "add_index :#{table}")
  end
  eval(code)
  change_table(table,&blk) if block_given?
  true
end

#disable_indexes(table) ⇒ Object

removes all the indexes



87
88
89
90
91
92
93
94
95
# File 'lib/fast_change_table/fast_change_table.rb', line 87

def disable_indexes(table)
  list = indexes(table)
  change_table_with_remaps table do |t|
    list.each do |i|
      t.remove_index :name => i.name
    end
  end
  list
end

#enable_indexes(table, list) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/fast_change_table/fast_change_table.rb', line 98

def enable_indexes(table, list)
  change_table_with_remaps table do |t|
    list.each do |i|
      options = {}
      options[:name]    = i.name    if i.name
      options[:length]  = i.lengths if i.lengths
      options[:unique]  = i.unique  if i.unique
      t.index i.columns, options
    end
  end
  true
end

#fast_add_indexes(table) {|phoney| ... } ⇒ Object

Yields:

  • (phoney)


38
39
40
41
42
# File 'lib/fast_change_table/fast_change_table.rb', line 38

def fast_add_indexes(table, &blk)
  phoney = PhoneyTable.new(table.to_s)
  yield phoney
  enable_indexes(table, phoney.indexes)
end

#fast_change_table(table_name, options = {}, &block) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/fast_change_table/fast_change_table.rb', line 4

def fast_change_table(table_name, options = {}, &block)
  options.symbolize_keys!
  old_table_name = "old_#{table_name}"
  rename_table(table_name, old_table_name)
  begin
   create_table_like(old_table_name, table_name, options)
   renamed_columns = change_table_with_remaps(table_name, options, &block)
   index_list = options[:disable_keys] == false  ? [] : disable_indexes(table_name)
   #prepare the columns names for the insert statements
   copy_table_data(old_table_name, table_name, renamed_columns)
   enable_indexes(table_name, index_list) unless options[:disable_keys] == false
   drop_table(old_table_name)
  rescue Exception => e
    puts "#{e}\n#{e.backtrace}"
    drop_table(table_name) if table_exists?(table_name)
    rename_table(old_table_name, table_name)
    raise e
  end
end

#table_schema_code(table) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/fast_change_table/fast_change_table.rb', line 78

def table_schema_code(table)
  dumper = ActiveRecord::SchemaDumper.send(:new, self)
  stream = StringIO.new
  dumper.send(:table, table.to_s, stream)
  stream.rewind
  code = stream.read
end