mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
First working version of writable canned queries, refs #698
This commit is contained in:
parent
dfdbdf378a
commit
5b252a2348
4 changed files with 73 additions and 7 deletions
|
|
@ -351,3 +351,9 @@ p.zero-results {
|
|||
.type-float, .type-int {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.success {
|
||||
padding: 1em;
|
||||
border: 1px solid green;
|
||||
background-color: #c7fbc7;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,12 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_color(database) }}">{{ metadata.title or database }}</h1>
|
||||
|
||||
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
|
||||
|
||||
<form class="sql" action="{{ database_url(database) }}{% if canned_query %}/{{ canned_query }}{% endif %}" method="get">
|
||||
<form class="sql" action="{{ database_url(database) }}{% if canned_query %}/{{ canned_query }}{% endif %}" method="{% if canned_write %}post{% else %}get{% endif %}">
|
||||
<h3>Custom SQL query{% if display_rows %} returning {% if truncated %}more than {% endif %}{{ "{:,}".format(display_rows|length) }} row{% if display_rows|length == 1 %}{% else %}s{% endif %}{% endif %} <span class="show-hide-sql">{% if hide_sql %}(<a href="{{ path_with_removed_args(request, {'_hide_sql': '1'}) }}">show</a>){% else %}(<a href="{{ path_with_added_args(request, {'_hide_sql': '1'}) }}">hide</a>){% endif %}</span></h3>
|
||||
{% if not hide_sql %}
|
||||
{% if editable and config.allow_sql %}
|
||||
|
|
@ -74,7 +75,12 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="zero-results">0 results</p>
|
||||
{% if success_message %}
|
||||
<p class="success">{{ success_message }}</p>
|
||||
{% endif %}
|
||||
{% if not canned_write %}
|
||||
<p class="zero-results">0 results</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% include "_codemirror_foot.html" %}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ class QueryView(DataView):
|
|||
canned_query=None,
|
||||
metadata=None,
|
||||
_size=None,
|
||||
named_parameters=None,
|
||||
write=False,
|
||||
):
|
||||
params = {key: request.args.get(key) for key in request.args}
|
||||
if "sql" in params:
|
||||
|
|
@ -113,7 +115,7 @@ class QueryView(DataView):
|
|||
if "_shape" in params:
|
||||
params.pop("_shape")
|
||||
# Extract any :named parameters
|
||||
named_parameters = self.re_named_parameter.findall(sql)
|
||||
named_parameters = named_parameters or self.re_named_parameter.findall(sql)
|
||||
named_parameter_values = {
|
||||
named_parameter: params.get(named_parameter) or ""
|
||||
for named_parameter in named_parameters
|
||||
|
|
@ -129,12 +131,46 @@ class QueryView(DataView):
|
|||
extra_args["custom_time_limit"] = int(params["_timelimit"])
|
||||
if _size:
|
||||
extra_args["page_size"] = _size
|
||||
results = await self.ds.execute(
|
||||
database, sql, params, truncate=True, **extra_args
|
||||
)
|
||||
columns = [r[0] for r in results.description]
|
||||
|
||||
templates = ["query-{}.html".format(to_css_class(database)), "query.html"]
|
||||
|
||||
# Execute query - as write or as read
|
||||
if write:
|
||||
if request.method == "POST":
|
||||
params = await request.post_vars()
|
||||
write_ok = await self.ds.databases[database].execute_write(
|
||||
sql, params, block=True
|
||||
)
|
||||
return self.redirect(request, request.path + '?_success=Query+executed_successfully')
|
||||
else:
|
||||
async def extra_template():
|
||||
return {
|
||||
"request": request,
|
||||
"path_with_added_args": path_with_added_args,
|
||||
"path_with_removed_args": path_with_removed_args,
|
||||
"named_parameter_values": named_parameter_values,
|
||||
"canned_query": canned_query,
|
||||
"success_message": request.raw_args.get("_success") or "",
|
||||
"canned_write": True,
|
||||
}
|
||||
|
||||
return (
|
||||
{
|
||||
"database": database,
|
||||
"rows": [],
|
||||
"truncated": False,
|
||||
"columns": [],
|
||||
"query": {"sql": sql, "params": params},
|
||||
},
|
||||
extra_template,
|
||||
templates,
|
||||
)
|
||||
else: # Not a write
|
||||
results = await self.ds.execute(
|
||||
database, sql, params, truncate=True, **extra_args
|
||||
)
|
||||
columns = [r[0] for r in results.description]
|
||||
|
||||
if canned_query:
|
||||
templates.insert(
|
||||
0,
|
||||
|
|
|
|||
|
|
@ -221,6 +221,22 @@ class RowTableShared(DataView):
|
|||
class TableView(RowTableShared):
|
||||
name = "table"
|
||||
|
||||
async def post(self, request, db_name, table_and_format):
|
||||
# Handle POST to a canned query
|
||||
canned_query = self.ds.get_canned_query(db_name, table_and_format)
|
||||
assert canned_query, "You may only POST to a canned query"
|
||||
return await QueryView(self.ds).data(
|
||||
request,
|
||||
db_name,
|
||||
None,
|
||||
canned_query["sql"],
|
||||
metadata=canned_query,
|
||||
editable=False,
|
||||
canned_query=table_and_format,
|
||||
named_parameters=canned_query.get("params"),
|
||||
write=bool(canned_query.get("write")),
|
||||
)
|
||||
|
||||
async def data(
|
||||
self,
|
||||
request,
|
||||
|
|
@ -241,6 +257,8 @@ class TableView(RowTableShared):
|
|||
metadata=canned_query,
|
||||
editable=False,
|
||||
canned_query=table,
|
||||
named_parameters=canned_query.get("params"),
|
||||
write=bool(canned_query.get("write")),
|
||||
)
|
||||
|
||||
db = self.ds.databases[database]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue