From 66fd63b11999e87c541b2023dd569b771927f283 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 24 Jan 2019 19:57:04 -0800 Subject: [PATCH] Ability to list just FTS4 or FTS5 table names --- docs/cli.rst | 5 +++++ docs/python-api.rst | 8 +++++--- sqlite_utils/cli.py | 10 ++++++++-- sqlite_utils/db.py | 20 ++++++++++---------- tests/test_cli.py | 14 +++++++++++++- tests/test_create.py | 6 +++--- tests/test_enable_fts.py | 4 ++-- tests/test_introspect.py | 8 +++++++- 8 files changed, 53 insertions(+), 22 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index 93b343a..fc47c29 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -16,6 +16,11 @@ You can list the names of tables in a database using the ``table_names`` subcomm cats chickens +If you just want to see the FTS4 tables, you can use ``--fts4`` (or ``--fts5`` for FTS5 tables):: + + $ sqlite-utils table_names --fts4 docs.db + docs_fts + Vacuum ====== diff --git a/docs/python-api.rst b/docs/python-api.rst index b3a29a5..3882be7 100644 --- a/docs/python-api.rst +++ b/docs/python-api.rst @@ -40,12 +40,14 @@ If the table does not yet exist, it will be created the first time you attempt t Listing tables ============== -You can list the names of tables in a database using the ``.table_names`` property:: +You can list the names of tables in a database using the ``.table_names()`` method:: - >>> db.table_names + >>> db.table_names() ['dogs'] -You can also iterate through the table objects themselves using ``.tables``:: +To see just the FTS4 tables, use ``.table_names(fts4=True)``. For FTS5, use ``.table_names(fts5=True)``. + +You can also iterate through the table objects themselves using the ``.tables`` property:: >>> db.tables [] diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 1a86379..94071cf 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -15,10 +15,16 @@ def cli(): type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False), required=True, ) -def table_names(path): +@click.option( + "--fts4", help="Just show FTS4 enabled tables", default=False, is_flag=True +) +@click.option( + "--fts5", help="Just show FTS5 enabled tables", default=False, is_flag=True +) +def table_names(path, fts4, fts5): """List the tables in the database""" db = sqlite_utils.Database(path) - for name in db.table_names: + for name in db.table_names(fts4=fts4, fts5=fts5): print(name) diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index ae8c57c..c182f8a 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -25,18 +25,18 @@ class Database: def __repr__(self): return "".format(self.conn) - @property - def table_names(self): - return [ - r[0] - for r in self.conn.execute( - "select name from sqlite_master where type = 'table'" - ).fetchall() - ] + def table_names(self, fts4=False, fts5=False): + where = ["type = 'table'"] + if fts4: + where.append("sql like '%FTS4%'") + if fts5: + where.append("sql like '%FTS5%'") + sql = "select name from sqlite_master where {}".format(" AND ".join(where)) + return [r[0] for r in self.conn.execute(sql).fetchall()] @property def tables(self): - return [self[name] for name in self.table_names] + return [self[name] for name in self.table_names()] def execute_returning_dicts(self, sql, params=None): cursor = self.conn.execute(sql, params or tuple()) @@ -106,7 +106,7 @@ class Table: def __init__(self, db, name): self.db = db self.name = name - self.exists = self.name in self.db.table_names + self.exists = self.name in self.db.table_names() def __repr__(self): return "
".format( diff --git a/tests/test_cli.py b/tests/test_cli.py index f24ddb1..fdb17a2 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,4 @@ -from sqlite_utils import cli +from sqlite_utils import cli, Database from click.testing import CliRunner import pytest import sqlite3 @@ -23,6 +23,18 @@ def test_table_names(db_path): assert "Gosh\nGosh2" == result.output.strip() +def test_table_names_fts4(db_path): + Database(db_path)["Gosh"].enable_fts(["c2"], fts_version="FTS4") + result = CliRunner().invoke(cli.cli, ["table_names", "--fts4", db_path]) + assert "Gosh_fts" == result.output.strip() + + +def test_table_names_fts5(db_path): + Database(db_path)["Gosh"].enable_fts(["c2"], fts_version="FTS5") + result = CliRunner().invoke(cli.cli, ["table_names", "--fts5", db_path]) + assert "Gosh_fts" == result.output.strip() + + def test_vacuum(db_path): result = CliRunner().invoke(cli.cli, ["vacuum", db_path]) assert 0 == result.exit_code diff --git a/tests/test_create.py b/tests/test_create.py index af0c39f..0a09fdc 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -6,7 +6,7 @@ import json def test_create_table(fresh_db): - assert [] == fresh_db.table_names + assert [] == fresh_db.table_names() table = fresh_db.create_table( "test_table", { @@ -18,7 +18,7 @@ def test_create_table(fresh_db): "datetime_col": datetime.datetime, }, ) - assert ["test_table"] == fresh_db.table_names + assert ["test_table"] == fresh_db.table_names() assert [ {"name": "text_col", "type": "TEXT"}, {"name": "float_col", "type": "FLOAT"}, @@ -44,7 +44,7 @@ def test_create_table(fresh_db): ) def test_create_table_from_example(fresh_db, example, expected_columns): fresh_db["people"].insert(example) - assert ["people"] == fresh_db.table_names + assert ["people"] == fresh_db.table_names() assert expected_columns == [ {"name": col.name, "type": col.type} for col in fresh_db["people"].columns ] diff --git a/tests/test_enable_fts.py b/tests/test_enable_fts.py index 707a761..196022e 100644 --- a/tests/test_enable_fts.py +++ b/tests/test_enable_fts.py @@ -7,7 +7,7 @@ search_records = [ def test_enable_fts(fresh_db): table = fresh_db["searchable"] table.insert_all(search_records) - assert ["searchable"] == fresh_db.table_names + assert ["searchable"] == fresh_db.table_names() table.enable_fts(["text", "country"], fts_version="FTS4") assert [ "searchable", @@ -16,7 +16,7 @@ def test_enable_fts(fresh_db): "searchable_fts_segdir", "searchable_fts_docsize", "searchable_fts_stat", - ] == fresh_db.table_names + ] == fresh_db.table_names() assert [("tanuki are tricksters", "Japan", "foo")] == table.search("tanuki") assert [("racoons are trash pandas", "USA", "bar")] == table.search("usa") assert [] == table.search("bar") diff --git a/tests/test_introspect.py b/tests/test_introspect.py index ac84419..0c7be8f 100644 --- a/tests/test_introspect.py +++ b/tests/test_introspect.py @@ -2,7 +2,13 @@ from sqlite_utils.db import Index def test_table_names(existing_db): - assert ["foo"] == existing_db.table_names + assert ["foo"] == existing_db.table_names() + + +def test_table_names_fts4(existing_db): + existing_db["woo"].insert({"title": "Hello"}) + existing_db["woo"].enable_fts(["title"], fts_version="FTS4") + assert ["woo_fts"] == existing_db.table_names(fts4=True) def test_tables(existing_db):