2015-06-12 18:02:36 +08:00
|
|
|
class DbHelper
|
|
|
|
|
|
|
|
REMAP_SQL ||= "
|
|
|
|
SELECT table_name, column_name
|
|
|
|
FROM information_schema.columns
|
|
|
|
WHERE table_schema = 'public'
|
|
|
|
AND is_updatable = 'YES'
|
|
|
|
AND (data_type LIKE 'char%' OR data_type LIKE 'text%')
|
|
|
|
ORDER BY table_name, column_name"
|
|
|
|
|
2018-11-08 14:20:09 +08:00
|
|
|
def self.remap(from, to, anchor_left: false, anchor_right: false, exclude_tables: [])
|
2018-11-08 09:57:01 +08:00
|
|
|
results = DB.query(REMAP_SQL).to_a
|
2018-11-08 14:20:09 +08:00
|
|
|
like = "#{anchor_left ? '' : "%"}#{from}#{anchor_right ? '' : "%"}"
|
|
|
|
|
2018-11-08 09:57:01 +08:00
|
|
|
remappable_columns = {}
|
|
|
|
|
|
|
|
results.each do |result|
|
|
|
|
remappable_columns[result.table_name] ||= []
|
|
|
|
remappable_columns[result.table_name] << result.column_name
|
|
|
|
end
|
|
|
|
|
2018-11-08 12:28:50 +08:00
|
|
|
exclude_tables = exclude_tables.map(&:to_s)
|
|
|
|
|
2018-11-08 09:57:01 +08:00
|
|
|
remappable_columns.each do |table_name, column_names|
|
2018-11-08 12:28:50 +08:00
|
|
|
next if exclude_tables.include?(table_name)
|
2018-11-08 09:57:01 +08:00
|
|
|
set_clause = column_names.map do |column_name|
|
2018-11-08 14:20:09 +08:00
|
|
|
"#{column_name} = REPLACE(#{column_name}, :from, :to)"
|
2018-11-08 09:57:01 +08:00
|
|
|
end.join(", ")
|
|
|
|
|
|
|
|
where_clause = column_names.map do |column_name|
|
2018-11-08 14:20:09 +08:00
|
|
|
"#{column_name} LIKE :like"
|
2018-11-08 09:57:01 +08:00
|
|
|
end.join(" OR ")
|
|
|
|
|
2018-11-08 14:20:09 +08:00
|
|
|
DB.exec(<<~SQL, from: from, to: to, like: like)
|
2018-11-08 09:57:01 +08:00
|
|
|
UPDATE #{table_name}
|
|
|
|
SET #{set_clause}
|
|
|
|
WHERE #{where_clause}
|
|
|
|
SQL
|
2015-06-12 18:02:36 +08:00
|
|
|
end
|
2018-04-23 16:26:33 +08:00
|
|
|
|
2018-04-23 15:57:13 +08:00
|
|
|
SiteSetting.refresh!
|
2015-06-12 18:02:36 +08:00
|
|
|
end
|
|
|
|
|
2018-06-08 01:16:03 +08:00
|
|
|
def self.find(needle, anchor_left = false, anchor_right = false)
|
2018-06-07 22:51:16 +08:00
|
|
|
connection = ActiveRecord::Base.connection.raw_connection
|
|
|
|
text_columns = connection.async_exec(REMAP_SQL).to_a
|
2018-06-08 01:16:03 +08:00
|
|
|
args = ["#{anchor_left ? '' : "%"}#{needle}#{anchor_right ? '' : "%"}"]
|
2018-06-07 22:51:16 +08:00
|
|
|
found = {}
|
|
|
|
|
|
|
|
text_columns.each do |rc|
|
|
|
|
table_name = rc["table_name"]
|
|
|
|
column_name = rc["column_name"]
|
|
|
|
result = connection.async_exec("SELECT #{column_name} FROM #{table_name} WHERE #{column_name} LIKE $1", args) rescue nil
|
|
|
|
if result&.ntuples > 0
|
2018-06-07 23:05:41 +08:00
|
|
|
found["#{table_name}.#{column_name}"] = result.map { |r| r[column_name] }
|
2018-06-07 22:51:16 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
found
|
|
|
|
end
|
|
|
|
|
2015-06-12 18:02:36 +08:00
|
|
|
end
|