From b66c72cc150428d743336a35dd0c8284919fcda0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Feb 2022 10:57:48 +0530 Subject: [PATCH] Auto clear dirtied_formats with a trigger --- resources/fts_sqlite.sql | 7 +++++-- src/calibre/db/fts/connect.py | 15 +++++++++++++++ src/calibre/db/tests/fts_api.py | 6 ++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/resources/fts_sqlite.sql b/resources/fts_sqlite.sql index 79b7b2daac..cfd503d654 100644 --- a/resources/fts_sqlite.sql +++ b/resources/fts_sqlite.sql @@ -6,12 +6,13 @@ CREATE TABLE fts_db.dirtied_formats ( id INTEGER PRIMARY KEY, CREATE TABLE fts_db.books_text ( id INTEGER PRIMARY KEY, book INTEGER NOT NULL, - format TEXT NOT NULL COLLATE NOCASE, timestamp REAL NOT NULL, + format TEXT NOT NULL COLLATE NOCASE, format_hash TEXT NOT NULL COLLATE NOCASE, format_size INTEGER NOT NULL, - text_hash TEXT NOT NULL COLLATE NOCASE, searchable_text TEXT NOT NULL DEFAULT "", + text_size INTEGER NOT NULL, + text_hash TEXT NOT NULL COLLATE NOCASE, UNIQUE(book, format) ); @@ -23,6 +24,7 @@ CREATE TRIGGER fts_db.books_fts_insert_trg AFTER INSERT ON fts_db.books_text BEGIN INSERT INTO books_fts(rowid, searchable_text) VALUES (NEW.id, NEW.searchable_text); INSERT INTO books_fts_stemmed(rowid, searchable_text) VALUES (NEW.id, NEW.searchable_text); + DELETE FROM dirtied_formats WHERE book=NEW.book AND format=NEW.format; END; CREATE TRIGGER fts_db.books_fts_delete_trg AFTER DELETE ON fts_db.books_text @@ -37,6 +39,7 @@ BEGIN INSERT INTO books_fts(rowid, searchable_text) VALUES (NEW.id, NEW.searchable_text); INSERT INTO books_fts_stemmed(books_fts_stemmed, rowid, searchable_text) VALUES('delete', OLD.id, OLD.searchable_text); INSERT INTO books_fts_stemmed(rowid, searchable_text) VALUES (NEW.id, NEW.searchable_text); + DELETE FROM dirtied_formats WHERE book=NEW.book AND format=NEW.format; END; PRAGMA fts_db.user_version=1; diff --git a/src/calibre/db/fts/connect.py b/src/calibre/db/fts/connect.py index 6c8271f226..0ca569c058 100644 --- a/src/calibre/db/fts/connect.py +++ b/src/calibre/db/fts/connect.py @@ -7,6 +7,8 @@ import builtins import os import sys +from calibre.utils.date import EPOCH, utcnow + from .schema_upgrade import SchemaUpgrade # TODO: db dump+restore @@ -43,3 +45,16 @@ class FTS: def clear_all_dirty(self): conn = self.get_connection() conn.execute('DELETE FROM fts_db.dirtied_formats') + + def add_text(self, book_id, fmt, text, text_hash='', fmt_size=0, fmt_hash=''): + conn = self.get_connection() + ts = (utcnow() - EPOCH).total_seconds() + fmt = fmt.upper() + if text: + conn.execute( + 'INSERT OR REPLACE INTO fts_db.books_text ' + '(book, timestamp, format, format_size, format_hash, searchable_text, text_size, text_hash) VALUES ' + '(?, ?, ?, ?, ?, ?, ?, ?)', ( + book_id, ts, fmt, fmt_size, fmt_hash, text, len(text), text_hash)) + else: + conn.execute('DELETE FROM fts_db.dirtied_formats WHERE book=? and format=?', (book_id, fmt)) diff --git a/src/calibre/db/tests/fts_api.py b/src/calibre/db/tests/fts_api.py index d866399523..b18b42150f 100644 --- a/src/calibre/db/tests/fts_api.py +++ b/src/calibre/db/tests/fts_api.py @@ -43,6 +43,12 @@ class FTSAPITest(BaseTest): self.ae(fts.all_currently_dirty(), []) cache.add_format(2, 'ADDED', BytesIO(b'data2')) self.ae(fts.all_currently_dirty(), [(2, 'ADDED')]) + fts.add_text(2, 'ADDED', 'data2') + self.ae(fts.all_currently_dirty(), []) + cache.add_format(2, 'ADDED', BytesIO(b'data2')) + self.ae(fts.all_currently_dirty(), [(2, 'ADDED')]) + fts.add_text(2, 'ADDED', 'data2') + self.ae(fts.all_currently_dirty(), []) def find_tests():