2015-06-12 06:02:36 -04:00
|
|
|
class DbHelper
|
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
REMAP_SQL ||= <<~SQL
|
2015-06-12 06:02:36 -04:00
|
|
|
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%')
|
2018-12-26 11:34:49 -05:00
|
|
|
ORDER BY table_name, column_name
|
|
|
|
SQL
|
2015-06-12 06:02:36 -04:00
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
def self.remap(from, to, anchor_left: false, anchor_right: false, excluded_tables: [])
|
2018-11-08 01:20:09 -05:00
|
|
|
like = "#{anchor_left ? '' : "%"}#{from}#{anchor_right ? '' : "%"}"
|
2018-12-26 11:34:49 -05:00
|
|
|
text_columns = Hash.new { |h, k| h[k] = [] }
|
2018-11-08 01:20:09 -05:00
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
DB.query(REMAP_SQL).each do |r|
|
|
|
|
text_columns[r.table_name] << r.column_name
|
2018-11-07 20:57:01 -05:00
|
|
|
end
|
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
text_columns.each do |table, columns|
|
|
|
|
next if excluded_tables.include?(table)
|
2018-11-07 23:28:50 -05:00
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
set = columns.map do |column|
|
|
|
|
"#{column} = REPLACE(#{column}, :from, :to)"
|
2018-11-07 20:57:01 -05:00
|
|
|
end.join(", ")
|
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
where = columns.map do |column|
|
|
|
|
"#{column} IS NOT NULL AND #{column} LIKE :like"
|
2018-11-07 20:57:01 -05:00
|
|
|
end.join(" OR ")
|
|
|
|
|
2018-11-08 01:20:09 -05:00
|
|
|
DB.exec(<<~SQL, from: from, to: to, like: like)
|
2018-12-26 11:34:49 -05:00
|
|
|
UPDATE #{table}
|
|
|
|
SET #{set}
|
|
|
|
WHERE #{where}
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
|
|
|
|
SiteSetting.refresh!
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.regexp_replace(pattern, replacement, flags: "gi", match: "~*", excluded_tables: [])
|
|
|
|
text_columns = Hash.new { |h, k| h[k] = [] }
|
|
|
|
|
|
|
|
DB.query(REMAP_SQL).each do |r|
|
|
|
|
text_columns[r.table_name] << r.column_name
|
|
|
|
end
|
|
|
|
|
|
|
|
text_columns.each do |table, columns|
|
|
|
|
next if excluded_tables.include?(table)
|
|
|
|
|
|
|
|
set = columns.map do |column|
|
|
|
|
"#{column} = REGEXP_REPLACE(#{column}, :pattern, :replacement, :flags)"
|
|
|
|
end.join(", ")
|
|
|
|
|
|
|
|
where = columns.map do |column|
|
|
|
|
"#{column} IS NOT NULL AND #{column} #{match} :pattern"
|
|
|
|
end.join(" OR ")
|
|
|
|
|
|
|
|
DB.exec(<<~SQL, pattern: pattern, replacement: replacement, flags: flags, match: match)
|
|
|
|
UPDATE #{table}
|
|
|
|
SET #{set}
|
|
|
|
WHERE #{where}
|
2018-11-07 20:57:01 -05:00
|
|
|
SQL
|
2015-06-12 06:02:36 -04:00
|
|
|
end
|
2018-04-23 04:26:33 -04:00
|
|
|
|
2018-04-23 03:57:13 -04:00
|
|
|
SiteSetting.refresh!
|
2015-06-12 06:02:36 -04:00
|
|
|
end
|
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
def self.find(needle, anchor_left: false, anchor_right: false, excluded_tables: [])
|
2018-06-07 10:51:16 -04:00
|
|
|
found = {}
|
2018-12-26 11:34:49 -05:00
|
|
|
like = "#{anchor_left ? '' : "%"}#{needle}#{anchor_right ? '' : "%"}"
|
|
|
|
|
|
|
|
DB.query(REMAP_SQL).each do |r|
|
|
|
|
next if excluded_tables.include?(r.table_name)
|
2018-06-07 10:51:16 -04:00
|
|
|
|
2018-12-26 11:34:49 -05:00
|
|
|
rows = DB.query(<<~SQL, like: like)
|
|
|
|
SELECT #{r.column_name}
|
|
|
|
FROM #{r.table_name}
|
|
|
|
WHERE #{r.column_name} LIKE :like
|
|
|
|
SQL
|
|
|
|
|
|
|
|
if rows.size > 0
|
|
|
|
found["#{r.table_name}.#{r.column_name}"] = rows.map { |row| row.send(r.column_name) }
|
2018-06-07 10:51:16 -04:00
|
|
|
end
|
|
|
|
end
|
2018-12-26 11:34:49 -05:00
|
|
|
|
2018-06-07 10:51:16 -04:00
|
|
|
found
|
|
|
|
end
|
|
|
|
|
2015-06-12 06:02:36 -04:00
|
|
|
end
|