kopia lustrzana https://github.com/simonw/datasette
rodzic
b07312c2b3
commit
07e208cc6d
|
@ -461,104 +461,3 @@ class DataView(BaseView):
|
|||
if self.ds.cors:
|
||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||
return response
|
||||
|
||||
async def custom_sql(
|
||||
self,
|
||||
request,
|
||||
database,
|
||||
hash,
|
||||
sql,
|
||||
editable=True,
|
||||
canned_query=None,
|
||||
metadata=None,
|
||||
_size=None,
|
||||
):
|
||||
params = request.raw_args
|
||||
if "sql" in params:
|
||||
params.pop("sql")
|
||||
if "_shape" in params:
|
||||
params.pop("_shape")
|
||||
# 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("_timelimit"):
|
||||
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"]
|
||||
if canned_query:
|
||||
templates.insert(
|
||||
0,
|
||||
"query-{}-{}.html".format(
|
||||
to_css_class(database), to_css_class(canned_query)
|
||||
),
|
||||
)
|
||||
|
||||
async def extra_template():
|
||||
display_rows = []
|
||||
for row in results.rows:
|
||||
display_row = []
|
||||
for column, value in zip(results.columns, row):
|
||||
display_value = value
|
||||
# Let the plugins have a go
|
||||
# pylint: disable=no-member
|
||||
plugin_value = pm.hook.render_cell(
|
||||
value=value,
|
||||
column=column,
|
||||
table=None,
|
||||
database=database,
|
||||
datasette=self.ds,
|
||||
)
|
||||
if plugin_value is not None:
|
||||
display_value = plugin_value
|
||||
else:
|
||||
if value in ("", None):
|
||||
display_value = jinja2.Markup(" ")
|
||||
elif is_url(str(display_value).strip()):
|
||||
display_value = jinja2.Markup(
|
||||
'<a href="{url}">{url}</a>'.format(
|
||||
url=jinja2.escape(value.strip())
|
||||
)
|
||||
)
|
||||
display_row.append(display_value)
|
||||
display_rows.append(display_row)
|
||||
return {
|
||||
"display_rows": display_rows,
|
||||
"custom_sql": True,
|
||||
"named_parameter_values": named_parameter_values,
|
||||
"editable": editable,
|
||||
"canned_query": canned_query,
|
||||
"metadata": metadata,
|
||||
"config": self.ds.config_dict(),
|
||||
"request": request,
|
||||
"path_with_added_args": path_with_added_args,
|
||||
"path_with_removed_args": path_with_removed_args,
|
||||
"hide_sql": "_hide_sql" in params,
|
||||
}
|
||||
|
||||
return (
|
||||
{
|
||||
"database": database,
|
||||
"rows": results.rows,
|
||||
"truncated": results.truncated,
|
||||
"columns": columns,
|
||||
"query": {"sql": sql, "params": params},
|
||||
},
|
||||
extra_template,
|
||||
templates,
|
||||
)
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import os
|
||||
import jinja2
|
||||
|
||||
from datasette.utils import to_css_class, validate_sql_select
|
||||
from datasette.utils import (
|
||||
to_css_class,
|
||||
validate_sql_select,
|
||||
is_url,
|
||||
path_with_added_args,
|
||||
path_with_removed_args,
|
||||
)
|
||||
from datasette.utils.asgi import AsgiFileDownload
|
||||
from datasette.plugins import pm
|
||||
|
||||
from .base import DatasetteError, DataView
|
||||
|
||||
|
@ -18,7 +26,7 @@ class DatabaseView(DataView):
|
|||
raise DatasetteError("sql= is not allowed", status=400)
|
||||
sql = request.raw_args.pop("sql")
|
||||
validate_sql_select(sql)
|
||||
return await self.custom_sql(
|
||||
return await QueryView(self.ds).data(
|
||||
request, database, hash, sql, _size=_size, metadata=metadata
|
||||
)
|
||||
|
||||
|
@ -85,3 +93,108 @@ class DatabaseDownload(DataView):
|
|||
filename=os.path.basename(filepath),
|
||||
content_type="application/octet-stream",
|
||||
)
|
||||
|
||||
|
||||
class QueryView(DataView):
|
||||
name = "query"
|
||||
|
||||
async def data(
|
||||
self,
|
||||
request,
|
||||
database,
|
||||
hash,
|
||||
sql,
|
||||
editable=True,
|
||||
canned_query=None,
|
||||
metadata=None,
|
||||
_size=None,
|
||||
):
|
||||
params = request.raw_args
|
||||
if "sql" in params:
|
||||
params.pop("sql")
|
||||
if "_shape" in params:
|
||||
params.pop("_shape")
|
||||
# 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("_timelimit"):
|
||||
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"]
|
||||
if canned_query:
|
||||
templates.insert(
|
||||
0,
|
||||
"query-{}-{}.html".format(
|
||||
to_css_class(database), to_css_class(canned_query)
|
||||
),
|
||||
)
|
||||
|
||||
async def extra_template():
|
||||
display_rows = []
|
||||
for row in results.rows:
|
||||
display_row = []
|
||||
for column, value in zip(results.columns, row):
|
||||
display_value = value
|
||||
# Let the plugins have a go
|
||||
# pylint: disable=no-member
|
||||
plugin_value = pm.hook.render_cell(
|
||||
value=value,
|
||||
column=column,
|
||||
table=None,
|
||||
database=database,
|
||||
datasette=self.ds,
|
||||
)
|
||||
if plugin_value is not None:
|
||||
display_value = plugin_value
|
||||
else:
|
||||
if value in ("", None):
|
||||
display_value = jinja2.Markup(" ")
|
||||
elif is_url(str(display_value).strip()):
|
||||
display_value = jinja2.Markup(
|
||||
'<a href="{url}">{url}</a>'.format(
|
||||
url=jinja2.escape(value.strip())
|
||||
)
|
||||
)
|
||||
display_row.append(display_value)
|
||||
display_rows.append(display_row)
|
||||
return {
|
||||
"display_rows": display_rows,
|
||||
"custom_sql": True,
|
||||
"named_parameter_values": named_parameter_values,
|
||||
"editable": editable,
|
||||
"canned_query": canned_query,
|
||||
"metadata": metadata,
|
||||
"config": self.ds.config_dict(),
|
||||
"request": request,
|
||||
"path_with_added_args": path_with_added_args,
|
||||
"path_with_removed_args": path_with_removed_args,
|
||||
"hide_sql": "_hide_sql" in params,
|
||||
}
|
||||
|
||||
return (
|
||||
{
|
||||
"database": database,
|
||||
"rows": results.rows,
|
||||
"truncated": results.truncated,
|
||||
"columns": columns,
|
||||
"query": {"sql": sql, "params": params},
|
||||
},
|
||||
extra_template,
|
||||
templates,
|
||||
)
|
||||
|
|
|
@ -26,6 +26,7 @@ from datasette.utils import (
|
|||
from datasette.utils.asgi import NotFound
|
||||
from datasette.filters import Filters
|
||||
from .base import DataView, DatasetteError, ureg
|
||||
from .database import QueryView
|
||||
|
||||
LINK_WITH_LABEL = (
|
||||
'<a href="{base_url}{database}/{table}/{link_id}">{label}</a> <em>{id}</em>'
|
||||
|
@ -221,8 +222,8 @@ class TableView(RowTableShared):
|
|||
_size=None,
|
||||
):
|
||||
canned_query = self.ds.get_canned_query(database, table)
|
||||
if canned_query is not None:
|
||||
return await self.custom_sql(
|
||||
if canned_query:
|
||||
return await QueryView(self.ds).data(
|
||||
request,
|
||||
database,
|
||||
hash,
|
||||
|
@ -231,6 +232,7 @@ class TableView(RowTableShared):
|
|||
editable=False,
|
||||
canned_query=table,
|
||||
)
|
||||
|
||||
db = self.ds.databases[database]
|
||||
is_view = bool(await db.get_view_definition(table))
|
||||
table_exists = bool(await db.table_exists(table))
|
||||
|
|
Ładowanie…
Reference in New Issue