Coverage for python/lsst/daf/butler/registry/interfaces/_opaque.py : 59%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21from __future__ import annotations
22"""Interfaces for the objects that manage opaque (logical) tables within a
23`Registry`.
24"""
26__all__ = ["OpaqueTableStorageManager", "OpaqueTableStorage"]
28from abc import ABC, abstractmethod
29from typing import (
30 Any,
31 Iterator,
32 Optional,
33)
35from ...core.ddl import TableSpec
36from ._database import Database, StaticTablesContext
39class OpaqueTableStorage(ABC):
40 """An interface that manages the records associated with a particular
41 opaque table in a `Registry`.
43 Parameters
44 ----------
45 name : `str`
46 Name of the opaque table.
47 """
48 def __init__(self, name: str):
49 self.name = name
51 @abstractmethod
52 def insert(self, *data: dict) -> None:
53 """Insert records into the table
55 Parameters
56 ----------
57 *data
58 Each additional positional argument is a dictionary that represents
59 a single row to be added.
60 """
61 raise NotImplementedError()
63 @abstractmethod
64 def fetch(self, **where: Any) -> Iterator[dict]:
65 """Retrieve records from an opaque table.
67 Parameters
68 ----------
69 **where
70 Additional keyword arguments are interpreted as equality
71 constraints that restrict the returned rows (combined with AND);
72 keyword arguments are column names and values are the values they
73 must have.
75 Yields
76 ------
77 row : `dict`
78 A dictionary representing a single result row.
79 """
80 raise NotImplementedError()
82 @abstractmethod
83 def delete(self, **where: Any) -> None:
84 """Remove records from an opaque table.
86 Parameters
87 ----------
88 **where
89 Additional keyword arguments are interpreted as equality
90 constraints that restrict the deleted rows (combined with AND);
91 keyword arguments are column names and values are the values they
92 must have.
93 """
94 raise NotImplementedError()
96 name: str
97 """The name of the logical table this instance manages (`str`).
98 """
101class OpaqueTableStorageManager(ABC):
102 """An interface that manages the opaque tables in a `Registry`.
104 `OpaqueTableStorageManager` primarily serves as a container and factory for
105 `OpaqueTableStorage` instances, which each provide access to the records
106 for a different (logical) opaque table.
108 Notes
109 -----
110 Opaque tables are primarily used by `Datastore` instances to manage their
111 internal data in the same database that hold the `Registry`, but are not
112 limited to this.
114 While an opaque table in a multi-layer `Registry` may in fact be the union
115 of multiple tables in different layers, we expect this to be rare, as
116 `Registry` layers will typically correspond to different leaf `Datastore`
117 instances (each with their own opaque table) in a `ChainedDatastore`.
118 """
120 @classmethod
121 @abstractmethod
122 def initialize(cls, db: Database, context: StaticTablesContext) -> OpaqueTableStorageManager:
123 """Construct an instance of the manager.
125 Parameters
126 ----------
127 db : `Database`
128 Interface to the underlying database engine and namespace.
129 context : `StaticTablesContext`
130 Context object obtained from `Database.declareStaticTables`; used
131 to declare any tables that should always be present in a layer
132 implemented with this manager.
134 Returns
135 -------
136 manager : `OpaqueTableStorageManager`
137 An instance of a concrete `OpaqueTableStorageManager` subclass.
138 """
139 raise NotImplementedError()
141 def __getitem__(self, name: str) -> OpaqueTableStorage:
142 """Interface to `get` that raises `LookupError` instead of returning
143 `None` on failure.
144 """
145 r = self.get(name)
146 if r is None:
147 raise LookupError(f"No logical table with name '{name}' found.")
148 return r
150 @abstractmethod
151 def get(self, name: str) -> Optional[OpaqueTableStorage]:
152 """Return an object that provides access to the records associated with
153 an opaque logical table.
155 Parameters
156 ----------
157 name : `str`
158 Name of the logical table.
160 Returns
161 -------
162 records : `OpaqueTableStorage` or `None`
163 The object representing the records for the given table in this
164 layer, or `None` if there are no records for that table in this
165 layer.
167 Notes
168 -----
169 Opaque tables must be registered with the layer (see `register`) by
170 the same client before they can safely be retrieved with `get`.
171 Unlike most other manager classes, the set of opaque tables cannot be
172 obtained from an existing data repository.
173 """
174 raise NotImplementedError()
176 @abstractmethod
177 def register(self, name: str, spec: TableSpec) -> OpaqueTableStorage:
178 """Ensure that this layer can hold records for the given opaque logical
179 table, creating new tables as necessary.
181 Parameters
182 ----------
183 name : `str`
184 Name of the logical table.
185 spec : `TableSpec`
186 Schema specification for the table to be created.
188 Returns
189 -------
190 records : `OpaqueTableStorage`
191 The object representing the records for the given element in this
192 layer.
194 Notes
195 -----
196 This operation may not be invoked within a transaction context block.
197 """
198 raise NotImplementedError()