add escape functionality from datsette

This commit is contained in:
Mark Neumann 2021-03-16 11:15:08 +00:00
commit 2d2376ffd8
2 changed files with 24 additions and 3 deletions

View file

@ -18,6 +18,8 @@ import uuid
SQLITE_MAX_VARS = 999
_quote_fts_re = re.compile(r'\s+|(".*?")')
_virtual_table_using_re = re.compile(
r"""
^ # Start of string
@ -254,6 +256,25 @@ class Database:
{"value": value},
).fetchone()[0]
def quote_fts(self, query):
# NOTE: This is not a query validator for FTS. Sqlite has
# a well defined query syntax here:
# https://www2.sqlite.org/fts5.html#full_text_query_syntax
# but this function just aggressively quotes strings
# to ensure that they are valid. In particular, passing
# queries which make use of the query syntax will be incorrect,
# e.g 'NEAR(one, two, 3)'.
# If query has unbalanced ", add one at end
if query.count('"') % 2:
query += '"'
bits = _quote_fts_re.split(query)
bits = [b for b in bits if b and b != '""']
return " ".join(
'"{}"'.format(bit) if not bit.startswith('"') else bit for bit in bits
)
def table_names(self, fts4=False, fts5=False):
where = ["type = 'table'"]
if fts4:

View file

@ -509,6 +509,6 @@ def test_quote_fts_query(fresh_db):
table.enable_fts(["text", "country"])
query = "cat's"
list(table.search(query))
result = fresh_db.quote_fts(query)
# Executing query does not crash.
list(table.search(result))