From 98611b3da05b1eab914fb0bdc8d65e963760ce46 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 17 Nov 2022 17:19:37 -0800 Subject: [PATCH] Include SQL schema for CodeMirror on query pages, closes #1897 Refs #1893 --- datasette/views/database.py | 25 ++++++++++++++++++++++--- tests/test_permissions.py | 24 ++++++++++++++++++------ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/datasette/views/database.py b/datasette/views/database.py index a306a666..f784da00 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -141,6 +141,9 @@ class DatabaseView(DataView): attached_databases = [d.name for d in await db.attached_databases()] + allow_execute_sql = await self.ds.permission_allowed( + request.actor, "execute-sql", database, default=True + ) return ( { "database": database, @@ -151,9 +154,10 @@ class DatabaseView(DataView): "hidden_count": len([t for t in tables if t["hidden"]]), "views": views, "queries": canned_queries, - "allow_execute_sql": await self.ds.permission_allowed( - request.actor, "execute-sql", database, default=True - ), + "allow_execute_sql": allow_execute_sql, + "table_columns": await _table_columns(self.ds, database) + if allow_execute_sql + else {}, }, { "database_actions": database_actions, @@ -510,6 +514,9 @@ class QueryView(DataView): "show_hide_text": show_hide_text, "show_hide_hidden": markupsafe.Markup(show_hide_hidden), "hide_sql": hide_sql, + "table_columns": await _table_columns(self.ds, database) + if allow_execute_sql + else {}, } return ( @@ -685,3 +692,15 @@ class TableCreateView(BaseView): if rows: details["row_count"] = len(rows) return Response.json(details, status=201) + + +async def _table_columns(datasette, database_name): + internal = datasette.get_database("_internal") + result = await internal.execute( + "select table_name, name from columns where database_name = ?", + [database_name], + ) + table_columns = {} + for row in result.rows: + table_columns.setdefault(row["table_name"], []).append(row["name"]) + return table_columns diff --git a/tests/test_permissions.py b/tests/test_permissions.py index a45a0fb1..cce46082 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -5,6 +5,7 @@ import copy import json import pytest_asyncio import pytest +import re import urllib @@ -252,24 +253,35 @@ def test_view_query(allow, expected_anon, expected_auth): ], ) def test_execute_sql(metadata): + schema_re = re.compile("const schema = ({.*?});", re.DOTALL) with make_app_client(metadata=metadata) as client: form_fragment = '