refactored tsquery sql to use rails escaping mechanisms
This commit is contained in:
@@ -1,11 +1,6 @@
|
|||||||
class PostQueryBuilder
|
class PostQueryBuilder
|
||||||
attr_accessor :query_string, :has_constraints
|
attr_accessor :query_string, :has_constraints
|
||||||
|
|
||||||
def self.escape_string_for_tsquery(token)
|
|
||||||
escaped_token = token.gsub(/\\|'/, '\0\0\0\0').gsub("?", "\\\\77").gsub("%", "\\\\37")
|
|
||||||
"''" + escaped_token + "''"
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(query_string)
|
def initialize(query_string)
|
||||||
@query_string = query_string
|
@query_string = query_string
|
||||||
@has_constraint = false
|
@has_constraint = false
|
||||||
@@ -53,7 +48,7 @@ class PostQueryBuilder
|
|||||||
|
|
||||||
def escape_string_for_tsquery(array)
|
def escape_string_for_tsquery(array)
|
||||||
array.map do |token|
|
array.map do |token|
|
||||||
PostQueryBuilder.escape_string_for_tsquery(token)
|
token.to_escaped_for_tsquery
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -75,7 +70,7 @@ class PostQueryBuilder
|
|||||||
end
|
end
|
||||||
|
|
||||||
if tag_query_sql.any?
|
if tag_query_sql.any?
|
||||||
relation = relation.where("posts.tag_index @@ to_tsquery('danbooru', E'" + tag_query_sql.join(" & ") + "')")
|
relation = relation.where("posts.tag_index @@ to_tsquery('danbooru', E?)", tag_query_sql.join(" & "))
|
||||||
end
|
end
|
||||||
|
|
||||||
relation
|
relation
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ class Artist < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def other_names_match(string)
|
def other_names_match(string)
|
||||||
where("other_names_index @@ to_tsquery('danbooru', ?)", Artist.normalize_name(string))
|
where("other_names_index @@ to_tsquery('danbooru', E?)", Artist.normalize_name(string).to_escaped_for_tsquery)
|
||||||
end
|
end
|
||||||
|
|
||||||
def group_name_matches(name)
|
def group_name_matches(name)
|
||||||
@@ -225,8 +225,8 @@ class Artist < ActiveRecord::Base
|
|||||||
|
|
||||||
def any_name_matches(name)
|
def any_name_matches(name)
|
||||||
stripped_name = normalize_name(name).to_escaped_for_sql_like
|
stripped_name = normalize_name(name).to_escaped_for_sql_like
|
||||||
name_for_tsquery = normalize_name(name).gsub(/\(/, "\\(").gsub(/\)/, "\\)")
|
name_for_tsquery = normalize_name(name).to_escaped_for_tsquery
|
||||||
where("(name LIKE ? ESCAPE E'\\\\' OR other_names_index @@ to_tsquery('danbooru', ?))", stripped_name, name_for_tsquery)
|
where("(name LIKE ? ESCAPE E'\\\\' OR other_names_index @@ to_tsquery('danbooru', E?))", stripped_name, name_for_tsquery)
|
||||||
end
|
end
|
||||||
|
|
||||||
def search(params)
|
def search(params)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class Comment < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def body_matches(query)
|
def body_matches(query)
|
||||||
where("body_index @@ plainto_tsquery(?)", query).order("comments.id DESC")
|
where("body_index @@ plainto_tsquery(?)", query.to_escaped_for_tsquery_split).order("comments.id DESC")
|
||||||
end
|
end
|
||||||
|
|
||||||
def hidden(user)
|
def hidden(user)
|
||||||
@@ -28,7 +28,7 @@ class Comment < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def post_tags_match(query)
|
def post_tags_match(query)
|
||||||
joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', E?)", query)
|
joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', ?)", query.to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_creator(user_id)
|
def for_creator(user_id)
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ class Dmail < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def search_message(query)
|
def search_message(query)
|
||||||
where("message_index @@ plainto_tsquery(?)", query)
|
where("message_index @@ plainto_tsquery(?)", query.to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unread
|
def unread
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class ForumPost < ActiveRecord::Base
|
|||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
def body_matches(body)
|
def body_matches(body)
|
||||||
where("forum_posts.text_index @@ plainto_tsquery(?)", body)
|
where("forum_posts.text_index @@ plainto_tsquery(E?)", body.to_escaped_for_tsquery)
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_user(user_id)
|
def for_user(user_id)
|
||||||
@@ -41,7 +41,7 @@ class ForumPost < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
if params[:topic_title_matches].present?
|
if params[:topic_title_matches].present?
|
||||||
q = q.joins(:topic).where("forum_topics.text_index @@ plainto_tsquery(?)", params[:topic_title_matches])
|
q = q.joins(:topic).where("forum_topics.text_index @@ plainto_tsquery(E?)", params[:topic_title_matches].to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:body_matches].present?
|
if params[:body_matches].present?
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class ForumTopic < ActiveRecord::Base
|
|||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
def title_matches(title)
|
def title_matches(title)
|
||||||
where("text_index @@ plainto_tsquery(?)", title)
|
where("text_index @@ plainto_tsquery(E?)", title.to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
def active
|
def active
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ class Note < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def body_matches(query)
|
def body_matches(query)
|
||||||
where("body_index @@ plainto_tsquery(?)", query.scan(/\S+/).join(" & "))
|
where("body_index @@ plainto_tsquery(E?)", query.to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_tags_match(query)
|
def post_tags_match(query)
|
||||||
joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', ?)", query)
|
joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', E?)", query.to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
def creator_name(name)
|
def creator_name(name)
|
||||||
|
|||||||
@@ -938,8 +938,7 @@ class Post < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def raw_tag_match(tag)
|
def raw_tag_match(tag)
|
||||||
tag = PostQueryBuilder.escape_string_for_tsquery(tag)
|
where("posts.tag_index @@ to_tsquery('danbooru', E?)", tag.to_escaped_for_tsquery)
|
||||||
where("posts.tag_index @@ to_tsquery('danbooru', E'" + tag + "')")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_match(query)
|
def tag_match(query)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class WikiPage < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def body_matches(query)
|
def body_matches(query)
|
||||||
where("body_index @@ plainto_tsquery(?)", query.scan(/\S+/).join(" & "))
|
where("body_index @@ plainto_tsquery(?)", query.to_escaped_for_tsquery_split)
|
||||||
end
|
end
|
||||||
|
|
||||||
def search(params = {})
|
def search(params = {})
|
||||||
|
|||||||
@@ -5,6 +5,14 @@ module Danbooru
|
|||||||
return self.gsub(/\\/, '\0\0').gsub(/(%|_)/, "\\\\\\1").gsub(/\*/, '%')
|
return self.gsub(/\\/, '\0\0').gsub(/(%|_)/, "\\\\\\1").gsub(/\*/, '%')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_escaped_for_tsquery_split
|
||||||
|
scan(/\S+/).map {|x| x.to_escaped_for_tsquery}.join(" & ")
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_escaped_for_tsquery
|
||||||
|
"'#{gsub(/\\|'/, '\0\0\0\0')}'"
|
||||||
|
end
|
||||||
|
|
||||||
def to_escaped_js
|
def to_escaped_js
|
||||||
return self.gsub(/\\/, '\0\0').gsub(/['"]/) {|m| "\\#{m}"}.gsub(/\r\n|\r|\n/, '\\n')
|
return self.gsub(/\\/, '\0\0').gsub(/['"]/) {|m| "\\#{m}"}.gsub(/\r\n|\r|\n/, '\\n')
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user