Coverage for python/lsst/daf/butler/tests/_dummyRegistry.py : 33%

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/>.
22__all__ = ("DummyRegistry", )
25from typing import Any, Iterable, Iterator, Optional, Type
27import sqlalchemy
29from lsst.daf.butler import ddl, DatasetRef, DimensionUniverse
30from lsst.daf.butler.registry.interfaces import (
31 Database,
32 DatasetRecordStorageManager,
33 DatastoreRegistryBridge,
34 DatastoreRegistryBridgeManager,
35 OpaqueTableStorageManager,
36 OpaqueTableStorage,
37 StaticTablesContext,
38 VersionTuple
39)
40from lsst.daf.butler.registry.bridge.ephemeral import EphemeralDatastoreRegistryBridge
43class DummyOpaqueTableStorage(OpaqueTableStorage):
45 def __init__(self, name: str, spec: ddl.TableSpec):
46 super().__init__(name=name)
47 self._rows = []
48 self._spec = spec
50 def insert(self, *data: dict):
51 # Docstring inherited from OpaqueTableStorage.
52 uniqueConstraints = list(self._spec.unique)
53 uniqueConstraints.append(tuple(field.name for field in self._spec.fields if field.primaryKey))
54 for d in data:
55 for constraint in uniqueConstraints:
56 matching = list(self.fetch(**{k: d[k] for k in constraint}))
57 if len(matching) != 0:
58 raise RuntimeError(f"Unique constraint {constraint} violation "
59 "in external table {self.name}.")
60 self._rows.append(d)
62 def fetch(self, **where: Any) -> Iterator[dict]:
63 # Docstring inherited from OpaqueTableStorage.
64 for d in self._rows:
65 if all(d[k] == v for k, v in where.items()):
66 yield d
68 def delete(self, columns: Iterable[str], *rows: dict):
69 # Docstring inherited from OpaqueTableStorage.
70 kept_rows = []
71 for table_row in self._rows:
72 for where_row in rows:
73 if all(table_row[k] == v for k, v in where_row.items()):
74 break
75 else:
76 kept_rows.append(table_row)
77 self._rows = kept_rows
80class DummyOpaqueTableStorageManager(OpaqueTableStorageManager):
82 def __init__(self):
83 self._storages = {}
85 @classmethod
86 def initialize(cls, db: Database, context: StaticTablesContext) -> OpaqueTableStorageManager:
87 # Docstring inherited from OpaqueTableStorageManager.
88 # Not used, but needed to satisfy ABC requirement.
89 return cls()
91 def get(self, name: str) -> Optional[OpaqueTableStorage]:
92 # Docstring inherited from OpaqueTableStorageManager.
93 return self._storage.get(name)
95 def register(self, name: str, spec: ddl.TableSpec) -> OpaqueTableStorage:
96 # Docstring inherited from OpaqueTableStorageManager.
97 return self._storages.setdefault(name, DummyOpaqueTableStorage(name, spec))
99 @classmethod
100 def currentVersion(cls) -> Optional[VersionTuple]:
101 # Docstring inherited from VersionedExtension.
102 return None
104 def schemaDigest(self) -> Optional[str]:
105 # Docstring inherited from VersionedExtension.
106 return None
109class DummyDatastoreRegistryBridgeManager(DatastoreRegistryBridgeManager):
111 def __init__(self, opaque: OpaqueTableStorageManager, universe: DimensionUniverse,
112 datasetIdColumnType: type):
113 super().__init__(opaque=opaque, universe=universe, datasetIdColumnType=datasetIdColumnType)
114 self._bridges = {}
116 @classmethod
117 def initialize(cls, db: Database, context: StaticTablesContext, *,
118 opaque: OpaqueTableStorageManager,
119 datasets: Type[DatasetRecordStorageManager],
120 universe: DimensionUniverse,
121 ) -> DatastoreRegistryBridgeManager:
122 # Docstring inherited from DatastoreRegistryBridgeManager
123 # Not used, but needed to satisfy ABC requirement.
124 return cls(opaque=opaque, universe=universe, datasetIdColumnType=datasets.getIdColumnType())
126 def refresh(self):
127 # Docstring inherited from DatastoreRegistryBridgeManager
128 pass
130 def register(self, name: str, *, ephemeral: bool = False) -> DatastoreRegistryBridge:
131 # Docstring inherited from DatastoreRegistryBridgeManager
132 return self._bridges.setdefault(name, EphemeralDatastoreRegistryBridge(name))
134 def findDatastores(self, ref: DatasetRef) -> Iterable[str]:
135 # Docstring inherited from DatastoreRegistryBridgeManager
136 for name, bridge in self._bridges.items():
137 if ref in bridge:
138 yield name
140 @classmethod
141 def currentVersion(cls) -> Optional[VersionTuple]:
142 # Docstring inherited from VersionedExtension.
143 return None
145 def schemaDigest(self) -> Optional[str]:
146 # Docstring inherited from VersionedExtension.
147 return None
150class DummyRegistry:
151 """Dummy Registry, for Datastore test purposes.
152 """
153 def __init__(self):
154 self._opaque = DummyOpaqueTableStorageManager()
155 self.dimensions = DimensionUniverse()
156 self._datastoreBridges = DummyDatastoreRegistryBridgeManager(
157 self._opaque, self.dimensions, sqlalchemy.BigInteger)
159 def getDatastoreBridgeManager(self):
160 return self._datastoreBridges