kopia lustrzana https://github.com/simonw/datasette
rodzic
f59c840e7d
commit
eed6a0fe36
|
@ -19,6 +19,7 @@ from .utils import (
|
|||
build_where_clauses,
|
||||
compound_pks_from_path,
|
||||
CustomJSONEncoder,
|
||||
detect_fts_sql,
|
||||
escape_css_string,
|
||||
escape_sqlite_table_name,
|
||||
get_all_foreign_keys,
|
||||
|
@ -427,6 +428,22 @@ class TableView(BaseView):
|
|||
where_clauses = []
|
||||
params = {}
|
||||
|
||||
# _search support:
|
||||
fts_table = None
|
||||
fts_sql = detect_fts_sql(table)
|
||||
fts_rows = list(await self.execute(name, fts_sql))
|
||||
if fts_rows:
|
||||
fts_table=fts_rows[0][0]
|
||||
|
||||
search = special_args.get('_search')
|
||||
if search and fts_table:
|
||||
where_clauses.append(
|
||||
'rowid in (select rowid from {fts_table} where {fts_table} match :search)'.format(
|
||||
fts_table=fts_table
|
||||
)
|
||||
)
|
||||
params['search'] = search
|
||||
|
||||
next = special_args.get('_next')
|
||||
offset = ''
|
||||
if next:
|
||||
|
@ -504,6 +521,8 @@ class TableView(BaseView):
|
|||
async def extra_template():
|
||||
return {
|
||||
'database_hash': hash,
|
||||
'supports_search': bool(fts_table),
|
||||
'search': search or '',
|
||||
'use_rowid': use_rowid,
|
||||
'display_columns': display_columns,
|
||||
'display_rows': await self.make_display_rows(name, hash, table, rows, display_columns, pks, is_view, use_rowid),
|
||||
|
|
|
@ -90,12 +90,13 @@ form.sql textarea {
|
|||
font-family: monospace;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
form.sql label {
|
||||
form label {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
width: 15%;
|
||||
}
|
||||
form.sql input[type=text] {
|
||||
form input[type=text],
|
||||
form input[type=search] {
|
||||
border: 1px solid #ccc;
|
||||
width: 60%;
|
||||
padding: 4px;
|
||||
|
@ -103,12 +104,15 @@ form.sql input[type=text] {
|
|||
display: inline-block;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
form input[type=search] {
|
||||
width: 40%;
|
||||
}
|
||||
@media only screen and (max-width: 576px) {
|
||||
form.sql textarea {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
form.sql input[type=submit] {
|
||||
form input[type=submit] {
|
||||
color: #fff;
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
|
@ -118,7 +122,7 @@ form.sql input[type=submit] {
|
|||
vertical-align: middle;
|
||||
border: 1px solid blue;
|
||||
padding: .275rem .75rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
<h2>{{ "{:,}".format(table_rows) }} total row{% if table_rows == 1 %}{% else %}s{% endif %} in this table</h2>
|
||||
{% endif %}
|
||||
|
||||
{% if supports_search %}
|
||||
<form action="/{{ database }}-{{ database_hash }}/{{ table|quote_plus }}" method="get">
|
||||
<p><input type="search" name="_search" value="{{ search }}"> <input type="submit" value="Search"></p>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if query.params %}
|
||||
<pre>{{ query.sql }}</pre>
|
||||
<pre>params = {{ query.params|tojson(4) }}</pre>
|
||||
|
|
|
@ -235,3 +235,20 @@ def get_all_foreign_keys(conn):
|
|||
})
|
||||
|
||||
return table_to_foreign_keys
|
||||
|
||||
|
||||
def detect_fts(conn, table, return_sql=False):
|
||||
"Detect if table has a corresponding FTS virtual table and return it"
|
||||
rows = conn.execute(detect_fts_sql(table)).fetchall()
|
||||
if len(rows) == 0:
|
||||
return None
|
||||
else:
|
||||
return rows[0][0]
|
||||
|
||||
|
||||
def detect_fts_sql(table):
|
||||
return r'''
|
||||
select name from sqlite_master
|
||||
where rootpage = 0
|
||||
and sql like '%VIRTUAL TABLE%USING FTS%content="{}"%';
|
||||
'''.format(table)
|
||||
|
|
|
@ -4,6 +4,7 @@ Tests for various datasette helper functions.
|
|||
|
||||
from datasette import utils
|
||||
import pytest
|
||||
import sqlite3
|
||||
import json
|
||||
|
||||
|
||||
|
@ -124,3 +125,26 @@ def test_validate_sql_select_bad(bad_sql):
|
|||
])
|
||||
def test_validate_sql_select_good(good_sql):
|
||||
utils.validate_sql_select(good_sql)
|
||||
|
||||
|
||||
def test_detect_fts():
|
||||
sql = '''
|
||||
CREATE TABLE "Dumb_Table" (
|
||||
"TreeID" INTEGER,
|
||||
"qSpecies" TEXT
|
||||
);
|
||||
CREATE TABLE "Street_Tree_List" (
|
||||
"TreeID" INTEGER,
|
||||
"qSpecies" TEXT,
|
||||
"qAddress" TEXT,
|
||||
"SiteOrder" INTEGER,
|
||||
"qSiteInfo" TEXT,
|
||||
"PlantType" TEXT,
|
||||
"qCaretaker" TEXT
|
||||
);
|
||||
CREATE VIRTUAL TABLE "Street_Tree_List_fts" USING FTS4 ("qAddress", "qCaretaker", "qSpecies", content="Street_Tree_List");
|
||||
'''
|
||||
conn = sqlite3.connect(':memory:')
|
||||
conn.executescript(sql)
|
||||
assert None is utils.detect_fts(conn, 'Dumb_Table')
|
||||
assert 'Street_Tree_List_fts' == utils.detect_fts(conn, 'Street_Tree_List')
|
||||
|
|
Ładowanie…
Reference in New Issue