def parseObject(self,dbsInst,selKey,sortName,sortOrder,input,case): """ Create a function call for DDQueryMaker. selKey is an input set of keys which we will look-up. The input is a list of conditions which will be applied to the query in a form of key:rval. Here rval will contain operator to be used, e.g. >200. Either look-up keys or conditions keys can be in form of a.b (table.col) or just keywords known to DD, e.g. dataset, file, run, etc. """ words = input _words= [] _fDict= {} f="" v="" for w in words: if w.find(":")!=-1: f,v=w.split(":") if v.find('not like')==0: v='not_like'+v[len('not like'):] try: funcFound=findKeyInAList(self.functions,selKey) if funcFound: selKey=selKey.replace("(","").replace(")","").replace(funcFound,"").strip() cName=self.getTabCol[selKey] if funcFound=="total": if cName.lower().find("numberof")!=-1 or cName.lower().find("size")!=-1: _fDict[cName]="sum" else: _fDict[cName]="count" else: _fDict[cName]=funcFound if selKey.find(".")!=-1: sKey,keyOut = selKey.split(".") else: sKey=selKey ################ # TODO: if f is in form a.b I need to check for functions if f.find(".")!=-1: fTabCol = self.getTabCol(f) fTab,fCol = fTabCol.split(".") fList = self.dbs_map[(fTab.lower(),sKey)] firstEl= fList[0] firstEl= '2'.join([fTabCol]+firstEl.split("2")[1:]) fList[0]=firstEl else: fList = self.dbs_map[(f,sKey)] if selKey.find(".")!=-1: sKey,keyOut = selKey.split(".") lastEl= fList[-1] lastEl= '2'.join(lastEl.split("2")[:-1]+[self.getTabCol(selKey)]) fList[-1]=lastEl ################ _call = "" count = 0 _fList=list(fList) _fList.reverse() for func in _fList: _call+= "self.makeQuery('%s','%s',rval="%(dbsInst,func) count+=1 _call+="'%s',case='%s'"%(v,case) if funcFound: _call+=",funcDict=%s"%_fDict for i in xrange(0,count): if i==count-1: _call+=",sortName='%s',sortOrder='%s')"%(sortName,sortOrder) else: _call+=")" _words.append(_call) except: traceback.print_exc() raise "ERROR: unable to parse your input: '%s'\nparse it as '%s'\n### List of known keywords %s\n### List of supported operators %s"%(selKey,words,str(self.keywords_sorted),self.operators) else: traceback.print_exc() raise "Keyword '%s' does not contain separator \":\"."%w eString = ' '.join(_words) if self.verbose: print "\n+++ Translate iList:\n%s\n\n%s\n"%(input,eString) return eString
def parseInput(self,dbsInst,input,backEnd,sortName,sortOrder,case): _input="%s"%input idx=input.lower().find('where') if idx!=-1: what=input[:idx] input = input[idx+len('where')+1:] selKey = what.lower().replace('find','').strip() else: selKey = "dataset" iList = input.split() if self.verbose: print "\nParser input='%s', iList='%s', selKey=%s"%(input,iList,selKey) msg = "Fail to parse your input" words = [] pDict = {} pattern = "" try: for idx in xrange(0,len(iList)): item = iList[idx] if self.oList.count(item): if pattern: key="q_%s"%idx pDict[key]=pattern words.append(key) pattern="" words.append(item) continue pattern+=" "+item if pattern: key="q_%s"%idx pDict[key]=pattern words.append(key) except: raise msg # check if user made multiple select, if so, check where clause for provided operators if (not self.keywords.count(selKey) and (selKey.find(",")!=-1 or selKey.find("total")!=-1)) or backEnd.lower()=="mysql": if self.verbose: if backEnd.lower()=="mysql": print "\n+++ Found MySQL backend, no INTERSECT, will do JOIN queires\n",_input else: print "\n+++ Found multiple selection, stop parsing\n",_input if input.find(" = ")==-1 and selKey.find("total")==-1 and selKey.find(",")!=-1: msg ="In order to query multiple fields you MUST provide at least one equal constrain\n" msg+="Example: find file,run where dataset=/a/b/c\n" raise msg sList=[] fDict={} selKey=selKey.replace(" ","") _toJoin="%s"%selKey for key in selKey.split(","): key=key.strip() # look for functions funcFound=findKeyInAList(self.functions,key) if funcFound and key.find("(")!=-1 and key.find(")")!=-1: sKey=key.replace("(","").replace(")","").replace(funcFound,"").strip() if not self.keywords.count(sKey): msg ="Fail to parse select expression, invalid key='%s'"%sKey msg+="\nList of known keys:\n%s"%str(self.keywords_sorted) raise msg _tabCol=self.getTabCol(sKey) tabName,colName=_tabCol.split(".") if funcFound=="total": if colName.lower().find("numberof")!=-1 or colName.lower().find("size")!=-1: fDict[_tabCol]="sum" else: fDict[_tabCol]="count" else: fDict[_tabCol]=funcFound key=sKey if not self.keywords.count(key): msg ="Fail to parse select expression, invalid key='%s'"%key msg+="\nList of known keys:\n%s"%str(self.keywords_sorted) raise msg sKey=self.getTabCol(key) sList.append(sKey) toSelect=','.join(sList) for val in pDict.values(): key,op,rval=val.split() if not self.keywords.count(key): msg ="Fail to parse where clause expression, invalid key='%s'"%key msg+="\nList of known keys:\n%s"%str(self.keywords_sorted) raise msg input=input.replace(key,self.getTabCol(key)) _select=self.getTabCol(key) _toJoin+=",%s"%key if not sList.count(_select): sList.append(_select) toJoin=','.join(sList) # resolve ambiguity, File,Lumi should go through runs _toJoinKeys=_toJoin.strip().split(",") if _toJoinKeys.count('file') and _toJoinKeys.count('lumi') and not _toJoinKeys.count('run'): toJoin+=",FileRunLumi.ID" if self.keywords.count(sortName): sortName=self.getTabCol(sortName) else: sortName=sList[0] fCall="self.makeJoinQuery(dbsInst='%s',toSelect='%s',toJoin='%s',wClause='%s',sortName='%s',sortOrder='%s',case='%s',funcDict=%s)"%(dbsInst,toSelect,toJoin,input,sortName,sortOrder,case,fDict) if self.verbose: print fCall return fCall # proceed with parsing for key in pDict.keys(): words[words.index(key)]=self.parsePattern(dbsInst,selKey,sortName,sortOrder,pDict[key],case) return ' '.join(words)