db (schema): create virtual table for FTS + migration

rel 361
This commit is contained in:
Goffi 2021-09-08 17:58:48 +02:00
commit 39bdd34d60
2 changed files with 96 additions and 2 deletions

View file

@ -0,0 +1,49 @@
"""create virtual table for Full-Text Search
Revision ID: 129ac51807e4
Revises: 8974efc51d22
Create Date: 2021-08-13 19:13:54.112538
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '129ac51807e4'
down_revision = '8974efc51d22'
branch_labels = None
depends_on = None
def upgrade():
queries = [
"CREATE VIRTUAL TABLE pubsub_items_fts "
"USING fts5(data, content=pubsub_items, content_rowid=id)",
"CREATE TRIGGER pubsub_items_fts_sync_ins AFTER INSERT ON pubsub_items BEGIN"
" INSERT INTO pubsub_items_fts(rowid, data) VALUES (new.id, new.data);"
"END",
"CREATE TRIGGER pubsub_items_fts_sync_del AFTER DELETE ON pubsub_items BEGIN"
" INSERT INTO pubsub_items_fts(pubsub_items_fts, rowid, data) "
"VALUES('delete', old.id, old.data);"
"END",
"CREATE TRIGGER pubsub_items_fts_sync_upd AFTER UPDATE ON pubsub_items BEGIN"
" INSERT INTO pubsub_items_fts(pubsub_items_fts, rowid, data) VALUES"
"('delete', old.id, old.data);"
" INSERT INTO pubsub_items_fts(rowid, data) VALUES(new.id, new.data);"
"END",
"INSERT INTO pubsub_items_fts(rowid, data) SELECT id, data from pubsub_items"
]
for q in queries:
op.execute(sa.DDL(q))
def downgrade():
queries = [
"DROP TRIGGER IF EXISTS pubsub_items_fts_sync_ins",
"DROP TRIGGER IF EXISTS pubsub_items_fts_sync_del",
"DROP TRIGGER IF EXISTS pubsub_items_fts_sync_upd",
"DROP TABLE IF EXISTS pubsub_items_fts",
]
for q in queries:
op.execute(sa.DDL(q))

View file

@ -23,7 +23,7 @@ import time
import enum
from sqlalchemy import (
MetaData, Column, Integer, Text, Float, Boolean, DateTime, Enum, JSON, ForeignKey,
UniqueConstraint, Index
UniqueConstraint, Index, DDL, event
)
from sqlalchemy.orm import declarative_base, relationship
@ -56,7 +56,7 @@ class SyncState(enum.Enum):
COMPLETED = 2
#: something wrong happened during synchronisation, won't sync
ERROR = 3
#: synchronisation won't be done even if a syncing analyser match
#: synchronisation won't be done even if a syncing analyser matches
NO_SYNC = 4
@ -529,3 +529,48 @@ class PubsubItem(Base):
parsed = Column(JSON)
node = relationship("PubsubNode", back_populates="items")
## Full-Text Search
# create
@event.listens_for(PubsubItem.__table__, "after_create")
def fts_create(target, connection, **kw):
"""Full-Text Search table creation"""
if connection.engine.name == "sqlite":
# Using SQLite FTS5
queries = [
"CREATE VIRTUAL TABLE pubsub_items_fts "
"USING fts5(data, content=pubsub_items, content_rowid=id)",
"CREATE TRIGGER pubsub_items_fts_sync_ins AFTER INSERT ON pubsub_items BEGIN"
" INSERT INTO pubsub_items_fts(rowid, data) VALUES (new.id, new.data);"
"END",
"CREATE TRIGGER pubsub_items_fts_sync_del AFTER DELETE ON pubsub_items BEGIN"
" INSERT INTO pubsub_items_fts(pubsub_items_fts, rowid, data) "
"VALUES('delete', old.id, old.data);"
"END",
"CREATE TRIGGER pubsub_items_fts_sync_upd AFTER UPDATE ON pubsub_items BEGIN"
" INSERT INTO pubsub_items_fts(pubsub_items_fts, rowid, data) VALUES"
"('delete', old.id, old.data);"
" INSERT INTO pubsub_items_fts(rowid, data) VALUES(new.id, new.data);"
"END"
]
for q in queries:
connection.execute(DDL(q))
# drop
@event.listens_for(PubsubItem.__table__, "before_drop")
def fts_drop(target, connection, **kw):
"Full-Text Search table drop" ""
if connection.engine.name == "sqlite":
# Using SQLite FTS5
queries = [
"DROP TRIGGER IF EXISTS pubsub_items_fts_sync_ins",
"DROP TRIGGER IF EXISTS pubsub_items_fts_sync_del",
"DROP TRIGGER IF EXISTS pubsub_items_fts_sync_upd",
"DROP TABLE IF EXISTS pubsub_items_fts",
]
for q in queries:
connection.execute(DDL(q))