diff --git a/app/jobs/tag_batch_change_job.rb b/app/jobs/tag_batch_change_job.rb index df42704f0..e66f824f2 100644 --- a/app/jobs/tag_batch_change_job.rb +++ b/app/jobs/tag_batch_change_job.rb @@ -51,7 +51,7 @@ class TagBatchChangeJob < ApplicationJob query = normalized_antecedent adds = normalized_consequent arel = query.inject(User.none) do |scope, x| - scope.or(User.where("blacklisted_tags like ?", "%" + x.to_escaped_for_sql_like + "%")) + scope.or(User.where_like(:blacklisted_tags, "*#{x}*")) end arel.find_each do |user| diff --git a/app/logical/tag_autocomplete.rb b/app/logical/tag_autocomplete.rb index 31f7a473f..31f4c1566 100644 --- a/app/logical/tag_autocomplete.rb +++ b/app/logical/tag_autocomplete.rb @@ -42,7 +42,7 @@ module TagAutocomplete def search_exact(query, n = 4) Tag - .where("name like ? escape e'\\\\'", query.to_escaped_for_sql_like + "%") + .where_like(:name, query + "*") .where("post_count > 0") .order("post_count desc") .limit(n) @@ -58,7 +58,7 @@ module TagAutocomplete Tag .where("name % ?", query) .where("abs(length(name) - ?) <= 3", query.size) - .where("name like ? escape E'\\\\'", query[0].to_escaped_for_sql_like + '%') + .where_like(:name, query[0] + "*") .where("post_count > 0") .order(Arel.sql("similarity(name, #{Tag.connection.quote(query)}) DESC")) .limit(n) @@ -102,9 +102,9 @@ module TagAutocomplete TagAlias .select("tags.name, tags.post_count, tags.category, tag_aliases.antecedent_name") .joins("INNER JOIN tags ON tags.name = tag_aliases.consequent_name") - .where("tag_aliases.antecedent_name LIKE ? ESCAPE E'\\\\'", wildcard_name.to_escaped_for_sql_like) + .where_like(:antecedent_name, wildcard_name) .active - .where("tags.name NOT LIKE ? ESCAPE E'\\\\'", wildcard_name.to_escaped_for_sql_like) + .where_not_like("tags.name", wildcard_name) .where("tags.post_count > 0") .order("tags.post_count desc") .limit(n) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index a9b289a04..2b58ad9d5 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -17,7 +17,11 @@ class ApplicationRecord < ActiveRecord::Base concerning :SearchMethods do class_methods do def qualified_column_for(attr) - "#{table_name}.#{column_for_attribute(attr).name}" + if attr.is_a?(Symbol) + "#{table_name}.#{column_for_attribute(attr).name}" + else + attr.to_s + end end def where_like(attr, value) diff --git a/app/models/artist.rb b/app/models/artist.rb index 67716dbea..b344a4bf4 100644 --- a/app/models/artist.rb +++ b/app/models/artist.rb @@ -438,11 +438,11 @@ class Artist < ApplicationRecord module SearchMethods def any_other_name_matches(regex) - where(id: Artist.from("unnest(other_names) AS other_name").where("other_name ~ ?", regex)) + where(id: Artist.from("unnest(other_names) AS other_name").where_regex("other_name", regex)) end def any_other_name_like(name) - where(id: Artist.from("unnest(other_names) AS other_name").where("other_name LIKE ?", name.to_escaped_for_sql_like)) + where(id: Artist.from("unnest(other_names) AS other_name").where_like("other_name", name)) end def any_name_matches(query) diff --git a/app/models/artist_commentary.rb b/app/models/artist_commentary.rb index 563c0e3bf..baacaf34d 100644 --- a/app/models/artist_commentary.rb +++ b/app/models/artist_commentary.rb @@ -14,8 +14,11 @@ class ArtistCommentary < ApplicationRecord module SearchMethods def text_matches(query) query = "*#{query}*" unless query =~ /\*/ - escaped_query = query.to_escaped_for_sql_like - where("original_title ILIKE ? ESCAPE E'\\\\' OR original_description ILIKE ? ESCAPE E'\\\\' OR translated_title ILIKE ? ESCAPE E'\\\\' OR translated_description ILIKE ? ESCAPE E'\\\\'", escaped_query, escaped_query, escaped_query, escaped_query) + + where_ilike(:original_title, query) + .or(where_ilike(:original_description, query)) + .or(where_ilike(:translated_title, query)) + .or(where_ilike(:translated_description, query)) end def deleted diff --git a/app/models/ban.rb b/app/models/ban.rb index e11b8414e..d3b0ae34b 100644 --- a/app/models/ban.rb +++ b/app/models/ban.rb @@ -17,14 +17,6 @@ class Ban < ApplicationRecord exists?(["user_id = ? AND expires_at > ?", user.id, Time.now]) end - def self.reason_matches(query) - if query =~ /\*/ - where("lower(bans.reason) LIKE ?", query.mb_chars.downcase.to_escaped_for_sql_like) - else - where("bans.reason @@ plainto_tsquery(?)", query) - end - end - def self.search(params) q = super diff --git a/app/models/tag.rb b/app/models/tag.rb index adfba0c30..045cdfc94 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -810,7 +810,7 @@ class Tag < ApplicationRecord end def name_matches(name) - where("tags.name LIKE ? ESCAPE E'\\\\'", normalize_name(name).to_escaped_for_sql_like) + where_like(:name, normalize_name(name)) end def search(params) @@ -876,9 +876,9 @@ class Tag < ApplicationRecord TagAlias .select("tags.name, tags.post_count, tags.category, tag_aliases.antecedent_name") .joins("INNER JOIN tags ON tags.name = tag_aliases.consequent_name") - .where("tag_aliases.antecedent_name LIKE ? ESCAPE E'\\\\'", wildcard_name.to_escaped_for_sql_like) + .where_like(:antecedent_name, wildcard_name) .active - .where("tags.name NOT LIKE ? ESCAPE E'\\\\'", wildcard_name.to_escaped_for_sql_like) + .where_not_like("tags.name", wildcard_name) .where("tags.post_count > 0") .order("tags.post_count desc") .limit(limit * 2) # Get extra records in case some duplicates get filtered out. diff --git a/app/models/tag_relationship.rb b/app/models/tag_relationship.rb index fffea1dd9..4e082db94 100644 --- a/app/models/tag_relationship.rb +++ b/app/models/tag_relationship.rb @@ -85,7 +85,7 @@ class TagRelationship < ApplicationRecord module SearchMethods def name_matches(name) - where("(antecedent_name like ? escape E'\\\\' or consequent_name like ? escape E'\\\\')", name.mb_chars.downcase.to_escaped_for_sql_like, name.mb_chars.downcase.to_escaped_for_sql_like) + where_ilike(:antecedent_name, name).or(where_ilike(:consequent_name, name)) end def status_matches(status) diff --git a/app/models/upload.rb b/app/models/upload.rb index a91234541..ae6628e61 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -203,7 +203,7 @@ class Upload < ApplicationRecord q = q.search_attributes(params, :uploader, :post, :source, :rating, :parent_id, :server, :md5, :server, :file_ext, :file_size, :image_width, :image_height, :referer_url) if params[:source_matches].present? - q = q.where("uploads.source LIKE ? ESCAPE E'\\\\'", params[:source_matches].to_escaped_for_sql_like) + q = q.where_like(:source, params[:source_matches]) end if params[:has_post].to_s.truthy? @@ -213,15 +213,15 @@ class Upload < ApplicationRecord end if params[:status].present? - q = q.where("uploads.status LIKE ? ESCAPE E'\\\\'", params[:status].to_escaped_for_sql_like) + q = q.where_like(:status, params[:status]) end if params[:backtrace].present? - q = q.where("uploads.backtrace LIKE ? ESCAPE E'\\\\'", params[:backtrace].to_escaped_for_sql_like) + q = q.where_like(:backtrace, params[:backtrace]) end if params[:tag_string].present? - q = q.where("uploads.tag_string LIKE ? ESCAPE E'\\\\'", params[:tag_string].to_escaped_for_sql_like) + q = q.where_like(:tag_string, params[:tag_string]) end q.apply_default_order(params) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index a03c5efea..18f6a57f6 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -43,14 +43,14 @@ class WikiPage < ApplicationRecord end def other_names_include(name) - name = normalize_other_name(name).downcase - subquery = WikiPage.from("unnest(other_names) AS other_name").where("lower(other_name) = ?", name) + name = normalize_other_name(name) + subquery = WikiPage.from("unnest(other_names) AS other_name").where_iequals("other_name", name) where(id: subquery) end def other_names_match(name) if name =~ /\*/ - subquery = WikiPage.from("unnest(other_names) AS other_name").where("other_name ILIKE ?", name.to_escaped_for_sql_like) + subquery = WikiPage.from("unnest(other_names) AS other_name").where_ilike("other_name", name) where(id: subquery) else other_names_include(name)