diff --git a/datasette/app.py b/datasette/app.py index 19d708f4..8852b036 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -243,6 +243,8 @@ class DatabaseView(BaseView): template = 'database.html' async def data(self, request, name, hash): + if request.args.get('sql'): + return await self.custom_sql(request, name, hash) tables = [] table_metadata = self.ds.metadata()[name]['tables'] for table_name, table_rows in table_metadata.items(): @@ -265,6 +267,25 @@ class DatabaseView(BaseView): 'database_hash': hash, } + async def custom_sql(self, request, name, hash): + params = request.raw_args + sql = params.pop('sql') + validate_sql_select(sql) + rows = await self.execute(name, sql, params) + columns = [r[0] for r in rows.description] + return { + 'database': name, + 'rows': rows, + 'columns': columns, + 'query': { + 'sql': sql, + 'params': params, + } + }, { + 'database_hash': hash, + 'custom_sql': True, + } + class DatabaseDownload(BaseView): async def view_get(self, request, name, hash, **kwargs): diff --git a/datasette/static/app.css b/datasette/static/app.css index fa8e6fde..b5559447 100644 --- a/datasette/static/app.css +++ b/datasette/static/app.css @@ -73,3 +73,34 @@ th { margin-top: 1em; margin-bottom: 0; } + +form.sql textarea { + border: 1px solid #ccc; + width: 70%; + height: 3em; + padding: 4px; + font-family: monospace; + font-size: 1.3em; +} +@media only screen and (max-width: 576px) { + form.sql textarea { + width: 95%; + } +} +form.sql p { + margin: 0; +} +form.sql input[type=submit] { + color: #fff; + background-color: #007bff; + border-color: #007bff; + font-weight: 400; + cursor: pointer; + text-align: center; + vertical-align: middle; + border: 1px solid blue; + padding: .275rem .75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: .25rem; +} diff --git a/datasette/templates/database.html b/datasette/templates/database.html index adaa8fd9..607d836e 100644 --- a/datasette/templates/database.html +++ b/datasette/templates/database.html @@ -3,7 +3,7 @@ {% block title %}{{ database }}{% endblock %} {% block content %} -
+