d3d9cca182
This requires a number of small changes in the data model code, as well as additional testing.
41 lines
1.7 KiB
Python
41 lines
1.7 KiB
Python
from peewee import NodeList, SQL, fn, TextField, Field
|
|
|
|
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('[', '!['))
|
|
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('*', '')
|
|
|
|
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)
|