/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 """ 00002 Perform multiple DBI lookups with a single DBI query... 00003 Made possible by restrictions on the nature of the lookups. 00004 00005 The canonical example is looking up entries in GDaqRunInfo based on the 00006 runNo field (RunNo attribute) 00007 00008 """ 00009 import logging 00010 log = logging.getLogger(__name__) 00011 00012 class IEntry(object): 00013 def __init__(self, row, vrec ): 00014 self.row = row 00015 self.vrec = vrec 00016 def __repr__(self): 00017 return "IEntry : SEQNO %s TimeStart %s TimeEnd %s " % ( self.vrec.seqno, self.vrec.contextrange.timestart, self.vrec.contextrange.timeend ) 00018 00019 class ILookup(dict): 00020 """ 00021 Example of use:: 00022 00023 il = ILookup( 10,100,1000, kls='GDaqRunInfo', ifield="runNo", iattr="RunNo" ) 00024 # corresponds to datasql WHERE clause : runNo in (10,100,1000) 00025 print il[10] 00026 00027 00028 The positional arguments are used in datasql **IN** list, the query must result in 00029 the same number of entries as positional arguments. 00030 The ``iattr`` is needed as DybDbi attribute names are often different from fieldnames, this 00031 is used after the query with in memory lookup to arrange the results of the query by the argument 00032 values. 00033 00034 Effectively the positional arguments must behave like primary keys with each arg 00035 corresponding to one row. 00036 00037 """ 00038 def __init__(self, *args , **kwa ): 00039 dict.__init__(self) 00040 00041 import DybDbi 00042 kls = getattr( DybDbi, kwa['kls'] ) 00043 rpt = kls.Rpt() 00044 00045 if len(args) > 1: 00046 datasql = "%s in %s" % ( kwa['ifield'], str(tuple(args)) ) 00047 else: 00048 datasql = "%s = %s" % ( kwa['ifield'], args[0] ) 00049 00050 rpt.ctx( sqlcontext=kwa['sqlcontext'] , datasql=datasql , task=-1, subsite=-1 ) 00051 if len(rpt) < len(args): 00052 log.warn("failed to lookup and entry for every argument ... trouble ahead " ) 00053 00054 for arg in args: 00055 row = rpt.FirstRowWithIntValueForKey( kwa['iattr'] , arg ) 00056 assert row, "Failed to find %s entry with arg %s using iattr %s " % ( kwa['kls'] , arg, kwa['iattr'] ) 00057 self[arg] = IEntry( row, rpt.GetValidityRec(row) ) 00058 00059 00060 class IRunLookup(ILookup): 00061 """ 00062 Specialization of :py:class:`DybDbi.ILookup`, for looking for run numbers in GDaqRunInfo, usage:: 00063 00064 iargs = (10,100,1000) 00065 irl = IRunLookup( *iargs ) 00066 for ia in iargs: 00067 print ia, irl[ia] 00068 00069 """ 00070 kls = 'GDaqRunInfo' 00071 ifield = "runNo" 00072 iattr = "RunNo" 00073 sqlcontext = "1=1" 00074 00075 def __init__(self, *args, **kwa ): 00076 ILookup.__init__(self, *args, kls=kwa.get('kls',self.kls), ifield=kwa.get('ifield',self.ifield), iattr=kwa.get('iattr',self.iattr), sqlcontext=kwa.get('sqlcontext',self.sqlcontext) ) 00077 00078 00079 def args_(): 00080 import argparse 00081 00082 cls = IRunLookup 00083 00084 ap = argparse.ArgumentParser(description=__doc__) 00085 ap.add_argument( 'iargs', nargs="+" , type=int, help='One or more integer arguments to lookup ') 00086 ap.add_argument( '-k', '--kls', default=cls.kls, help='Name of DybDbi class. Default %(default)s ') 00087 ap.add_argument( '-d', '--ifield', default=cls.ifield, help='Payload integer fieldname corresponding to positional argument values. Default %(default)s ') 00088 ap.add_argument( '-s', '--sqlcontext', default=cls.sqlcontext, help='Extended query SQL context. Default %(default)s ') 00089 ap.add_argument( '-i', '--iattr', default=cls.iattr, help='DybDbi integer attribute name, used for the in memory lookup to arrange entries by argument. Default %(default)s ') 00090 00091 ap.add_argument( '--dbconf', default=None , help='Name of section of ~/.my.cnf with DB connection parameters. Default %(default)s ') 00092 args = ap.parse_args() 00093 return args 00094 00095 def main(): 00096 import os 00097 args = args_() 00098 if args.dbconf: 00099 os.environ['DBCONF'] = args.dbconf 00100 il = ILookup( *args.iargs , kls=args.kls , ifield=args.ifield , iattr=args.iattr, sqlcontext=args.sqlcontext ) 00101 for iarg in args.iargs: 00102 print iarg, il[iarg] 00103 return il 00104 00105 def check_irunlookup(): 00106 iargs = (10,100,1000) 00107 irl = IRunLookup( *iargs ) 00108 for ia in iargs: 00109 print ia, irl[ia] 00110 00111 00112 if __name__ == '__main__': 00113 il = main() 00114