Auto clear dirtied_formats with a trigger

This commit is contained in:
Kovid Goyal 2022-02-08 10:57:48 +05:30
parent 2ecdbfb194
commit b66c72cc15
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 26 additions and 2 deletions

View File

@ -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;

View File

@ -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))

View File

@ -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():