Hide keyboard shortcuts

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/>. 

21 

22__all__ = ("DummyRegistry", ) 

23 

24 

25from typing import Any, Iterable, Iterator, Optional, Type 

26 

27from lsst.daf.butler import ddl, DatasetRef, DimensionUniverse 

28from lsst.daf.butler.registry.interfaces import ( 

29 Database, 

30 DatasetRecordStorageManager, 

31 DatastoreRegistryBridge, 

32 DatastoreRegistryBridgeManager, 

33 OpaqueTableStorageManager, 

34 OpaqueTableStorage, 

35 StaticTablesContext, 

36 VersionTuple 

37) 

38from lsst.daf.butler.registry.bridge.ephemeral import EphemeralDatastoreRegistryBridge 

39 

40 

41class DummyOpaqueTableStorage(OpaqueTableStorage): 

42 

43 def __init__(self, name: str, spec: ddl.TableSpec): 

44 super().__init__(name=name) 

45 self._rows = [] 

46 self._spec = spec 

47 

48 def insert(self, *data: dict): 

49 # Docstring inherited from OpaqueTableStorage. 

50 uniqueConstraints = list(self._spec.unique) 

51 uniqueConstraints.append(tuple(field.name for field in self._spec.fields if field.primaryKey)) 

52 for d in data: 

53 for constraint in uniqueConstraints: 

54 matching = list(self.fetch(**{k: d[k] for k in constraint})) 

55 if len(matching) != 0: 

56 raise RuntimeError(f"Unique constraint {constraint} violation " 

57 "in external table {self.name}.") 

58 self._rows.append(d) 

59 

60 def fetch(self, **where: Any) -> Iterator[dict]: 

61 # Docstring inherited from OpaqueTableStorage. 

62 for d in self._rows: 

63 if all(d[k] == v for k, v in where.items()): 

64 yield d 

65 

66 def delete(self, **where: Any): 

67 # Docstring inherited from OpaqueTableStorage. 

68 kept = [] 

69 for d in self._rows: 

70 if not all(d[k] == v for k, v in where.items()): 

71 kept.append(d) 

72 self._rows = kept 

73 

74 

75class DummyOpaqueTableStorageManager(OpaqueTableStorageManager): 

76 

77 def __init__(self): 

78 self._storages = {} 

79 

80 @classmethod 

81 def initialize(cls, db: Database, context: StaticTablesContext) -> OpaqueTableStorageManager: 

82 # Docstring inherited from OpaqueTableStorageManager. 

83 # Not used, but needed to satisfy ABC requirement. 

84 return cls() 

85 

86 def get(self, name: str) -> Optional[OpaqueTableStorage]: 

87 # Docstring inherited from OpaqueTableStorageManager. 

88 return self._storage.get(name) 

89 

90 def register(self, name: str, spec: ddl.TableSpec) -> OpaqueTableStorage: 

91 # Docstring inherited from OpaqueTableStorageManager. 

92 return self._storages.setdefault(name, DummyOpaqueTableStorage(name, spec)) 

93 

94 @classmethod 

95 def currentVersion(cls) -> Optional[VersionTuple]: 

96 # Docstring inherited from VersionedExtension. 

97 return None 

98 

99 def schemaDigest(self) -> Optional[str]: 

100 # Docstring inherited from VersionedExtension. 

101 return None 

102 

103 

104class DummyDatastoreRegistryBridgeManager(DatastoreRegistryBridgeManager): 

105 

106 def __init__(self, opaque: OpaqueTableStorageManager, universe: DimensionUniverse): 

107 super().__init__(opaque=opaque, universe=universe) 

108 self._bridges = {} 

109 

110 @classmethod 

111 def initialize(cls, db: Database, context: StaticTablesContext, *, 

112 opaque: OpaqueTableStorageManager, 

113 datasets: Type[DatasetRecordStorageManager], 

114 universe: DimensionUniverse, 

115 ) -> DatastoreRegistryBridgeManager: 

116 # Docstring inherited from DatastoreRegistryBridgeManager 

117 # Not used, but needed to satisfy ABC requirement. 

118 return cls(opaque=opaque, universe=universe) 

119 

120 def refresh(self): 

121 # Docstring inherited from DatastoreRegistryBridgeManager 

122 pass 

123 

124 def register(self, name: str, *, ephemeral: bool = False) -> DatastoreRegistryBridge: 

125 # Docstring inherited from DatastoreRegistryBridgeManager 

126 return self._bridges.setdefault(name, EphemeralDatastoreRegistryBridge(name)) 

127 

128 def findDatastores(self, ref: DatasetRef) -> Iterable[str]: 

129 # Docstring inherited from DatastoreRegistryBridgeManager 

130 for name, bridge in self._bridges.items(): 

131 if ref in bridge: 

132 yield name 

133 

134 @classmethod 

135 def currentVersion(cls) -> Optional[VersionTuple]: 

136 # Docstring inherited from VersionedExtension. 

137 return None 

138 

139 def schemaDigest(self) -> Optional[str]: 

140 # Docstring inherited from VersionedExtension. 

141 return None 

142 

143 

144class DummyRegistry: 

145 """Dummy Registry, for Datastore test purposes. 

146 """ 

147 def __init__(self): 

148 self._opaque = DummyOpaqueTableStorageManager() 

149 self.dimensions = DimensionUniverse() 

150 self._datastoreBridges = DummyDatastoreRegistryBridgeManager(self._opaque, self.dimensions) 

151 

152 def getDatastoreBridgeManager(self): 

153 return self._datastoreBridges