mirror of
https://github.com/quay/quay.git
synced 2026-01-26 06:21:37 +03:00
* autoprune: fix tags returned by autoprune worker (PROJQUAY-8070) * fixing tests * moving limit and offset to db_regex_search * adding test cases
81 lines
2.8 KiB
Python
81 lines
2.8 KiB
Python
import inspect
|
|
import re
|
|
|
|
from peewee import SQL, Field, NodeList, fn
|
|
|
|
|
|
def _escape_wildcard(search_query):
|
|
"""
|
|
Escapes the wildcards found in the given search query so that they are treated as *characters*
|
|
rather than wildcards when passed to a LIKE or ILIKE clause with an ESCAPE '!'.
|
|
"""
|
|
search_query = (
|
|
search_query.replace("!", "!!").replace("%", "!%").replace("_", "!_").replace("[", "![")
|
|
)
|
|
|
|
# Just to be absolutely sure.
|
|
search_query = search_query.replace("'", "")
|
|
search_query = search_query.replace('"', "")
|
|
search_query = search_query.replace("`", "")
|
|
|
|
return search_query
|
|
|
|
|
|
def prefix_search(field, prefix_query):
|
|
"""
|
|
Returns the wildcard match for searching for the given prefix query.
|
|
"""
|
|
# Escape the known wildcard characters.
|
|
prefix_query = _escape_wildcard(prefix_query)
|
|
return Field.__pow__(field, NodeList((prefix_query + "%", SQL("ESCAPE '!'"))))
|
|
|
|
|
|
def match_mysql(field, search_query):
|
|
"""
|
|
Generates a full-text match query using a Match operation, which is needed for MySQL.
|
|
"""
|
|
if field.name.find("`") >= 0: # Just to be safe.
|
|
raise Exception("How did field name '%s' end up containing a backtick?" % field.name)
|
|
|
|
# Note: There is a known bug in MySQL (https://bugs.mysql.com/bug.php?id=78485) that causes
|
|
# queries of the form `*` to raise a parsing error. If found, simply filter out.
|
|
search_query = search_query.replace("*", "")
|
|
|
|
# Just to be absolutely sure.
|
|
search_query = search_query.replace("'", "")
|
|
search_query = search_query.replace('"', "")
|
|
search_query = search_query.replace("`", "")
|
|
|
|
return NodeList(
|
|
(fn.MATCH(SQL("`%s`" % field.name)), fn.AGAINST(SQL("%s", [search_query]))), parens=True
|
|
)
|
|
|
|
|
|
def match_like(field, search_query):
|
|
"""
|
|
Generates a full-text match query using an ILIKE operation, which is needed for SQLite and
|
|
Postgres.
|
|
"""
|
|
escaped_query = _escape_wildcard(search_query)
|
|
clause = NodeList(("%" + escaped_query + "%", SQL("ESCAPE '!'")))
|
|
return Field.__pow__(field, clause)
|
|
|
|
|
|
def regex_search(query, field, pattern, offset, limit, matches=True):
|
|
return (
|
|
query.where(field.regexp(pattern)).offset(offset).limit(limit)
|
|
if matches
|
|
else query.where(~field.regexp(pattern)).offset(offset).limit(limit)
|
|
)
|
|
|
|
|
|
def regex_sqlite(query, field, pattern, offset, limit, matches=True):
|
|
# fetching all rows of the query here irrespective of limit and offset as sqlite does not support regexes.
|
|
rows = query.execute()
|
|
result = (
|
|
[row for row in rows if re.search(pattern, getattr(row, field.name))]
|
|
if matches
|
|
else [row for row in rows if not re.search(pattern, getattr(row, field.name))]
|
|
)
|
|
return result[offset : offset + limit]
|