0
@@ -7,9 +7,42 @@ class SingleTableInheritanceCleaver
0
DISALLOWED_COLUMN_NAMES = %w(id type)
0
class SourceClass < ActiveRecord::Base
0
+ public :merge_conditions, :construct_finder_sql
0
+ def last_id_for_chunk options
0
+ offset = options[:limit] - 1
0
+ max_id_attrs = self.connection.execute(
0
+ construct_finder_sql(options.merge(:select => 'id', :offset => offset, :limit => 1))
0
+ return false unless max_id_attrs
0
+ max_id_attrs['id'].to_i
0
class DestinationClass < ActiveRecord::Base
0
+ def self.copy_chunk table_name, starting_id, new_options = {}
0
+ set_table_name table_name
0
+ options = new_options.clone
0
+ options[:conditions] = merge_conditions(new_options[:conditions], [ 'id >= ?', starting_id ] )
0
+ columns = options.delete(:columns)
0
+ sql_column_names = columns.join(', ')
0
+ sql = "INSERT INTO #{table_name} (#{sql_column_names}) #{SourceClass.construct_finder_sql(options.merge(:select => sql_column_names))}"
0
+ previous_max = self.maximum('id')
0
+ self.connection.insert sql
0
+ current_max = self.maximum('id')
0
+ return false unless current_max.to_i != previous_max.to_i
0
+ last_id_processed = SourceClass.last_id_for_chunk(options)
0
+ return false unless last_id_processed
0
def initialize(source, options = {})
0
@@ -42,7 +75,7 @@ class SingleTableInheritanceCleaver
0
additional_conditions = options[:conditions] || {}
0
self.destinations.each do |source_type, destination_table_name|
0
- self.conditions[destination_table_name] =
merge_conditions(additional_conditions, :type => source_type)
0
+ self.conditions[destination_table_name] =
SourceClass.merge_conditions(additional_conditions, :type => source_type)
0
@@ -75,37 +108,14 @@ class SingleTableInheritanceCleaver
0
def cleave_chunk source_type, destination_table_name, starting_id = 0
0
return nil unless self.destinations.keys.include?(source_type)
0
- DestinationClass.set_table_name destination_table_name
0
- previous_max = DestinationClass.maximum('id')
0
- column_names = column_names(destination_table_name)
0
- conditions = merge_conditions(self.conditions[destination_table_name], [ 'id >= ?', starting_id ] )
0
- sql_column_names = column_names.join(', ')
0
- 'INSERT INTO ', destination_table_name,
0
- '(', sql_column_names, ') ',
0
- job_select(sql_column_names, conditions)
0
- SourceClass.connection.insert sql
0
- current_max = DestinationClass.maximum('id')
0
- return false unless current_max.to_i != previous_max.to_i
0
- last_id_processed = SourceClass.connection.execute(job_select('id', conditions)).map do |r| r['id'].to_i end.max
0
- def job_select columns, conditions
0
- ' FROM ', SourceClass.table_name,
0
- ' WHERE ', conditions,
0
+ DestinationClass.copy_chunk(
0
+ destination_table_name,
0
+ :columns => column_names(destination_table_name),
0
+ :conditions => conditions[destination_table_name],
0
def column_names(destination_table_name)
0
@@ -121,8 +131,8 @@ class SingleTableInheritanceCleaver
0
puts [ Time.now, ': ', what ].join if output
0
- def merge_conditions condition1, condition2
0
- SourceClass.send(:merge_conditions, condition1, condition2)
0
+ def merge_conditions *args
0
+ SourceClass.merge_conditions *args
Comments
No one has commented yet.