mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Rewrite tables endpoint to use SQL LIKE instead of Python regex
This commit is contained in:
parent
8e47f99874
commit
eb5a95ee6e
1 changed files with 35 additions and 25 deletions
|
|
@ -948,31 +948,41 @@ class TablesView(BaseView):
|
||||||
if not q:
|
if not q:
|
||||||
return Response.json({"matches": []})
|
return Response.json({"matches": []})
|
||||||
|
|
||||||
# Use the new allowed_resources() method
|
# Build SQL LIKE pattern from search terms
|
||||||
tables = await self.ds.allowed_resources("view-table", request.actor)
|
# Split search terms by whitespace and build pattern: %term1%term2%term3%
|
||||||
|
|
||||||
# Convert to list of matches with name and url
|
|
||||||
matches = [
|
|
||||||
{
|
|
||||||
"name": f"{table.parent}: {table.child}",
|
|
||||||
"url": self.ds.urls.table(table.parent, table.child),
|
|
||||||
}
|
|
||||||
for table in tables
|
|
||||||
]
|
|
||||||
|
|
||||||
# Apply search filter
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Split search terms by whitespace
|
|
||||||
terms = q.split()
|
terms = q.split()
|
||||||
# Build regex pattern: .*term1.*term2.*term3.*
|
pattern = "%" + "%".join(terms) + "%"
|
||||||
pattern = ".*" + ".*".join(re.escape(term) for term in terms) + ".*"
|
|
||||||
regex = re.compile(pattern, re.IGNORECASE)
|
|
||||||
|
|
||||||
# Filter tables matching the pattern (extract table name from "db: table")
|
matches = []
|
||||||
matches = [m for m in matches if regex.match(m["name"].split(": ", 1)[1])]
|
# Query each database's sqlite_master for matching tables
|
||||||
|
for db_name in self.ds.databases.keys():
|
||||||
# Sort by shortest table name first
|
db = self.ds.databases[db_name]
|
||||||
matches.sort(key=lambda m: len(m["name"].split(": ", 1)[1]))
|
try:
|
||||||
|
# Use SQL to find matching table names, ordered by shortest first
|
||||||
|
result = await db.execute(
|
||||||
|
"""
|
||||||
|
SELECT name
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type='table'
|
||||||
|
AND name LIKE ? COLLATE NOCASE
|
||||||
|
ORDER BY length(name), name
|
||||||
|
""",
|
||||||
|
[pattern]
|
||||||
|
)
|
||||||
|
# Check permissions for each matching table
|
||||||
|
for row in result.rows:
|
||||||
|
table_name = row[0]
|
||||||
|
if await self.ds.permission_allowed(
|
||||||
|
request.actor,
|
||||||
|
"view-table",
|
||||||
|
resource=(db_name, table_name)
|
||||||
|
):
|
||||||
|
matches.append({
|
||||||
|
"name": f"{db_name}: {table_name}",
|
||||||
|
"url": self.ds.urls.table(db_name, table_name),
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
# Skip databases that can't be queried
|
||||||
|
continue
|
||||||
|
|
||||||
return Response.json({"matches": matches})
|
return Response.json({"matches": matches})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue