mirror of
https://github.com/moebooru/moebooru
synced 2025-08-22 01:47:48 +00:00
58 lines
1.8 KiB
Ruby
58 lines
1.8 KiB
Ruby
module QueryParser
|
|
# Extracts the tokens from a query string
|
|
#
|
|
# === Parameters
|
|
# * :query_string<String>: the query to parse
|
|
def parse(query_string)
|
|
query_string.to_s.downcase.scan(/\S+/)
|
|
end
|
|
|
|
# Extracts the metatokens (tokens matching \S+:\S+). Returns a two element array: the first element contains plain tokens, and the second element contains metatokens.
|
|
#
|
|
# === Parameters
|
|
# * :parsed_query<Array>: a list of tokens
|
|
def parse_meta(parsed_query)
|
|
hoge = [ [], {} ]
|
|
|
|
parsed_query.each do |token|
|
|
if token =~ /^(.+?):(.+)$/
|
|
hoge[1][Regexp.last_match[1]] = Regexp.last_match[2]
|
|
else
|
|
hoge[0] << token
|
|
end
|
|
end
|
|
|
|
hoge
|
|
end
|
|
|
|
# Given an array of keywords to search for, return an array of strings for to_tsquery.
|
|
# Words need to be escaped to prevent to_tsquery from parsing them as its own clumsy
|
|
# search syntax; note that this is separate from SQL string escaping, and the final SQL
|
|
# query will ultimately be double-escaped.
|
|
def escape_for_tsquery(array)
|
|
keywords = array.map do |token|
|
|
next if token.empty?
|
|
escaped_token = token.gsub(/\\|'/, '\0\0\0\0')
|
|
"'" + escaped_token + "'"
|
|
end.compact
|
|
query = []
|
|
if keywords.any?
|
|
query << "(" + keywords.join(" & ") + ")"
|
|
end
|
|
query
|
|
end
|
|
|
|
# Escape an SQL string. This is used only for escaping nested strings, within things like
|
|
# to_tsquery parameters; the results must always be passed as a normal parameter to ensure
|
|
# correct, safe escaping.
|
|
def generate_sql_escape(token)
|
|
escaped_token = token.gsub(/\\|'/, '\0\0\0\0').gsub("?", "\\\\77")
|
|
"'" + escaped_token + "'"
|
|
end
|
|
|
|
module_function :parse
|
|
module_function :parse_meta
|
|
module_function :escape_for_tsquery
|
|
module_function :generate_sql_escape
|
|
end
|