--- ZSQLExtend/ZSQLExtend.py 2003/12/03 17:38:43 1.2 +++ ZSQLExtend/ZSQLExtend.py 2007/02/09 17:39:44 1.102 @@ -1,203 +1,1688 @@ from OFS.Folder import Folder -from Globals import Persistent from Acquisition import Implicit -from Globals import DTMLFile +from Globals import DTMLFile,package_home,Persistent import urllib import re import string +import sys +#from pyPgSQL import libpq from AccessControl import getSecurityManager +from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate +from Products.PageTemplates.PageTemplateFile import PageTemplateFile -def quoteString(name): - #return re.sub(r'([\(\)\?])',"\\\1",name) - #return "Euklid" - return name +from Products.ZSQLMethods.SQL import SQLConnectionIDs +from xml.sax.saxutils import escape +from types import * +import Shared.DC.ZRDB.DA +import logging +import os.path +import os +import copy +import unicodedata + +import logging + +#ersetzt logging +def logger(txt,method,txt2): + """logging""" + logging.info(txt+ txt2) + + +from OFS.SimpleItem import SimpleItem + +def getTextFromNode(nodename): + """get the cdata content of a node""" + if nodename is None: + return "" + nodelist=nodename.childNodes + rc = "" + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc -class ZSQLExtendFolder(Persistent, Implicit, Folder): +def analyseIntSearch(word): + #analyse integer searches + + splitted=word.split("-") + + if len(splitted)==1: + return "="+splitted[0] + + if splitted[0]=="": + return "< "+splitted[1] + + if splitted[1]=='': + return "> "+splitted[0] + else: + return "BETWEEN "+splitted[0]+" AND "+splitted[1] + + + +def sql_quote(v): + # quote dictionary + quote_dict = {"\'": "''", "\\": "\\\\"} + for dkey in quote_dict.keys(): + if string.find(v, dkey) >= 0: + v=string.join(string.split(v,dkey),quote_dict[dkey]) + return "'%s'" % v + +def showSQLConnectionIDs(self): + return SQLConnectionIDs(self) + +class ZSQLIndex(SimpleItem): + """index""" + meta_type="ZSQLIndex" + + def __init__(self,index,id,table=''): + self.index=[x for x in index] + self.id=id + self.table=table + + def setIndex(self,index): + self.index=[x for x in index] + + def getIndex(self): + return self.index + +class ZSQLExtendFolder(Folder,Persistent, Implicit): """Folder""" meta_type="ZSQLExtendFolder" - def ZSQLInlineSearch(self,**argv): + def ZSQLQuote(self,str): + """quote str for sql""" + return sql_quote(str) + + + def normalizeField(self,table,fieldname, newFieldName=None,mode="alter", RESPONSE=None): + """normalize a field""" + import unicodedata + + if not newFieldName: + newFieldName=fieldname+"_normal" + + def normal(str): + if str: + return unicodedata.normalize('NFKD', str.decode('utf-8')).encode('ASCII', 'ignore') + else: + return "" + if mode=="create": # create the field + qstr="""alter table %s add %s %s""" + self.ZSQLSimpleSearch(qstr%(table,newFieldName,'text')) + + qstr="select oid,%s from %s"%(fieldname,table) + for result in self.ZSQLSimpleSearch(qstr): + qstr="update %s set %s = %s where oid = %s" + + self.ZSQLSimpleSearch(qstr%(table,newFieldName,self.ZSQLQuote(normal(getattr(result,fieldname))),result.oid)) + + def importAccessModell(self,configFileName,RESPONSE=None): + """import tables from access + @param configFileName: xml-configfile + """ + from Ft.Xml import Parse + fh=file(configFileName) + + doc=Parse(fh) + + x=doc.xpath("//pathToFolder/@path") + + + if not (len(x)==1): # tag ist nich eineindeutig + return False + + pathToFolder=x[0].value + + for db in doc.xpath("//db"): + + containers=db.xpath("./@container") + identifiers=db.xpath("./@identify") + + + if not (len(containers)==1): + return False + else: + container=containers[0].value + + if not (len(identifiers)==1): + identifier=None + else: + identifier=identifiers[0].value + + self.xsdToTable(container.lower(),container,modus="drop",filename=os.path.join(pathToFolder,container.lower()+".xsd")) + self.importXMLFileAccess(container.lower(),container,filename=os.path.join(pathToFolder,container.lower()+".xml"),identify=identifier) + + return "DONE" + + def xsdToTable(self,table,elementNameForTable,modus="update", filename=None,data=None,RESPONSE=None): + """reads an xsd file an creates the columns of a table out of its structure + @param table: name of the table the xml shall be imported into + @param elementNameForTable: must be a element of type complex type. the element of the sequence in the complex type + define the columns of the table >table< + @param data (optional): data to be imported + + @param filename (optional) or filename + @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes. + @param RESPONSE: (optional) + + """ + #from xml.dom.minidom import parseString,parse + + from Ft.Xml import Parse + logger("import xsd",logging.INFO,"called") + #fh=file("/tmp/fmpxml.xml") + import bz2 + import base64 + + + ret="" + if data: + data=bz2.decompress(base64.decodestring(data)) + + #logger("import xsd",logging.INFO,"received file") + doc=Parse(data) + #logger("import xsd",logging.INFO,"parsed file") + + elif filename: + fh=file(filename) + txt=fh.read() + + doc=Parse(txt) + #logger("import xsd",logging.INFO,"parsed file") + + + Nss={'xsd':'http://www.w3.org/2001/XMLSchema'} + definingSequence=doc.xpath("""//xsd:element[@name='%s']/xsd:complexType/xsd:sequence/xsd:element/@name"""%elementNameForTable,explicitNss=Nss) + + fieldNames=[x.value for x in definingSequence] + + + + #check if table exists + + qstr="""select relname from pg_class where relname = '%s'"""%table + if not(self.ZSQLSimpleSearch(qstr)) or (len (self.ZSQLSimpleSearch(qstr))<1): # if not the create the table + columns=[] + create=True + else: + create=False + + logger("update xsd: fieldnames",logging.INFO,repr(fieldNames)) + qstr="""select attname from pg_attribute, pg_class where attrelid = pg_class.oid and relname = '%s' """ + columns=[x.attname for x in self.ZSQLSimpleSearch(qstr%table)] + + + if (modus=="drop") and (not create): #table shall be deleted, therefore it should exist (not create) + print "drop" + qstr="""DROP TABLE %s """ + self.ZSQLSimpleSearch(qstr%table) + columns=[] + create=True + + for fieldName in fieldNames: + if type(fieldName) is UnicodeType: + fieldName=fieldName.encode('utf-8') + logging.info("update xml: fieldname",logging.INFO,repr(fieldName)) + if fieldName.lower() not in columns: + + if create:# table does not exist therefore create with one column + qstr="""create table %s (%s %s)""" + create=False + else:# otherwise add the field + qstr="""alter table %s add %s %s""" + + self.ZSQLSimpleSearch(qstr%(table,fieldName,'text')) + logger("update xsd: fieldname add",logging.INFO,qstr%(table,fieldName,'text')) + + + def importXMLFileAccess(self,table,container,data=None,identify=None,filename=None,RESPONSE=None): + ''' + Import XML file in access format into the table + @param table: name of the table the xml shall be imported into + @param containerTagName: XML-Tag which describes a dataset + @param data: data to be imported + @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes. + @param RESPONSE: (optional) + ''' + from xml.dom.pulldom import parseString,parse + + logger("import xml",logging.INFO,"called") + #fh=file("/tmp/fmpxml.xml") + import bz2 + import base64 + + ret="" + if data: + data=bz2.decompress(base64.decodestring(data)) + + logger("import xml",logging.INFO,"received file") + doc=parseString(data) + logger("import xml",logging.INFO,"parsed file") + + elif filename: + fh=file(filename) + doc=parse(fh) + logger("import xml",logging.INFO,"parsed file") + while 1: + node=doc.getEvent() + + if node is None: + break; + else: + if node[1].nodeName.lower()==container.lower(): # make everything case insensitive + doc.expandNode(node[1]) + + dataSet={} + for col in node[1].childNodes: + if col.nodeType is col.ELEMENT_NODE: + data=col.nodeName + dataSet[data]=getTextFromNode(col) + + update=False + + if identify: + + field=dataSet[identify] + + searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field) + logger("import xml",logging.INFO,searchStr) + search=self.ZSQLSimpleSearch(searchStr) + if search: + update=True + + if update: + tmp=[] + for fieldName in dataSet.keys(): + tmp.append("""%s = %s"""%(fieldName,self.ZSQLQuote(dataSet[fieldName]))) + setStr=",".join(tmp) + + field=dataSet[identify] + + queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field) + logger("update xml",logging.INFO,queryStr) + self.ZSQLSimpleSearch(queryStr) + ret+="ud: %s \n"%field + else: + + + fields=",".join(dataSet.keys()) + values=",".join([""" %s """%self.ZSQLQuote(dataSet[x]) for x in dataSet.keys()]) + + + queryStr="""INSERT INTO %s (%s) VALUES (%s)"""%(table,fields,values) + self.ZSQLSimpleSearch(queryStr) + logger("update xml",logging.INFO,queryStr) + + + + + return ret + + + def importXMLFile(self,table,data=None,identify=None,filename=None,RESPONSE=None): + #TODO: finish importXMLFile + ''' + Import XML file into the table + @param table: name of the table the xml shall be imported into + @param containerTagName: XML-Tag which describes a dataset + @param file: xmlfile handle + @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes. + @param RESPONSE: (optional) + ''' + from xml.dom.pulldom import parseString + + doc=parseString(file.read()) + while 1: + node=doc.getEvent() + + if node is None: + break; + else: + if node[1].nodeName==containerTagName: + doc.expandNode(node[1]) + cols=node[1].getElementsByTagName('COL') + dataSet=[] + for col in cols: + data=col.getElementsByTagName('DATA') + dataSet.append(getTextFromNode(data[0])) + update=False + if identify: + + nr=fieldNames.index(identify) + field=dataSet[nr] + + searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field) + logger("import xml",logging.INFO,searchStr) + search=self.ZSQLSimpleSearch(searchStr) + if search: + update=True + + if update: + tmp=[] + for fieldName in fieldNames: + tmp.append("""%s = %s"""%(fieldName,self.ZSQLQuote(dataSet[fieldNames.index(fieldName)]))) + setStr=",".join(tmp) + nr=fieldNames.index(identify) + field=dataSet[nr] + + queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field) + logger("update xml",logging.INFO,queryStr) + self.ZSQLSimpleSearch(queryStr) + ret+="ud: %s \n"%field + else: + + + fields=",".join(fieldNames) + values=",".join([""" %s """%self.ZSQLQuote(x) for x in dataSet]) + + + queryStr="""INSERT INTO %s (%s) VALUES (%s)"""%(table,fields,values) + self.ZSQLSimpleSearch(queryStr) + logger("update xml",logging.INFO,queryStr) + ret+="ad: %s \n"%field + + elif node[1].nodeName=="METADATA": + fieldNames=[] + doc.expandNode(node[1]) + + names=node[1].getElementsByTagName('FIELD') + + for name in names: + fieldNames.append(name.getAttribute('NAME')) + + logger("update xml: fieldnames",logging.INFO,repr(fieldNames)) + qstr="""select attname from pg_attribute, pg_class where attrelid = pg_class.oid and relname = '%s' """ + columns=[x.attname for x in self.ZSQLSimpleSearch(qstr%table)] + + for fieldName in fieldNames: + logger("update xml: fieldname",logging.INFO,repr(fieldName)) + if fieldName not in columns: + qstr="""alter table %s add %s %s""" + self.ZSQLSimpleSearch(qstr%(table,fieldName,'text')) + logger("update xml: fieldname add",logging.INFO,qstr%(table,fieldName,'text')) + #fn=node[1].getAttribute("xml:id") + #nf=file("xtf/"+fn+".xtf",'w') + #nf.write(""""""+node[1].toxml()+"") + #print "wrote: %s"%fn + + + def importXMLFileFMP(self,table,data=None,filename=None,update_fields=None,id_field=None,sync_mode=False,RESPONSE=None): + ''' + Import FileMaker XML file (FMPXMLRESULT format) into the table. + @param table: name of the table the xml shall be imported into + @param data: xml data as bz2 string + @param filename: xmlfile filename + @param update_fields: (optional) list of fields to update; default is to create all fields + @param id_field: (optional) field which uniquely identifies an entry for updating purposes. + @param sync_mode: (optional) really synchronise, i.e. delete entries not in XML file + @param RESPONSE: (optional) + ''' + from xml.dom.pulldom import parseString,parse + import transaction + + ret = "" + + if data: + data=bz2.decompress(base64.decodestring(data)) + zLOG.LOG("fmpxml",zLOG.INFO,"received file") + doc=parseString(data) + zLOG.LOG("fmpxml",zLOG.INFO,"parsed file") + + elif filename: + fh=file(filename) + zLOG.LOG("fmpxml",zLOG.INFO,"reading file") + doc=parse(fh) + zLOG.LOG("fmpxml",zLOG.INFO,"parsed file") + + dbIDs = {} + rowcnt = 0 + + if id_field is not None: + # prepare a list of ids for sync mode + qstr="select %s from %s"%(id_field,table) + for id in self.ZSQLSimpleSearch(qstr): + # value 0: not updated + dbIDs[id[0]] = 0; + rowcnt += 1 + + zLOG.LOG("fmpxml",zLOG.INFO,"%d entries in DB to sync"%rowcnt) + + fieldNames = [] + rowcnt = 0 + id_val = '' + + while 1: + node=doc.getEvent() + + if node is None: + break; + + # METADATA tag defines number and names of fields in FMPXMLRESULT + if node[1].nodeName == 'METADATA': + doc.expandNode(node[1]) + + names=node[1].getElementsByTagName('FIELD') + + for name in names: + fn = name.getAttribute('NAME') + fieldNames.append(fn) + + if update_fields is None: + # update all fields + update_fields = fieldNames + + zLOG.LOG("fmpxml fieldnames:",zLOG.INFO,repr(fieldNames)) + # get list of fields in db table + qstr="""select attname from pg_attribute, pg_class where attrelid = pg_class.oid and relname = '%s'""" + columns=[x.attname for x in self.ZSQLSimpleSearch(qstr%table)] + + # adjust db table to fields in XML and fieldlist + for fieldName in fieldNames: + zLOG.LOG("fmpxml fieldname:",zLOG.INFO,repr(fieldName)) + if (fieldName not in columns) and (fieldName in update_fields): + qstr="""alter table %s add %s %s""" + self.ZSQLSimpleSearch(qstr%(table,fieldName,'text')) + zLOG.LOG("fmpxml add field:",zLOG.INFO,qstr%(table,fieldName,'text')) + + # ROW tags (in RESULTSET tag) hold data + elif node[1].nodeName == 'ROW': + rowcnt += 1 + + doc.expandNode(node[1]) + cols=node[1].getElementsByTagName('COL') + dataSet={} + i = 0 + # populate with data + for col in cols: + data=col.getElementsByTagName('DATA') + dataSet[fieldNames[i]] = getTextFromNode(data[0]) + i += 1 + + update=False + + # synchronize by id_field + if id_field: + id_val=dataSet[id_field] + if id_val in dbIDs: + dbIDs[id_val] += 1 + update=True + + if update: + # update existing row (by id_field) + setvals=[] + for fieldName in update_fields: + setvals.append("%s = %s"%(fieldName,self.ZSQLQuote(dataSet[fieldName]))) + setStr=string.join(setvals, ',') + id_val=dataSet[id_field] + qstr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,id_field,id_val) + #zLOG.LOG("fmpxml update:",zLOG.INFO,queryStr) + self.ZSQLSimpleSearch(qstr) + ret+="up: %s \n"%id_val + else: + # create new row + fields=string.join(update_fields, ',') + values=string.join([" %s "%self.ZSQLQuote(dataSet[x]) for x in update_fields], ',') + qstr="""INSERT INTO %s (%s) VALUES (%s)"""%(table,fields,values) + self.ZSQLSimpleSearch(qstr) + #zLOG.LOG("fmpxml: insert",zLOG.INFO,queryStr) + ret+="ad: %s \n"%dataSet.get(id_field, rowcnt) + + #zLOG.LOG("fmpxml row:",zLOG.INFO,"%d (%s)"%(rowcnt,id_val)) + if (rowcnt % 10) == 0: + zLOG.LOG("fmpxml row:",zLOG.INFO,"%d (%s)"%(rowcnt,id_val)) + transaction.commit() + + transaction.commit() + if sync_mode: + # delete unmatched entries in db + for id in dbIDs.keys(): + # find all not-updated fields + if dbIDs[id] == 0: + zLOG.LOG("fmpxml delete:",zLOG.INFO,id) + qstr = "DELETE FROM %s WHERE %s = '%s'" + self.ZSQLSimpleSearch(qstr%(table,id_field,id)) + + elif dbIDs[id] > 1: + zLOG.LOG("fmpxml sync:",zLOG.INFO,"id used more than once?"+id) + + transaction.commit() + + return ret + + def generateIndex(self,field,index_name,table,RESPONSE=None): + """erzeuge index aus feld""" + index={} + founds=self.ZSQLSimpleSearch("""SELECT %s,oid FROM %s LIMIT 2000"""%(field,table)) + + for found in founds: + tmp=getattr(found,field,None) + if tmp: + strings=tmp.split(" ") + for string in strings: + if index.get(string): + index[string].append(found.oid) + else: + index[string]=[found.oid] + RESPONSE.write(string+"\n") + + if not hasattr(self,index_name): + obj=ZSQLIndex(index,index_name,table) + self._setObject(index_name,obj) + + self._getOb(index_name).setIndex(index) + + def getIndex(self,index_name): + """getIndex""" + founds=self.ZopeFind(self,obj_ids=[index_name]) + + return founds[0][1].getIndex() + + + def testneu(self): + """test""" + relStatement="""period like '%s%%'""" + statement="select * from cdli_cat" + wherePart="museum_no like 'VAT%'" + classes=['Uruk III','Uruk IV'] + return self.searchRel(relStatement,statement,wherePart,classes) + + def URLquote(self,txt): + """urlquote""" + return urllib.quote(txt) + + def searchRel(self,relStatement,statement,wherePart,classes): + """suche relative haufigkeiten""" + ret={} + allRecords=len(self.ZSQLSimpleSearch(statement + " where "+wherePart)) + + for oneclass in classes: + ret[oneclass]=len(self.ZSQLSimpleSearch(statement + " where ("+wherePart+") and "+ relStatement%oneclass)) + + return (ret,allRecords) + + def content_html(self): + """template fuer content""" + + try: + obj=getattr(self,"ZSQLBibliography_template") + return obj() + except: + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ZSQLBibliography_template_standard.zpt'),content_type='text/html').__of__(self) + pt.content_type="text/html" + + return pt() + + + def getWeight(self): + """getLabe""" + try: + return self.weight + except: + return "" + + def getLabel(self): + """getLabe""" + try: + return self.label + except: + return "" + + def getDescription(self): + """getLabe""" + try: + return self.description + except: + return "" + + manage_options=Folder.manage_options+( + {'label':'Main Config','action':'changeZSQLExtendForm'}, + ) + + def changeZSQLExtendForm(self): + """change folder config""" + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeZSQLExtendForm.zpt')).__of__(self) + return pt() + + + def changeZSQLExtend(self,label,description,weight=0,REQUEST=None,connection_id=None): + """change it""" + self.connection_id=connection_id + self.weight=weight + self.label=label + self.description=description + + if REQUEST is not None: + return self.manage_main(self, REQUEST) + + def formatAscii(self,str,url=None): + """ersetze ascii umbrueche durch
""" + #url=None + str=str.rstrip().lstrip() + + if url and str: + + retStr="" + words=str.split("\n") + + for word in words: + strUrl=url%word + #print "str",strUrl + retStr+="""%s
"""%(strUrl,word) + str=retStr + if str: + return re.sub(r"[\n]","
",str) + else: + return "" + + def getSAttribute(self,obj,atribute,pref=''): + """get Attribute or emptystring""" + + #print "obj",obj + try: + return pref+getattr(obj,atribute) + except: + return "" + + def getS(self,str): + """make none to empty string""" + if str: + return str + else: + return "" + + def actualPath(self,url=None): + """path""" + + if self.REQUEST['HTTP_X_FORWARDED_SERVER']=='': + host=self.REQUEST['HTTP_HOST'] + else: + host=self.REQUEST['HTTP_X_FORWARDED_SERVER'] + if not url: + return "http://"+host+self.REQUEST['PATH_TRANSLATED'] + else: + temp=self.REQUEST[url].split("/") + temp[2]=host + return string.join(temp,"/") + + def getRequest(self): + """request""" + return self.REQUEST + + def lowerEnd(self,path): + """oinly for demo""" + return os.path.splitext(path)[0]+".jpg" + + def ZSQLisEmpty(self,field): + """Teste ob Treffer leer""" + #print "field",field + if not field: + return 1 + if field=="": + return 1 + return 0 + + def ZSQLsearchOptions(self,fieldname=""): + """return HTML Fragment with search options""" + + ret=""""""%fieldname + return ret + + def ZSQLSelectionFromCRList(self,fieldname,listField,boxType="checkbox",checked=None): + """generate select options from a cr seperated list""" + fields=listField.split("\n") + ret="" + for field in fields: + if checked and (field in checked.split("\n")): + ret+="""%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8')) + else: + ret+="""%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8')) + return ret + + def ZSQLSelectionFromSearchList(self,fieldname,results,fieldnameResult,boxType="checkbox",checked=None): + """generate select options from a cr seperated list""" + + ret="" + if not results: return "" + + for result in results: + field=getattr(result,fieldnameResult) + if field: + if checked and (getattr(result,fieldnameResult) in checked.split("\n")): + ret+="""%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8')) + else: + ret+="""%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8')) + return ret + + + def ZSQLOptionsFromCRList(self,fieldname,listField, multiple='',start=None,startValue=None,size=None,selected=None): + """generate select oprions form a cr seperated list""" + fields=listField.split("\n") + if size: + ret=""" + """%(fieldname,multiple) + if start: + if start==' ': + start='' + if not startValue: + startValue=start + + ret+=""""""%(startValue,start) + for field in fields: + if selected and (field in selected.split("\n")): + ret+=""""""%(field.encode('utf-8'),field.encode('utf-8')) + else: + ret+=""""""%(field.encode('utf-8'),field.encode('utf-8')) + ret+="""""" + return ret + + def ZSQLOptionsFromSearchList(self,fieldname,results,fieldName,valueName=None,start=None, multiple='',startValue=None,additionalSelect="",size=None,linelen=None,selected=None): + """generate select options form a search list + es wird + + """%(fieldname,multiple,size,additionalSelect) + else: + ret="""""" + return ret + + + def ZSQLInlineSearchU(self,storename=None,args=None,**argv): + """one element if exists""" + qs=[] + if storename: + """store""" + storename=storename + else: + storename="foundCount" + + if args: + argTmp=args + else: + argTmp=argv + + + #print "INLINE:",argv + for a in argTmp.keys(): + aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_" + qs.append(aFiltered+"="+urllib.quote(str(argTmp[a]))) + #return [] + ret = self.parseQueryString(string.join(qs,","),"_",storename=storename) + + try: + return ret[0] + except: + return None + + + def ZSQLSequentialSearch(self,_fieldlist,_searchTerm,storename=None,args=None,**argv): + """get a list of tuples (fields,searchoptions,table) to search the searchTerm in, returns dictionary. """ + #print "do search with:",_fieldlist,_searchTerm,storename,args,argv + ret={} + if args: + argTmp=args + else: + argTmp=argv + + for field in _fieldlist: + + argTmp2=copy.deepcopy(argTmp) + argTmp2[field[0]]=_searchTerm + argTmp2['_op_'+field[0]]=field[1] + argTmp2['_table']=field[2] + + ret[field[0]]=(self.ZSQLInlineSearch(storename=storename,args=argTmp2),field[3],field[4],field[5],field[6]) + + return ret + + + def ZSQLInlineSearch(self,storename=None,args=None,**argv): + """inlinesearch""" + + qs=[] + if storename: + """store""" + else: + storename="foundCount" + + + + if args: + argTmp=args + else: + argTmp=argv + + + #print "INLINE:",argv + for a in argTmp.keys(): + aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_" + qs.append(aFiltered+"="+urllib.quote(str(argTmp[a]))) + + + #return [] + + return self.parseQueryString(string.join(qs,","),"_",storename=storename) + + def ZSQLInlineSearch2(self,query): """inlinesearch""" qs=[] + #print "INLINE:",query + return self.ZSQLSimpleSearch(query) + def ZSQLResetConnection(self): + """reset the connectione""" + try: + self.getConnectionObj().manage_close_connection() + except: + logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2]) + try: + self.getConnectionObj().manage_open_connection() + except: + logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2]) + + def ZSQLSimpleSearch(self,query=None,max_rows=1000000): + """simple search""" - for a in argv.keys(): - qs.append(a+"="+urllib.quote(str(argv[a]))) + #print query + if not query: + query=self.query + + + if (hasattr(self,"_v_searchSQL") and (self._v_searchSQL == None)) or (not hasattr(self,"_v_searchSQL")): + + self._v_searchSQL=Shared.DC.ZRDB.DA.DA("_v_searchSQL","_v_searchSQL",self.getConnectionObj().getId(),"var","") + + self._v_searchSQL.max_rows_=max_rows + try: + return self._v_searchSQL.__call__(var=query) + except : + + if sys.exc_info()[0]=="Database Error": + try: + self.getConnectionObj().manage_open_connection() + except: + logger("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2]) + else: + try: + + self._v_searchSQL.max_rows_=max_rows + + return self._v_searchSQL.__call__(var=query) + except : - return self.parseQueryString(string.join(qs,","),"_") + if sys.exc_info()[0]=="Database Error": + try: + self.getConnectionObj().manage_open_connection() + except: + logger("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2]) + + def getConnectionObj(self): + if hasattr(self,'connection_id'): + return getattr(self,self.connection_id) + + + def ZSQLSimpleSearch2(self,query=None): + """ returrn SQLSearch""" + + if not query: + query=self.query + if getattr(self,'_v_search',None): + + return self._v_search(var=query) + + if hasattr(self,'search') and (self.search.meta_type=="Z SQL Method"): + self._v_search=self.search + return self.search(var=query) + else: + if hasattr(self.aq_parent.aq_parent,'search') and (self.aq_parent.aq_parent.search.meta_type=="Z SQL Method"): + self._v_search=self.aq_parent.aq_parent.search + return self.aq_parent.aq_parent.search(var=query) + else: + search=self.ZopeFind(self,obj_metatypes=["Z SQL Method"],search_sub=1) + if search: + self._v_search=search[0][1] + return search[0][1](var=query) + else: + return [] - def ZSQLAdd(self): + + + def ZSQLAdd(self,format=None,RESPONSE=None,args=None,**argv): """Neuer Eintrag""" - qs=self.REQUEST['QUERY_STRING'] + + if args: + argTmp=args + else: + argTmp=argv + + qs_temp=[] + + for a in self.REQUEST.form.keys(): + qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a]))) + + qs=string.join(qs_temp,",") + + for field in argTmp.keys(): + if field[0]=="_": + fieldTmp="-"+field[1:] + else: + fieldTmp=field + + qs+=",%s=%s"%(fieldTmp,argTmp[field]) + + addList={} - for q in qs.split("&"): + for q in qs.split(","): name=re.sub("r'+'"," ",q.split("=")[0].lower()) value=q.split("=")[1] - value=re.sub(r'\+'," ",value) - value=urllib.unquote(value) + value=re.sub(r'\+'," ",value) + value=urllib.unquote(value) if name=="-table": table=urllib.unquote(value) elif name=="-format": format=urllib.unquote(value) - elif (not name[0]=="-") and (not len(value)==0): + elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0): addList[urllib.unquote(name)]=urllib.unquote(value) keyList=[] valueList=[] for x in addList.keys(): keyList.append("\""+x+"\"") - valueList.append("\'"+addList[x]+"\'") + valueList.append(sql_quote(addList[x])) keyString=string.join(keyList,",") valueString=string.join(valueList,",") queryString="INSERT INTO %s (%s) VALUES (%s)"%(table,keyString,valueString) - self.search(var=queryString) - return self.REQUEST.RESPONSE.redirect(format) + + self.ZSQLSimpleSearch(queryString) + + if RESPONSE and format: + return RESPONSE.redirect(format) + else: + return True + + def ZSQLChange(self,format=None,RESPONSE=None,USE_FORM=None,args=None,**argv): + """change entries""" + #qs=self.REQUEST['QUERY_STRING'] + # very bad hack + + qs_temp=[] + if USE_FORM or RESPONSE: + for a in self.REQUEST.form.keys(): + + qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a]))) + + + if args: + arg_tmp=args + else: + arg_tmp=argv + + for field in arg_tmp.keys(): + + if field[0]=="_": + fieldTmp="-"+field[1:] + else: + fieldTmp=field + + qs_temp.append("%s=%s"%(fieldTmp,arg_tmp[field])) + - def ZSQLChange(self): - """Ändern von Einträgen""" - qs=self.REQUEST['QUERY_STRING'] - #print "CHANGE QS",self.REQUEST - #return self.REQUEST changeList=[] - for q in qs.split("&"): + logging.info("ZSQLChange qs_temp: %s"%repr(qs_temp)) + for q in qs_temp: + name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower())) - value=q.split("=")[1] + value="=".join(q.split("=")[1:]) value=re.sub(r'\+'," ",value) - value=urllib.unquote(value) - if name=="-table": - table=urllib.unquote(value) + value=urllib.unquote(value) + + if name=="-table": + table=urllib.unquote(value) elif name=="-identify": identify=urllib.unquote(value) - identify=identify.split("=")[0]+"=\'"+identify.split("=")[1]+"\'" + identify=identify.split("=")[0]+"="+sql_quote(identify.split("=")[1]) elif name=="-format": format=urllib.unquote(value) - elif (not name[0]=="-") and (not len(value)==0): - changeList.append("\""+name+"\"=\'"+urllib.unquote(value)+"\'") + #elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0): + elif (not (name[0]=="-" or name[0]=="_")): + + if value=="": + changeList.append("\""+name+"\"=null") + else: + changeList.append("\""+name+"\"="+sql_quote(urllib.unquote(value))) + changeString=string.join(changeList,",") + queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify) - self.search(var=queryString) - return self.REQUEST.RESPONSE.redirect(format) + logger("ZSQLExtend",logging.INFO,"CHANGE: "+queryString) + + self.ZSQLSimpleSearch(queryString) + + + if RESPONSE and format: + return RESPONSE.redirect(format) + else: + return True + + + def ZSQLFindIndexed(self,qs="",select="oid,*",storename=None,indexedFields=['data_line'],restrictField='id_text',**argv): + """find2""" + + for index in self.ZopeFind(self,obj_ids=indexedFields): + txt=argv.get(index[0],None) + if txt: + oids=index[1].getIndex()[txt] + + search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv) + + search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv) + return search2 - def ZSQLFind(self,qs="",select="*"): - """Find""" + def ZSQLFind2(self,qs="",select="oid,*",storename=None,tableList=['cdli_translit','cdli_cat'],restrictField='id_text',**argv): + """find2""" + + search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv) + + search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv) + return search2 + + + + def ZSQLFind(self,qs="",select="oid,*",storename=None,tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None,**argv): + """search in database""" + def delEmpty(list): + """"loesche leere elemente aus der liste""" + ret=[] + for x in list: + splitted=x.split("=") + if (len(splitted)>1) and not (splitted[1]==' '): + ret.append(x) + return ret if qs=="": + #kein querystring ubergeben if self.REQUEST['QUERY_STRING']: qs=self.REQUEST['QUERY_STRING'] + qs=string.join(qs.split("&"),",") + + for field in argv.keys(): + if field[0]=="_": + fieldTmp="-"+field[1:] + else: + fieldTmp=field + + qs+=",%s=%s"%(fieldTmp,argv[field]) + else: - qs=self.REQUEST.SESSION['query'] + + qs=self.REQUEST.SESSION.get('query','') + + for field in argv.keys(): + if field[0]=="_": + fieldTmp="-"+field[1:] + else: + fieldTmp=field + + qs+=",%s=%s"%(fieldTmp,argv[field]) + + + else: + self.REQUEST['QUERY_STRING']=qs + qs=string.join(qs.split("&"),",") - return self.parseQueryString(qs,"-",select=select,storemax="yes") + + + + qs=re.sub("\\+"," ",qs)#TODO: Austauschen da Leerzeichen bei http-get durch + ersetzt wird, generell sollte alles auf post umgeschrieben werden. vom search formular. - def ZSQLFoundCount(self,founds): - try: - return len(founds) - except: - return 0 + qs=string.join(delEmpty(qs.split(",")),",") + + if storename: + """store""" + else: + storename="foundCount" + + #store query for further usage + self.REQUEST.SESSION['query']=qs - def parseQueryString(self,qs,iCT,storemax="no",select=None): - """analysierren den QueryString""" + #print "calling Query with",repr(NoQuery) + ret=self.parseQueryString(qs,"-",select=select,storemax="yes",storename=storename,tableExt=tableExt,NoQuery=NoQuery,NoLimit=NoLimit,restrictField=restrictField,restrictConnect=restrictConnect,filter=filter) + #print self.REQUEST.SESSION["foundCount"] + + + + return ret + + def ZSQLFoundCountLen(self,var): + return len(var) + + def ZSQLFoundCount(self,qs="",select="*",storename=None): + + ## if qs=="": + +## if self.REQUEST['QUERY_STRING']: + +## qs=self.REQUEST['QUERY_STRING'] +## qs=string.join(qs.split("&"),",") +## else: + +## qs=self.REQUEST.SESSION['query'] +## else: +## qs=string.join(qs.split("&"),",") + + +## temp= self.parseQueryString(qs,"-",select=select,storemax="yes",nostore="yes") + if storename: + """store""" + else: + storename="foundCount" + + return self.REQUEST.SESSION[storename]['count'] + + def ZSQLRangeStart(self,storename=None): + + if storename: + """store""" + else: + storename="foundCount" + + return int(self.REQUEST.SESSION[storename]['rangeStart'])+1 + + def ZSQLRangeSize(self,storename=None): + + if storename: + """store""" + else: + storename="foundCount" + + return self.REQUEST.SESSION[storename]['rangeSize'] + + def ZSQLRangeEnd(self,storename=None): + + if storename: + """store""" + else: + storename="foundCount" + + return str(min(int(self.REQUEST.SESSION[storename]['rangeEnd']),int(self.REQUEST.SESSION[storename]['count']))) + + def ZSQLNewQuery(self,linkText,storename=None,**argv): + """suche neu""" + return self.ZSQLNewSearch(linkText,storename,url=self.REQUEST['URL'],args=argv) + + def ZSQLNewSearch(self,linkText,storename=None,url=None,args=None,**argv): + """suche mit alten parametern bis auf die in argv getauschten""" + str = self.ZSQLNewSearchURL(storename, url, args, **argv) + return """ %s"""%(str,linkText) + + + def ZSQLNewSearchURL(self, storename=None,url=None,args=None,**argv): + """suche mit alten parametern bis auf die in argv getauschten""" + + if storename: + """store""" + else: + storename="foundCount" + qs=self.REQUEST.SESSION[storename]['qs'] + + if args: + argv=args + + querys=qs.split(",") + argList=[] + arg="" + queryList=[x.split("=")[0] for x in querys] + + for argTmp in argv.keys(): + + + arg=argTmp[0:] + if arg[0]=="_":arg="-"+argTmp[1:] # aender _ in - als standard + + if arg not in queryList: # noch nicht drin + querys.append("%s=%s"%(arg,argv[argTmp])) + argList.append(arg) + + + + newquery=[] + for query in querys: + queryArg=query.split("=")[0] + qarg=queryArg[0:] + if qarg[0]=="-":qarg="_"+queryArg[1:] # aender _ in - als standard + + if queryArg in argList: + newquery.append("%s=%s"%(queryArg,argv[qarg])) + else: + newquery.append(query) + + if url: + str=url+"?"+"&".join(newquery) + else: + str="ZSQLSearch?"+"&".join(newquery) + + return str + + def parseQueryString(self,qs,iCT,storemax="no",select=None,nostore=None,storename=None,tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None): + """analysieren den QueryString""" + + + #setzte generische werte + lop="AND" # standardsuche mit and - max="ALL" #standard alle auswählen + max="ALL" #standard alle auswaehlen + maxstr="" whereList=[] sort="" op="bw" opfields={} + lopfields={} #Verknuepfung bei mehrfachauswahl von einem feld + sortfields={} #order of sortfields + diacritics={} #diacritische zeichen, falls "no", dann werden diese fuer das feld gefiltert. + sortAllFields=None + skip="" + rangeStart=0 + limit=0 + searchFields={} + searchFieldsOnly={} + queryTemplate=[] if not select: - select="*" + select="oid,*" - #check for op in the case of inline search - if iCT=="_": - for q in qs.split(","): - name=re.sub("r'+'"," ",q.split("=")[0].lower()) - value=urllib.unquote(q.split("=")[1]) + #check for op + splitted=qs.split(",") + + if tableExt: + table=tableExt + if restrictField: + select=restrictField + + + #erster durchgang suche operatoren + for q in splitted: + + name=re.sub("r'+'"," ",q.split("=")[0].lower()) + try: + value=urllib.unquote(q.split("=",1)[1]) + except: + value="" + #print "Hi",name[0:3],q if name[0:3]==iCT+"op": op=value + field=name[4:] opfields[field]=op - #now analyse the querystring + if name[0:4]==iCT+"lop": + lop=value + + field=name[5:] + lopfields[field]=lop + + if name[0:11]==iCT+"diacritics": + field=name[12:] + diacritics[field]=value + + if name[0:10]==iCT+"sortorder": + #sort=value + + field=name[11:] + sortAllFields=None + #no field selected + if field=="": + sortAllFields=value + else: + sortfields[field]=value + + #zweiter durchgang analysiere felder for q in qs.split(","): + + + + name=re.sub("r'+'"," ",q.split("=")[0].lower()) try: - - name=re.sub("r'+'"," ",q.split("=")[0].lower()) - value=urllib.unquote(q.split("=")[1]) - value=quoteString(value) - if name==iCT+"lop": - lop=value - elif name==iCT+"table": + value=urllib.unquote(q.split("=",1)[1]) + except: + value="" + + punktsplit=name.split(".") #sonderfall feld mit punkten(tabelle.suchFeld.ausgewaehltesFeld,feldinoriginal), d.h. suche in anderer tabelle: + + #analysiere alle anderen faelle + + if diacritics.get(name,'yes')=='no': + """filter diacritische zeichen""" + value=unicodedata.normalize('NFKD', value.decode('utf-8')).encode('ASCII', 'ignore') + + if name==iCT+"lop": + lop=value + elif name==iCT+"table": + if not tableExt: table=value - elif name==iCT+"select": + elif name==iCT+"select": + if not restrictField: select=value - elif name==iCT+"max": - max=str(value) - - elif name==iCT+"join": - whereList.append(value) - elif name==iCT+"sort": - sort="ORDER BY "+value - elif name==iCT+"token": + elif name==iCT+"max": + if not NoLimit: + maxstr="LIMIT "+str(value) + limit=str(value) + elif name==iCT+"skip": + skip="OFFSET "+str(value) + rangeStart=str(value) + elif name==iCT+"join": + whereList.append(value) + elif name==iCT+"sort": + sortstrs=[] + for word in value.split(','): + wordstr=word.lstrip().rstrip() + if sortAllFields: + order=sortAllFields + else: + order=sortfields.get(wordstr,'ASC') + + if not (wordstr == ""): + sortstrs.append(wordstr+" "+order) + if len(sortstrs)>0: + sort="ORDER BY "+string.join(sortstrs,',') + + + elif name==iCT+"token": + if not nostore=="yes": self.REQUEST.SESSION['token']=value - elif name==iCT+"op": - op=value - + elif name==iCT+"op": + op=value + + + #sonderfall Name hat das Format: + #TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE_-table + #i.e. erzeugt wird + #das Statement + #WHERE IDENTIFIER_IN_TABELLE in (select * from SELECT_FIELD + #where LOWER(SUCHFELD_IN_DIESER_TABELLE) something value) + #something is defined by _op_TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE + + elif (not name[0]==iCT) and len(punktsplit)==4: + if opfields.has_key(name): + op=opfields[name] + else: + op="ct" + namealt=name + name="LOWER("+punktsplit[1]+")" + value=value.lower() + if op=="ct": + tmp=(name+" LIKE "+sql_quote("%"+value+"%")) + elif op=="gt": + tmp=(name+">"+sql_quote(value)) + elif op=="lt": + tmp=(name+"<"+sql_quote(value)) + elif op=="eq": + tmp=(name+"="+sql_quote(value)) + elif op=="bw": + tmp=(name+" LIKE "+sql_quote(value+"%")) + elif op=="ew": + tmp=(name+" LIKE "+sql_quote("%"+value)) + elif op=="all": + tmps=[] + for word in value.split(" "): + tmps.append(name+" LIKE "+sql_quote("%"+word+"%")) + + tmp=string.join(tmps,' AND ') + + elif op=="numerical": + term=analyseIntSearch(value) + tmp=(name+" "+term) + elif op=="grep": + tmp=(name+" ~* "+sql_quote(value)) + elif op=="one": + tmps=[] + for word in value.split(" "): + tmps.append(name+" LIKE "+sql_quote("%"+word+"%")) + + tmp=string.join(tmps,' OR ') + + op="all" + + + searchTmp="""%s in (select %s from %s where %s)"""%(punktsplit[3],punktsplit[2],punktsplit[0],tmp) + + queryTemplate.append(searchTmp) + elif (not name[0]==iCT) and (not len(value)==0): - elif (not name[0]==iCT) and (not len(value)==0): - if opfields.has_key(name): - op=opfields[name] - if op=="ct": - whereList.append(name+"~\'.*"+value+".*\'") - elif op=="gt": - whereList.append(name+">\'"+value+"\'") - elif op=="lt": - whereList.append(name+"<\'"+value+"\'") - elif op=="eq": - whereList.append(name+"=\'"+value+"\'") - elif op=="bw": - whereList.append(name+"~\'"+value+".*\'") - elif op=="ew": - whereList.append(name+"~\'.*"+value+"\'") + #print "OP",op,name + value=value.lower() + tmp="" + if opfields.has_key(name): + op=opfields[name] + else: op="ct" - except: - print "END" + namealt=name + name="LOWER("+name+")" + if op=="ct": + tmp=(name+" LIKE "+sql_quote("%"+value+"%")) + elif op=="gt": + tmp=(name+">"+sql_quote(value)) + elif op=="lt": + tmp=(name+"<"+sql_quote(value)) + elif op=="eq": + tmp=(name+"="+sql_quote(value)) + elif op=="bw": + tmp=(name+" LIKE "+sql_quote(value+"%")) + elif op=="ew": + tmp=(name+" LIKE "+sql_quote("%"+value)) + elif op=="all": + tmps=[] + for word in value.split(" "): + tmps.append(name+" LIKE "+sql_quote("%"+word+"%")) + + tmp=string.join(tmps,' AND ') + + elif op=="numerical": + term=analyseIntSearch(value) + tmp=(name+" "+term) + elif op=="grep": + tmp=(name+" ~* "+sql_quote(value)) + elif op=="one": + tmps=[] + for word in value.split(" "): + tmps.append(name+" LIKE "+sql_quote("%"+word+"%")) + + tmp=string.join(tmps,' OR ') + + op="all" + + if (not tableExt) or (namealt.split('.')[0]==tableExt): + if searchFields.has_key(namealt): + searchFields[namealt]+=lopfields.get(name,'OR')+" "+tmp + searchFieldsOnly[namealt]+=lopfields.get(name,'OR')+" "+value + else: + searchFields[namealt]=tmp + searchFieldsOnly[namealt]=value + + + whereList=["("+searchFields[x]+")" for x in searchFields.keys()] + whereList+=queryTemplate + if len(whereList)>0: - where="WHERE "+string.join(whereList," "+lop+" ") + if filter: + whereStr="("+string.join(whereList," "+lop+" ")+") AND "+filter + else: + whereStr=string.join(whereList," "+lop+" ") + where="WHERE "+whereStr else: - where="" + if filter: + where="WHERE "+filter + else: + where="" + + if restrictConnect: + + if len(where)==0: + where="WHERE "+restrictConnect[0]+" in ("+restrictConnect[1]+")" + else: + where+="and "+restrictConnect[0]+" in ("+restrictConnect[1]+")" + #print "QE",table + #print (select,table,where,sort,maxstr,skip) + query="SELECT %s FROM %s %s %s %s %s"%(select,table,where,sort,maxstr,skip) + + if not nostore=="yes": + + self.REQUEST.SESSION['qs']=opfields + #print "IAMHERE again:", query + + if storename and (not NoQuery): + + query2="SELECT count(*) FROM %s %s"%(table,where) + + #print "QUERYSTRING:",self.REQUEST.SESSION[storename]['queryString2'] + if not self.REQUEST.SESSION.has_key(storename): + self.REQUEST.SESSION[storename]={} + + self.REQUEST.SESSION[storename]['qs']=qs #sichere Querystring + + if self.REQUEST.SESSION[storename].has_key('queryString2'): + + if not self.REQUEST.SESSION[storename]['queryString2']==query2: + #print "HOOOOO",storename + self.REQUEST.SESSION[storename]['queryString2']=query2 + try: + self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count + except: + self.REQUEST.SESSION[storename]['count']=0 + #print "QUERY",query2,"::::",self.REQUEST.SESSION[storename]['queryString2'] + + else: + + self.REQUEST.SESSION[storename]['queryString2']=query2 + if self.ZSQLSimpleSearch(query2): + self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count + else: + self.REQUEST.SESSION[storename]['count']=0 + #print "QUERYNEW",self.REQUEST.SESSION[storename]['queryString2'] + + + self.REQUEST.SESSION[storename]['rangeStart']=rangeStart + if limit=="all": + self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count'] + else: + self.REQUEST.SESSION[storename]['rangeEnd']=int(rangeStart)+int(limit) + self.REQUEST.SESSION[storename]['rangeSize']=limit + self.REQUEST.SESSION[storename]['searchFields']=searchFields + + self.REQUEST.SESSION[storename]['searchFieldsOnly']=searchFieldsOnly + + if not NoQuery: + + return self.ZSQLQuery(query) + else: + + return query + + def ZSQLUniqueQuery(self,value,returns): + """unique relation""" + if returns: + statement="""select %s from %s where %s = '%s' """%(returns[1],returns[0],returns[2],value) + founds=self.ZSQLSimpleSearch(statement) + if founds: + return getattr(founds[0],returns[1]) + else: + return value + else: + return value - query="SELECT %s FROM %s %s %s"%(select,table,where,sort) + def ZSQLQuery(self,query,debug=None): + """query""" + if debug: + logger("ZSQLQuery", logging.INFO, query) + + return self.ZSQLSimpleSearch(query) - self.REQUEST.SESSION['qs']=opfields - return self.search(var=query) def ZSQLSearch(self): """To be done""" + + formatfile=self.REQUEST['URL1'] #generisch redirect zur gleichen url + + #zerlege querystring in key value paare + #TODO: check if this is really necessary, use argv** + rq=self.REQUEST['QUERY_STRING'] querys=rq.split("&") - - - for querytemp in querys: + for querytemp in querys: #zerg query=querytemp.split("=") + try: if query[0].lower()=="-format": formatfile=query[1] except: - """nothing""" - #print formatfile + pass + + #sichern self.REQUEST.SESSION['query']=string.join(self.REQUEST['QUERY_STRING'].split("&"),",") - return self.REQUEST.RESPONSE.redirect(urllib.unquote(formatfile)) + self.REQUEST.SESSION['come_from_search']="yes" + + return self.REQUEST.RESPONSE.redirect(urllib.unquote(formatfile)+"?"+rq) def ZSQLint(self,string): @@ -206,7 +1691,131 @@ class ZSQLExtendFolder(Persistent, Impli return(int(string)) except: return 0 - def prevLink(self,html): + + def getZSQLSearchFieldsList(self,storename="foundCount"): + """get searchfieldList""" + #print self.REQUEST.SESSION[storename]['searchFields'].keys() + return self.REQUEST.SESSION[storename]['searchFieldsOnly'].keys() + + def getZSQLSearchFields(self,field,storename="foundCount"): + """get searchfield""" + #print "SF",self.REQUEST.SESSION[storename]['searchFields'] + + return self.REQUEST.SESSION[storename]['searchFieldsOnly'][field] + + + def nextLink(self,html,storename="foundCount"): + """nextLink""" + + try: + limit=self.REQUEST.SESSION[storename]['rangeSize'] + if int(limit)==0 : + limit="1" + newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])+int(limit) + except: + limit=1 + newRangeStart=0 + + if newRangeStart>=self.REQUEST.SESSION[storename]['count']: + #newRangeStart=self.REQUEST.SESSION[storename]['count']-1 + return "" + + #create new query string + + if self.REQUEST['QUERY_STRING']=="": + qs=self.REQUEST.SESSION['query'] + + queries=string.split(qs,",")[0:] + + + else: + qs=self.REQUEST['QUERY_STRING'] + queries=string.split(qs,"&")[0:] + + + + newquery=[] + + skipFound=0 + + for query in queries: + + if query[0]=="_" : query="-"+query[1:] + + if query.split("=")[0].lower()=="-skip": + + skipFound=1 + query="-skip=%i"%newRangeStart + newquery.append(query) + + if skipFound==0 : + query="-skip=%i"%newRangeStart + newquery.append(query) + + newquerystring=string.join(newquery,"&") + return "%s"%(self.REQUEST['URL']+"?"+newquerystring,html) + + + + def prevLink(self,html,storename="foundCount"): + """prev link""" + + try: + limit=self.REQUEST.SESSION[storename]['rangeSize'] + if int(limit)==0 : + limit="1" + newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])-int(limit) + except: + limit=1 + newRangeStart=0 + if newRangeStart <0: + return "" + + #print "limit",limit,newRangeStart,int(self.REQUEST.SESSION[storename]['rangeStart']) + + if newRangeStart<0: + newRangeStart=0 + + #create new query string + + if self.REQUEST['QUERY_STRING']=="": + qs=self.REQUEST.SESSION['query'] + #qs=re.sub(r'_','-',qs) #aendern fuer query + queries=string.split(qs,",") + + + else: + qs=self.REQUEST['QUERY_STRING'] + queries=string.split(qs,"&") + + + + newquery=[] + + skipFound=0 + + for query in queries: + #print query.split("=")[0] + + if query[0]=="_" : query[0]="-" + + if query.split("=")[0].lower()=="-skip": + #print"HI" + query="-skip=%i"%newRangeStart + skipFound=1 + newquery.append(query) + + if skipFound==0 : + query="-skip=%i"%newRangeStart + newquery.append(query) + + newquerystring=string.join(newquery,"&") + + return "%s"%(self.REQUEST['URL']+"?"+newquerystring,html) + + + + def prevLink_old(self,html): """prev link""" if self.REQUEST['QUERY_STRING']=="": qs=self.REQUEST.SESSION['query'] @@ -231,9 +1840,9 @@ class ZSQLExtendFolder(Persistent, Impli else: queries.append("-offset=%i"%offsetnew) newquerystring=string.join(queries,"&") - return "%s"%(self.REQUEST['URL0']+"?"+newquerystring,html) + return "%s"%(self.actualPath()+"?"+newquerystring,html) - def nextLink(self,html): + def nextLink_old(self,html): """prev link""" if self.REQUEST['QUERY_STRING']=="": qs=self.REQUEST.SESSION['query'] @@ -261,27 +1870,279 @@ class ZSQLExtendFolder(Persistent, Impli queries.append("-offset=%i"%offsetnew) newquerystring=string.join(queries,"&") - return "%s"%(self.REQUEST['URL0']+"?"+newquerystring,html) + return "%s"%(self.actualPath()+"?"+newquerystring,html) - def ZSQLrangeStart(self): - if self.REQUEST['QUERY_STRING']=="": - qs=self.REQUEST.SESSION['query'] + +manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals()) + +def manage_addZSQLExtendFolder(self, id, title='', label='', description='', + createPublic=0, + createUserF=0, + connection_id=None, + REQUEST=None): + """Add a new Folder object with id *id*. + + If the 'createPublic' and 'createUserF' parameters are set to any true + value, an 'index_html' and a 'UserFolder' objects are created respectively + in the new folder. + """ + + + ob=ZSQLExtendFolder() + ob.id=str(id) + ob.title=title + self._setObject(id, ob) + ob=self._getOb(id) + setattr(ob,'label',label) + setattr(ob,'description',description) + setattr(ob,'connection_id',connection_id) + + checkPermission=getSecurityManager().checkPermission + + if createUserF: + if not checkPermission('Add User Folders', ob): + raise Unauthorized, ( + 'You are not authorized to add User Folders.' + ) + ob.manage_addUserFolder() + + if createPublic: + if not checkPermission('Add Page Templates', ob): + raise Unauthorized, ( + 'You are not authorized to add Page Templates.' + ) + ob.manage_addProduct['PageTemplates'].manage_addPageTemplate( + id='index_html', title='') + + if REQUEST is not None: + return self.manage_main(self, REQUEST, update_menu=1) + + + +class ZSQLBibliography(Folder,ZSQLExtendFolder): + """Bibliography""" + meta_type="ZSQLBibliography" + def getLabel(self): + try: + return self.label + except: + return "" + + def getDescription(self): + try: + return self.description + except: + return "" + + def changeZSQLBibliographyForm(self): + """change folder config""" + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeZSQLBibliographyForm.zpt')).__of__(self) + return pt() + + + def content_html(self): + """template fuer content""" + + try: + obj=getattr(self,"ZSQLBibliography_template") + return obj() + except: + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ZSQLBibliography_template_standard.zpt')).__of__(self) + pt.content_type="text/html" + return pt() + + def changeZSQLBibliography(self,tableName,label,description,connection_id=None,REQUEST=None): + """change it""" + self.connection_id=connection_id + self.tableName=tableName + self.label=label + self.description=description + + if REQUEST is not None: + return self.manage_main(self, REQUEST) + + manage_options=Folder.manage_options+( + {'label':'Main Config','action':'changeZSQLBibliographyForm'}, + {'label':'Generate RDF Template','action':'generateRDFTemplate'}, + {'label':'Generate XML Template','action':'generateXMLTemplate'}, + ) + + + def getFieldLabel(self,fields,field): + """get labels""" + try: + ret =fields[0][field] + if ret == "": + return field + else: + return ret + except: + return field + + def getFieldValue(self,found,field): + """get value""" + try: + ret=getattr(found,field) + if ret == "": + return None + else: + return ret + except: + return None + + def findTagsFromMapping(self,referenceType): + """gib hash mit label -> generic zurueck""" + self.referencetypes=self.ZopeFind(self.standardMD) + bibdata={} + retdata={} + fieldlist=self.standardMD.fieldList + + for referenceTypeF in self.referencetypes: + #print referenceType,referenceTypeF[1].title + if referenceTypeF[1].title == referenceType: + bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields + bibdata['data']=referenceTypeF[1] + self.fields=bibdata[referenceType] + for field in fieldlist: + if referenceTypeF[1].getValue(field)[0]==None: + retdata[field]=field + else: + retdata[field]=referenceTypeF[1].getValue(field)[0] + + return retdata,fieldlist + + def findLabelsFromMapping(self,referenceType): + """gib hash mit label -> generic zurueck""" + self.referencetypes=self.ZopeFind(self.standardMD) + bibdata={} + retdata={} + fieldlist=self.standardMD.fieldList + + for referenceTypeF in self.referencetypes: + #print referenceType,referenceTypeF[1].title + if referenceTypeF[1].title == referenceType: + bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields + bibdata['data']=referenceTypeF[1] + self.fields=bibdata[referenceType] + for field in fieldlist: + retdata[field]=referenceTypeF[1].getValue(field)[1] + + return retdata,fieldlist + + def createRDFTag(self,tag,content,namespace="cdli"): + """create RDF""" + if content: + tag=namespace+":"+tag + if (type(content) is StringType) or (type(content) is UnicodeType): + ret=""" <%s>%s"""%(tag,escape(content),tag) + else: + ret=""" <%s>%s"""%(tag,content,tag) + return ret.decode('latin-1') else: - qs=self.REQUEST['QUERY_STRING'] - offset=re.search(r'offset\=(.*)\,',qs.lower()) - if not offset: - offset=1 - return offset -# def search(self,**argv): -# """to be done""" + return "" + + def createIndexTag(self,tag,content): + """create tag""" + + if content: + if (type(content) is StringType) or (type(content) is UnicodeType): + ret=""" <%s>%s"""%(tag,escape(content),tag) + else: + ret=""" <%s>%s"""%(tag,content,tag) + return ret.decode('latin-1') + else: + return "" + + def getXML2(self): + """crate index meta""" + fn=os.path.splitext(self.REQUEST['fn'])[0]+"." + self.REQUEST['fn']=fn -manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals()) + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record2.xml')).__of__(self) + pt.content_type="text/xml" + return pt() + + + def generateRDFTemplate(self,REQUEST=None): + """generateRDFtemplate""" + zt=ZopePageTemplate('record.rdf') + self._setObject('record.rdf',zt) + default_content_fn = os.path.join(package_home(globals()), + 'zpt','record.rdf') + text = open(default_content_fn).read() + zt.pt_edit(text, 'text/xml') + + + if REQUEST is not None: + return self.manage_main(self, REQUEST) + + def generateXMLTemplate(self,REQUEST=None): + """generateXMLtemplate""" + zt=ZopePageTemplate('record.xml') + self._setObject('record.xml',zt) + default_content_fn = os.path.join(package_home(globals()), + 'zpt','record.xml') + text = open(default_content_fn).read() + zt.pt_edit(text, 'text/xml') + + + if REQUEST is not None: + return self.manage_main(self, REQUEST) + def getMetaDataRDF(self): + """crate index meta""" + find=self.ZopeFind(self,obj_ids=["record.rdf"]) + if not find: + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record.rdf')).__of__(self) + pt.content_type="text/xml" + return pt() + else: + return find[0][1]() + + def getMetaDataXML(self): + """crate index meta""" + find=self.ZopeFind(self,obj_ids=["record.xml"]) + if not find: + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record.xml')).__of__(self) + pt.content_type="text/xml" + return pt() + else: + return find[0][1]() + + + def getMetaDatasXML(self): + """index""" + # check if the request's host part was OK + http_host = self.REQUEST['HTTP_HOST'] + host_port = self.REQUEST['SERVER_PORT'] + fix_host = None + if http_host and http_host.rfind(host_port) == -1: + #print "HTTP_HOST needs fixing!" + fix_host = http_host + ":" + host_port + + ret=""" + """ + for found in self.ZSQLSimpleSearch("select oid from %s limit ALL"%self.tableName): + base_url = self.absolute_url() + if fix_host: + #print "replacing ", http_host, " by ", fix_host + base_url = string.replace(base_url, http_host, fix_host, 1) + + link=base_url+"/"+"record.html?oid=%i"%found.oid + metalink=base_url+"/"+"getMetaDataXML?oid=%i"%found.oid + + ret+="""\n"""%(link,metalink) + + return ret+"\n" -def manage_addZSQLExtendFolder(self, id, title='', + +manage_addZSQLBibliographyForm=DTMLFile('ZSQLBibliographyAdd', globals()) + +def manage_addZSQLBibliography(self, id, tableName,label,description,title='', createPublic=0, createUserF=0, + connection_id=None, REQUEST=None): """Add a new Folder object with id *id*. @@ -291,12 +2152,16 @@ def manage_addZSQLExtendFolder(self, id, """ - ob=ZSQLExtendFolder() + ob=ZSQLBibliography() ob.id=str(id) ob.title=title self._setObject(id, ob) ob=self._getOb(id) - + setattr(ob,'tableName',tableName) + setattr(ob,'label',label) + setattr(ob,'description',description) + setattr(ob,'connection_id',connection_id) + checkPermission=getSecurityManager().checkPermission if createUserF: @@ -318,3 +2183,5 @@ def manage_addZSQLExtendFolder(self, id, return self.manage_main(self, REQUEST, update_menu=1) + + \ No newline at end of file