annotate sat/memory/sqla.py @ 3665:72b0e4053ab0

core (memory/slqa): implement `getProfileById` rel 361
author Goffi <goffi@goffi.org>
date Wed, 08 Sep 2021 17:58:48 +0200
parents 9ae6ec74face
children bd13391ee29e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
2
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia: an XMPP client
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
5
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
10
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
15
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
18
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
19 import sys
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
20 import time
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
21 import asyncio
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
22 from datetime import datetime
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
23 from asyncio.subprocess import PIPE
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
24 from pathlib import Path
3664
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
25 from typing import Union, Dict, List, Tuple, Iterable, Any, Callable, Optional
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
26 from sqlalchemy.ext.asyncio import AsyncSession, AsyncEngine, create_async_engine
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from sqlalchemy.exc import IntegrityError, NoResultFound
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
28 from sqlalchemy.orm import (
3664
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
29 sessionmaker, subqueryload, joinedload, selectinload, contains_eager
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
30 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
31 from sqlalchemy.orm.decl_api import DeclarativeMeta
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from sqlalchemy.future import select
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
33 from sqlalchemy.engine import Engine, Connection
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
34 from sqlalchemy import update, delete, and_, or_, event, func
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
35 from sqlalchemy.sql.functions import coalesce, sum as sum_, now, count
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
36 from sqlalchemy.dialects.sqlite import insert
3664
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
37 from sqlalchemy import text, literal_column, Integer
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
38 from alembic import script as al_script, config as al_config
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
39 from alembic.runtime import migration as al_migration
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
40 from twisted.internet import defer
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
41 from twisted.words.protocols.jabber import jid
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
42 from twisted.words.xish import domish
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
43 from sat.core.i18n import _
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
44 from sat.core import exceptions
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
45 from sat.core.log import getLogger
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
46 from sat.core.constants import Const as C
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
47 from sat.core.core_types import SatXMPPEntity
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
48 from sat.tools.utils import aio
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
49 from sat.tools.common import uri
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
50 from sat.memory import migration
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
51 from sat.memory import sqla_config
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
52 from sat.memory.sqla_mapping import (
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
53 NOT_IN_EXTRA,
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
54 SyncState,
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
55 Base,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
56 Profile,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
57 Component,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
58 History,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
59 Message,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
60 Subject,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
61 Thread,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
62 ParamGen,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
63 ParamInd,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
64 PrivateGen,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
65 PrivateInd,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
66 PrivateGenBin,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
67 PrivateIndBin,
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
68 File,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
69 PubsubNode,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
70 PubsubItem,
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
71 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
72
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
73
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
74 log = getLogger(__name__)
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
75 migration_path = Path(migration.__file__).parent
3664
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
76 #: mapping of Libervia search query operators to SQLAlchemy method name
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
77 OP_MAP = {
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
78 "==": "__eq__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
79 "eq": "__eq__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
80 "!=": "__ne__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
81 "ne": "__ne__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
82 ">": "__gt__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
83 "gt": "__gt__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
84 "<": "__le__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
85 "le": "__le__",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
86 "between": "between",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
87 "in": "in_",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
88 "not_in": "not_in",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
89 "overlap": "in_",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
90 "ioverlap": "in_",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
91 "disjoint": "in_",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
92 "idisjoint": "in_",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
93 "like": "like",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
94 "ilike": "ilike",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
95 "not_like": "notlike",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
96 "not_ilike": "notilike",
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
97 }
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
98
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
99
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
100 @event.listens_for(Engine, "connect")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
101 def set_sqlite_pragma(dbapi_connection, connection_record):
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
102 cursor = dbapi_connection.cursor()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
103 cursor.execute("PRAGMA foreign_keys=ON")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
104 cursor.close()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
105
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
106
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
107 class Storage:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
108
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
109 def __init__(self):
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
110 self.initialized = defer.Deferred()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
111 # we keep cache for the profiles (key: profile name, value: profile id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
112 # profile id to name
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
113 self.profiles: Dict[int, str] = {}
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
114 # profile id to component entry point
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
115 self.components: Dict[int, str] = {}
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
116
3665
72b0e4053ab0 core (memory/slqa): implement `getProfileById`
Goffi <goffi@goffi.org>
parents: 3664
diff changeset
117 def getProfileById(self, profile_id):
72b0e4053ab0 core (memory/slqa): implement `getProfileById`
Goffi <goffi@goffi.org>
parents: 3664
diff changeset
118 return self.profiles.get(profile_id)
72b0e4053ab0 core (memory/slqa): implement `getProfileById`
Goffi <goffi@goffi.org>
parents: 3664
diff changeset
119
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
120 async def migrateApply(self, *args: str, log_output: bool = False) -> None:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
121 """Do a migration command
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
122
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
123 Commands are applied by running Alembic in a subprocess.
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
124 Arguments are alembic executables commands
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
125
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
126 @param log_output: manage stdout and stderr:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
127 - if False, stdout and stderr are buffered, and logged only in case of error
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
128 - if True, stdout and stderr will be logged during the command execution
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
129 @raise exceptions.DatabaseError: something went wrong while running the
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
130 process
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
131 """
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
132 stdout, stderr = 2 * (None,) if log_output else 2 * (PIPE,)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
133 proc = await asyncio.create_subprocess_exec(
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
134 sys.executable, "-m", "alembic", *args,
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
135 stdout=stdout, stderr=stderr, cwd=migration_path
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
136 )
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
137 log_out, log_err = await proc.communicate()
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
138 if proc.returncode != 0:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
139 msg = _(
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
140 "Can't {operation} database (exit code {exit_code})"
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
141 ).format(
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
142 operation=args[0],
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
143 exit_code=proc.returncode
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
144 )
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
145 if log_out or log_err:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
146 msg += f":\nstdout: {log_out.decode()}\nstderr: {log_err.decode()}"
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
147 log.error(msg)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
148
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
149 raise exceptions.DatabaseError(msg)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
150
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
151 async def createDB(self, engine: AsyncEngine, db_config: dict) -> None:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
152 """Create a new database
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
153
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
154 The database is generated from SQLAlchemy model, then stamped by Alembic
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
155 """
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
156 # the dir may not exist if it's not the XDG recommended one
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
157 db_config["path"].parent.mkdir(0o700, True, True)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
158 async with engine.begin() as conn:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
159 await conn.run_sync(Base.metadata.create_all)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
160
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
161 log.debug("stamping the database")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
162 await self.migrateApply("stamp", "head")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
163 log.debug("stamping done")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
164
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
165 def _checkDBIsUpToDate(self, conn: Connection) -> bool:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
166 al_ini_path = migration_path / "alembic.ini"
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
167 al_cfg = al_config.Config(al_ini_path)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
168 directory = al_script.ScriptDirectory.from_config(al_cfg)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
169 context = al_migration.MigrationContext.configure(conn)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
170 return set(context.get_current_heads()) == set(directory.get_heads())
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
171
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
172 async def checkAndUpdateDB(self, engine: AsyncEngine, db_config: dict) -> None:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
173 """Check that database is up-to-date, and update if necessary"""
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
174 async with engine.connect() as conn:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
175 up_to_date = await conn.run_sync(self._checkDBIsUpToDate)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
176 if up_to_date:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
177 log.debug("Database is up-to-date")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
178 else:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
179 log.info("Database needs to be updated")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
180 log.info("updating…")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
181 await self.migrateApply("upgrade", "head", log_output=True)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
182 log.info("Database is now up-to-date")
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
183
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
184 @aio
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
185 async def initialise(self) -> None:
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
186 log.info(_("Connecting database"))
3583
16ade4ad63f3 core (memory/sqla_mapping): fix some technical debt:
Goffi <goffi@goffi.org>
parents: 3582
diff changeset
187
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
188 db_config = sqla_config.getDbConfig()
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
189 engine = create_async_engine(
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
190 db_config["url"],
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
191 future=True,
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
192 )
3583
16ade4ad63f3 core (memory/sqla_mapping): fix some technical debt:
Goffi <goffi@goffi.org>
parents: 3582
diff changeset
193
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
194 new_base = not db_config["path"].exists()
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
195 if new_base:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
196 log.info(_("The database is new, creating the tables"))
3582
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
197 await self.createDB(engine, db_config)
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
198 else:
71516731d0aa core (memory/sqla): database migration using Alembic:
Goffi <goffi@goffi.org>
parents: 3537
diff changeset
199 await self.checkAndUpdateDB(engine, db_config)
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
200
3583
16ade4ad63f3 core (memory/sqla_mapping): fix some technical debt:
Goffi <goffi@goffi.org>
parents: 3582
diff changeset
201 self.session = sessionmaker(
16ade4ad63f3 core (memory/sqla_mapping): fix some technical debt:
Goffi <goffi@goffi.org>
parents: 3582
diff changeset
202 engine, expire_on_commit=False, class_=AsyncSession
16ade4ad63f3 core (memory/sqla_mapping): fix some technical debt:
Goffi <goffi@goffi.org>
parents: 3582
diff changeset
203 )
16ade4ad63f3 core (memory/sqla_mapping): fix some technical debt:
Goffi <goffi@goffi.org>
parents: 3582
diff changeset
204
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
205 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
206 result = await session.execute(select(Profile))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
207 for p in result.scalars():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
208 self.profiles[p.name] = p.id
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
209 result = await session.execute(select(Component))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
210 for c in result.scalars():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
211 self.components[c.profile_id] = c.entry_point
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
212
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
213 self.initialized.callback(None)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
214
3596
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
215 ## Generic
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
216
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
217 @aio
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
218 async def add(self, db_obj: DeclarativeMeta) -> None:
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
219 """Add an object to database"""
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
220 async with self.session() as session:
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
221 async with session.begin():
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
222 session.add(db_obj)
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
223
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
224 @aio
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
225 async def delete(self, db_obj: DeclarativeMeta) -> None:
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
226 """Delete an object from database"""
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
227 async with self.session() as session:
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
228 async with session.begin():
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
229 await session.delete(db_obj)
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
230 await session.commit()
2d97c695af05 core (memory/sqla): generic methods to add and delete ORM objects directly
Goffi <goffi@goffi.org>
parents: 3595
diff changeset
231
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
232 ## Profiles
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
233
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
234 def getProfilesList(self) -> List[str]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
235 """"Return list of all registered profiles"""
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
236 return list(self.profiles.keys())
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
237
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
238 def hasProfile(self, profile_name: str) -> bool:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
239 """return True if profile_name exists
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
240
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
241 @param profile_name: name of the profile to check
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
242 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
243 return profile_name in self.profiles
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
244
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
245 def profileIsComponent(self, profile_name: str) -> bool:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
246 try:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
247 return self.profiles[profile_name] in self.components
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
248 except KeyError:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
249 raise exceptions.NotFound("the requested profile doesn't exists")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
250
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
251 def getEntryPoint(self, profile_name: str) -> str:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
252 try:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
253 return self.components[self.profiles[profile_name]]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
254 except KeyError:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
255 raise exceptions.NotFound("the requested profile doesn't exists or is not a component")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
256
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
257 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
258 async def createProfile(self, name: str, component_ep: Optional[str] = None) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
259 """Create a new profile
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
260
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
261 @param name: name of the profile
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
262 @param component: if not None, must point to a component entry point
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
263 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
264 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
265 profile = Profile(name=name)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
266 async with session.begin():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
267 session.add(profile)
3638
257135d5c5c2 core (memory/sqla): fix key/value inversion in self.profiles
Goffi <goffi@goffi.org>
parents: 3621
diff changeset
268 self.profiles[profile.name] = profile.id
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
269 if component_ep is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
270 async with session.begin():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
271 component = Component(profile=profile, entry_point=component_ep)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
272 session.add(component)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
273 self.components[profile.id] = component_ep
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
274 return profile
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
275
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
276 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
277 async def deleteProfile(self, name: str) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
278 """Delete profile
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
279
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
280 @param name: name of the profile
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
281 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
282 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
283 result = await session.execute(select(Profile).where(Profile.name == name))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
284 profile = result.scalar()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
285 await session.delete(profile)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
286 await session.commit()
3638
257135d5c5c2 core (memory/sqla): fix key/value inversion in self.profiles
Goffi <goffi@goffi.org>
parents: 3621
diff changeset
287 del self.profiles[profile.name]
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
288 if profile.id in self.components:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
289 del self.components[profile.id]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
290 log.info(_("Profile {name!r} deleted").format(name = name))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
291
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
292 ## Params
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
293
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
294 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
295 async def loadGenParams(self, params_gen: dict) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
296 """Load general parameters
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
297
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
298 @param params_gen: dictionary to fill
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
299 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
300 log.debug(_("loading general parameters from database"))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
301 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
302 result = await session.execute(select(ParamGen))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
303 for p in result.scalars():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
304 params_gen[(p.category, p.name)] = p.value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
305
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
306 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
307 async def loadIndParams(self, params_ind: dict, profile: str) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
308 """Load individual parameters
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
309
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
310 @param params_ind: dictionary to fill
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
311 @param profile: a profile which *must* exist
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
312 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
313 log.debug(_("loading individual parameters from database"))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
314 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
315 result = await session.execute(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
316 select(ParamInd).where(ParamInd.profile_id == self.profiles[profile])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
317 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
318 for p in result.scalars():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
319 params_ind[(p.category, p.name)] = p.value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
320
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
321 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
322 async def getIndParam(self, category: str, name: str, profile: str) -> Optional[str]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
323 """Ask database for the value of one specific individual parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
324
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
325 @param category: category of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
326 @param name: name of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
327 @param profile: %(doc_profile)s
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
328 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
329 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
330 result = await session.execute(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
331 select(ParamInd.value)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
332 .filter_by(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
333 category=category,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
334 name=name,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
335 profile_id=self.profiles[profile]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
336 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
337 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
338 return result.scalar_one_or_none()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
339
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
340 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
341 async def getIndParamValues(self, category: str, name: str) -> Dict[str, str]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
342 """Ask database for the individual values of a parameter for all profiles
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
343
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
344 @param category: category of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
345 @param name: name of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
346 @return dict: profile => value map
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
347 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
348 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
349 result = await session.execute(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
350 select(ParamInd)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
351 .filter_by(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
352 category=category,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
353 name=name
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
354 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
355 .options(subqueryload(ParamInd.profile))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
356 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
357 return {param.profile.name: param.value for param in result.scalars()}
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
358
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
359 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
360 async def setGenParam(self, category: str, name: str, value: Optional[str]) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
361 """Save the general parameters in database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
362
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
363 @param category: category of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
364 @param name: name of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
365 @param value: value to set
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
366 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
367 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
368 stmt = insert(ParamGen).values(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
369 category=category,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
370 name=name,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
371 value=value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
372 ).on_conflict_do_update(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
373 index_elements=(ParamGen.category, ParamGen.name),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
374 set_={
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
375 ParamGen.value: value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
376 }
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
377 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
378 await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
379 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
380
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
381 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
382 async def setIndParam(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
383 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
384 category:str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
385 name: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
386 value: Optional[str],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
387 profile: str
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
388 ) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
389 """Save the individual parameters in database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
390
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
391 @param category: category of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
392 @param name: name of the parameter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
393 @param value: value to set
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
394 @param profile: a profile which *must* exist
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
395 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
396 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
397 stmt = insert(ParamInd).values(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
398 category=category,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
399 name=name,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
400 profile_id=self.profiles[profile],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
401 value=value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
402 ).on_conflict_do_update(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
403 index_elements=(ParamInd.category, ParamInd.name, ParamInd.profile_id),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
404 set_={
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
405 ParamInd.value: value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
406 }
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
407 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
408 await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
409 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
410
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
411 def _jid_filter(self, jid_: jid.JID, dest: bool = False):
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
412 """Generate condition to filter on a JID, using relevant columns
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
413
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
414 @param dest: True if it's the destinee JID, otherwise it's the source one
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
415 @param jid_: JID to filter by
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
416 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
417 if jid_.resource:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
418 if dest:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
419 return and_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
420 History.dest == jid_.userhost(),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
421 History.dest_res == jid_.resource
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
422 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
423 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
424 return and_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
425 History.source == jid_.userhost(),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
426 History.source_res == jid_.resource
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
427 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
428 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
429 if dest:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
430 return History.dest == jid_.userhost()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
431 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
432 return History.source == jid_.userhost()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
433
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
434 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
435 async def historyGet(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
436 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
437 from_jid: Optional[jid.JID],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
438 to_jid: Optional[jid.JID],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
439 limit: Optional[int] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
440 between: bool = True,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
441 filters: Optional[Dict[str, str]] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
442 profile: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
443 ) -> List[Tuple[
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
444 str, int, str, str, Dict[str, str], Dict[str, str], str, str, str]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
445 ]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
446 """Retrieve messages in history
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
447
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
448 @param from_jid: source JID (full, or bare for catchall)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
449 @param to_jid: dest JID (full, or bare for catchall)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
450 @param limit: maximum number of messages to get:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
451 - 0 for no message (returns the empty list)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
452 - None for unlimited
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
453 @param between: confound source and dest (ignore the direction)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
454 @param filters: pattern to filter the history results
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
455 @return: list of messages as in [messageNew], minus the profile which is already
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
456 known.
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
457 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
458 # we have to set a default value to profile because it's last argument
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
459 # and thus follow other keyword arguments with default values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
460 # but None should not be used for it
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
461 assert profile is not None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
462 if limit == 0:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
463 return []
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
464 if filters is None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
465 filters = {}
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
466
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
467 stmt = (
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
468 select(History)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
469 .filter_by(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
470 profile_id=self.profiles[profile]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
471 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
472 .outerjoin(History.messages)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
473 .outerjoin(History.subjects)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
474 .outerjoin(History.thread)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
475 .options(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
476 contains_eager(History.messages),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
477 contains_eager(History.subjects),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
478 contains_eager(History.thread),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
479 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
480 .order_by(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
481 # timestamp may be identical for 2 close messages (specially when delay is
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
482 # used) that's why we order ties by received_timestamp. We'll reverse the
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
483 # order when returning the result. We use DESC here so LIMIT keep the last
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
484 # messages
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
485 History.timestamp.desc(),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
486 History.received_timestamp.desc()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
487 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
488 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
489
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
490
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
491 if not from_jid and not to_jid:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
492 # no jid specified, we want all one2one communications
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
493 pass
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
494 elif between:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
495 if not from_jid or not to_jid:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
496 # we only have one jid specified, we check all messages
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
497 # from or to this jid
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
498 jid_ = from_jid or to_jid
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
499 stmt = stmt.where(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
500 or_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
501 self._jid_filter(jid_),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
502 self._jid_filter(jid_, dest=True)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
503 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
504 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
505 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
506 # we have 2 jids specified, we check all communications between
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
507 # those 2 jids
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
508 stmt = stmt.where(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
509 or_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
510 and_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
511 self._jid_filter(from_jid),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
512 self._jid_filter(to_jid, dest=True),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
513 ),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
514 and_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
515 self._jid_filter(to_jid),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
516 self._jid_filter(from_jid, dest=True),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
517 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
518 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
519 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
520 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
521 # we want one communication in specific direction (from somebody or
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
522 # to somebody).
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
523 if from_jid is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
524 stmt = stmt.where(self._jid_filter(from_jid))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
525 if to_jid is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
526 stmt = stmt.where(self._jid_filter(to_jid, dest=True))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
527
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
528 if filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
529 if 'timestamp_start' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
530 stmt = stmt.where(History.timestamp >= float(filters['timestamp_start']))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
531 if 'before_uid' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
532 # orignially this query was using SQLITE's rowid. This has been changed
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
533 # to use coalesce(received_timestamp, timestamp) to be SQL engine independant
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
534 stmt = stmt.where(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
535 coalesce(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
536 History.received_timestamp,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
537 History.timestamp
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
538 ) < (
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
539 select(coalesce(History.received_timestamp, History.timestamp))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
540 .filter_by(uid=filters["before_uid"])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
541 ).scalar_subquery()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
542 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
543 if 'body' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
544 # TODO: use REGEXP (function to be defined) instead of GLOB: https://www.sqlite.org/lang_expr.html
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
545 stmt = stmt.where(Message.message.like(f"%{filters['body']}%"))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
546 if 'search' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
547 search_term = f"%{filters['search']}%"
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
548 stmt = stmt.where(or_(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
549 Message.message.like(search_term),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
550 History.source_res.like(search_term)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
551 ))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
552 if 'types' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
553 types = filters['types'].split()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
554 stmt = stmt.where(History.type.in_(types))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
555 if 'not_types' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
556 types = filters['not_types'].split()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
557 stmt = stmt.where(History.type.not_in(types))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
558 if 'last_stanza_id' in filters:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
559 # this request get the last message with a "stanza_id" that we
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
560 # have in history. This is mainly used to retrieve messages sent
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
561 # while we were offline, using MAM (XEP-0313).
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
562 if (filters['last_stanza_id'] is not True
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
563 or limit != 1):
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
564 raise ValueError("Unexpected values for last_stanza_id filter")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
565 stmt = stmt.where(History.stanza_id.is_not(None))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
566
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
567 if limit is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
568 stmt = stmt.limit(limit)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
569
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
570 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
571 result = await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
572
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
573 result = result.scalars().unique().all()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
574 result.reverse()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
575 return [h.as_tuple() for h in result]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
576
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
577 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
578 async def addToHistory(self, data: dict, profile: str) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
579 """Store a new message in history
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
580
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
581 @param data: message data as build by SatMessageProtocol.onMessage
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
582 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
583 extra = {k: v for k, v in data["extra"].items() if k not in NOT_IN_EXTRA}
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
584 messages = [Message(message=mess, language=lang)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
585 for lang, mess in data["message"].items()]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
586 subjects = [Subject(subject=mess, language=lang)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
587 for lang, mess in data["subject"].items()]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
588 if "thread" in data["extra"]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
589 thread = Thread(thread_id=data["extra"]["thread"],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
590 parent_id=data["extra"].get["thread_parent"])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
591 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
592 thread = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
593 try:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
594 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
595 async with session.begin():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
596 session.add(History(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
597 uid=data["uid"],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
598 stanza_id=data["extra"].get("stanza_id"),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
599 update_uid=data["extra"].get("update_uid"),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
600 profile_id=self.profiles[profile],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
601 source_jid=data["from"],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
602 dest_jid=data["to"],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
603 timestamp=data["timestamp"],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
604 received_timestamp=data.get("received_timestamp"),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
605 type=data["type"],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
606 extra=extra,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
607 messages=messages,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
608 subjects=subjects,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
609 thread=thread,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
610 ))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
611 except IntegrityError as e:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
612 if "unique" in str(e.orig).lower():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
613 log.debug(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
614 f"message {data['uid']!r} is already in history, not storing it again"
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
615 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
616 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
617 log.error(f"Can't store message {data['uid']!r} in history: {e}")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
618 except Exception as e:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
619 log.critical(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
620 f"Can't store message, unexpected exception (uid: {data['uid']}): {e}"
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
621 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
622
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
623 ## Private values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
624
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
625 def _getPrivateClass(self, binary, profile):
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
626 """Get ORM class to use for private values"""
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
627 if profile is None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
628 return PrivateGenBin if binary else PrivateGen
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
629 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
630 return PrivateIndBin if binary else PrivateInd
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
631
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
632
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
633 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
634 async def getPrivates(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
635 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
636 namespace:str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
637 keys: Optional[Iterable[str]] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
638 binary: bool = False,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
639 profile: Optional[str] = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
640 ) -> Dict[str, Any]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
641 """Get private value(s) from databases
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
642
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
643 @param namespace: namespace of the values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
644 @param keys: keys of the values to get None to get all keys/values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
645 @param binary: True to deserialise binary values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
646 @param profile: profile to use for individual values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
647 None to use general values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
648 @return: gotten keys/values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
649 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
650 if keys is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
651 keys = list(keys)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
652 log.debug(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
653 f"getting {'general' if profile is None else 'individual'}"
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
654 f"{' binary' if binary else ''} private values from database for namespace "
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
655 f"{namespace}{f' with keys {keys!r}' if keys is not None else ''}"
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
656 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
657 cls = self._getPrivateClass(binary, profile)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
658 stmt = select(cls).filter_by(namespace=namespace)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
659 if keys:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
660 stmt = stmt.where(cls.key.in_(list(keys)))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
661 if profile is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
662 stmt = stmt.filter_by(profile_id=self.profiles[profile])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
663 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
664 result = await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
665 return {p.key: p.value for p in result.scalars()}
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
666
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
667 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
668 async def setPrivateValue(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
669 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
670 namespace: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
671 key:str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
672 value: Any,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
673 binary: bool = False,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
674 profile: Optional[str] = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
675 ) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
676 """Set a private value in database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
677
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
678 @param namespace: namespace of the values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
679 @param key: key of the value to set
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
680 @param value: value to set
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
681 @param binary: True if it's a binary values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
682 binary values need to be serialised, used for everything but strings
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
683 @param profile: profile to use for individual value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
684 if None, it's a general value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
685 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
686 cls = self._getPrivateClass(binary, profile)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
687
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
688 values = {
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
689 "namespace": namespace,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
690 "key": key,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
691 "value": value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
692 }
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
693 index_elements = [cls.namespace, cls.key]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
694
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
695 if profile is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
696 values["profile_id"] = self.profiles[profile]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
697 index_elements.append(cls.profile_id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
698
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
699 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
700 await session.execute(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
701 insert(cls).values(**values).on_conflict_do_update(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
702 index_elements=index_elements,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
703 set_={
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
704 cls.value: value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
705 }
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
706 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
707 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
708 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
709
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
710 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
711 async def delPrivateValue(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
712 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
713 namespace: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
714 key: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
715 binary: bool = False,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
716 profile: Optional[str] = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
717 ) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
718 """Delete private value from database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
719
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
720 @param category: category of the privateeter
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
721 @param key: key of the private value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
722 @param binary: True if it's a binary values
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
723 @param profile: profile to use for individual value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
724 if None, it's a general value
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
725 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
726 cls = self._getPrivateClass(binary, profile)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
727
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
728 stmt = delete(cls).filter_by(namespace=namespace, key=key)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
729
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
730 if profile is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
731 stmt = stmt.filter_by(profile_id=self.profiles[profile])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
732
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
733 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
734 await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
735 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
736
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
737 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
738 async def delPrivateNamespace(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
739 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
740 namespace: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
741 binary: bool = False,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
742 profile: Optional[str] = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
743 ) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
744 """Delete all data from a private namespace
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
745
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
746 Be really cautious when you use this method, as all data with given namespace are
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
747 removed.
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
748 Params are the same as for delPrivateValue
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
749 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
750 cls = self._getPrivateClass(binary, profile)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
751
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
752 stmt = delete(cls).filter_by(namespace=namespace)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
753
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
754 if profile is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
755 stmt = stmt.filter_by(profile_id=self.profiles[profile])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
756
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
757 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
758 await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
759 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
760
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
761 ## Files
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
762
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
763 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
764 async def getFiles(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
765 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
766 client: Optional[SatXMPPEntity],
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
767 file_id: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
768 version: Optional[str] = '',
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
769 parent: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
770 type_: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
771 file_hash: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
772 hash_algo: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
773 name: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
774 namespace: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
775 mime_type: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
776 public_id: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
777 owner: Optional[jid.JID] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
778 access: Optional[dict] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
779 projection: Optional[List[str]] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
780 unique: bool = False
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
781 ) -> List[dict]:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
782 """Retrieve files with with given filters
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
783
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
784 @param file_id: id of the file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
785 None to ignore
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
786 @param version: version of the file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
787 None to ignore
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
788 empty string to look for current version
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
789 @param parent: id of the directory containing the files
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
790 None to ignore
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
791 empty string to look for root files/directories
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
792 @param projection: name of columns to retrieve
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
793 None to retrieve all
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
794 @param unique: if True will remove duplicates
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
795 other params are the same as for [setFile]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
796 @return: files corresponding to filters
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
797 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
798 if projection is None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
799 projection = [
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
800 'id', 'version', 'parent', 'type', 'file_hash', 'hash_algo', 'name',
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
801 'size', 'namespace', 'media_type', 'media_subtype', 'public_id',
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
802 'created', 'modified', 'owner', 'access', 'extra'
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
803 ]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
804
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
805 stmt = select(*[getattr(File, f) for f in projection])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
806
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
807 if unique:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
808 stmt = stmt.distinct()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
809
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
810 if client is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
811 stmt = stmt.filter_by(profile_id=self.profiles[client.profile])
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
812 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
813 if public_id is None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
814 raise exceptions.InternalError(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
815 "client can only be omitted when public_id is set"
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
816 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
817 if file_id is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
818 stmt = stmt.filter_by(id=file_id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
819 if version is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
820 stmt = stmt.filter_by(version=version)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
821 if parent is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
822 stmt = stmt.filter_by(parent=parent)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
823 if type_ is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
824 stmt = stmt.filter_by(type=type_)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
825 if file_hash is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
826 stmt = stmt.filter_by(file_hash=file_hash)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
827 if hash_algo is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
828 stmt = stmt.filter_by(hash_algo=hash_algo)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
829 if name is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
830 stmt = stmt.filter_by(name=name)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
831 if namespace is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
832 stmt = stmt.filter_by(namespace=namespace)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
833 if mime_type is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
834 if '/' in mime_type:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
835 media_type, media_subtype = mime_type.split("/", 1)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
836 stmt = stmt.filter_by(media_type=media_type, media_subtype=media_subtype)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
837 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
838 stmt = stmt.filter_by(media_type=mime_type)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
839 if public_id is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
840 stmt = stmt.filter_by(public_id=public_id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
841 if owner is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
842 stmt = stmt.filter_by(owner=owner)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
843 if access is not None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
844 raise NotImplementedError('Access check is not implemented yet')
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
845 # a JSON comparison is needed here
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
846
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
847 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
848 result = await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
849
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
850 return [dict(r) for r in result]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
851
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
852 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
853 async def setFile(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
854 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
855 client: SatXMPPEntity,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
856 name: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
857 file_id: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
858 version: str = "",
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
859 parent: str = "",
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
860 type_: str = C.FILE_TYPE_FILE,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
861 file_hash: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
862 hash_algo: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
863 size: int = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
864 namespace: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
865 mime_type: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
866 public_id: Optional[str] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
867 created: Optional[float] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
868 modified: Optional[float] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
869 owner: Optional[jid.JID] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
870 access: Optional[dict] = None,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
871 extra: Optional[dict] = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
872 ) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
873 """Set a file metadata
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
874
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
875 @param client: client owning the file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
876 @param name: name of the file (must not contain "/")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
877 @param file_id: unique id of the file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
878 @param version: version of this file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
879 @param parent: id of the directory containing this file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
880 Empty string if it is a root file/directory
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
881 @param type_: one of:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
882 - file
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
883 - directory
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
884 @param file_hash: unique hash of the payload
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
885 @param hash_algo: algorithm used for hashing the file (usually sha-256)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
886 @param size: size in bytes
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
887 @param namespace: identifier (human readable is better) to group files
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
888 for instance, namespace could be used to group files in a specific photo album
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
889 @param mime_type: media type of the file, or None if not known/guessed
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
890 @param public_id: ID used to server the file publicly via HTTP
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
891 @param created: UNIX time of creation
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
892 @param modified: UNIX time of last modification, or None to use created date
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
893 @param owner: jid of the owner of the file (mainly useful for component)
3621
9e1a993ad1bf core (memory/sqla): minor docstring line lenght fix
Goffi <goffi@goffi.org>
parents: 3596
diff changeset
894 @param access: serialisable dictionary with access rules. See [memory.memory] for
9e1a993ad1bf core (memory/sqla): minor docstring line lenght fix
Goffi <goffi@goffi.org>
parents: 3596
diff changeset
895 details
3537
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
896 @param extra: serialisable dictionary of any extra data
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
897 will be encoded to json in database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
898 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
899 if mime_type is None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
900 media_type = media_subtype = None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
901 elif '/' in mime_type:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
902 media_type, media_subtype = mime_type.split('/', 1)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
903 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
904 media_type, media_subtype = mime_type, None
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
905
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
906 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
907 async with session.begin():
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
908 session.add(File(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
909 id=file_id,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
910 version=version.strip(),
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
911 parent=parent,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
912 type=type_,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
913 file_hash=file_hash,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
914 hash_algo=hash_algo,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
915 name=name,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
916 size=size,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
917 namespace=namespace,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
918 media_type=media_type,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
919 media_subtype=media_subtype,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
920 public_id=public_id,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
921 created=time.time() if created is None else created,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
922 modified=modified,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
923 owner=owner,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
924 access=access,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
925 extra=extra,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
926 profile_id=self.profiles[client.profile]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
927 ))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
928
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
929 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
930 async def fileGetUsedSpace(self, client: SatXMPPEntity, owner: jid.JID) -> int:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
931 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
932 result = await session.execute(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
933 select(sum_(File.size)).filter_by(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
934 owner=owner,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
935 type=C.FILE_TYPE_FILE,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
936 profile_id=self.profiles[client.profile]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
937 ))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
938 return result.scalar_one_or_none() or 0
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
939
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
940 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
941 async def fileDelete(self, file_id: str) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
942 """Delete file metadata from the database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
943
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
944 @param file_id: id of the file to delete
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
945 NOTE: file itself must still be removed, this method only handle metadata in
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
946 database
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
947 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
948 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
949 await session.execute(delete(File).filter_by(id=file_id))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
950 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
951
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
952 @aio
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
953 async def fileUpdate(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
954 self,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
955 file_id: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
956 column: str,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
957 update_cb: Callable[[dict], None]
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
958 ) -> None:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
959 """Update a column value using a method to avoid race conditions
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
960
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
961 the older value will be retrieved from database, then update_cb will be applied to
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
962 update it, and file will be updated checking that older value has not been changed
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
963 meanwhile by an other user. If it has changed, it tries again a couple of times
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
964 before failing
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
965 @param column: column name (only "access" or "extra" are allowed)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
966 @param update_cb: method to update the value of the colum
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
967 the method will take older value as argument, and must update it in place
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
968 update_cb must not care about serialization,
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
969 it get the deserialized data (i.e. a Python object) directly
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
970 @raise exceptions.NotFound: there is not file with this id
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
971 """
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
972 if column not in ('access', 'extra'):
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
973 raise exceptions.InternalError('bad column name')
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
974 orm_col = getattr(File, column)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
975
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
976 for i in range(5):
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
977 async with self.session() as session:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
978 try:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
979 value = (await session.execute(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
980 select(orm_col).filter_by(id=file_id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
981 )).scalar_one()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
982 except NoResultFound:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
983 raise exceptions.NotFound
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
984 update_cb(value)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
985 stmt = update(orm_col).filter_by(id=file_id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
986 if not value:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
987 # because JsonDefaultDict convert NULL to an empty dict, we have to
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
988 # test both for empty dict and None when we have and empty dict
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
989 stmt = stmt.where((orm_col == None) | (orm_col == value))
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
990 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
991 stmt = stmt.where(orm_col == value)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
992 result = await session.execute(stmt)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
993 await session.commit()
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
994
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
995 if result.rowcount == 1:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
996 break
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
997
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
998 log.warning(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
999 _("table not updated, probably due to race condition, trying again "
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1000 "({tries})").format(tries=i+1)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1001 )
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1002
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1003 else:
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1004 raise exceptions.DatabaseError(
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1005 _("Can't update file {file_id} due to race condition")
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1006 .format(file_id=file_id)
f9a5b810f14d core (memory/storage): backend storage is now based on SQLAlchemy
Goffi <goffi@goffi.org>
parents:
diff changeset
1007 )
3595
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1008
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1009 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1010 async def getPubsubNode(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1011 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1012 client: SatXMPPEntity,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1013 service: jid.JID,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1014 name: str,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1015 with_items: bool = False,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1016 ) -> Optional[PubsubNode]:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1017 """
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1018 """
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1019 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1020 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1021 select(PubsubNode)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1022 .filter_by(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1023 service=service,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1024 name=name,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1025 profile_id=self.profiles[client.profile],
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1026 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1027 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1028 if with_items:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1029 stmt = stmt.options(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1030 joinedload(PubsubNode.items)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1031 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1032 result = await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1033 return result.unique().scalar_one_or_none()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1034
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1035 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1036 async def setPubsubNode(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1037 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1038 client: SatXMPPEntity,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1039 service: jid.JID,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1040 name: str,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1041 analyser: Optional[str] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1042 type_: Optional[str] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1043 subtype: Optional[str] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1044 ) -> PubsubNode:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1045 node = PubsubNode(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1046 profile_id=self.profiles[client.profile],
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1047 service=service,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1048 name=name,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1049 subscribed=False,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1050 analyser=analyser,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1051 type_=type_,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1052 subtype=subtype,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1053 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1054 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1055 async with session.begin():
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1056 session.add(node)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1057 return node
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1058
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1059 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1060 async def updatePubsubNodeSyncState(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1061 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1062 node: PubsubNode,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1063 state: SyncState
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1064 ) -> None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1065 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1066 async with session.begin():
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1067 await session.execute(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1068 update(PubsubNode)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1069 .filter_by(id=node.id)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1070 .values(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1071 sync_state=state,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1072 sync_state_updated=time.time(),
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1073 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1074 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1075
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1076 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1077 async def deletePubsubNode(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1078 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1079 profiles: Optional[List[str]],
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1080 services: Optional[List[jid.JID]],
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1081 names: Optional[List[str]]
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1082 ) -> None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1083 """Delete items cached for a node
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1084
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1085 @param profiles: profile names from which nodes must be deleted.
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1086 None to remove nodes from ALL profiles
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1087 @param services: JIDs of pubsub services from which nodes must be deleted.
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1088 None to remove nodes from ALL services
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1089 @param names: names of nodes which must be deleted.
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1090 None to remove ALL nodes whatever is their names
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1091 """
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1092 stmt = delete(PubsubNode)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1093 if profiles is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1094 stmt = stmt.where(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1095 PubsubNode.profile.in_(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1096 [self.profiles[p] for p in profiles]
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1097 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1098 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1099 if services is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1100 stmt = stmt.where(PubsubNode.service.in_(services))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1101 if names is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1102 stmt = stmt.where(PubsubNode.name.in_(names))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1103 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1104 await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1105 await session.commit()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1106
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1107 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1108 async def cachePubsubItems(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1109 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1110 client: SatXMPPEntity,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1111 node: PubsubNode,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1112 items: List[domish.Element],
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1113 parsed_items: Optional[List[dict]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1114 ) -> None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1115 """Add items to database, using an upsert taking care of "updated" field"""
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1116 if parsed_items is not None and len(items) != len(parsed_items):
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1117 raise exceptions.InternalError(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1118 "parsed_items must have the same lenght as items"
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1119 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1120 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1121 async with session.begin():
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1122 for idx, item in enumerate(items):
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1123 parsed = parsed_items[idx] if parsed_items else None
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1124 stmt = insert(PubsubItem).values(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1125 node_id = node.id,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1126 name = item["id"],
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1127 data = item,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1128 parsed = parsed,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1129 ).on_conflict_do_update(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1130 index_elements=(PubsubItem.node_id, PubsubItem.name),
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1131 set_={
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1132 PubsubItem.data: item,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1133 PubsubItem.parsed: parsed,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1134 PubsubItem.updated: now()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1135 }
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1136 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1137 await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1138 await session.commit()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1139
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1140 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1141 async def deletePubsubItems(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1142 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1143 node: PubsubNode,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1144 items_names: Optional[List[str]] = None
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1145 ) -> None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1146 """Delete items cached for a node
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1147
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1148 @param node: node from which items must be deleted
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1149 @param items_names: names of items to delete
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1150 if None, ALL items will be deleted
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1151 """
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1152 stmt = delete(PubsubItem)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1153 if node is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1154 if isinstance(node, list):
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1155 stmt = stmt.where(PubsubItem.node_id.in_([n.id for n in node]))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1156 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1157 stmt = stmt.filter_by(node_id=node.id)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1158 if items_names is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1159 stmt = stmt.where(PubsubItem.name.in_(items_names))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1160 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1161 await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1162 await session.commit()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1163
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1164 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1165 async def purgePubsubItems(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1166 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1167 services: Optional[List[jid.JID]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1168 names: Optional[List[str]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1169 types: Optional[List[str]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1170 subtypes: Optional[List[str]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1171 profiles: Optional[List[str]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1172 created_before: Optional[datetime] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1173 updated_before: Optional[datetime] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1174 ) -> None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1175 """Delete items cached for a node
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1176
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1177 @param node: node from which items must be deleted
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1178 @param items_names: names of items to delete
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1179 if None, ALL items will be deleted
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1180 """
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1181 stmt = delete(PubsubItem)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1182 node_fields = {
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1183 "service": services,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1184 "name": names,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1185 "type_": types,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1186 "subtype": subtypes,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1187 }
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1188 if any(x is not None for x in node_fields.values()):
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1189 sub_q = select(PubsubNode.id)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1190 for col, values in node_fields.items():
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1191 if values is None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1192 continue
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1193 sub_q = sub_q.where(getattr(PubsubNode, col).in_(values))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1194 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1195 stmt
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1196 .where(PubsubItem.node_id.in_(sub_q))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1197 .execution_options(synchronize_session=False)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1198 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1199
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1200 if profiles is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1201 stmt = stmt.where(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1202 PubsubItem.profile_id.in_([self.profiles[p] for p in profiles])
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1203 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1204
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1205 if created_before is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1206 stmt = stmt.where(PubsubItem.created < created_before)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1207
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1208 if updated_before is not None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1209 stmt = stmt.where(PubsubItem.updated < updated_before)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1210
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1211 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1212 await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1213 await session.commit()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1214
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1215 @aio
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1216 async def getItems(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1217 self,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1218 node: PubsubNode,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1219 max_items: Optional[int] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1220 before: Optional[str] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1221 after: Optional[str] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1222 from_index: Optional[int] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1223 order_by: Optional[List[str]] = None,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1224 desc: bool = True,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1225 force_rsm: bool = False,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1226 ) -> Tuple[List[PubsubItem], dict]:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1227 """Get Pubsub Items from cache
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1228
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1229 @param node: retrieve items from this node (must be synchronised)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1230 @param max_items: maximum number of items to retrieve
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1231 @param before: get items which are before the item with this name in given order
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1232 empty string is not managed here, use desc order to reproduce RSM
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1233 behaviour.
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1234 @param after: get items which are after the item with this name in given order
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1235 @param from_index: get items with item index (as defined in RSM spec)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1236 starting from this number
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1237 @param order_by: sorting order of items (one of C.ORDER_BY_*)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1238 @param desc: direction or ordering
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1239 @param force_rsm: if True, force the use of RSM worklow.
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1240 RSM workflow is automatically used if any of before, after or
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1241 from_index is used, but if only RSM max_items is used, it won't be
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1242 used by default. This parameter let's use RSM workflow in this
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1243 case. Note that in addition to RSM metadata, the result will not be
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1244 the same (max_items without RSM will returns most recent items,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1245 i.e. last items in modification order, while max_items with RSM
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1246 will return the oldest ones (i.e. first items in modification
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1247 order).
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1248 to be used when max_items is used from RSM
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1249 """
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1250
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1251 metadata = {
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1252 "service": node.service,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1253 "node": node.name,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1254 "uri": uri.buildXMPPUri(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1255 "pubsub",
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1256 path=node.service.full(),
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1257 node=node.name,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1258 ),
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1259 }
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1260 if max_items is None:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1261 max_items = 20
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1262
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1263 use_rsm = any((before, after, from_index is not None))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1264 if force_rsm and not use_rsm:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1265 #
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1266 use_rsm = True
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1267 from_index = 0
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1268
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1269 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1270 select(PubsubItem)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1271 .filter_by(node_id=node.id)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1272 .limit(max_items)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1273 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1274
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1275 if not order_by:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1276 order_by = [C.ORDER_BY_MODIFICATION]
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1277
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1278 order = []
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1279 for order_type in order_by:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1280 if order_type == C.ORDER_BY_MODIFICATION:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1281 if desc:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1282 order.extend((PubsubItem.updated.desc(), PubsubItem.id.desc()))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1283 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1284 order.extend((PubsubItem.updated.asc(), PubsubItem.id.asc()))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1285 elif order_type == C.ORDER_BY_CREATION:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1286 if desc:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1287 order.append(PubsubItem.id.desc())
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1288 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1289 order.append(PubsubItem.id.asc())
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1290 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1291 raise exceptions.InternalError(f"Unknown order type {order_type!r}")
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1292
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1293 stmt = stmt.order_by(*order)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1294
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1295 if use_rsm:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1296 # CTE to have result row numbers
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1297 row_num_q = select(
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1298 PubsubItem.id,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1299 PubsubItem.name,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1300 # row_number starts from 1, but RSM index must start from 0
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1301 (func.row_number().over(order_by=order)-1).label("item_index")
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1302 ).filter_by(node_id=node.id)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1303
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1304 row_num_cte = row_num_q.cte()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1305
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1306 if max_items > 0:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1307 # as we can't simply use PubsubItem.id when we order by modification,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1308 # we need to use row number
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1309 item_name = before or after
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1310 row_num_limit_q = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1311 select(row_num_cte.c.item_index)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1312 .where(row_num_cte.c.name==item_name)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1313 ).scalar_subquery()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1314
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1315 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1316 select(row_num_cte.c.item_index, PubsubItem)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1317 .join(row_num_cte, PubsubItem.id == row_num_cte.c.id)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1318 .limit(max_items)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1319 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1320 if before:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1321 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1322 stmt
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1323 .where(row_num_cte.c.item_index<row_num_limit_q)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1324 .order_by(row_num_cte.c.item_index.desc())
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1325 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1326 elif after:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1327 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1328 stmt
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1329 .where(row_num_cte.c.item_index>row_num_limit_q)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1330 .order_by(row_num_cte.c.item_index.asc())
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1331 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1332 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1333 stmt = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1334 stmt
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1335 .where(row_num_cte.c.item_index>=from_index)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1336 .order_by(row_num_cte.c.item_index.asc())
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1337 )
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1338 # from_index is used
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1339
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1340 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1341 if max_items == 0:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1342 items = result = []
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1343 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1344 result = await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1345 result = result.all()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1346 if before:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1347 result.reverse()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1348 items = [row[-1] for row in result]
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1349 rows_count = (
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1350 await session.execute(row_num_q.with_only_columns(count()))
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1351 ).scalar_one()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1352
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1353 try:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1354 index = result[0][0]
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1355 except IndexError:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1356 index = None
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1357
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1358 try:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1359 first = result[0][1].name
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1360 except IndexError:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1361 first = None
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1362 last = None
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1363 else:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1364 last = result[-1][1].name
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1365
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1366
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1367 metadata["rsm"] = {
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1368 "index": index,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1369 "count": rows_count,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1370 "first": first,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1371 "last": last,
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1372 }
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1373 metadata["complete"] = index + len(result) == rows_count
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1374
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1375 return items, metadata
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1376
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1377 async with self.session() as session:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1378 result = await session.execute(stmt)
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1379
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1380 result = result.scalars().all()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1381 if desc:
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1382 result.reverse()
7510648e8e3a core (memory/sqla): methods to manipulate pubsub tables
Goffi <goffi@goffi.org>
parents: 3583
diff changeset
1383 return result, metadata
3664
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1384
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1385 def _getSqlitePath(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1386 self,
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1387 path: List[Union[str, int]]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1388 ) -> str:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1389 """generate path suitable to query JSON element with SQLite"""
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1390 return f"${''.join(f'[{p}]' if isinstance(p, int) else f'.{p}' for p in path)}"
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1391
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1392 @aio
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1393 async def searchPubsubItems(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1394 self,
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1395 query: dict,
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1396 ) -> Tuple[List[PubsubItem]]:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1397 """Search for pubsub items in cache
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1398
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1399 @param query: search terms. Keys can be:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1400 :fts (str):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1401 Full-Text Search query. Currently SQLite FT5 engine is used, its query
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1402 syntax can be used, see `FTS5 Query documentation
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1403 <https://sqlite.org/fts5.html#full_text_query_syntax>`_
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1404 :profiles (list[str]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1405 filter on nodes linked to those profiles
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1406 :nodes (list[str]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1407 filter on nodes with those names
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1408 :services (list[jid.JID]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1409 filter on nodes from those services
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1410 :types (list[str|None]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1411 filter on nodes with those types. None can be used to filter on nodes with
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1412 no type set
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1413 :subtypes (list[str|None]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1414 filter on nodes with those subtypes. None can be used to filter on nodes with
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1415 no subtype set
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1416 :parsed (list[dict]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1417 Filter on a parsed data field. The dict must contain 3 keys: ``path``
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1418 which is a list of str or int giving the path to the field of interest
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1419 (str for a dict key, int for a list index), ``operator`` with indicate the
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1420 operator to use to check the condition, and ``value`` which depends of
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1421 field type and operator.
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1422
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1423 See documentation for details on operators (it's currently explained at
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1424 ``doc/libervia-cli/pubsub_cache.rst`` in ``search`` command
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1425 documentation).
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1426
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1427 :order-by (list[dict]):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1428 Indicates how to order results. The dict can contain either a ``order``
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1429 for a well-know order or a ``path`` for a parsed data field path
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1430 (``order`` and ``path`` can't be used at the same time), an an optional
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1431 ``direction`` which can be ``asc`` or ``desc``. See documentation for
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1432 details on well-known orders (it's currently explained at
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1433 ``doc/libervia-cli/pubsub_cache.rst`` in ``search`` command
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1434 documentation).
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1435
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1436 :index (int):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1437 starting index of items to return from the query result. It's translated
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1438 to SQL's OFFSET
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1439
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1440 :limit (int):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1441 maximum number of items to return. It's translated to SQL's LIMIT.
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1442
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1443 @result: found items (the ``node`` attribute will be filled with suitable
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1444 PubsubNode)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1445 """
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1446 # TODO: FTS and parsed data filters use SQLite specific syntax
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1447 # when other DB engines will be used, this will have to be adapted
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1448 stmt = select(PubsubItem)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1449
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1450 # Full-Text Search
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1451 fts = query.get("fts")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1452 if fts:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1453 fts_select = text(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1454 "SELECT rowid, rank FROM pubsub_items_fts(:fts_query)"
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1455 ).bindparams(fts_query=fts).columns(rowid=Integer).subquery()
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1456 stmt = (
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1457 stmt
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1458 .select_from(fts_select)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1459 .outerjoin(PubsubItem, fts_select.c.rowid == PubsubItem.id)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1460 )
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1461
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1462 # node related filters
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1463 profiles = query.get("profiles")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1464 if (profiles
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1465 or any(query.get(k) for k in ("nodes", "services", "types", "subtypes"))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1466 ):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1467 stmt = stmt.join(PubsubNode).options(contains_eager(PubsubItem.node))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1468 if profiles:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1469 try:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1470 stmt = stmt.where(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1471 PubsubNode.profile_id.in_(self.profiles[p] for p in profiles)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1472 )
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1473 except KeyError as e:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1474 raise exceptions.ProfileUnknownError(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1475 f"This profile doesn't exist: {e.args[0]!r}"
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1476 )
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1477 for key, attr in (
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1478 ("nodes", "name"),
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1479 ("services", "service"),
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1480 ("types", "type_"),
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1481 ("subtypes", "subtype")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1482 ):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1483 value = query.get(key)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1484 if not value:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1485 continue
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1486 if key in ("types", "subtypes") and None in value:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1487 # NULL can't be used with SQL's IN, so we have to add a condition with
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1488 # IS NULL, and use a OR if there are other values to check
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1489 value.remove(None)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1490 condition = getattr(PubsubNode, attr).is_(None)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1491 if value:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1492 condition = or_(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1493 getattr(PubsubNode, attr).in_(value),
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1494 condition
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1495 )
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1496 else:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1497 condition = getattr(PubsubNode, attr).in_(value)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1498 stmt = stmt.where(condition)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1499 else:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1500 stmt = stmt.options(selectinload(PubsubItem.node))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1501
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1502 # parsed data filters
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1503 parsed = query.get("parsed", [])
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1504 for filter_ in parsed:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1505 try:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1506 path = filter_["path"]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1507 operator = filter_["op"]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1508 value = filter_["value"]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1509 except KeyError as e:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1510 raise ValueError(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1511 f'missing mandatory key {e.args[0]!r} in "parsed" filter'
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1512 )
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1513 try:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1514 op_attr = OP_MAP[operator]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1515 except KeyError:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1516 raise ValueError(f"invalid operator: {operator!r}")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1517 sqlite_path = self._getSqlitePath(path)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1518 if operator in ("overlap", "ioverlap", "disjoint", "idisjoint"):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1519 col = literal_column("json_each.value")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1520 if operator[0] == "i":
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1521 col = func.lower(col)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1522 value = [str(v).lower() for v in value]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1523 condition = (
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1524 select(1)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1525 .select_from(func.json_each(PubsubItem.parsed, sqlite_path))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1526 .where(col.in_(value))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1527 ).scalar_subquery()
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1528 if operator in ("disjoint", "idisjoint"):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1529 condition = condition.is_(None)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1530 stmt = stmt.where(condition)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1531 elif operator == "between":
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1532 try:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1533 left, right = value
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1534 except (ValueError, TypeError):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1535 raise ValueError(_(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1536 "invalid value for \"between\" filter, you must use a 2 items "
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1537 "array: {value!r}"
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1538 ).format(value=value))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1539 col = func.json_extract(PubsubItem.parsed, sqlite_path)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1540 stmt = stmt.where(col.between(left, right))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1541 else:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1542 # we use func.json_extract instead of generic JSON way because SQLAlchemy
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1543 # add a JSON_QUOTE to the value, and we want SQL value
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1544 col = func.json_extract(PubsubItem.parsed, sqlite_path)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1545 stmt = stmt.where(getattr(col, op_attr)(value))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1546
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1547 # order
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1548 order_by = query.get("order-by") or [{"order": "creation"}]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1549
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1550 for order_data in order_by:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1551 order, path = order_data.get("order"), order_data.get("path")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1552 if order and path:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1553 raise ValueError(_(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1554 '"order" and "path" can\'t be used at the same time in '
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1555 '"order-by" data'
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1556 ))
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1557 if order:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1558 if order == "creation":
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1559 col = PubsubItem.id
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1560 elif order == "modification":
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1561 col = PubsubItem.updated
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1562 elif order == "item_id":
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1563 col = PubsubItem.name
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1564 elif order == "rank":
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1565 if not fts:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1566 raise ValueError(
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1567 "'rank' order can only be used with Full-Text Search (fts)"
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1568 )
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1569 col = literal_column("rank")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1570 else:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1571 raise NotImplementedError(f"Unknown {order!r} order")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1572 else:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1573 # we have a JSON path
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1574 # sqlite_path = self._getSqlitePath(path)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1575 col = PubsubItem.parsed[path]
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1576 direction = order_data.get("direction", "ASC").lower()
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1577 if not direction in ("asc", "desc"):
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1578 raise ValueError(f"Invalid order-by direction: {direction!r}")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1579 stmt = stmt.order_by(getattr(col, direction)())
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1580
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1581 # offset, limit
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1582 index = query.get("index")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1583 if index:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1584 stmt = stmt.offset(index)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1585 limit = query.get("limit")
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1586 if limit:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1587 stmt = stmt.limit(limit)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1588
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1589 async with self.session() as session:
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1590 result = await session.execute(stmt)
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1591
9ae6ec74face memory (sqla): implement `searchPubsubItems`:
Goffi <goffi@goffi.org>
parents: 3638
diff changeset
1592 return result.scalars().all()