mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
parent
9f47b6e4d8
commit
5d8084a285
3 changed files with 37 additions and 4 deletions
|
|
@ -4,6 +4,7 @@ from sanic.exceptions import NotFound
|
|||
from sanic.views import HTTPMethodView
|
||||
from sanic_jinja2 import SanicJinja2
|
||||
from jinja2 import FileSystemLoader
|
||||
import re
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
from concurrent import futures
|
||||
|
|
@ -286,6 +287,7 @@ async def favicon(request):
|
|||
|
||||
class DatabaseView(BaseView):
|
||||
template = 'database.html'
|
||||
re_named_parameter = re.compile(':([a-zA-Z0-0_]+)')
|
||||
|
||||
async def data(self, request, name, hash):
|
||||
if request.args.get('sql'):
|
||||
|
|
@ -316,6 +318,19 @@ class DatabaseView(BaseView):
|
|||
params = request.raw_args
|
||||
sql = params.pop('sql')
|
||||
validate_sql_select(sql)
|
||||
|
||||
# Extract any :named parameters
|
||||
named_parameters = self.re_named_parameter.findall(sql)
|
||||
named_parameter_values = {
|
||||
named_parameter: params.get(named_parameter) or ''
|
||||
for named_parameter in named_parameters
|
||||
}
|
||||
|
||||
# Set to blank string if missing from params
|
||||
for named_parameter in named_parameters:
|
||||
if named_parameter not in params:
|
||||
params[named_parameter] = ''
|
||||
|
||||
extra_args = {}
|
||||
if params.get('_sql_time_limit_ms'):
|
||||
extra_args['custom_time_limit'] = int(params['_sql_time_limit_ms'])
|
||||
|
|
@ -335,6 +350,7 @@ class DatabaseView(BaseView):
|
|||
}, {
|
||||
'database_hash': hash,
|
||||
'custom_sql': True,
|
||||
'named_parameter_values': named_parameter_values,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -83,14 +83,24 @@ form.sql textarea {
|
|||
font-family: monospace;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
form.sql label {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
width: 15%;
|
||||
}
|
||||
form.sql input[type=text] {
|
||||
border: 1px solid #ccc;
|
||||
width: 60%;
|
||||
padding: 4px;
|
||||
font-family: monospace;
|
||||
display: inline-block;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
@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;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="stylesheet" href="/-/static/codemirror-5.31.0-min.css" />
|
||||
<script src="/-/static/codemirror-5.31.0-sql.min.js"></script>
|
||||
<style>
|
||||
.CodeMirror { height: 70px; width: 80%; border: 1px solid #ddd; }
|
||||
.CodeMirror { height: auto; min-height: 70px; width: 80%; border: 1px solid #ddd; }
|
||||
.CodeMirror-scroll { max-height: 200px; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
|
@ -33,7 +33,14 @@
|
|||
{% endif %}
|
||||
|
||||
<form class="sql" action="/{{ database }}-{{ database_hash }}" method="get">
|
||||
<h3>Custom SQL query</h3>
|
||||
<p><textarea name="sql">{% if query and query.sql %}{{ query.sql }}{% else %}select * from {{ tables[0].name|escape_table_name }}{% endif %}</textarea></p>
|
||||
{% if named_parameter_values %}
|
||||
<h3>Query parameters</h3>
|
||||
{% for name, value in named_parameter_values.items() %}
|
||||
<p><label for="qp{{ loop.counter }}">{{ name }}</label> <input type="text" id="qp{{ loop.counter }}" name="{{ name }}" value="{{ value }}"></p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<p><input type="submit" value="Run SQL"></p>
|
||||
</form>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue