CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
conddblib.py
Go to the documentation of this file.
1 '''CMS Conditions DB Python library.
2 '''
3 
4 __author__ = 'Miguel Ojeda'
5 __copyright__ = 'Copyright 2013, CERN'
6 __credits__ = ['Giacomo Govi', 'Miguel Ojeda', 'Andreas Pfeiffer']
7 __license__ = 'Unknown'
8 __maintainer__ = 'Giacomo Govi'
9 __email__ = 'mojedasa@cern.ch'
10 
11 
12 import os
13 import hashlib
14 import logging
15 
16 import sqlalchemy
17 import sqlalchemy.ext.declarative
18 
19 authPathEnvVar = 'COND_AUTH_PATH'
20 schema_name = 'CMS_CONDITIONS'
21 dbuser_name = 'cms_conditions'
22 dbreader_user_name = 'cms_cond_general_r'
23 dbwriter_user_name = 'cms_cond_general_w'
24 devdbwriter_user_name = 'cms_test_conditions'
25 logger = logging.getLogger(__name__)
26 
27 # Set initial level to WARN. This so that log statements don't occur in
28 # the absense of explicit logging being enabled.
29 if logger.level == logging.NOTSET:
30  logger.setLevel(logging.WARN)
31 
32 
33 class EnumMetaclass(type):
34  def __init__(cls, name, bases, dct):
35  cls._members = sorted([member for member in dir(cls) if not member.startswith('_')])
36  cls._map = dict([(member, getattr(cls, member)) for member in cls._members])
37  cls._reversemap = dict([(value, key) for (key, value) in cls._map.items()])
38  super(EnumMetaclass, cls).__init__(name, bases, dct)
39 
40  def __len__(cls):
41  return len(cls._members)
42 
43  def __getitem__(cls, key):
44  '''Returns the value for this key (if the key is an integer,
45  the value is the nth member from the sorted members list).
46  '''
47 
48  if isinstance(key, int):
49  # for tuple() and list()
50  key = cls._members[key]
51  return cls._map[key]
52 
53  def __call__(cls, value):
54  '''Returns the key for this value.
55  '''
56 
57  return cls._reversemap[value]
58 
59 
60 class Enum(object):
61  '''A la PEP 435, simplified.
62  '''
63 
64  __metaclass__ = EnumMetaclass
65 
66 
67 # Utility functions
68 def hash(data):
69  return hashlib.sha1(data).hexdigest()
70 
71 
72 # Constants
73 empty_label = '-'
74 
75 name_length = 100
76 description_length = 4000
77 hash_length = len(hash(''))
78 
79 web_experts_email = 'cms-cond-dev@cern.ch'
80 offline_db_experts_email = 'cms-offlinedb-exp@cern.ch'
81 offline_db_experts_phone = '+41 22 76 70817, or 70817 from CERN; check https://twiki.cern.ch/twiki/bin/viewauth/CMS/DBShifterHelpPage if it does not work; availability depends on the state of the LHC'
82 
83 contact_help = 'If you need assistance, please write an email to %s and %s. If you need immediate/urgent assistance, you can call the Offline DB expert on call (%s).' % (offline_db_experts_email, web_experts_email, offline_db_experts_phone)
84 database_help = '''
85  The database parameter (--db) refers to the database where the tool
86  will connect to read all the data. By default, the production account
87  (through Frontier) will be used.
88 
89  In subcommands which take a source and a destination, --db always refers to
90  the source, and --destdb to the destination. For both of them the following
91  rules apply.
92 
93  The database parameter can be an official alias, a filename or any
94  valid SQLAlchemy URL.
95 
96  The official aliases are the following strings (first column):
97 
98  Alias Level Database RO/RW Notes
99  ------------ ----------- ------------- ---------- -------------------------------
100 
101  pro Production Frontier (ADG) read-only Default.
102  arc Archive Frontier read-only
103  int Integration Frontier read-only
104  dev Development Frontier read-only
105  boost Production Frontier read-only
106  boostprep Development Frontier read-only
107 
108  orapro Production Oracle (ADG) read-only Password required.
109  oraarc Archive Oracle read-only Password required.
110  oraint Integration Oracle read-write Password required.
111  oradev Development Oracle read-write Password required.
112 
113  onlineorapro Production Oracle read-write Password required. Online only.
114  onlineoraint Online Int Oracle read-write Password required. Online only.
115 
116  Most of the time, if you are a regular user, you will want to read/copy
117  conditions from the Frontier production account. Therefore, you can omit
118  the --db parameter, unless you want to read from somewhere else,
119  e.g. from your local SQLite file.
120 
121  In addition, the parameter may be a filename (path) pointing to a local
122  SQLite file, e.g.
123 
124  file.db
125  relative/path/to/file.db
126  /absolute/path/to/file.db
127 
128  Finally, any valid SQLAlchemy URL can be used. This allows full
129  flexibility in cases where it may be needed, e.g.
130 
131  sqlite:// In-memory, volatile SQLite DB.
132  oracle://user@devdb11 Your private Oracle DB in devdb11 [*]
133 
134  [*] See https://account.cern.ch/ -> Services for more information
135  on personal Oracle accounts.
136 
137  For the official aliases, the password will be asked automatically
138  interactively. The same applies for Oracle URLs where the password
139  was not provided inside it, e.g.:
140 
141  oracle://user@devdb11 The tool will prompt you for the password.
142  oracle://user:pass@devdb11 Password inlined. [+]
143 
144  [+] Caution: Never write passwords in command-line parameters in
145  multi-user machines (e.g. lxplus), since other users can see them
146  in the process table (e.g. ps).
147 
148  This means that both the official aliases and the filenames are shortcuts
149  to the full SQLAlchemy URL equivalents, e.g. the following are the same:
150 
151  relative/path/to/file.db === sqlite:///relative/path/to/file.db
152  /absolute/path/to/file.db === sqlite:////absolute/path/to/file.db
153 '''
154 
156  any = 'any'
157  validation = 'validation'
158  mc = 'mc'
159  runmc = 'runmc'
160  hlt = 'hlt'
161  express = 'express'
162  prompt = 'prompt'
163  pcl = 'pcl'
164  offline = 'offline'
165 
166 class TimeType(Enum):
167  run = 'Run'
168  time = 'Time'
169  lumi = 'Lumi'
170  hash = 'Hash'
171  user = 'User'
172 
173 
174 # Schema definition
175 _Base = sqlalchemy.ext.declarative.declarative_base()
176 
177 def fq_name( schema_name, table_name ):
178  name = table_name
179  if schema_name is not None:
180  name = '%s.%s' %(schema_name, table_name)
181  return name
182 
183 db_models = {}
184 
185 class _Col(Enum):
186  nullable = 0
187  notNull = 1
188  pk = 2
189 
190 class DbRef:
191  def __init__(self,refType, refColumn):
192  self.rtype = refType
193  self.rcol = refColumn
194 
195 def fq_col( schema, table, column ):
196  fqn = '%s.%s' %(table, column)
197  if schema is not None:
198  fqn = '%s.%s' %(schema,fqn)
199  return fqn
200 
201 def make_dbtype( backendName, schemaName, baseType ):
202  members = {}
203  deps_reg = set()
204  dbtype_name = '%s_%s' %(baseType.__name__,backendName)
205  members['__tablename__'] = baseType.__tablename__
206  members['__table_args__'] = None
207  if schemaName is not None:
208  members['__table_args__'] = {'schema': schemaName }
209  for k,v in baseType.columns.items():
210  if isinstance(v[0],DbRef):
211  refColDbt = v[0].rtype.columns[v[0].rcol][0]
212  pk = (True if v[1]==_Col.pk else False)
213  if v[1]==_Col.pk:
214  members[k] = sqlalchemy.Column(refColDbt,sqlalchemy.ForeignKey(fq_col(schemaName,v[0].rtype.__tablename__,v[0].rcol)),primary_key=True)
215  else:
216  nullable = (False if v[1] == _Col.notNull else True)
217  members[k] = sqlalchemy.Column(refColDbt,sqlalchemy.ForeignKey(fq_col(schemaName,v[0].rtype.__tablename__,v[0].rcol)),nullable=nullable)
218  if v[0].rtype.__name__ not in deps_reg:
219  deps_reg.add(v[0].rtype.__name__)
220  reftype_name = '%s_%s' %(v[0].rtype.__name__,backendName)
221  members[(v[0].rtype.__name__).lower()] = sqlalchemy.orm.relationship(reftype_name)
222  else:
223  if v[1]==_Col.pk:
224  members[k] = sqlalchemy.Column(v[0],primary_key=True)
225  else:
226  nullable = (True if v[1]==_Col.nullable else False)
227  members[k] = sqlalchemy.Column(v[0],nullable=nullable)
228  dbType = type(dbtype_name,(_Base,),members)
229 
230  if backendName not in db_models.keys():
231  db_models[backendName] = {}
232  db_models[backendName][baseType.__name__] = dbType
233  return dbType
234 
235 def getSchema(tp):
236  if tp.__table_args__ is not None:
237  return tp.__table_args__['schema']
238  return None
239 
240 class Tag:
241  __tablename__ = 'TAG'
242  columns = { 'name': (sqlalchemy.String(name_length),_Col.pk),
243  'time_type': (sqlalchemy.Enum(*tuple(TimeType)),_Col.notNull),
244  'object_type': (sqlalchemy.String(name_length),_Col.notNull),
245  'synchronization': (sqlalchemy.Enum(*tuple(Synchronization)),_Col.notNull),
246  'description': (sqlalchemy.String(description_length),_Col.notNull),
247  'last_validated_time':(sqlalchemy.BIGINT,_Col.notNull),
248  'end_of_validity':(sqlalchemy.BIGINT,_Col.notNull),
249  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
250  'modification_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
251 
252 
253 class Payload:
254  __tablename__ = 'PAYLOAD'
255  columns = { 'hash': (sqlalchemy.CHAR(hash_length),_Col.pk),
256  'object_type': (sqlalchemy.String(name_length),_Col.notNull),
257  'data': (sqlalchemy.BLOB,_Col.notNull),
258  'streamer_info':(sqlalchemy.BLOB,_Col.notNull),
259  'version':(sqlalchemy.String(20),_Col.notNull),
260  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
261 
262 
263 class IOV:
264  __tablename__ = 'IOV'
265  columns = { 'tag_name':(DbRef(Tag,'name'),_Col.pk),
266  'since':(sqlalchemy.BIGINT,_Col.pk),
267  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.pk),
268  'payload_hash':(DbRef(Payload,'hash'),_Col.pk) }
269 
270 
271 class GlobalTag:
272  __tablename__ = 'GLOBAL_TAG'
273  columns = { 'name':(sqlalchemy.String(name_length),_Col.pk),
274  'validity': (sqlalchemy.BIGINT,_Col.notNull),
275  'description':(sqlalchemy.String(description_length),_Col.notNull),
276  'release':(sqlalchemy.String(name_length),_Col.notNull),
277  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
278  'snapshot_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
279 
281  __tablename__ = 'GLOBAL_TAG_MAP'
282  columns = { 'global_tag_name':(DbRef(GlobalTag,'name'),_Col.pk),
283  'record':(sqlalchemy.String(name_length),_Col.pk),
284  'label':(sqlalchemy.String(name_length),_Col.pk),
285  'tag_name':(DbRef(Tag,'name'),_Col.notNull) }
286 
287 
288 
289 class TagLog:
290  __tablename__ = 'TAG_LOG'
291  columns = { 'tag_name':(DbRef(Tag,'name'),_Col.pk),
292  'event_time':(sqlalchemy.TIMESTAMP,_Col.pk),
293  'action':(sqlalchemy.String(100),_Col.pk),
294  'user_name':(sqlalchemy.String(100),_Col.notNull),
295  'host_name':(sqlalchemy.String(100),_Col.notNull),
296  'command':(sqlalchemy.String(500),_Col.notNull),
297  'user_text':(sqlalchemy.String(4000),_Col.notNull) }
298 
299 
300 # CondDB object
301 class Connection(object):
302 
303  def __init__(self, url, init=False):
304  # Workaround to avoid creating files if not present.
305  # Python's sqlite3 module does not use sqlite3_open_v2(),
306  # and therefore we cannot disable SQLITE_OPEN_CREATE.
307  # Only in the case of creating a new database we skip the check.
308  if url.drivername == 'sqlite':
309 
310  #if not init and url.database is not None and not os.path.isfile(url.database):
311  # # url.database is None if opening a in-memory DB, e.g. 'sqlite://'
312  # raise Exception('SQLite database %s not found.' % url.database)
313 
314  self.engine = sqlalchemy.create_engine(url)
315 
316  enabled_foreign_keys = self.engine.execute('pragma foreign_keys').scalar()
317  supports_foreign_keys = enabled_foreign_keys is not None
318  if not supports_foreign_keys:
319  logger.warning('Your SQLite database does not support foreign keys, so constraints will not be checked. Please upgrade.')
320  elif not enabled_foreign_keys:
321  self.engine.execute('pragma foreign_keys = on')
322 
323  else:
324  self.engine = sqlalchemy.create_engine(url)
325 
326  self._session = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(bind=self.engine))
327 
328  self._is_frontier = url.drivername == 'oracle+frontier'
329  self._is_oracle = url.drivername == 'oracle'
330  self._is_sqlite = url.drivername == 'sqlite'
331 
332  self._is_read_only = self._is_frontier or url.host in {
333  'cms_orcon_adg',
334  'cmsarc_lb',
335  }
336 
337  self._is_official = self._is_frontier or url.host in {
338  'cms_orcon_adg',
339  'cmsarc_lb',
340  'cms_orcoff_int',
341  'cms_orcoff_prep',
342  'cms_orcon_prod',
343  'cmsintr_lb',
344  }
345  self._url = url
346  self._backendName = ('sqlite' if self._is_sqlite else 'oracle' )
347  self._schemaName = ( None if self._is_sqlite else schema_name )
348  logging.debug(' ... using db "%s", schema "%s"' % (url, self._schemaName) )
349  logging.debug('Loading db types...')
350  self.get_dbtype(Tag).__name__
351  self.get_dbtype(Payload)
352  self.get_dbtype(IOV)
353  self.get_dbtype(TagLog)
354  self.get_dbtype(GlobalTag)
355  self.get_dbtype(GlobalTagMap)
356  self._is_valid = self.is_valid()
357 
358  def get_dbtype(self,theType):
359  basename = theType.__name__
360  if self._backendName not in db_models.keys() or basename not in db_models[self._backendName].keys():
361  return make_dbtype( self._backendName, self._schemaName, theType )
362  else:
363  return db_models[self._backendName][basename]
364 
365  def session(self):
366  s = self._session()
367  s.get_dbtype = self.get_dbtype
368  s._is_sqlite = self._is_sqlite
369  return s
370 
371  @property
372  def metadata(self):
373  return _Base.metadata
374 
375  @property
376  def is_frontier(self):
377  return self._is_frontier
378 
379  @property
380  def is_oracle(self):
381  return self._is_oracle
382 
383  @property
384  def is_sqlite(self):
385  return self._is_sqlite
386 
387  @property
388  def is_read_only(self):
389  return self._is_read_only
390 
391  @property
392  def is_official(self):
393  return self._is_official
394 
395  def is_valid(self):
396  '''Tests whether the current DB looks like a valid CMS Conditions one.
397  '''
398  engine_connection = self.engine.connect()
399  # temporarely avoid the check on the GT tables - there are releases in use where C++ does not create these tables.
400  _Tag = self.get_dbtype(Tag)
401  _IOV = self.get_dbtype(IOV)
402  _Payload = self.get_dbtype(Payload)
403  ret = all([self.engine.dialect.has_table(engine_connection, table.__tablename__,getSchema(table)) for table in [_Tag, _IOV, _Payload]])
404  engine_connection.close()
405  return ret
406 
407  def init(self, drop=False):
408  '''Initializes a database.
409  '''
410  logging.info('Initializing database...')
411  if drop:
412  logging.debug('Dropping tables...')
413  self.metadata.drop_all(self.engine)
414  else:
415  if self._is_valid:
416  raise Exception('Looks like the database is already a valid CMS Conditions one.')
417 
418  logging.debug('Creating tables...')
419  self.get_dbtype(Tag).__table__.create(bind = self.engine)
420  self.get_dbtype(Payload).__table__.create(bind = self.engine)
421  self.get_dbtype(IOV).__table__.create(bind = self.engine)
422  self.get_dbtype(TagLog).__table__.create(bind = self.engine)
423  self.get_dbtype(GlobalTag).__table__.create(bind = self.engine)
424  self.get_dbtype(GlobalTagMap).__table__.create(bind = self.engine)
425  self._is_valid = self.is_valid()
426 
427 # Connection helpers
429  import subprocess
430  return subprocess.Popen(['cmsGetFnConnect', 'frontier://%s' % database], stdout = subprocess.PIPE).communicate()[0].strip()
431 
432 def _getCMSSQLAlchemyConnectionString(technology,service,schema_name):
433  if technology == 'frontier':
434  import urllib
435  return '%s://@%s/%s' % ('oracle+frontier', urllib.quote_plus(_getCMSFrontierConnectionString(service)), schema_name )
436  elif technology == 'oracle':
437  return '%s://%s@%s' % (technology, schema_name, service)
438 
439 # Entry point
440 def make_url(database='pro',read_only = True):
441 
442  if ':' in database and '://' not in database: # check if we really got a shortcut like "pro:<schema>" (and not a url like proto://...), if so, disentangle
443  database, schema = database.split(':')
444 
445  officialdbs = {
446  # frontier
447  'pro' : ('frontier','PromptProd', { 'R': schema_name }, ),
448  'arc' : ('frontier','FrontierArc', { 'R': schema_name }, ),
449  'int' : ('frontier','FrontierInt', { 'R': schema_name }, ),
450  'dev' : ('frontier','FrontierPrep', { 'R': schema_name }, ),
451  # oracle adg
452  'orapro': ('oracle', 'cms_orcon_adg', { 'R': dbreader_user_name }, ),
453  'oraarc': ('oracle', 'cmsarc_lb', { 'R': dbreader_user_name }, ),
454  # oracle masters
455  'oraint': ('oracle', 'cms_orcoff_int', { 'R': dbreader_user_name,
456  'W': dbwriter_user_name }, ),
457  'oradev': ('oracle', 'cms_orcoff_prep', { 'R': dbreader_user_name,
458  'W': devdbwriter_user_name }, ),
459  'onlineorapro': ('oracle', 'cms_orcon_prod', { 'R': dbreader_user_name,
460  'W': dbwriter_user_name }, ),
461  'onlineoraint': ('oracle', 'cmsintr_lb', { 'R': dbreader_user_name,
462  'W': dbwriter_user_name }, ),
463  }
464 
465  if database in officialdbs.keys():
466  key = ('R' if read_only else 'W')
467  mapping = officialdbs[database]
468  tech = mapping[0]
469  service = mapping[1]
470  schema_dict = mapping[2]
471  if key in schema_dict.keys():
472  database = _getCMSSQLAlchemyConnectionString(tech,service,schema_dict[key])
473  else:
474  raise Exception("Read-only database %s://%s cannot be accessed in update mode." %(tech,service))
475 
476  logging.debug('connection string set to "%s"' % database)
477 
478  try:
479  url = sqlalchemy.engine.url.make_url(database)
480  except sqlalchemy.exc.ArgumentError:
481  url = sqlalchemy.engine.url.make_url('sqlite:///%s' % database)
482  return url
483 
484 def connect(url, init=False, authPath=None, verbose=0):
485  '''Returns a Connection instance to the CMS Condition DB.
486 
487  See database_help for the description of the database parameter.
488 
489  The verbosity level is as follows:
490 
491  0 = No output (default).
492  1 = SQL statements issued, including their parameters.
493  2 = In addition, results of the queries (all rows and the column headers).
494  '''
495 
496  if url.drivername == 'oracle':
497  if url.username is None:
498  logging.error('Could not resolve the username for the connection %s. Please provide a connection in the format oracle://[user]:[pass]@[host]' %url )
499  raise Exception('Connection format error: %s' %url )
500  if url.password is None:
501  if authPath is None:
502  if authPathEnvVar in os.environ:
503  authPath = os.environ[authPathEnvVar]
504  authFile = None
505  if authPath is not None:
506  authFile = os.path.join(authPath,'.netrc')
507  if authFile is not None:
508  print 'url=%s host=%s username=%s' %(url,url.host,url.username)
509  entryKey = url.host.lower()+"/"+url.username.lower()
510  logging.debug('Looking up credentials for %s in file %s ' %(entryKey,authFile) )
511  import netrc
512  params = netrc.netrc( authFile ).authenticators(entryKey)
513  if params is not None:
514  (username, account, password) = params
515  url.password = password
516  else:
517  msg = 'The entry %s has not been found in the .netrc file.' %entryKey
518  raise TypeError(msg)
519  else:
520  import getpass
521  pwd = getpass.getpass('Password for %s: ' % str(url))
522  if pwd is None or pwd == '':
523  pwd = getpass.getpass('Password for %s: ' % str(url))
524  if pwd is None or pwd == '':
525  raise Exception('Empty password provided, bailing out...')
526  url.password = pwd
527 
528  if verbose >= 1:
529  logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
530 
531  if verbose >= 2:
532  logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
533 
534  return Connection(url, init=init)
535 
536 
537 def _exists(session, primary_key, value):
538  ret = None
539  try:
540  ret = session.query(primary_key).\
541  filter(primary_key == value).\
542  count() != 0
543  except sqlalchemy.exc.OperationalError:
544  pass
545 
546  return ret
547 
548 def _inserted_before(timestamp):
549  '''To be used inside filter().
550  '''
551 
552  if timestamp is None:
553  # XXX: Returning None does not get optimized (skipped) by SQLAlchemy,
554  # and returning True does not work in Oracle (generates "and 1"
555  # which breaks Oracle but not SQLite). For the moment just use
556  # this dummy condition.
557  return sqlalchemy.literal(True) == sqlalchemy.literal(True)
558 
559  return conddb.IOV.insertion_time <= _parse_timestamp(timestamp)
560 
561 def listObject(session, name, snapshot=None):
562 
563  is_tag = _exists(session, Tag.name, name)
564  result = {}
565  if is_tag:
566  result['type'] = 'Tag'
567  result['name'] = session.query(Tag).get(name).name
568  result['timeType'] = session.query(Tag.time_type).\
569  filter(Tag.name == name).\
570  scalar()
571 
572  result['iovs'] = session.query(IOV.since, IOV.insertion_time, IOV.payload_hash, Payload.object_type).\
573  join(IOV.payload).\
574  filter(
575  IOV.tag_name == name,
576  _inserted_before(snapshot),
577  ).\
578  order_by(IOV.since.desc(), IOV.insertion_time.desc()).\
579  from_self().\
580  order_by(IOV.since, IOV.insertion_time).\
581  all()
582 
583  try:
584  is_global_tag = _exists(session, GlobalTag.name, name)
585  if is_global_tag:
586  result['type'] = 'GlobalTag'
587  result['name'] = session.query(GlobalTag).get(name)
588  result['tags'] = session.query(GlobalTagMap.record, GlobalTagMap.label, GlobalTagMap.tag_name).\
589  filter(GlobalTagMap.global_tag_name == name).\
590  order_by(GlobalTagMap.record, GlobalTagMap.label).\
591  all()
592  except sqlalchemy.exc.OperationalError:
593  sys.stderr.write("No table for GlobalTags found in DB.\n\n")
594 
595  if not is_tag and not is_global_tag:
596  raise Exception('There is no tag or global tag named %s in the database.' % name)
597 
598  return result
599 
600 def getPayload(session, hash):
601  # get payload from DB:
602  data, payloadType = session.query(Payload.data, Payload.object_type).filter(Payload.hash == hash).one()
603  return data
def _exists
Definition: conddblib.py:537
def make_dbtype
Definition: conddblib.py:201
def getSchema
Definition: conddblib.py:235
def _getCMSSQLAlchemyConnectionString
Definition: conddblib.py:432
static void * communicate(void *obj)
Definition: DQMNet.cc:1251
def fq_col
Definition: conddblib.py:195
def fq_name
Definition: conddblib.py:177
def _getCMSFrontierConnectionString
Definition: conddblib.py:428
def _inserted_before
Definition: conddblib.py:548
def listObject
Definition: conddblib.py:561
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def make_url
Definition: conddblib.py:440
def connect
Definition: conddblib.py:484
dbl *** dir
Definition: mlp_gen.cc:35
def hash
Definition: conddblib.py:68
T get(const Candidate &c)
Definition: component.h:55
double scalar(const CLHEP::HepGenMatrix &m)
Return the matrix as a scalar. Raise an assertion if the matris is not .
Definition: matutil.cc:183
def getPayload
Definition: conddblib.py:600