diff --git a/lib/db_helper.rb b/lib/db_helper.rb index 04c9f8d3fb3..237a86bacdc 100644 --- a/lib/db_helper.rb +++ b/lib/db_helper.rb @@ -8,10 +8,8 @@ class DbHelper AND (data_type LIKE 'char%' OR data_type LIKE 'text%') ORDER BY table_name, column_name" - def self.remap(from, to, anchor_left: false, anchor_right: false, exclude_tables: []) + def self.remap(from, to, exclude_tables: []) results = DB.query(REMAP_SQL).to_a - like = "#{anchor_left ? '' : "%"}#{from}#{anchor_right ? '' : "%"}" - remappable_columns = {} results.each do |result| @@ -24,14 +22,14 @@ class DbHelper remappable_columns.each do |table_name, column_names| next if exclude_tables.include?(table_name) set_clause = column_names.map do |column_name| - "#{column_name} = REPLACE(#{column_name}, :from, :to)" + "#{column_name} = REGEXP_REPLACE(#{column_name}, :from, :to)" end.join(", ") where_clause = column_names.map do |column_name| - "#{column_name} LIKE :like" + "#{column_name} ~* :from" end.join(" OR ") - DB.exec(<<~SQL, from: from, to: to, like: like) + DB.exec(<<~SQL, from: from, to: to, from: from) UPDATE #{table_name} SET #{set_clause} WHERE #{where_clause} diff --git a/spec/lib/db_helper_spec.rb b/spec/lib/db_helper_spec.rb index e9d796257cf..c8de4bbd550 100644 --- a/spec/lib/db_helper_spec.rb +++ b/spec/lib/db_helper_spec.rb @@ -40,5 +40,29 @@ RSpec.describe DbHelper do expect(post.reload.cooked).to eq('test') end + + it 'accepts a POSIX regular expression' do + url = "https://some.complicated.url/that/I/can/come/up.with" + + post = Fabricate(:post, + cooked: "something something#{url}something something" + ) + + url2 = "https://some.other.complicated/url/I/can/come/up.with" + + post2 = Fabricate(:post, + cooked: "something #{url2} something something" + ) + + DbHelper.remap("(#{url}|#{url2})", "DISCOURSE!") + + expect(post.reload.cooked).to eq( + 'something somethingDISCOURSE!something something' + ) + + expect(post2.reload.cooked).to eq( + "something DISCOURSE! something something" + ) + end end end