Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tables starting with an underscore should be treated as hidden #2104

Closed
simonw opened this issue Jul 17, 2023 · 7 comments
Closed

Tables starting with an underscore should be treated as hidden #2104

simonw opened this issue Jul 17, 2023 · 7 comments

Comments

@simonw
Copy link
Owner

simonw commented Jul 17, 2023

Plugins can then take advantage of this pattern, for example:

@simonw
Copy link
Owner Author

simonw commented Jul 17, 2023

Relevant code:

async def hidden_table_names(self):
# Mark tables 'hidden' if they relate to FTS virtual tables
hidden_tables = [
r[0]
for r in (
await self.execute(
"""
select name from sqlite_master
where rootpage = 0
and (
sql like '%VIRTUAL TABLE%USING FTS%'
) or name in ('sqlite_stat1', 'sqlite_stat2', 'sqlite_stat3', 'sqlite_stat4')
"""
)
).rows
]
has_spatialite = await self.execute_fn(detect_spatialite)
if has_spatialite:
# Also hide Spatialite internal tables
hidden_tables += [
"ElementaryGeometries",
"SpatialIndex",
"geometry_columns",
"spatial_ref_sys",
"spatialite_history",
"sql_statements_log",
"sqlite_sequence",
"views_geometry_columns",
"virts_geometry_columns",
"data_licenses",
"KNN",
"KNN2",
] + [
r[0]
for r in (
await self.execute(
"""
select name from sqlite_master
where name like "idx_%"
and type = "table"
"""
)
).rows
]
# Add any from metadata.json
db_metadata = self.ds.metadata(database=self.name)
if "tables" in db_metadata:
hidden_tables += [
t
for t in db_metadata["tables"]
if db_metadata["tables"][t].get("hidden")
]
# Also mark as hidden any tables which start with the name of a hidden table
# e.g. "searchable_fts" implies "searchable_fts_content" should be hidden
for table_name in await self.table_names():
for hidden_table in hidden_tables[:]:
if table_name.startswith(hidden_table):
hidden_tables.append(table_name)
continue
return hidden_tables

@asg017
Copy link
Contributor

asg017 commented Jul 18, 2023

For filtering virtual table's "shadow tables" (ex the FTS5 _content and most the spatialite tables), you can use pragma_table_list (first appeared in SQLite 3.37 (2021-11-27), which has a type column that calls out type="shadow" tables https://www.sqlite.org/pragma.html#pragma_table_list

@simonw
Copy link
Owner Author

simonw commented Mar 7, 2024

We really need this for Datasette Cloud, we have _hidden_but_not_hidden tables all over the place!

@simonw
Copy link
Owner Author

simonw commented Mar 7, 2024

Had to figure out how to run a LIKE query with a literal _ in it - this is the syntax:

or name like '\_%' escape '\'

@simonw
Copy link
Owner Author

simonw commented Mar 7, 2024

There isn't any documentation on hidden tables right now, fixing that.

@simonw
Copy link
Owner Author

simonw commented Mar 7, 2024

For filtering virtual table's "shadow tables" (ex the FTS5 _content and most the spatialite tables), you can use pragma_table_list (first appeared in SQLite 3.37 (2021-11-27), which has a type column that calls out type="shadow" tables

Neat!

CleanShot 2024-03-07 at 00 01 55@2x

Aside: Datasette doesn't allow select * from pragma_table_list() now but I can fix that easily.

@simonw
Copy link
Owner Author

simonw commented Mar 7, 2024

Added new documentation listing all of the different types of hidden table here: https://docs.datasette.io/en/latest/pages.html#hidden-tables

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants