public
Fork of stopdropandrew/single-table-inheritance-cleaver
Description: chops STI tables arms and legs off, leaving them in a pile on the floor
Clone URL: git://github.com/duncanbeevers/single-table-inheritance-cleaver.git
Search Repo:
Rely on ActiveRecord for mysql construction
Get max id of last processed chunk.
duncanbeevers (author)
Thu Jul 17 12:24:23 -0700 2008
commit  ce4d443f866cdccde717bc0026be2afd86deedf8
tree    8dbb54cb0fdecc6277e29ad2536c61b20399ad95
parent  9f421ce17b01ff64fdb52d71c4fdb122dead5554
...
7
8
9
 
 
 
 
 
 
 
 
 
 
 
 
10
11
 
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
14
15
...
42
43
44
45
 
46
47
48
...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
 
 
 
 
 
 
 
109
110
111
...
121
122
123
124
125
 
 
126
127
128
...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
75
76
77
 
78
79
80
81
...
108
109
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
 
 
 
 
 
 
 
112
113
114
115
116
117
118
119
120
121
...
131
132
133
 
 
134
135
136
137
138
0
@@ -7,9 +7,42 @@ class SingleTableInheritanceCleaver
0
   DISALLOWED_COLUMN_NAMES = %w(id type)
0
 
0
   class SourceClass < ActiveRecord::Base
0
+ class << self
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
+ ).first
0
+ return false unless max_id_attrs
0
+
0
+ max_id_attrs['id'].to_i
0
+ end
0
+ end
0
   end
0
-
0
+
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
+
0
+ columns = options.delete(:columns)
0
+ sql_column_names = columns.join(', ')
0
+
0
+ sql = "INSERT INTO #{table_name} (#{sql_column_names}) #{SourceClass.construct_finder_sql(options.merge(:select => sql_column_names))}"
0
+
0
+ previous_max = self.maximum('id')
0
+ self.connection.insert sql
0
+ current_max = self.maximum('id')
0
+
0
+ return false unless current_max.to_i != previous_max.to_i
0
+
0
+ last_id_processed = SourceClass.last_id_for_chunk(options)
0
+ return false unless last_id_processed
0
+
0
+ last_id_processed + 1
0
+ end
0
   end
0
 
0
   def initialize(source, options = {})
0
@@ -42,7 +75,7 @@ class SingleTableInheritanceCleaver
0
     additional_conditions = options[:conditions] || {}
0
     self.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
     end
0
   end
0
   
0
@@ -75,37 +108,14 @@ class SingleTableInheritanceCleaver
0
   
0
   def cleave_chunk source_type, destination_table_name, starting_id = 0
0
     return nil unless self.destinations.keys.include?(source_type)
0
-
0
- DestinationClass.set_table_name destination_table_name
0
- previous_max = DestinationClass.maximum('id')
0
- column_names = column_names(destination_table_name)
0
-
0
- conditions = merge_conditions(self.conditions[destination_table_name], [ 'id >= ?', starting_id ] )
0
- sql_column_names = column_names.join(', ')
0
-
0
- sql = [
0
- 'INSERT INTO ', destination_table_name,
0
- '(', sql_column_names, ') ',
0
- job_select(sql_column_names, conditions)
0
- ].join
0
-
0
- SourceClass.connection.insert sql
0
- current_max = DestinationClass.maximum('id')
0
-
0
- return false unless current_max.to_i != previous_max.to_i
0
-
0
- last_id_processed = SourceClass.connection.execute(job_select('id', conditions)).map do |r| r['id'].to_i end.max
0
- last_id_processed + 1
0
- end
0
 
0
- def job_select columns, conditions
0
- [
0
- 'SELECT ', columns,
0
- ' FROM ', SourceClass.table_name,
0
- ' WHERE ', conditions,
0
- ' ORDER BY id',
0
- ' LIMIT ', chunk_size
0
- ].join
0
+ DestinationClass.copy_chunk(
0
+ destination_table_name,
0
+ starting_id,
0
+ :columns => column_names(destination_table_name),
0
+ :conditions => conditions[destination_table_name],
0
+ :limit => chunk_size
0
+ )
0
   end
0
 
0
   def column_names(destination_table_name)
0
@@ -121,8 +131,8 @@ class SingleTableInheritanceCleaver
0
     puts [ Time.now, ': ', what ].join if output
0
   end
0
 
0
- def merge_conditions condition1, condition2
0
- SourceClass.send(:merge_conditions, condition1, condition2)
0
+ def merge_conditions *args
0
+ SourceClass.merge_conditions *args
0
   end
0
 
0
 end

Comments

    No one has commented yet.