76a3161d1ac9a17d0f58bb1dede4701af839decc
[rails.git] / db / migrate / 006_remove_segments.rb
1 require 'lib/migrate'
2
3 class RemoveSegments < ActiveRecord::Migration
4   def self.up
5     prefix = File.join Dir.tmpdir, "006_remove_segments.#{$$}."
6
7     cmd = "db/migrate/006_remove_segments_helper"
8     src = "#{cmd}.cc"
9     if not File.exists? cmd or File.mtime(cmd) < File.mtime(src) then 
10       system 'c++ -O3 -Wall `mysql_config --cflags --libs` ' +
11         "#{src} -o #{cmd}" or fail
12     end
13
14     conn_opts = ActiveRecord::Base.connection.
15       instance_eval { @connection_options }
16     args = conn_opts.map { |arg| arg.to_s } + [prefix]
17     fail "#{cmd} failed" unless system cmd, *args
18
19     tempfiles = ['ways', 'way_nodes', 'way_tags',
20       'relations', 'relation_members', 'relation_tags'].
21       map { |base| prefix + base }
22     ways, way_nodes, way_tags,
23       relations, relation_members, relation_tags = tempfiles
24
25     drop_table :segments
26     drop_table :way_segments
27     create_table :way_nodes, myisam_table do |t|
28       t.column :id,          :bigint, :limit => 64, :null => false
29       t.column :node_id,     :bigint, :limit => 64, :null => false
30       t.column :version,     :bigint, :limit => 20, :null => false
31       t.column :sequence_id, :bigint, :limit => 11, :null => false
32     end
33     add_primary_key :way_nodes, [:id, :version, :sequence_id]
34
35     drop_table :current_segments
36     drop_table :current_way_segments
37     create_table :current_way_nodes, innodb_table do |t|
38       t.column :id,          :bigint, :limit => 64, :null => false
39       t.column :node_id,     :bigint, :limit => 64, :null => false
40       t.column :sequence_id, :bigint, :limit => 11, :null => false
41     end
42     add_primary_key :current_way_nodes, [:id, :sequence_id]
43
44     execute "DELETE FROM way_tags"
45     execute "DELETE FROM ways"
46     execute "DELETE FROM current_way_tags"
47     execute "DELETE FROM current_ways"
48
49     # now get the data back
50     csvopts = "FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\\n'"
51
52     tempfiles.each { |fn| File.chmod 0644, fn }
53
54     execute "LOAD DATA LOCAL INFILE '#{ways}' INTO TABLE ways #{csvopts} (id, user_id, timestamp) SET visible = 1, version = 1"
55     execute "LOAD DATA LOCAL INFILE '#{way_nodes}' INTO TABLE way_nodes #{csvopts} (id, node_id, sequence_id) SET version = 1"
56     execute "LOAD DATA LOCAL INFILE '#{way_tags}' INTO TABLE way_tags #{csvopts} (id, k, v) SET version = 1"
57
58     execute "INSERT INTO current_ways SELECT id, user_id, timestamp, visible FROM ways"
59     execute "INSERT INTO current_way_nodes SELECT id, node_id, sequence_id FROM way_nodes"
60     execute "INSERT INTO current_way_tags SELECT id, k, v FROM way_tags"
61
62     # and then readd the index
63     add_index :current_way_nodes, [:node_id], :name => "current_way_nodes_node_idx"
64
65     execute "LOAD DATA LOCAL INFILE '#{relations}' INTO TABLE relations #{csvopts} (id, user_id, timestamp) SET visible = 1, version = 1"
66     execute "LOAD DATA LOCAL INFILE '#{relation_members}' INTO TABLE relation_members #{csvopts} (id, member_type, member_id, member_role) SET version = 1"
67     execute "LOAD DATA LOCAL INFILE '#{relation_tags}' INTO TABLE relation_tags #{csvopts} (id, k, v) SET version = 1"
68
69     # FIXME: This will only work if there were no relations before the
70     # migration!
71     execute "INSERT INTO current_relations SELECT id, user_id, timestamp, visible FROM relations"
72     execute "INSERT INTO current_relation_members SELECT id, member_type, member_id, member_role FROM relation_members"
73     execute "INSERT INTO current_relation_tags SELECT id, k, v FROM relation_tags"
74
75     tempfiles.each { |fn| File.unlink fn }
76   end
77
78   def self.down
79     raise IrreversibleMigration.new
80   end
81 end