diff --git a/lib/remap.rb b/lib/remap.rb new file mode 100644 index 00000000000..45755fb3310 --- /dev/null +++ b/lib/remap.rb @@ -0,0 +1,43 @@ +class Remap + def initialize(from, to, regex: false, verbose: false) + @from = from + @to = to + @regex = regex + @verbose = verbose + end + + def perform + sql = "SELECT table_name, column_name +FROM information_schema.columns +WHERE table_schema='public' and (data_type like 'char%' or data_type like 'text%') and is_updatable = 'YES'" + + cnn = ActiveRecord::Base.connection.raw_connection + + results = cnn.async_exec(sql).to_a + + results.each do |result| + table_name = result["table_name"] + column_name = result["column_name"] + + log "Remapping #{table_name} #{column_name}" + + result = if @regex + cnn.async_exec("UPDATE #{table_name} + SET #{column_name} = regexp_replace(#{column_name}, $1, $2, 'g') + WHERE NOT #{column_name} IS NULL + AND #{column_name} <> regexp_replace(#{column_name}, $1, $2, 'g')", [@from, @to]) + else + cnn.async_exec("UPDATE #{table_name} + SET #{column_name} = replace(#{column_name}, $1, $2) + WHERE NOT #{column_name} IS NULL + AND #{column_name} <> replace(#{column_name}, $1, $2)", [@from, @to]) + end + + log "#{result.cmd_tuples} rows affected!" + end + end + + def log(message) + puts(message) if @verbose + end +end diff --git a/script/discourse b/script/discourse index 22929741a4d..3cf57078fe2 100755 --- a/script/discourse +++ b/script/discourse @@ -30,6 +30,7 @@ class DiscourseCLI < Thor option :regex, type: :boolean def remap(from, to) load_rails + require 'remap' if options[:regex] puts "Rewriting all occurences of #{from} to #{to} using regexp_replace" @@ -237,36 +238,13 @@ class DiscourseCLI < Thor end def do_remap(from, to, regex = false) - sql = "SELECT table_name, column_name -FROM information_schema.columns -WHERE table_schema='public' and (data_type like 'char%' or data_type like 'text%') and is_updatable = 'YES'" - - cnn = ActiveRecord::Base.connection.raw_connection - - results = cnn.async_exec(sql).to_a - - results.each do |result| - table_name = result["table_name"] - column_name = result["column_name"] - puts "Remapping #{table_name} #{column_name}" - begin - result = if regex - cnn.async_exec("UPDATE #{table_name} - SET #{column_name} = regexp_replace(#{column_name}, $1, $2, 'g') - WHERE NOT #{column_name} IS NULL - AND #{column_name} <> regexp_replace(#{column_name}, $1, $2, 'g')", [from, to]) - else - cnn.async_exec("UPDATE #{table_name} - SET #{column_name} = replace(#{column_name}, $1, $2) - WHERE NOT #{column_name} IS NULL - AND #{column_name} <> replace(#{column_name}, $1, $2)", [from, to]) - end - puts "#{result.cmd_tuples} rows affected!" - rescue => ex - puts "Error: #{ex}" - puts "The remap has only been partially applied due to the error above. Please re-run the script again." - exit(1) - end + begin + Remap.new(from, to, regex: regex, verbose: true).perform + puts 'Done', '' + rescue => ex + puts "Error: #{ex}" + puts "The remap has only been partially applied due to the error above. Please re-run the script again." + exit(1) end end