kopia lustrzana https://github.com/simonw/datasette
rodzic
f4794df070
commit
ff2ab9dc7d
|
@ -303,7 +303,15 @@ class TableView(BaseView):
|
||||||
async def data(self, request, name, hash, table):
|
async def data(self, request, name, hash, table):
|
||||||
table = urllib.parse.unquote_plus(table)
|
table = urllib.parse.unquote_plus(table)
|
||||||
pks = await self.pks_for_table(name, table)
|
pks = await self.pks_for_table(name, table)
|
||||||
use_rowid = not pks
|
is_view = bool(list(await self.execute(name, "SELECT count(*) from sqlite_master WHERE type = 'view' and name=:n", {
|
||||||
|
'n': table,
|
||||||
|
}))[0][0])
|
||||||
|
view_definition = None
|
||||||
|
if is_view:
|
||||||
|
view_definition = list(await self.execute(name, 'select sql from sqlite_master where name = :n and type="view"', {
|
||||||
|
'n': table,
|
||||||
|
}))[0][0];
|
||||||
|
use_rowid = not pks and not is_view
|
||||||
if use_rowid:
|
if use_rowid:
|
||||||
select = 'rowid, *'
|
select = 'rowid, *'
|
||||||
order_by = 'rowid'
|
order_by = 'rowid'
|
||||||
|
@ -311,6 +319,9 @@ class TableView(BaseView):
|
||||||
select = '*'
|
select = '*'
|
||||||
order_by = ', '.join(pks)
|
order_by = ', '.join(pks)
|
||||||
|
|
||||||
|
if is_view:
|
||||||
|
order_by = ''
|
||||||
|
|
||||||
# Special args start with _ and do not contain a __
|
# Special args start with _ and do not contain a __
|
||||||
# That's so if there is a column that starts with _
|
# That's so if there is a column that starts with _
|
||||||
# it can still be queried using ?_col__exact=blah
|
# it can still be queried using ?_col__exact=blah
|
||||||
|
@ -354,7 +365,10 @@ class TableView(BaseView):
|
||||||
if where_clauses:
|
if where_clauses:
|
||||||
where_clause = 'where {} '.format(' and '.join(where_clauses))
|
where_clause = 'where {} '.format(' and '.join(where_clauses))
|
||||||
|
|
||||||
sql = 'select {} from "{}" {}order by {} limit {}'.format(
|
if order_by:
|
||||||
|
order_by = 'order by {} '.format(order_by)
|
||||||
|
|
||||||
|
sql = 'select {} from "{}" {}{}limit {}'.format(
|
||||||
select, table, where_clause, order_by, self.page_size + 1,
|
select, table, where_clause, order_by, self.page_size + 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -375,6 +389,8 @@ class TableView(BaseView):
|
||||||
return {
|
return {
|
||||||
'database': name,
|
'database': name,
|
||||||
'table': table,
|
'table': table,
|
||||||
|
'is_view': is_view,
|
||||||
|
'view_definition': view_definition,
|
||||||
'rows': rows[:self.page_size],
|
'rows': rows[:self.page_size],
|
||||||
'table_rows': table_rows,
|
'table_rows': table_rows,
|
||||||
'columns': columns,
|
'columns': columns,
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
{% for table in tables %}
|
{% for table in tables %}
|
||||||
<div class="db-table">
|
<div class="db-table">
|
||||||
<h2><a href="/{{ database }}-{{ database_hash }}/{{ table.name }}">{{ table.name }}</a></h2>
|
<h2><a href="/{{ database }}-{{ database_hash }}/{{ table.name|urlencode }}">{{ table.name }}</a></h2>
|
||||||
<p><em>{% for column in table.columns[:9] %}{{ column }}{% if not loop.last %}, {% endif %}{% endfor %}{% if table.columns|length > 9 %}...{% endif %}</em></p>
|
<p><em>{% for column in table.columns[:9] %}{{ column }}{% if not loop.last %}, {% endif %}{% endfor %}{% if table.columns|length > 9 %}...{% endif %}</em></p>
|
||||||
<p>{{ "{:,}".format(table.table_rows) }} row{% if table.table_rows == 1 %}{% else %}s{% endif %}</p>
|
<p>{{ "{:,}".format(table.table_rows) }} row{% if table.table_rows == 1 %}{% else %}s{% endif %}</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,31 +30,9 @@
|
||||||
<h2>Views</h2>
|
<h2>Views</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{% for view in views %}
|
{% for view in views %}
|
||||||
<li><a href="/{{ database }}-{{ database_hash }}/{{ view }}">{{ view }}</a></li>
|
<li><a href="/{{ database }}-{{ database_hash }}/{{ view|urlencode }}">{{ view }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for row in rows %}
|
|
||||||
<tr>
|
|
||||||
{% for td in row %}
|
|
||||||
<td>
|
|
||||||
{% if loop.index == 2 and row.type in ("table", "view") %}
|
|
||||||
<a href="/{{ database }}-{{ database_hash }}/{{ td }}">{{ td }}</a>
|
|
||||||
{% else %}
|
|
||||||
{{ td }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="hd"><a href="/">home</a> / <a href="/{{ database }}-{{ database_hash }}">{{ database }}</a></div>
|
<div class="hd"><a href="/">home</a> / <a href="/{{ database }}-{{ database_hash }}">{{ database }}</a></div>
|
||||||
|
|
||||||
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_hash[:6] }}">{{ table }}</h1>
|
<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_hash[:6] }}">{{ table }}{% if is_view %} (view){% endif %}</h1>
|
||||||
|
|
||||||
{% if table_rows != None %}
|
{% if table_rows != None %}
|
||||||
<h2>{{ "{:,}".format(table_rows) }} total row{% if table_rows == 1 %}{% else %}s{% endif %} in this table</h2>
|
<h2>{{ "{:,}".format(table_rows) }} total row{% if table_rows == 1 %}{% else %}s{% endif %} in this table</h2>
|
||||||
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
<p>This data as <a href="{{ url_json }}">.json</a>, <a href="{{ url_jsono }}">.jsono</a></p>
|
<p>This data as <a href="{{ url_json }}">.json</a>, <a href="{{ url_jsono }}">.jsono</a></p>
|
||||||
|
|
||||||
|
{% if view_definition %}
|
||||||
|
<pre>{{ view_definition }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -91,6 +91,21 @@ def test_table_page(three_table_app_client):
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
||||||
|
def test_view(three_table_app_client):
|
||||||
|
_, response = three_table_app_client.get('/four_tables/simple_view')
|
||||||
|
assert response.status == 200
|
||||||
|
_, response = three_table_app_client.get('/four_tables/simple_view.jsono')
|
||||||
|
assert response.status == 200
|
||||||
|
data = response.json
|
||||||
|
assert data['rows'] == [{
|
||||||
|
'upper_content': 'HELLO',
|
||||||
|
'content': 'hello',
|
||||||
|
}, {
|
||||||
|
'upper_content': 'WORLD',
|
||||||
|
'content': 'world',
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
FOUR_TABLES = '''
|
FOUR_TABLES = '''
|
||||||
CREATE TABLE simple_primary_key (
|
CREATE TABLE simple_primary_key (
|
||||||
pk varchar(30) primary key,
|
pk varchar(30) primary key,
|
||||||
|
@ -115,4 +130,7 @@ CREATE TABLE "Table With Space In Name" (
|
||||||
|
|
||||||
INSERT INTO simple_primary_key VALUES (1, 'hello');
|
INSERT INTO simple_primary_key VALUES (1, 'hello');
|
||||||
INSERT INTO simple_primary_key VALUES (2, 'world');
|
INSERT INTO simple_primary_key VALUES (2, 'world');
|
||||||
|
|
||||||
|
CREATE VIEW simple_view AS
|
||||||
|
SELECT content, upper(content) AS upper_content FROM simple_primary_key;
|
||||||
'''
|
'''
|
||||||
|
|
Ładowanie…
Reference in New Issue