mover 0.2.1 → 0.2.2

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.
Files changed (5) hide show
  1. data/lib/mover.rb +48 -7
  2. data/require.rb +1 -1
  3. data/spec/log/test.log +11527 -6294
  4. data/spec/mover_spec.rb +19 -12
  5. metadata +20 -9
data/lib/mover.rb CHANGED
@@ -75,13 +75,54 @@ module Mover
75
75
  # Execute
76
76
  transaction do
77
77
  exec_callbacks.call before
78
- connection.execute(<<-SQL)
79
- INSERT INTO #{to_class.table_name} (#{insert.join(', ')})
80
- SELECT #{select.join(', ')}
81
- FROM #{from_class.table_name}
82
- #{where}
83
- SQL
84
- connection.execute("DELETE FROM #{from_class.table_name} #{where}") unless copy
78
+ if copy
79
+ # for copy existing rows require an UPDATE statment, new rows require an INSERT statement
80
+ from_ids = from_class.find(:all, :select => "id", :conditions => where[5..-1]).collect(&:id)
81
+ to_ids = to_class.find(:all, :select => "id", :conditions => where[5..-1]).collect(&:id)
82
+ trash_ids = to_ids - from_ids
83
+ # rid of the 'extra' to_ids to ensure to_ids is always be a subset of from_ids
84
+ insert_ids = from_ids - to_ids - trash_ids
85
+ update_ids = to_ids - insert_ids - trash_ids
86
+
87
+ unless update_ids.empty?
88
+ # add table scope to columns for the UPDATE statement
89
+ update = []
90
+ insert.each_with_index{|col, i|
91
+ to = insert[i].include?('`') ? "#{to_class.table_name}.#{insert[i]}" : insert[i]
92
+ from = select[i].include?('`') ? "#{from_class.table_name}.#{select[i]}" : select[i]
93
+ update << "#{to} = #{from}"
94
+ }
95
+ where_ids = update_ids.collect{|x| "#{from_class.table_name}.id = #{x}"}
96
+ connection.execute(<<-SQL)
97
+ UPDATE #{to_class.table_name}
98
+ INNER JOIN #{from_class.table_name}
99
+ ON #{to_class.table_name}.id = #{from_class.table_name}.id
100
+ AND (#{where_ids.join(' AND ')})
101
+ SET #{update.join(', ')}
102
+ SQL
103
+ end
104
+
105
+ unless insert_ids.empty?
106
+ # insert ids, same as move except using a different where clause
107
+ where_ids = insert_ids.collect{|x| "#{from_class.table_name}.id = #{x}"}
108
+ sql =<<-SQL
109
+ INSERT INTO #{to_class.table_name} (#{insert.join(', ')})
110
+ SELECT #{select.join(', ')}
111
+ FROM #{from_class.table_name}
112
+ WHERE (#{where_ids.join(' OR ')})
113
+ SQL
114
+ connection.execute(sql)
115
+ end
116
+ else
117
+ # moves
118
+ connection.execute(<<-SQL)
119
+ INSERT INTO #{to_class.table_name} (#{insert.join(', ')})
120
+ SELECT #{select.join(', ')}
121
+ FROM #{from_class.table_name}
122
+ #{where}
123
+ SQL
124
+ connection.execute("DELETE FROM #{from_class.table_name} #{where}")
125
+ end
85
126
  exec_callbacks.call after
86
127
  end
87
128
  end
data/require.rb CHANGED
@@ -17,7 +17,7 @@ Require do
17
17
  name 'mover'
18
18
  homepage "http://github.com/winton/#{name}"
19
19
  summary "Move ActiveRecord records across tables like it ain't no thang"
20
- version '0.2.1'
20
+ version '0.2.2'
21
21
  end
22
22
 
23
23
  bin { require 'lib/mover' }