diff --git a/datasette/templates/index.html b/datasette/templates/index.html index 1133b84d..58956582 100644 --- a/datasette/templates/index.html +++ b/datasette/templates/index.html @@ -12,16 +12,16 @@ {% for database in databases %}

{{ database.name }}

- {{ "{:,}".format(database.table_rows_sum) }} rows in {{ database.tables_count }} table{% if database.tables_count != 1 %}s{% endif %}{% if database.tables_count and database.hidden_tables_count %}, {% endif %} - {% if database.hidden_tables_count %} - {{ "{:,}".format(database.hidden_table_rows_sum) }} rows in {{ database.hidden_tables_count }} hidden table{% if database.hidden_tables_count != 1 %}s{% endif %} - {% endif %} - {% if database.views_count %} - {% if database.tables_count or database.hidden_tables_count %} - {% endif %} + {{ "{:,}".format(database.table_rows_sum) }} rows in {{ database.tables_count }} table{% if database.tables_count != 1 %}s{% endif %}{% if database.tables_count and database.hidden_tables_count %}, {% endif -%} + {% if database.hidden_tables_count -%} + {{ "{:,}".format(database.hidden_table_rows_sum) }} rows in {{ database.hidden_tables_count }} hidden table{% if database.hidden_tables_count != 1 %}s{% endif -%} + {% endif -%} + {% if database.views_count -%} + {% if database.tables_count or database.hidden_tables_count %}, {% endif -%} {{ "{:,}".format(database.views_count) }} view{% if database.views_count != 1 %}s{% endif %} {% endif %}

-

{% for table in database.tables_truncated %}{{ table.name }}{% if not loop.last %}, {% endif %}{% endfor %}{% if database.tables_more %}, ...{% endif %}

+

{% for table in database.tables_and_views_truncated %}{{ table.name }}{% if not loop.last %}, {% endif %}{% endfor %}{% if database.tables_and_views_more %}, ...{% endif %}

{% endfor %} {% endblock %} diff --git a/datasette/views/index.py b/datasette/views/index.py index bb6154cf..31116baf 100644 --- a/datasette/views/index.py +++ b/datasette/views/index.py @@ -14,6 +14,9 @@ from datasette.version import __version__ from .base import HASH_LENGTH, RenderMixin +TRUNCATE_AT = 5 + + class IndexView(RenderMixin): name = "index" @@ -42,6 +45,21 @@ class IndexView(RenderMixin): ), } hidden_tables = [t for t in tables.values() if t["hidden"]] + visible_tables = [t for t in tables.values() if not t["hidden"]] + + tables_and_views_truncated = list( + sorted( + (t for t in tables.values() if t not in hidden_tables), + key=lambda t: t["count"] or 0, + reverse=True, + )[:TRUNCATE_AT] + ) + + # Only add views if this is less than TRUNCATE_AT + if len(tables_and_views_truncated) < TRUNCATE_AT: + num_views_to_add = TRUNCATE_AT - len(tables_and_views_truncated) + for view_name in views[:num_views_to_add]: + tables_and_views_truncated.append({"name": view_name}) databases.append( { @@ -51,13 +69,10 @@ class IndexView(RenderMixin): if db.hash else hashlib.md5(name.encode("utf8")).hexdigest()[:6], "path": self.database_url(name), - "tables_truncated": sorted( - (t for t in tables.values() if t not in hidden_tables), - key=lambda t: t["count"] or 0, - reverse=True, - )[:5], - "tables_count": len(tables), - "tables_more": len(tables) > 5, + "tables_and_views_truncated": tables_and_views_truncated, + "tables_and_views_more": (len(visible_tables) + len(views)) + > TRUNCATE_AT, + "tables_count": len(visible_tables), "table_rows_sum": sum((t["count"] or 0) for t in tables.values()), "hidden_table_rows_sum": sum( t["count"] for t in hidden_tables if t["count"] is not None diff --git a/tests/fixtures.py b/tests/fixtures.py index 23c8c7a8..bc6d55b2 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -612,6 +612,8 @@ CREATE TABLE searchable ( text2 text ); +CREATE VIEW searchable_view AS SELECT * FROM searchable; + INSERT INTO searchable VALUES (1, 'barry cat', 'terry dog'); INSERT INTO searchable VALUES (2, 'terry dog', 'sara weasel'); diff --git a/tests/test_api.py b/tests/test_api.py index a5e2163d..00c884a7 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -24,9 +24,9 @@ def test_homepage(app_client): assert response.json.keys() == {"fixtures": 0}.keys() d = response.json["fixtures"] assert d["name"] == "fixtures" - assert d["tables_count"] == 26 - assert len(d["tables_truncated"]) == 5 - assert d["tables_more"] is True + assert d["tables_count"] == 21 + assert len(d["tables_and_views_truncated"]) == 5 + assert d["tables_and_views_more"] is True # 4 hidden FTS tables + no_primary_key (hidden in metadata) assert d["hidden_tables_count"] == 5 # 201 in no_primary_key, plus 5 in other hidden tables: @@ -448,8 +448,8 @@ def test_no_files_uses_memory_database(app_client_no_files): "path": "/:memory:", "table_rows_sum": 0, "tables_count": 0, - "tables_more": False, - "tables_truncated": [], + "tables_and_views_more": False, + "tables_and_views_truncated": [], "views_count": 0, } } == response.json diff --git a/tests/test_html.py b/tests/test_html.py index 7b16e6d0..07644c27 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -32,16 +32,17 @@ def test_homepage(app_client_two_attached_databases): h2 = soup.select("h2")[1] assert "extra_database" == h2.text.strip() counts_p, links_p = h2.find_all_next("p") - assert "7 rows in 5 tables, 5 rows in 4 hidden tables" == counts_p.text.strip().replace( - " ", "" - ).replace( - "\n", "" + assert ( + "7 rows in 1 table, 5 rows in 4 hidden tables, 1 view" == counts_p.text.strip() ) # We should only show visible, not hidden tables here: table_links = [ {"href": a["href"], "text": a.text.strip()} for a in links_p.findAll("a") ] - assert [{"href": "/extra_database/searchable", "text": "searchable"}] == table_links + assert [ + {"href": "/extra_database/searchable", "text": "searchable"}, + {"href": "/extra_database/searchable_view", "text": "searchable_view"}, + ] == table_links def test_memory_database_page(app_client_with_memory):