1 class RemoveSegments < ActiveRecord::Migration[4.2]
 
   3     have_segs = select_value("SELECT count(*) FROM current_segments").to_i.nonzero?
 
   6       prefix = File.join Dir.tmpdir, "008_remove_segments.#{$PROCESS_ID}."
 
   8       cmd = "db/migrate/008_remove_segments_helper"
 
  10       if !File.exist?(cmd) || File.mtime(cmd) < File.mtime(src)
 
  11         system("c++ -O3 -Wall `mysql_config --cflags --libs` " \
 
  12                "#{src} -o #{cmd}") || raise
 
  15       conn_opts = ApplicationRecord.connection
 
  16                                    .instance_eval { @connection_options }
 
  17       args = conn_opts.map(&:to_s) + [prefix]
 
  18       raise "#{cmd} failed" unless system cmd, *args
 
  20       tempfiles = %w[ways way_nodes way_tags relations relation_members relation_tags]
 
  21                   .map { |base| prefix + base }
 
  22       ways, way_nodes, way_tags,
 
  23   relations, relation_members, relation_tags = tempfiles
 
  27     drop_table :way_segments
 
  28     create_table :way_nodes, :id => false do |t|
 
  29       t.column :id,          :bigint, :null => false
 
  30       t.column :node_id,     :bigint, :null => false
 
  31       t.column :version,     :bigint, :null => false
 
  32       t.column :sequence_id, :bigint, :null => false
 
  34     add_primary_key :way_nodes, [:id, :version, :sequence_id]
 
  36     drop_table :current_segments
 
  37     drop_table :current_way_segments
 
  38     create_table :current_way_nodes, :id => false do |t|
 
  39       t.column :id,          :bigint, :null => false
 
  40       t.column :node_id,     :bigint, :null => false
 
  41       t.column :sequence_id, :bigint, :null => false
 
  43     add_primary_key :current_way_nodes, [:id, :sequence_id]
 
  44     add_index :current_way_nodes, [:node_id], :name => "current_way_nodes_node_idx"
 
  46     execute "TRUNCATE way_tags"
 
  47     execute "TRUNCATE ways"
 
  48     execute "TRUNCATE current_way_tags"
 
  49     execute "TRUNCATE current_ways"
 
  51     # now get the data back
 
  52     csvopts = "FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\\n'"
 
  54     tempfiles.each { |fn| File.chmod 0o644, fn } if have_segs
 
  57       execute "LOAD DATA INFILE '#{ways}' INTO TABLE ways #{csvopts} (id, user_id, timestamp) SET visible = 1, version = 1"
 
  58       execute "LOAD DATA INFILE '#{way_nodes}' INTO TABLE way_nodes #{csvopts} (id, node_id, sequence_id) SET version = 1"
 
  59       execute "LOAD DATA INFILE '#{way_tags}' INTO TABLE way_tags #{csvopts} (id, k, v) SET version = 1"
 
  61       execute "INSERT INTO current_ways SELECT id, user_id, timestamp, visible FROM ways"
 
  62       execute "INSERT INTO current_way_nodes SELECT id, node_id, sequence_id FROM way_nodes"
 
  63       execute "INSERT INTO current_way_tags SELECT id, k, v FROM way_tags"
 
  67       execute "LOAD DATA INFILE '#{relations}' INTO TABLE relations #{csvopts} (id, user_id, timestamp) SET visible = 1, version = 1"
 
  68       execute "LOAD DATA INFILE '#{relation_members}' INTO TABLE relation_members #{csvopts} (id, member_type, member_id, member_role) SET version = 1"
 
  69       execute "LOAD DATA INFILE '#{relation_tags}' INTO TABLE relation_tags #{csvopts} (id, k, v) SET version = 1"
 
  71       # FIXME: This will only work if there were no relations before the
 
  73       execute "INSERT INTO current_relations SELECT id, user_id, timestamp, visible FROM relations"
 
  74       execute "INSERT INTO current_relation_members SELECT id, member_type, member_id, member_role FROM relation_members"
 
  75       execute "INSERT INTO current_relation_tags SELECT id, k, v FROM relation_tags"
 
  78     tempfiles.each { |fn| File.unlink fn } if have_segs
 
  82     raise ActiveRecord::IrreversibleMigration