12Module containing all functionality necessary to mange local metadata and payload
17from conditions_db
import PayloadInformation
22 Class to handle local sqlite dump of conditions database metadata
24 This class can create and read
sqlite dumps of the central
database in a format
25 compatible
with the local metadata provider
in basf2.
28 APPLICATION_ID = 0xb2cdb
34 -- first drop all tables we care about
35 DROP VIEW IF EXISTS iov_payloads;
36 DROP INDEX IF EXISTS iov_index;
37 DROP TABLE IF EXISTS iovs;
38 DROP TABLE IF EXISTS globaltags;
39 DROP VIEW IF EXISTS full_payloads;
40 DROP TABLE IF EXISTS payloads;
41 DROP TABLE IF EXISTS payloadNames;
42 DROP TABLE IF EXISTS baseUrls;
44 -- table to store the base urls for normalization: Mostly we have the
45 -- same base url
for all payloads but we only want to store the string
46 -- once so give it an id
47 CREATE TABLE baseUrls (
48 baseUrlId INTEGER PRIMARY KEY,
52 -- table to store all distinct payload names only once
53 CREATE TABLE payloadNames (
54 payloadNameId INTEGER PRIMARY KEY,
55 payloadName TEXT UNIQUE
58 -- Payload information
for each payload.
59 -- payloadId, revision, checksum, payloadUrl are taken directly without
60 -- change
from the central database.
61 -- payloadName
and baseUrl are put into local tables defined above,
62 -- these ids are local to the file.
63 -- payloadUrl
is taken
from the database
except if it follows the usual
64 -- `dbstore/{payloadName}/dbstore_{payloadName}_rev_{revision}.root`
in
65 -- which case it
is set to NULL
and created on the fly
from the pattern.
66 CREATE TABLE payloads (
67 payloadId INTEGER PRIMARY KEY,
68 payloadNameId INTEGER NOT NULL,
69 revision INTEGER NOT NULL,
70 checksum text NOT NULL,
71 payloadUrl text DEFAULT NULL,
72 baseUrlId INTEGER NOT NULL,
73 CONSTRAINT name_rev UNIQUE (payloadNameId, revision),
74 FOREIGN KEY (payloadNameId) REFERENCES payloadNames (payloadNameId)
75 ON UPDATE CASCADE ON DELETE RESTRICT
76 FOREIGN KEY (baseUrlId) REFERENCES baseUrls (baseUrlId)
77 ON UPDATE CASCADE ON DELETE RESTRICT
80 -- Payload information
with the local ids
and the payloadUrl resolved
81 -- Information
in this view
is identical to the central server
82 CREATE VIEW full_payloads AS
83 SELECT payloadId, payloadName, revision, checksum,
84 ifnull(payloadUrl,
'dbstore/' || payloadName ||
'/dbstore_' ||
85 payloadName ||
'_rev_' || revision ||
'.root')
86 as payloadUrl, baseUrl
87 FROM payloads NATURAL JOIN payloadNames NATURAL JOIN baseUrls;
89 -- table
for all globaltags
in this file. All values taken directly
from
91 CREATE TABLE globaltags (
92 globalTagId INTEGER PRIMARY KEY,
93 globalTagName text UNIQUE,
94 globalTagStatus text NOT NULL
97 -- table
for all iovs
in all globaltags
in this file, all values taken
98 -- directly
from the central server
100 globalTagId INTEGER NOT NULL,
101 payloadId INTEGER NOT NULL,
102 firstExp INTEGER NOT NULL,
103 firstRun INTEGER NOT NULL,
104 finalExp INTEGER NOT NULL,
105 finalRun INTEGER NOT NULL,
106 FOREIGN KEY (globalTagId) REFERENCES globaltags (globalTagId)
107 ON UPDATE CASCADE ON DELETE CASCADE,
108 FOREIGN KEY (payloadId) REFERENCES payloads (payloadId)
109 ON UPDATE CASCADE ON DELETE RESTRICT
111 -- composite index on the iovs to exclude duplicates
and allow
113 CREATE UNIQUE INDEX iov_index on iovs (
114 globalTagId, firstExp, firstRun, finalExp, finalRun, payloadId
117 -- full view returning the full information on all iovs
in all globaltags
118 CREATE VIEW iov_payloads AS
119 SELECT globalTagName, payloadId, payloadName, revision, checksum,
120 firstExp, firstRun, finalExp, finalRun, payloadUrl, baseUrl
121 FROM globaltags NATURAL JOIN iovs NATURAL JOIN full_payloads;
126 Open an sqlite database and make sure that the schema exists
in the
127 correct version
or create it
if ``mode=overwrite``
130 filename (str): name of the database file
131 readonly (str): how to open the file. Can be one of ``read`` to open
132 the file readonly, ``append` to append new data to an existing file
133 and ``overwrite`` to recreate all tables
and overwrite the contents.
143 self.
_database = sqlite3.connect(f
"file:{filename}?mode=ro", uri=
True)
144 elif mode
in [
"append",
"overwrite"]:
145 self.
_database = sqlite3.connect(filename)
147 raise RuntimeError(
"invalid mode: please supply one of 'read', 'append', 'overwrite'")
149 if mode ==
"overwrite":
153 self.
_database.execute(f
"PRAGMA application_id = {self.APPLICATION_ID}")
154 self.
_database.execute(f
"PRAGMA user_version = {self.SCHEMA_VERSION}")
158 application_id = self.
_database.execute(
"PRAGMA application_id").fetchone()[0]
160 raise RuntimeError(
"Not a b2conditionsdb database file")
161 schema_version = self.
_database.execute(
"PRAGMA user_version").fetchone()[0]
163 raise RuntimeError(
"Cannot use sqlite file: different schema version, please recreate")
166 """Get the number of distinct payloads known to this file"""
167 cursor = self.
_database.execute(
"SELECT count(*) from full_payloads")
168 return cursor.fetchone()[0]
172 Resolve the id for a named entity
in the database file.
174 Create new entities on demand
and cache all known entities
177 name (str): name to lookup
178 entity (str): type of the entity, currently ``baseUrl``
or ``payloadName``
181 if entity
not in self.
_cache:
182 self.
_cache[entity] = {row[0]: row[1]
for row
in self.
_database.execute(f
"SELECT {entity}, {entity}Id from {entity}s")}
184 cache = self.
_cache[entity]
185 if name
not in cache:
186 cache[name] = len(cache) + 1
187 self.
_database.execute(f
"INSERT INTO {entity}s ({entity}Id, {entity}) VALUES (?,?)", (cache[name], name))
192 Add a globaltag to the database file. If the globaltag already exists in
193 the file its contents will be replaced.
195 Parameters: tag_id (str): id of the globaltag
in the central database
196 name (str): name of the globaltag
in the central database state (str):
197 state of the globaltag
in the central database iovs
198 (list(PayloadInformation)): all iovs valid
for this globaltag
200 self._database.execute("INSERT OR REPLACE INTO globaltags VALUES (?,?,?)", (tag_id, name, state))
202 self.
_database.execute(
"DELETE from iovs WHERE globalTagId=?", (tag_id,))
207 if p.payload_id
not in all_payloads:
211 if p.payload_url.lstrip(
'/') != f
"dbstore/{p.name}/dbstore_{p.name}_rev_{p.revision}.root":
213 all_payloads[p.payload_id] = (p.payload_id, name, p.revision, p.checksum, url, base_url)
214 all_iovs.append((tag_id, p.payload_id) + p.iov)
216 self.
_database.executemany(
"INSERT OR REPLACE INTO payloads VALUES (?,?,?,?,?,?)", all_payloads.values())
217 self.
_database.executemany(
"INSERT INTO iovs VALUES (?,?,?,?,?,?)", all_iovs)
223 """Return the list of globaltags stored in the file
226 a list of (id, name, state) tuples for all globaltags
228 return [row
for row
in self.
_database.execute(
"SELECT globalTagId, globalTagName, globalTagStatus FROM globaltags "
229 "ORDER by globalTagName")]
232 """Get all payloads existing in this file
235 a sorted list of `PayloadInformation` objects for all payloads defined
in this file
with the iov set to
None
238 self.
_database.execute(
"SELECT payloadId, payloadName, revision, checksum, "
239 "payloadUrl, baseUrl from full_payloads")])
243 """Get all iovs for a given globaltag
246 globalTag (str): name of the globaltag
247 exp (int): experiment number to check (or None to
return all iovs)
248 run (int): run number to check (
or None to
return all iovs)
249 message (str): ignored, just
for compatibility
with `ConditionsDB.get_all_iovs`
252 a sorted list of `PayloadInformation` objects
254 params = {"globalTag": globalTag}
257 payloadId, payloadName, revision, checksum, payloadUrl, baseUrl,
258 firstExp, firstRun, finalExp, finalRun
260 WHERE globalTagName=:globalTag"""
262 params.update({
"exp": exp,
"run": run})
264 ((firstExp==:exp AND firstRun<=:run) OR firstExp<:exp) AND
265 (finalExp<0 OR (finalRun<0 AND finalExp>=:exp) OR (finalExp>:exp) OR (finalExp==:exp AND finalRun>=:run))"""
C++ wrapper around the sqlite C Api for convenient use of SQLite statements in C++.