"""Database-backed keyring implementation.""" from lacre._keyringcommon import KeyRing, KeyCache from lacre.dbschema import init_identities_table, table_metadata import logging import sqlalchemy from sqlalchemy.sql import select LOG = logging.getLogger(__name__) class KeyRingSchema: def __init__(self): self._meta = table_metadata() self._id_table = init_identities_table() def identities(self): return self._id_table class DatabaseKeyRing(KeyRing): """Database-backed key storage.""" def __init__(self, database_url, schema: KeyRingSchema): self._schema = schema self._url = database_url self._initialised = False def _ensure_initialised(self): if not self._initialised: self._engine = sqlalchemy.create_engine(self._url) self._connection = self._engine.connect() def load(self): """Do nothing, database contents doesn't need to be cached.""" pass def freeze_identities(self) -> KeyCache: """Return a static, async-safe copy of the identity map.""" self._ensure_initialised() return self._load_identities() def _load_identities(self) -> KeyCache: identities = self._schema.identities() all_identities = select(identities.c.fingerprint, identities.c.email) result = self._connection.execute(all_identities) LOG.debug('Retrieving all keys') return KeyCache({key_id: email for key_id, email in result})