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
e37f4077c0
commit
18c5bd1805
4 changed files with 72 additions and 7 deletions
|
|
@ -345,3 +345,8 @@ p.zero-results {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
.success {
|
||||||
|
padding: 1em;
|
||||||
|
border: 1px solid green;
|
||||||
|
background-color: #c7fbc7;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,12 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_color(database) }}">{{ metadata.title or database }}</h1>
|
<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 %}
|
{% 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>
|
<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 not hide_sql %}
|
||||||
{% if editable and config.allow_sql %}
|
{% if editable and config.allow_sql %}
|
||||||
|
|
@ -74,7 +75,12 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
{% include "_codemirror_foot.html" %}
|
{% include "_codemirror_foot.html" %}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,8 @@ class QueryView(DataView):
|
||||||
canned_query=None,
|
canned_query=None,
|
||||||
metadata=None,
|
metadata=None,
|
||||||
_size=None,
|
_size=None,
|
||||||
|
named_parameters=None,
|
||||||
|
write=False,
|
||||||
):
|
):
|
||||||
params = request.raw_args
|
params = request.raw_args
|
||||||
if "sql" in params:
|
if "sql" in params:
|
||||||
|
|
@ -113,7 +115,7 @@ class QueryView(DataView):
|
||||||
if "_shape" in params:
|
if "_shape" in params:
|
||||||
params.pop("_shape")
|
params.pop("_shape")
|
||||||
# Extract any :named parameters
|
# 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_values = {
|
||||||
named_parameter: params.get(named_parameter) or ""
|
named_parameter: params.get(named_parameter) or ""
|
||||||
for named_parameter in named_parameters
|
for named_parameter in named_parameters
|
||||||
|
|
@ -129,12 +131,46 @@ class QueryView(DataView):
|
||||||
extra_args["custom_time_limit"] = int(params["_timelimit"])
|
extra_args["custom_time_limit"] = int(params["_timelimit"])
|
||||||
if _size:
|
if _size:
|
||||||
extra_args["page_size"] = _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"]
|
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:
|
if canned_query:
|
||||||
templates.insert(
|
templates.insert(
|
||||||
0,
|
0,
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,22 @@ class RowTableShared(DataView):
|
||||||
class TableView(RowTableShared):
|
class TableView(RowTableShared):
|
||||||
name = "table"
|
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(
|
async def data(
|
||||||
self,
|
self,
|
||||||
request,
|
request,
|
||||||
|
|
@ -231,6 +247,8 @@ class TableView(RowTableShared):
|
||||||
metadata=canned_query,
|
metadata=canned_query,
|
||||||
editable=False,
|
editable=False,
|
||||||
canned_query=table,
|
canned_query=table,
|
||||||
|
named_parameters=canned_query.get("params"),
|
||||||
|
write=bool(canned_query.get("write")),
|
||||||
)
|
)
|
||||||
|
|
||||||
db = self.ds.databases[database]
|
db = self.ds.databases[database]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue