From c9d6798f2438e95be0b30d35f7da2b728c89aaf3 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sat, 30 Nov 2024 16:34:22 -0500 Subject: [PATCH] Refactor messages to belong to any number of newsgroups --- db/newsgroup.sql | 19 ++++++------- lib/nntp/tiny/message.py | 37 ++++++++++++------------- lib/nntp/tiny/session.py | 58 +++++++++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 51 deletions(-) diff --git a/db/newsgroup.sql b/db/newsgroup.sql index 96faed3..cc76631 100644 --- a/db/newsgroup.sql +++ b/db/newsgroup.sql @@ -8,25 +8,26 @@ create table newsgroup ( description TEXT NOT NULL ); -create table newsgroup_message ( +create table message ( id INTEGER PRIMARY KEY NOT NULL, created_on DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - newsgroup_id INTEGER NOT NULL, message_id TEXT NOT NULL UNIQUE, reference_ids TEXT, sender TEXT NOT NULL, subject TEXT NOT NULL, - content TEXT NOT NULL, - - FOREIGN KEY(newsgroup_id) REFERENCES newsgroup(id) + content TEXT NOT NULL ); -create index newsgroup_message_newsgroup_id_idx on newsgroup_message ( - newsgroup_id, id +create table newsgroup_message ( + newsgroup_id INTEGER NOT NULL, + message_id INTEGER NOT NULL, + + FOREIGN KEY(newsgroup_id) REFERENCES newsgroup(id), + FOREIGN KEY(message_id) REFERENCES message(id) ); -create index newsgroup_message_newsgroup_date_idx on newsgroup_message ( - newsgroup_id, created_on +create unique index newsgroup_message_newsgroup_id_idx on newsgroup_message ( + newsgroup_id, message_id ); create table server_permission ( diff --git a/lib/nntp/tiny/message.py b/lib/nntp/tiny/message.py index 802fdce..872ace7 100644 --- a/lib/nntp/tiny/message.py +++ b/lib/nntp/tiny/message.py @@ -76,16 +76,18 @@ class MessageRange(): return "?" - def where(self): + def where(self, table=None): + prefix = '' if table is None else f"{table}." + if self.id is not None: - return "id = %d" % (self.id) + return prefix + "message_id = %d" % (self.id) if self.min is not None and self.max is None: - return "id >= %d" % (self.min) + return prefix + "message_id >= %d" % (self.min) elif self.min is not None and self.max is not None: - return "id >= %d and id <= %d" % (self.min, self.max) + return prefix + "message_id >= %d and id <= %d" % (self.min, self.max) elif self.min is None and self.max is not None: - return "id <= %d" % (self.max) + return prefix + "message_id <= %d" % (self.max) @staticmethod def parse(r: str): @@ -127,17 +129,15 @@ class Message(DatabaseTable): '_body', '_key', 'id', - 'newsgroup_id', 'state', 'line', 'content', ) - name = 'newsgroup_message' + name = 'message' key = 'id' columns = ( 'id', - 'newsgroup_id', 'created_on', 'message_id', 'reference_ids', @@ -149,16 +149,15 @@ class Message(DatabaseTable): RE_HEADER = re.compile(r'^([A-Za-z0-9\-]+): (.*)$') def __init__(self): - self._cache = dict() - self._headers = None - self._headers_lc = None - self._body = None - self._key = None - self.id = None - self.newsgroup_id = None - self.state = MessageState.EMPTY - self.line = None - self.content = '' + self._cache = dict() + self._headers = None + self._headers_lc = None + self._body = None + self._key = None + self.id = None + self.state = MessageState.EMPTY + self.line = None + self.content = '' @staticmethod def __from_row__(row): @@ -171,7 +170,6 @@ class Message(DatabaseTable): message.content = row['content'] message.id = row['id'] - message.newsgroup_id = row['newsgroup_id'] message.created_on = row['created_on'] message.message_id = row['message_id'] message.reference_ids = row['reference_ids'] @@ -182,7 +180,6 @@ class Message(DatabaseTable): def __values__(self) -> tuple: return ( - self.newsgroup_id, self.created_on, self.message_id, self.reference_ids, diff --git a/lib/nntp/tiny/session.py b/lib/nntp/tiny/session.py index 8006040..62a524e 100644 --- a/lib/nntp/tiny/session.py +++ b/lib/nntp/tiny/session.py @@ -126,9 +126,9 @@ class Session(): sql = """ select - count(id), - min(id), - max(id) + count(message_id), + min(message_id), + max(message_id) from newsgroup_message where @@ -167,12 +167,12 @@ class Session(): sql = """ select - max(id) + max(message_id) from newsgroup_message where newsgroup_id = ? - and id < ? + and message_id < ? """ cr = self.db.execute(sql, (self.newsgroup.id, self.article_id)) @@ -194,11 +194,11 @@ class Session(): sql = """ select - min(id) + min(message_id) from newsgroup_message where - newsgroup_id = ? + message_id = ? and id > ? """ @@ -215,9 +215,9 @@ class Session(): def _newsgroup_summary(self, newsgroup: Newsgroup) -> str: sql = """ select - count(id), - min(id), - max(id) + count(message_id), + min(message_id), + max(message_id) from newsgroup_message where @@ -247,7 +247,7 @@ class Session(): sql = """ select - id + message_id from newsgroup_message where @@ -272,8 +272,8 @@ class Session(): def _newsgroup_summary(self, newsgroup: Newsgroup): sql = """ select - min(id), - max(id) + min(message_id), + max(message_id) from newsgroup_message where @@ -312,11 +312,13 @@ class Session(): def _newsgroup_last_active(self, newsgroup: Newsgroup): sql = """ select - max(created_on) + max(message.created_on) from - newsgroup_message + newsgroup_message, + message where - newsgroup_id = ? + message.id = newsgroup_message.id + and newsgroup_message.newsgroup_id = ? """ cr = self.db.execute(sql, (newsgroup.id,)) @@ -460,12 +462,14 @@ class Session(): sql = """ select - message_id + message.id from - newsgroup_message + newsgroup_message, + message where - newsgroup_id = ? - and created_on >= ? + message.id = newsgroup_message.message_id + and newsgroup_message.newsgroup_id = ? + and message.created_on >= ? """ for name in self.server.newsgroups: @@ -538,8 +542,18 @@ class Session(): msgrange = MessageRange.parse(identifier) - sql = f"select * from {Message.name} where " - sql += " newsgroup_id = ? and " + msgrange.where() + sql = """ + select + message.* + from + newsgroup_message, + message + where + message.id = newsgroup_message.id + and newsgroup_message.newsgroup_id = ? + """ + + sql += " and " + msgrange.where('message') cr = self.db.query_sql(Message, sql, (self.newsgroup.id,))