Skip to content

Commit

Permalink
count all rows button on table page, refs #2408
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Aug 22, 2024
1 parent dc1d152 commit 9ecce07
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
33 changes: 32 additions & 1 deletion datasette/templates/table.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ <h1>{{ metadata.get("title") or table }}{% if is_view %} (view){% endif %}{% if
{% endif %}

{% if count or human_description_en %}
<h3>{% if count or count == 0 %}{{ "{:,}".format(count) }} row{% if count == 1 %}{% else %}s{% endif %}{% endif %}
<h3>
{% if count == count_limit + 1 %}&gt;{{ "{:,}".format(count_limit) }} rows
{% if allow_execute_sql and query.sql %} <a class="count-sql" style="font-size: 0.8em; padding-left: 0.5em" href="{{ urls.database_query(database, count_sql) }}">count all rows</a>{% endif %}
{% elif count or count == 0 %}{{ "{:,}".format(count) }} row{% if count == 1 %}{% else %}s{% endif %}{% endif %}
{% if human_description_en %}{{ human_description_en }}{% endif %}
</h3>
{% endif %}
Expand Down Expand Up @@ -172,4 +175,32 @@ <h3>Advanced export</h3>
<pre class="wrapped-sql">{{ view_definition }}</pre>
{% endif %}

{% if allow_execute_sql and query.sql %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const countLink = document.querySelector('a.count-sql');
if (countLink) {
countLink.addEventListener('click', function(ev) {
ev.preventDefault();
// Replace countLink with span with same style attribute
const span = document.createElement('span');
span.textContent = 'counting...';
span.setAttribute('style', countLink.getAttribute('style'));
countLink.replaceWith(span);
countLink.setAttribute('disabled', 'disabled');
let url = countLink.href.replace(/(\?|$)/, '.json$1');
fetch(url)
.then(response => response.json())
.then(data => {
const count = data['rows'][0]['count(*)'];
const formattedCount = count.toLocaleString();
span.closest('h3').textContent = formattedCount + ' rows';
})
.catch(error => countLink.textContent = 'error');
});
}
});
</script>
{% endif %}

{% endblock %}
6 changes: 6 additions & 0 deletions datasette/url_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ def database(self, database, format=None):
db = self.ds.get_database(database)
return self.path(tilde_encode(db.route), format=format)

def database_query(self, database, sql, format=None):
path = f"{self.database(database)}/-/query?" + urllib.parse.urlencode(
{"sql": sql}
)
return self.path(path, format=format)

def table(self, database, table, format=None):
path = f"{self.database(database)}/{tilde_encode(table)}"
if format is not None:
Expand Down
11 changes: 10 additions & 1 deletion datasette/views/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ async def fetch_data(request, _next=None):
database=resolved.db.name,
table=resolved.table,
),
count_limit=resolved.db.count_limit,
),
request=request,
view_name="table",
Expand Down Expand Up @@ -1280,6 +1281,9 @@ async def table_view_data(
if extra_extras:
extras.update(extra_extras)

async def extra_count_sql():
return count_sql

async def extra_count():
"Total count of rows matching these filters"
# Calculate the total count for this query
Expand All @@ -1299,8 +1303,11 @@ async def extra_count():

# Otherwise run a select count(*) ...
if count_sql and count is None and not nocount:
count_sql_limited = (
f"select count(*) from (select * {from_sql} limit 10001)"
)
try:
count_rows = list(await db.execute(count_sql, from_sql_params))
count_rows = list(await db.execute(count_sql_limited, from_sql_params))
count = count_rows[0][0]
except QueryInterrupted:
pass
Expand Down Expand Up @@ -1615,6 +1622,7 @@ async def extra_facets_timed_out(extra_facet_results):
"facet_results",
"facets_timed_out",
"count",
"count_sql",
"human_description_en",
"next_url",
"metadata",
Expand Down Expand Up @@ -1647,6 +1655,7 @@ async def extra_facets_timed_out(extra_facet_results):

registry = Registry(
extra_count,
extra_count_sql,
extra_facet_results,
extra_facets_timed_out,
extra_suggested_facets,
Expand Down

0 comments on commit 9ecce07

Please sign in to comment.