?_searchmode=raw option (#686)

This commit is contained in:
Simon Willison 2020-02-24 21:56:03 -08:00 committed by GitHub
commit 6cb65555f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 4 deletions

View file

@ -356,13 +356,18 @@ class TableView(RowTableShared):
pair for pair in special_args.items() if pair[0].startswith("_search")
)
search = ""
search_mode_raw = special_args.get("_searchmode") == "raw"
if fts_table and search_args:
if "_search" in search_args:
# Simple ?_search=xxx
search = search_args["_search"]
where_clauses.append(
"{fts_pk} in (select rowid from {fts_table} where {fts_table} match escape_fts(:search))".format(
fts_table=escape_sqlite(fts_table), fts_pk=escape_sqlite(fts_pk)
"{fts_pk} in (select rowid from {fts_table} where {fts_table} match {match_clause})".format(
fts_table=escape_sqlite(fts_table),
fts_pk=escape_sqlite(fts_pk),
match_clause=":search"
if search_mode_raw
else "escape_fts(:search)",
)
)
extra_human_descriptions.append('search matches "{}"'.format(search))
@ -375,10 +380,12 @@ class TableView(RowTableShared):
raise DatasetteError("Cannot search by that column", status=400)
where_clauses.append(
"rowid in (select rowid from {fts_table} where {search_col} match escape_fts(:search_{i}))".format(
"rowid in (select rowid from {fts_table} where {search_col} match {match_clause})".format(
fts_table=escape_sqlite(fts_table),
search_col=escape_sqlite(search_col),
i=i,
match_clause=":search_{}".format(i)
if search_mode_raw
else "escape_fts(:search_{})".format(i),
)
)
extra_human_descriptions.append(

View file

@ -281,6 +281,12 @@ Special table arguments
Like ``_search=`` but allows you to specify the column to be searched, as
opposed to searching all columns that have been indexed by FTS.
``?_searchmode=raw``
With this option, queries passed to ``?_search=`` or ``?_search_COLUMN=`` will
not have special characters escaped. This means you can make use of the full
set of `advanced SQLite FTS syntax <https://www.sqlite.org/fts5.html#full_text_query_syntax>`__,
though this could potentially result in errors if the wrong syntax is used.
``?_where=SQL-fragment``
If the :ref:`config_allow_sql` config option is enabled, this parameter
can be used to pass one or more additional SQL fragments to be used in the

View file

@ -952,6 +952,19 @@ def test_sortable_columns_metadata(app_client):
"/fixtures/searchable.json?_search=AND",
[],
),
(
# Without _searchmode=raw this should return no results
"/fixtures/searchable.json?_search=te*+AND+do*",
[],
),
(
# _searchmode=raw
"/fixtures/searchable.json?_search=te*+AND+do*&_searchmode=raw",
[
[1, "barry cat", "terry dog", "panther"],
[2, "terry dog", "sara weasel", "puma"],
],
),
(
"/fixtures/searchable.json?_search=weasel",
[[2, "terry dog", "sara weasel", "puma"]],