Mercurial > libervia-backend
comparison sat/memory/sqla_mapping.py @ 3796:24c1c06c865b
core (memory/mapping): add `origin_id` column to History + constraints update:
- `origin_id` is added as a column instead of being just in extra, as it an important data
to filter on.
- Add some constraints.
- Add `serialise` method to Message and Subject.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 17 Jun 2022 14:15:23 +0200 |
parents | 658ddbabaf36 |
children | fe4725bf42fb |
comparison
equal
deleted
inserted
replaced
3795:967a8e109cda | 3796:24c1c06c865b |
---|---|
14 # GNU Affero General Public License for more details. | 14 # GNU Affero General Public License for more details. |
15 | 15 |
16 # You should have received a copy of the GNU Affero General Public License | 16 # You should have received a copy of the GNU Affero General Public License |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | 18 |
19 from typing import Dict, Any | |
20 from datetime import datetime | |
21 import enum | |
22 import json | |
19 import pickle | 23 import pickle |
20 import json | |
21 from datetime import datetime | |
22 import time | 24 import time |
23 import enum | 25 |
24 from sqlalchemy import ( | 26 from sqlalchemy import ( |
25 MetaData, Column, Integer, Text, Float, Boolean, DateTime, Enum, JSON, ForeignKey, | 27 Boolean, |
26 UniqueConstraint, Index, DDL, event | 28 Column, |
29 DDL, | |
30 DateTime, | |
31 Enum, | |
32 Float, | |
33 ForeignKey, | |
34 Index, | |
35 Integer, | |
36 JSON, | |
37 MetaData, | |
38 Text, | |
39 UniqueConstraint, | |
40 event, | |
27 ) | 41 ) |
28 | |
29 from sqlalchemy.orm import declarative_base, relationship | 42 from sqlalchemy.orm import declarative_base, relationship |
43 from sqlalchemy.sql.functions import now | |
30 from sqlalchemy.types import TypeDecorator | 44 from sqlalchemy.types import TypeDecorator |
31 from sqlalchemy.sql.functions import now | |
32 from twisted.words.protocols.jabber import jid | 45 from twisted.words.protocols.jabber import jid |
33 from wokkel import generic | 46 from wokkel import generic |
34 | 47 |
35 | 48 |
36 Base = declarative_base( | 49 Base = declarative_base( |
44 } | 57 } |
45 ) | 58 ) |
46 ) | 59 ) |
47 # keys which are in message data extra but not stored in extra field this is | 60 # keys which are in message data extra but not stored in extra field this is |
48 # because those values are stored in separate fields | 61 # because those values are stored in separate fields |
49 NOT_IN_EXTRA = ('stanza_id', 'received_timestamp', 'update_uid') | 62 NOT_IN_EXTRA = ('origin_id', 'stanza_id', 'received_timestamp', 'update_uid') |
50 | 63 |
51 | 64 |
52 class SyncState(enum.Enum): | 65 class SyncState(enum.Enum): |
53 #: synchronisation is currently in progress | 66 #: synchronisation is currently in progress |
54 IN_PROGRESS = 1 | 67 IN_PROGRESS = 1 |
182 | 195 |
183 class History(Base): | 196 class History(Base): |
184 __tablename__ = "history" | 197 __tablename__ = "history" |
185 __table_args__ = ( | 198 __table_args__ = ( |
186 UniqueConstraint("profile_id", "stanza_id", "source", "dest"), | 199 UniqueConstraint("profile_id", "stanza_id", "source", "dest"), |
200 UniqueConstraint("profile_id", "origin_id", "source", name="uq_origin_id"), | |
187 Index("history__profile_id_timestamp", "profile_id", "timestamp"), | 201 Index("history__profile_id_timestamp", "profile_id", "timestamp"), |
188 Index( | 202 Index( |
189 "history__profile_id_received_timestamp", "profile_id", "received_timestamp" | 203 "history__profile_id_received_timestamp", "profile_id", "received_timestamp" |
190 ) | 204 ) |
191 ) | 205 ) |
192 | 206 |
193 uid = Column(Text, primary_key=True) | 207 uid = Column(Text, primary_key=True) |
208 origin_id = Column(Text) | |
194 stanza_id = Column(Text) | 209 stanza_id = Column(Text) |
195 update_uid = Column(Text) | 210 update_uid = Column(Text) |
196 profile_id = Column(ForeignKey("profiles.id", ondelete="CASCADE")) | 211 profile_id = Column(ForeignKey("profiles.id", ondelete="CASCADE")) |
197 source = Column(Text) | 212 source = Column(Text) |
198 dest = Column(Text) | 213 dest = Column(Text) |
257 dt = datetime.fromtimestamp(self.timestamp) | 272 dt = datetime.fromtimestamp(self.timestamp) |
258 return f"History<{self.source_jid.full()}->{self.dest_jid.full()} [{dt}]>" | 273 return f"History<{self.source_jid.full()}->{self.dest_jid.full()} [{dt}]>" |
259 | 274 |
260 def serialise(self): | 275 def serialise(self): |
261 extra = self.extra | 276 extra = self.extra |
277 if self.origin_id is not None: | |
278 extra["origin_id"] = self.origin_id | |
262 if self.stanza_id is not None: | 279 if self.stanza_id is not None: |
263 extra["stanza_id"] = self.stanza_id | 280 extra["stanza_id"] = self.stanza_id |
264 if self.update_uid is not None: | 281 if self.update_uid is not None: |
265 extra["update_uid"] = self.update_uid | 282 extra["update_uid"] = self.update_uid |
266 if self.received_timestamp is not None: | 283 if self.received_timestamp is not None: |
317 | 334 |
318 id = Column( | 335 id = Column( |
319 Integer, | 336 Integer, |
320 primary_key=True, | 337 primary_key=True, |
321 ) | 338 ) |
322 history_uid = Column(ForeignKey("history.uid", ondelete="CASCADE")) | 339 history_uid = Column(ForeignKey("history.uid", ondelete="CASCADE"), nullable=False) |
323 message = Column(Text) | 340 message = Column(Text, nullable=False) |
324 language = Column(Text) | 341 language = Column(Text) |
342 | |
343 def serialise(self) -> Dict[str, Any]: | |
344 s = {} | |
345 if self.message: | |
346 s["message"] = str(self.message) | |
347 if self.language: | |
348 s["language"] = str(self.language) | |
349 return s | |
325 | 350 |
326 def __repr__(self): | 351 def __repr__(self): |
327 lang_str = f"[{self.language}]" if self.language else "" | 352 lang_str = f"[{self.language}]" if self.language else "" |
328 msg = f"{self.message[:20]}…" if len(self.message)>20 else self.message | 353 msg = f"{self.message[:20]}…" if len(self.message)>20 else self.message |
329 content = f"{lang_str}{msg}" | 354 content = f"{lang_str}{msg}" |
338 | 363 |
339 id = Column( | 364 id = Column( |
340 Integer, | 365 Integer, |
341 primary_key=True, | 366 primary_key=True, |
342 ) | 367 ) |
343 history_uid = Column(ForeignKey("history.uid", ondelete="CASCADE")) | 368 history_uid = Column(ForeignKey("history.uid", ondelete="CASCADE"), nullable=False) |
344 subject = Column(Text) | 369 subject = Column(Text, nullable=False) |
345 language = Column(Text) | 370 language = Column(Text) |
371 | |
372 def serialise(self) -> Dict[str, Any]: | |
373 s = {} | |
374 if self.subject: | |
375 s["subject"] = str(self.subject) | |
376 if self.language: | |
377 s["language"] = str(self.language) | |
378 return s | |
346 | 379 |
347 def __repr__(self): | 380 def __repr__(self): |
348 lang_str = f"[{self.language}]" if self.language else "" | 381 lang_str = f"[{self.language}]" if self.language else "" |
349 msg = f"{self.subject[:20]}…" if len(self.subject)>20 else self.subject | 382 msg = f"{self.subject[:20]}…" if len(self.subject)>20 else self.subject |
350 content = f"{lang_str}{msg}" | 383 content = f"{lang_str}{msg}" |