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