|
|
| version 1.105, 2007/02/22 13:23:20 | version 1.141, 2011/02/23 19:43:04 |
|---|---|
| Line 4 from Globals import DTMLFile,package_hom | Line 4 from Globals import DTMLFile,package_hom |
| import urllib | import urllib |
| import re | import re |
| import string | import string |
| import sys | |
| #from pyPgSQL import libpq | #from pyPgSQL import libpq |
| from AccessControl import getSecurityManager | from AccessControl import getSecurityManager,Unauthorized |
| from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate | from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate |
| from Products.PageTemplates.PageTemplateFile import PageTemplateFile | from Products.PageTemplates.PageTemplateFile import PageTemplateFile |
| from Products.ZSQLMethods.SQL import SQLConnectionIDs | from Products.ZSQLMethods.SQL import SQLConnectionIDs |
| from Shared.DC.ZRDB.Results import Results | |
| from xml.sax.saxutils import escape | from xml.sax.saxutils import escape |
| from types import * | from types import * |
| import Shared.DC.ZRDB.DA | import Shared.DC.ZRDB.DA |
| Line 19 import os.path | Line 20 import os.path |
| import os | import os |
| import copy | import copy |
| import unicodedata | import unicodedata |
| import tempfile | |
| import logging | import sys |
| #ersetzt logging | #ersetzt logging |
| def logger(txt,method,txt2): | def logger(txt,method,txt2): |
| Line 57 def analyseIntSearch(word): | Line 58 def analyseIntSearch(word): |
| else: | else: |
| return "BETWEEN "+splitted[0]+" AND "+splitted[1] | return "BETWEEN "+splitted[0]+" AND "+splitted[1] |
| def unicodify(str): | |
| """decode str (utf-8 or latin-1 representation) into unicode object""" | |
| if not str: | |
| return u"" | |
| if type(str) is StringType: | |
| try: | |
| return str.decode('utf-8') | |
| except: | |
| return str.decode('latin-1') | |
| else: | |
| return str | |
| def utf8ify(str): | |
| """encode unicode object or string into byte string in utf-8 representation""" | |
| if not str: | |
| return "" | |
| if type(str) is StringType: | |
| return str | |
| else: | |
| return str.encode('utf-8') | |
| def setPsycopg2UseUnicode(): | |
| """force Psycopg2DA to return unicode objects""" | |
| try: | |
| import psycopg2 | |
| import psycopg2.extensions | |
| psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) | |
| except: | |
| logging.error("Unable to force psycopg2 to use unicode") | |
| def sql_quote(v): | def sql_quote(v): |
| Line 70 def sql_quote(v): | Line 101 def sql_quote(v): |
| def showSQLConnectionIDs(self): | def showSQLConnectionIDs(self): |
| return SQLConnectionIDs(self) | return SQLConnectionIDs(self) |
| class Options: | |
| """options class""" | |
| class ZSQLIndex(SimpleItem): | class ZSQLIndex(SimpleItem): |
| """index""" | """index""" |
| meta_type="ZSQLIndex" | meta_type="ZSQLIndex" |
| Line 86 class ZSQLIndex(SimpleItem): | Line 120 class ZSQLIndex(SimpleItem): |
| return self.index | return self.index |
| class ZSQLExtendFolder(Folder,Persistent, Implicit): | class ZSQLExtendFolder(Folder,Persistent, Implicit): |
| """Folder""" | """Klasse die Methoden fuer die Abfrage einer SQL-Datenbank zur Verfuegung stellt. |
| """ | |
| meta_type="ZSQLExtendFolder" | meta_type="ZSQLExtendFolder" |
| def ZSQLQuote(self,str): | def ZSQLQuote(self,str): |
| """quote str for sql""" | """quote str for sql""" |
| return sql_quote(str) | return sql_quote(str) |
| def unicodify(self, s): | |
| """return unicode object for string (utf-8 or latin1) or unicode object s""" | |
| return unicodify(s) | |
| def utf8ify(self, s): | |
| """return utf-8 encoded string object for string or unicode object s""" | |
| return utf8ify(s) | |
| def normalizeField(self,table,fieldname, newFieldName=None,mode="alter", RESPONSE=None): | def normalizeField(self,table,fieldname, newFieldName=None,mode="alter", RESPONSE=None): |
| """normalize a field""" | """normalize a field, d.h. entfernt alle diakritischen Zeichen und ersetzt diese |
| durch den Grundbuchstaben in einer Spalte einer Tabelle | |
| @param table: Tabellename | |
| @param fieldname: Name der Spalte | |
| @param newFieldName: (optional) default ist fieldname+"_normal" | |
| @param mode: (optional) default ist "alter". Mode "alter" aendert ein bestehendes Feld newFieldName, mode "create" erzeugt diese zuerst. | |
| """ | |
| import unicodedata | import unicodedata |
| if not newFieldName: | if not newFieldName: |
| newFieldName=fieldname+"_normal" | newFieldName=fieldname+"_normal" |
| #normalisierungs routine | |
| def normal(str): | def normal(str): |
| if str: | if str: |
| return unicodedata.normalize('NFKD', str.decode('utf-8')).encode('ASCII', 'ignore') | return unicodedata.normalize('NFKD', str.decode('utf-8')).encode('ASCII', 'ignore') |
| else: | else: |
| return "" | return "" |
| if mode=="create": # create the field | if mode=="create": # create the field |
| qstr="""alter table %s add %s %s""" | qstr="""alter table %s add %s %s""" |
| self.ZSQLSimpleSearch(qstr%(table,newFieldName,'text')) | self.ZSQLSimpleSearch(qstr%(table,newFieldName,'text')) |
| Line 302 class ZSQLExtendFolder(Folder,Persistent | Line 354 class ZSQLExtendFolder(Folder,Persistent |
| logger("update xml",logging.INFO,queryStr) | logger("update xml",logging.INFO,queryStr) |
| self.ZSQLSimpleSearch(queryStr) | self.ZSQLSimpleSearch(queryStr) |
| ret+="ud: %s \n"%field | ret+="ud: %s \n"%field |
| else: | |
| else: | |
| fields=",".join(dataSet.keys()) | fields=",".join(dataSet.keys()) |
| values=",".join([""" %s """%self.ZSQLQuote(dataSet[x]) for x in dataSet.keys()]) | values=",".join([""" %s """%self.ZSQLQuote(dataSet[x]) for x in dataSet.keys()]) |
| Line 313 class ZSQLExtendFolder(Folder,Persistent | Line 364 class ZSQLExtendFolder(Folder,Persistent |
| self.ZSQLSimpleSearch(queryStr) | self.ZSQLSimpleSearch(queryStr) |
| logger("update xml",logging.INFO,queryStr) | logger("update xml",logging.INFO,queryStr) |
| return ret | return ret |
| def importXMLFile(self,table,data=None,identify=None,filename=None,RESPONSE=None): | def importXMLFileFMP(self,table,dsn=None,uploadfile=None,update_fields=None,id_field=None,sync_mode=False, |
| #TODO: finish importXMLFile | lc_names=True,keep_fields=False,ascii_db=False,replace=False,backup=False, |
| ''' | debug=False,log_to_response=False, |
| Import XML file into the table | redirect_url=None,RESPONSE=None): |
| @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("""<texts xmlns="http://emegir.info/xtf" xmlns:lem="http://emegir.info/lemma" >"""+node[1].toxml()+"</texts>") | |
| #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. | Import FileMaker XML file (FMPXMLRESULT format) into the table. |
| @param table: name of the table the xml shall be imported into | @param dsn: database connection string |
| @param data: xml data as bz2 string | @param table: name of the table the xml shall be imported into (may be comma-separated list) |
| @param filename: xmlfile filename | @param uploadfile: xmlfile file |
| @param update_fields: (optional) list of fields to update; default is to create all fields | @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 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 sync_mode: (optional) really synchronise, i.e. delete entries not in XML file |
| @param lc_names: (optional) lower case and clean up field names from XML | |
| @param keep_fields: (optional) don't add fields to SQL database | |
| @param ascii_db: (optional) assume ascii encoding in db | |
| @param replace: (optional) delete and re-insert data | |
| @param backup: (optional) create backup of old table (breaks indices) | |
| @param RESPONSE: (optional) | @param RESPONSE: (optional) |
| ''' | @param redirect_url: (optional) url for redirecting after the upload is done |
| from xml.dom.pulldom import parseString,parse | """ |
| import transaction | |
| ret = "" | |
| if data: | |
| data=bz2.decompress(base64.decodestring(data)) | |
| logger("fmpxml",logging.INFO,"received file") | |
| doc=parseString(data) | |
| logger("fmpxml",logging.INFO,"parsed file") | |
| elif filename: | |
| fh=file(filename) | |
| logger("fmpxml",logging.INFO,"reading file") | |
| doc=parse(fh) | |
| logger("fmpxml",logging.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 | |
| logger("fmpxml",logging.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 | |
| logger("fmpxml fieldnames:",logging.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: | |
| logger("fmpxml fieldname:",logging.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')) | |
| logger("fmpxml add field:",logging.INFO,qstr%(table,fieldName,'text')) | |
| # ROW tags (in RESULTSET tag) hold data | tfilehd,filename=tempfile.mkstemp() |
| elif node[1].nodeName == 'ROW': | tfile=os.fdopen(tfilehd,'w') |
| rowcnt += 1 | logging.info("importXMLFileFMP: importing %s"%uploadfile) |
| for c in uploadfile.read(): | |
| tfile.write(c) | |
| tfile.close() | |
| from importFMPXML import importFMPXML | |
| if not dsn: | |
| dsn=self.getConnectionObj().connection_string | |
| logging.debug("dsn: %s"%dsn) | |
| logging.debug("table: %s"%table) | |
| logging.debug("update_fields: %s"%update_fields) | |
| logging.debug("id_field: %s"%id_field) | |
| logging.debug("sync_mode: %s"%sync_mode) | |
| logging.debug("lc_names: %s"%lc_names) | |
| logging.debug("keep_fields: %s"%keep_fields) | |
| logging.debug("ascii_db: %s"%ascii_db) | |
| logging.debug("replace: %s"%replace) | |
| logging.debug("backup: %s"%backup) | |
| logging.debug("debug: %s"%debug) | |
| logging.debug("log_to_response: %s"%log_to_response) | |
| logging.debug("RESPONSE: %s"%repr(RESPONSE)) | |
| tablelist=table.split(',') | |
| logging.debug("tablelist: %s"%tablelist) | |
| #table=tables | |
| for t in tablelist : | |
| logging.debug("table: %s"%table) | |
| options=Options() | |
| options.dsn=dsn | |
| options.table=t | |
| options.filename=filename | |
| options.update_fields=update_fields | |
| options.id_field=id_field | |
| options.sync_mode=sync_mode | |
| options.lc_names=lc_names | |
| options.replace_table=replace | |
| options.keep_fields=keep_fields | |
| options.ascii_db=ascii_db | |
| options.replace_table=replace | |
| options.backup_table=backup | |
| options.debug=debug | |
| if RESPONSE and log_to_response: | |
| # set up logging to response as plain text | |
| logging.debug("Setting up logging to RESPONSE") | |
| RESPONSE.setHeader("Content-Type","text/plain; charset=utf-8") | |
| RESPONSE.write("Import FMPXML file...\n\n") | |
| RESPONSE.flush() | |
| loghandler = logging.StreamHandler(RESPONSE) | |
| if debug: | |
| loghandler.setLevel(logging.DEBUG) | |
| else: | |
| loghandler.setLevel(logging.INFO) | |
| logger = logging.getLogger('db.import.fmpxml') | |
| logger.addHandler(loghandler) | |
| options.use_logger_instance = logger | |
| doc.expandNode(node[1]) | try: |
| cols=node[1].getElementsByTagName('COL') | err = None |
| dataSet={} | importFMPXML(options) |
| i = 0 | logging.info("importXMLFileFMP: done") |
| # populate with data | except Exception, err: |
| for col in cols: | logging.error("Error importing: %s"%err) |
| data=col.getElementsByTagName('DATA') | |
| dataSet[fieldNames[i]] = getTextFromNode(data[0]) | |
| i += 1 | |
| update=False | if RESPONSE and log_to_response: |
| loghandler.flush() | |
| if err is not None: | |
| RESPONSE.write("\n\nERROR while importing: %s"%err) | |
| else: | |
| RESPONSE.write("\n\n DONE!") | |
| # synchronize by id_field | elif RESPONSE and redirect_url: |
| if id_field: | RESPONSE.redirect(redirect_url) |
| id_val=dataSet[id_field] | |
| if id_val in dbIDs: | |
| dbIDs[id_val] += 1 | |
| update=True | |
| if update: | os.remove(filename) |
| # 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) | |
| #logger("fmpxml update:",logging.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) | |
| #logger("fmpxml: insert",logging.INFO,queryStr) | |
| ret+="ad: %s \n"%dataSet.get(id_field, rowcnt) | |
| #logger("fmpxml row:",logging.INFO,"%d (%s)"%(rowcnt,id_val)) | |
| if (rowcnt % 10) == 0: | |
| logger("fmpxml row:",logging.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: | |
| logger("fmpxml delete:",logging.INFO,id) | |
| qstr = "DELETE FROM %s WHERE %s = '%s'" | |
| self.ZSQLSimpleSearch(qstr%(table,id_field,id)) | |
| elif dbIDs[id] > 1: | |
| logger("fmpxml sync:",logging.INFO,"id used more than once?"+id) | |
| transaction.commit() | def generateIndex(self,field,index_name,table,RESPONSE=None): |
| """erzeuge ein Index Objekt einem Feld (experimental) | |
| @param field: Feldname zu dem ein Index erzeugt werden soll | |
| @param index_name: Name des Index | |
| @param table: Tabellen name""" | |
| return ret | |
| def generateIndex(self,field,index_name,table,RESPONSE=None): | |
| """erzeuge index aus feld""" | |
| index={} | index={} |
| founds=self.ZSQLSimpleSearch("""SELECT %s,oid FROM %s LIMIT 2000"""%(field,table)) | founds=self.ZSQLSimpleSearch("""SELECT %s,oid FROM %s """%(field,table)) |
| for found in founds: | for found in founds: |
| tmp=getattr(found,field,None) | tmp=getattr(found,field,None) |
| Line 572 class ZSQLExtendFolder(Folder,Persistent | Line 498 class ZSQLExtendFolder(Folder,Persistent |
| self._getOb(index_name).setIndex(index) | self._getOb(index_name).setIndex(index) |
| def getIndex(self,index_name): | def getIndex(self,index_name): |
| """getIndex""" | """getIndex from index_name |
| return an indexObject with index_name | |
| """ | |
| founds=self.ZopeFind(self,obj_ids=[index_name]) | founds=self.ZopeFind(self,obj_ids=[index_name]) |
| return founds[0][1].getIndex() | 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): | def URLquote(self,txt): |
| """urlquote""" | """urlquote |
| @param txt: text der urlgequoted werden soll. | |
| """ | |
| return urllib.quote(txt) | return urllib.quote(txt) |
| def createIdSet(self, resultset, idField=None): | |
| """returns a (frozen)set of IDs from a SQL-resultset (using idField) or a list (if idField=None)""" | |
| logging.debug("createidset for idfield %s"%idField) | |
| if idField is None: | |
| return frozenset(resultset) | |
| else: | |
| idlist = [r[idField] for r in resultset] | |
| return frozenset(idlist) | |
| def opIdSet(self, a, b, op): | |
| """operate on sets a and b""" | |
| logging.debug("opidset with op %s"%op) | |
| if (op == 'intersect'): | |
| return a.intersection(b) | |
| elif (op == 'union'): | |
| return a.union(b) | |
| elif (op == 'diff'): | |
| return a.difference(b) | |
| def searchRel(self,relStatement,statement,wherePart,classes): | def searchRel(self,relStatement,statement,wherePart,classes): |
| """suche relative haufigkeiten""" | """suche relative haufigkeiten (experimental)""" |
| ret={} | ret={} |
| allRecords=len(self.ZSQLSimpleSearch(statement + " where "+wherePart)) | allRecords=len(self.ZSQLSimpleSearch(statement + " where "+wherePart)) |
| Line 601 class ZSQLExtendFolder(Folder,Persistent | Line 545 class ZSQLExtendFolder(Folder,Persistent |
| return (ret,allRecords) | return (ret,allRecords) |
| def content_html(self): | def content_html(self): |
| """template fuer content""" | """template fuer content_html Aufruf, notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt""" |
| try: | try: |
| obj=getattr(self,"ZSQLBibliography_template") | obj=getattr(self,"ZSQLBibliography_template") |
| Line 614 class ZSQLExtendFolder(Folder,Persistent | Line 558 class ZSQLExtendFolder(Folder,Persistent |
| def getWeight(self): | def getWeight(self): |
| """getLabe""" | """getWeight, gewicht notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt""" |
| try: | try: |
| return self.weight | return self.weight |
| except: | except: |
| return "" | return "" |
| def getLabel(self): | def getLabel(self): |
| """getLabe""" | """getLabel notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt""" |
| try: | try: |
| return self.label | return self.label |
| except: | except: |
| return "" | return "" |
| def getDescription(self): | def getDescription(self): |
| """getLabe""" | """getDEscription: notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt""" |
| try: | try: |
| return self.description | return self.description |
| except: | except: |
| Line 644 class ZSQLExtendFolder(Folder,Persistent | Line 588 class ZSQLExtendFolder(Folder,Persistent |
| return pt() | return pt() |
| def changeZSQLExtend(self,label,description,weight=0,REQUEST=None,connection_id=None): | def changeZSQLExtend(self,label,description,weight=0,connection_id=None,autocommit=None,REQUEST=None,): |
| """change it""" | """change the Konfiguration""" |
| self.connection_id=connection_id | self.connection_id=connection_id |
| self.weight=weight | self.weight=weight |
| self.label=label | self.label=label |
| self.description=description | self.description=description |
| self.autocommit = (autocommit == "on") | |
| if REQUEST is not None: | if REQUEST is not None: |
| return self.manage_main(self, REQUEST) | return self.manage_main(self, REQUEST) |
| def formatAscii(self,str,url=None): | def formatAscii(self,str,url=None): |
| """ersetze ascii umbrueche durch <br>""" | """ersetze ascii umbrueche durch <br> |
| #url=None | @param str: string der Formatiert werden soll. |
| @param url: (optional) default ist "None", sonderfall erzeugt einen Link aus String mit unterliegender url | |
| """ | |
| #logging.debug("formatascii str=%s url=%s"%(repr(str),repr(url))) | |
| if not str: | |
| return "" | |
| str=str.rstrip().lstrip() | str=str.rstrip().lstrip() |
| if url and str: | if url and str: |
| Line 670 class ZSQLExtendFolder(Folder,Persistent | Line 622 class ZSQLExtendFolder(Folder,Persistent |
| retStr+="""<a href="%s">%s</a><br/>"""%(strUrl,word) | retStr+="""<a href="%s">%s</a><br/>"""%(strUrl,word) |
| str=retStr | str=retStr |
| if str: | if str: |
| return re.sub(r"[\n]","<br/>",str) | retStr = re.sub(r"[\n]","<br/>",str) |
| #logging.debug("formatascii out=%s"%(repr(retStr))) | |
| return retStr | |
| else: | else: |
| return "" | return "" |
| Line 712 class ZSQLExtendFolder(Folder,Persistent | Line 666 class ZSQLExtendFolder(Folder,Persistent |
| """oinly for demo""" | """oinly for demo""" |
| return os.path.splitext(path)[0]+".jpg" | return os.path.splitext(path)[0]+".jpg" |
| def ZSQLisEmpty(self,field): | def ZSQLisEmpty(self,str): |
| """Teste ob Treffer leer""" | """Teste ob String leer bzw. none ist. |
| """ | |
| #print "field",field | #print "field",field |
| if not field: | if not str: |
| return 1 | return 1 |
| if field.strip()=="": | if str.strip()=="": |
| return 1 | return 1 |
| return 0 | return 0 |
| def ZSQLMultiSearch(self,_table,_searchField,_value,_idField,_additionalStatement="",_select=None,_subselectAddition="",_storename=None): | |
| """ | |
| Durchsucht in einer Tabelle "table" die Spalte "searchfield" nach dem allen Vorkommnissen | |
| von Worten in value und gibt alle Werte mit gleichem id field zurueck, d.h. es wird die "und" suche ueber mehrere Eintrsege in einer | |
| Tabelle mit gleichem idField werd realisiert, | |
| z.B. fuer simplesearch ueber mehrere Felder | |
| @param _table: Tabelle, die durchsucht werden soll. | |
| @param _searchField: Feld, das durchsucht wird | |
| @param _value: String der gesucht werden soll, gesucht wird nach allen Worten des Strings, die durch " "-getrennt sind. | |
| @param _idField: Feld mit id fuer die identifikation gleicher Eintraege | |
| @param _additionalStatement: (optional) Zusaetzliches SQL Statement, dass zwischen dem ersten "select from" und dem ersten "where" eingegefuegt wird. | |
| @param _subselectAddition: (optiona) Zusaetliche SQL Statement die hinter das select statement der subselects eingefuegt werde. | |
| @param _select: (optional) Alternativer Wert fuer den ersten SELECT Aufruf. | |
| @param _storename: (optional) Name fuer die Zwischenspeicherung von Werten in der Session | |
| """ | |
| if _storename: | |
| """store""" | |
| else: | |
| _storename="foundCount" | |
| queries=[] | |
| #baue jede einzelne abfrage | |
| splitted=_value.split(" ") | |
| if not _select: | |
| _select=_idField | |
| query="select %s from %s %s where lower(%s) like '%%%s%%'"%(_select,_table,_additionalStatement,_searchField,splitted[0].lower()) | |
| if len(splitted)>1: # mehr als ein Wort | |
| query+=" and %s in"%_idField # dann einschraenken | |
| for v in splitted[1:]: | |
| queries.append("select %s from %s %s where lower(%s) like '%%%s%%'"%(_idField,_table,_subselectAddition,_searchField,v.lower())) | |
| intersect=" intersect ".join(queries) # nun baue sie zusammen | |
| query+="(%s)"%intersect | |
| logging.info("ZSQLSimple: %s"%query) | |
| retT=self.ZSQLSimpleSearch(query) | |
| logging.info("ZSQLSimple: %s"%retT) | |
| #das Ergebis enthaelt unter u.U. eine id mehrfach, dieses wir jetzt vereinheitlicht. | |
| retFinalT={} | |
| for x in retT: | |
| split=_idField.split(".") | |
| if len(split)>1: | |
| f=split[1] | |
| else: | |
| f=_idField | |
| retFinalT[getattr(x,f)]=x | |
| ret=list(retFinalT.values()) | |
| #aus Kompatibilaetsgruenen mit ZSQLSearch / ZSQLInlineSeach noch einzelne Felder in der SESSION belegen. | |
| if not self.REQUEST.SESSION.has_key(_storename): | |
| self.REQUEST.SESSION[_storename]={} | |
| self.REQUEST.SESSION[_storename]['searchFieldsOnly']={} | |
| self.REQUEST.SESSION[_storename]['qs']=query | |
| return ret | |
| def ZSQLsearchOptions(self,fieldname=""): | def ZSQLsearchOptions(self,fieldname=""): |
| """return HTML Fragment with search options""" | """return HTML Fragment with search options""" |
| Line 733 class ZSQLExtendFolder(Folder,Persistent | Line 753 class ZSQLExtendFolder(Folder,Persistent |
| return ret | return ret |
| def ZSQLSelectionFromCRList(self,fieldname,listField,boxType="checkbox",checked=None): | def ZSQLSelectionFromCRList(self,fieldname,listField,boxType="checkbox",checked=None): |
| """generate select options from a cr seperated list""" | """generate selection HTML Fragemnt from a cr seperated list |
| @param fieldname: Wert fuer das "name"-Attribute der erzeugten input-Tags | |
| @param listField: "cr" (\n) getrennte Liste der Werte | |
| @param boxType: (optional) default ist "checkbox", moegliche Werte "checkbox" und "radio" | |
| @param checked: "cr" getrennt Liste von Werten aus listField, die als ausgewahlt markiert werden sollen. | |
| """ | |
| fields=listField.split("\n") | fields=listField.split("\n") |
| ret="" | ret="" |
| for field in fields: | for field in fields: |
| Line 744 class ZSQLExtendFolder(Folder,Persistent | Line 769 class ZSQLExtendFolder(Folder,Persistent |
| return ret | return ret |
| def ZSQLSelectionFromSearchList(self,fieldname,results,fieldnameResult,boxType="checkbox",checked=None): | def ZSQLSelectionFromSearchList(self,fieldname,results,fieldnameResult,boxType="checkbox",checked=None): |
| """generate select options from a cr seperated list""" | """generate select options from research-results Objekt |
| generate selection HTML Fragemnt from a cr seperated list | |
| @param fieldname: Wert fuer das "name"-Attribute der erzeugten input-Tags | |
| @param results: result Object einer SQL-suche | |
| @param fieldNameResult: Feldname des Resultobjekts, das angezeigt werden soll. | |
| @param boxType: (optional) default ist "checkbox", moegliche Werte "checkbox" und "radio" | |
| @param checked: "cr" getrennt Liste von Werten aus results.fieldNameResult, die als ausgewahlt markiert werden sollen. | |
| """ | |
| ret="" | ret="" |
| if not results: return "" | if not results: return "" |
| Line 784 class ZSQLExtendFolder(Folder,Persistent | Line 816 class ZSQLExtendFolder(Folder,Persistent |
| ret+="""</select>""" | ret+="""</select>""" |
| return ret | return ret |
| def ZSQLOptionsFromSearchList(self,fieldname,results,fieldName,valueName=None,start=None, multiple='',startValue=None,additionalSelect="",size=None,linelen=None,selected=None): | def ZSQLOptionsFromSearchList(self,fieldname, |
| results,fieldName, | |
| valueName=None,start=None, | |
| multiple='',startValue=None, | |
| additionalSelect="",size=None, | |
| linelen=None,selected=None, | |
| clear=False): | |
| """generate select options form a search list | """generate select options form a search list |
| es wird | es wird |
| <select name=fieldname mutiple> | <select name=fieldname mutiple> |
| Line 792 class ZSQLExtendFolder(Folder,Persistent | Line 830 class ZSQLExtendFolder(Folder,Persistent |
| <option value=result.fieldName>result.fieldValue</option> | <option value=result.fieldName>result.fieldValue</option> |
| erzeugt. | erzeugt. |
| @parameter fieldname: Name fuer name-wert im select-tag | @param fieldname: Name fuer name-wert im select-tag |
| @results results: Resultobject einer SQL-suche | @param results: Resultobject einer SQL-suche |
| @parameter fieldName: Name des Feldes, das als value in den option-tag geschrieben werden soll. | @param fieldName: Name des Feldes, das als value in den option-tag geschrieben werden soll. |
| @parameter valueName: (optional) Name des Feldes, dass als im option-tag ausgegeben wird, default wert ist valueName=fieldName | @param valueName: (optional) Name des Feldes, dass als im option-tag ausgegeben wird, default wert ist valueName=fieldName |
| @start: (optional) falls zusaetzliches option tag erzeugt werden soll, gibt start an was im option tag steht | @param start: (optional) falls zusaetzliches option tag erzeugt werden soll, gibt start an was im option tag steht |
| @startValue: gibt den entsprechenden Wert an. | @param startValue (optional): gibt den entsprechenden Wert an. |
| @linelen: (optional) maximale laenge eines Eintrages | @param selected (optional): Wert der ausgewaehlt sein soll. |
| @param linelen: (optional) maximale laenge eines Eintrages | |
| der im Klappmenue noch angezeigt wird, laengeres wird abgeschnitten. | der im Klappmenue noch angezeigt wird, laengeres wird abgeschnitten. |
| @param addionalSaelect (optional): zusaetzlicher text fuer den select tag | |
| @param clear (optional): setze auf den startwert. | |
| """ | """ |
| if not valueName: | if not valueName: |
| valueName=fieldName | valueName=fieldName |
| Line 816 class ZSQLExtendFolder(Folder,Persistent | Line 857 class ZSQLExtendFolder(Folder,Persistent |
| if not startValue: | if not startValue: |
| startValue=start | startValue=start |
| if clear: | |
| ret+="""<option selected value="%s" >%s</option>"""%(startValue,start) | |
| else: | |
| ret+="""<option value="%s" >%s</option>"""%(startValue,start) | ret+="""<option value="%s" >%s</option>"""%(startValue,start) |
| for result in results: | for result in results: |
| field=getattr(result,fieldName) | field=getattr(result,fieldName) |
| fieldValue=getattr(result,valueName) | fieldValue=getattr(result,valueName) |
| if fieldValue: | if linelen and fieldValue and (len(fieldValue) > string.atoi(linelen)): |
| displayValue = fieldValue[:string.atoi(linelen)] | |
| if not linelen: | else: |
| displayValue = fieldValue | |
| if displayValue: #show only if value not none | |
| if field == selected: | if field == selected: |
| ret+="""<option value="%s" selected>%s</option>"""%(field,fieldValue) | ret+="""<option value="%s" selected>%s</option>"""%(field,displayValue) |
| else: | else: |
| ret+="""<option value="%s">%s</option>"""%(field,fieldValue) | ret+="""<option value="%s">%s</option>"""%(field,displayValue) |
| else: | |
| mist = """%s"""%(fieldValue) | |
| if len(mist) > string.atoi(linelen): | |
| mist = mist[:string.atoi(linelen)] | |
| ret+="""<option value="%s">%s</option>"""%(field,mist) | |
| ret+="""</select>""" | ret+="""</select>""" |
| return ret | return ret |
| Line 892 class ZSQLExtendFolder(Folder,Persistent | Line 933 class ZSQLExtendFolder(Folder,Persistent |
| def ZSQLInlineSearch(self,storename=None,args=None,**argv): | def ZSQLInlineSearch(self,storename=None,args=None,**argv): |
| """inlinesearch""" | """inlinesearch""" |
| #logging.debug("ZSQLInlineSearch args=%s argv=%s"%(args,argv)) | |
| qs=[] | qs=[] |
| if storename: | if storename: |
| """store""" | """store""" |
| else: | else: |
| storename="foundCount" | storename="foundCount" |
| if args: | if args: |
| argTmp=args | argTmp=args |
| else: | else: |
| Line 914 class ZSQLExtendFolder(Folder,Persistent | Line 953 class ZSQLExtendFolder(Folder,Persistent |
| if type(argTmp[a]) is ListType: # ein parameter zweimal | if type(argTmp[a]) is ListType: # ein parameter zweimal |
| value="" | value="" |
| #TODO find a better solution, currently only the last non empty entry is used. | #TODO find a better solution, currently only the last non empty entry is used. |
| for x in argTmp[a]: | #for x in argTmp[a]: |
| if x: | # if x: |
| value=x | # value=x |
| # version: join with spaces (makes sense with checkbox and -op=all) | |
| value = " ".join(argTmp[a]) | |
| else: | else: |
| try: | |
| value=str(argTmp[a]) | value=str(argTmp[a]) |
| qs.append(aFiltered+"="+urllib.quote(value)) | except: |
| value=utf8ify(argTmp[a]) | |
| qs.append(aFiltered+"="+urllib.quote(value)) | |
| #logging.debug("InlineSearch:"+string.join(qs,",")) | |
| #return [] | #return [] |
| Line 945 class ZSQLExtendFolder(Folder,Persistent | Line 990 class ZSQLExtendFolder(Folder,Persistent |
| except: | except: |
| logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2]) | logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2]) |
| def ZSQLSimpleSearch(self,query=None,max_rows=1000000): | def ZSQLSimpleSearch(self,query=None,max_rows=1000000): |
| """simple search""" | """new simple search""" |
| logging.debug("new ZSQLSimpleSearch X %s"%query) | |
| # get Connection instance | |
| con = self.getConnectionObj() | |
| # call to get db object | |
| dbc = con() | |
| if getattr(self, 'autocommit', False): | |
| # force transaction isolation level (for psycopg2 0=autocommit) | |
| logging.debug(" old tilevel="+dbc.tilevel) | |
| dbc.tilevel = 0 | |
| # modified code from ZPsycopgDA.db without _register: | |
| c = dbc.getcursor() | |
| desc = () | |
| r = [] | |
| try: | |
| try: | |
| c.execute(qs) | |
| except psycopg2.OperationalError: | |
| #logging.exception("Operational error on connection, closing it.") | |
| try: | |
| # Only close our connection | |
| dbc.putconn(True) | |
| except: | |
| #logging.debug("Something went wrong when we tried to close the pool", exc_info=True) | |
| pass | |
| if c.description is not None: | |
| if max_rows: | |
| r = c.fetchmany(max_rows) | |
| else: | |
| r = c.fetchall() | |
| desc = c.description | |
| dbc.failures = 0 | |
| except StandardError, err: | |
| raise err | |
| res = (dbc.convert_description(desc), r) | |
| else: | |
| # just use DA's query method | |
| res = dbc.query(query, max_rows=max_rows) | |
| # return result set as Result object with Brains | |
| return Results(res) | |
| def oldZSQLSimpleSearch(self,query=None,max_rows=1000000): | |
| """simple search""" | |
| logging.error("ZSQLSimpleSearch X %s"%query) | |
| #print query | #print query |
| if not query: | if not query: |
| query=self.query | query=self.query |
| Line 956 class ZSQLExtendFolder(Folder,Persistent | Line 1051 class ZSQLExtendFolder(Folder,Persistent |
| if (hasattr(self,"_v_searchSQL") and (self._v_searchSQL == None)) or (not hasattr(self,"_v_searchSQL")): | 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","<dtml-var var>") | self._v_searchSQL=Shared.DC.ZRDB.DA.DA("_v_searchSQL","_v_searchSQL",self.getConnectionObj().getId(),"var","<dtml-var var>") |
| #self._v_searchSQL=self.getConnectionObj()() | |
| self._v_searchSQL.max_rows_=max_rows | self._v_searchSQL.max_rows_=max_rows |
| #self._v_searchSQL.set_client_encoding('UNICODE') | |
| try: | try: |
| return self._v_searchSQL.__call__(var=query) | logging.error("I am here") |
| t=self._v_searchSQL.__call__(var=query) | |
| #t=self._v_searchSQL.query(query) | |
| logging.error("I am here %s"%t) | |
| return t | |
| except : | except : |
| logger("ZSQLSimpleSearch ERROR1",logging.ERROR, '%s %s'%sys.exc_info()[:2]) | |
| if sys.exc_info()[0]=="Database Error": | if sys.exc_info()[0]=="Database Error": |
| try: | try: |
| self.getConnectionObj().manage_open_connection() | self.getConnectionObj().manage_open_connection() |
| except: | except: |
| logger("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2]) | logger("ZSQLSimpleSearch ERROR2",logging.ERROR, '%s %s'%sys.exc_info()[:2]) |
| else: | else: |
| try: | try: |
| self._v_searchSQL.max_rows_=max_rows | self._v_searchSQL.max_rows_=max_rows |
| #self._v_searchSQL.set_client_encoding('UNICODE') | |
| return self._v_searchSQL.__call__(var=query) | return self._v_searchSQL.__call__(var=query) |
| #return self._v_searchSQL.query(query) | |
| except : | except : |
| logger("ZSQLSimpleSearch ERROR2",logging.ERROR, '%s %s'%sys.exc_info()[:2]) | |
| if sys.exc_info()[0]=="Database Error": | if sys.exc_info()[0]=="Database Error": |
| try: | try: |
| self.getConnectionObj().manage_open_connection() | self.getConnectionObj().manage_open_connection() |
| Line 1012 class ZSQLExtendFolder(Folder,Persistent | Line 1115 class ZSQLExtendFolder(Folder,Persistent |
| def ZSQLAdd(self,format=None,RESPONSE=None,args=None,**argv): | def ZSQLAdd(self,format=None,RESPONSE=None,args=None,_useRequest=True,**argv): |
| """Neuer Eintrag""" | """Neuer Eintrag""" |
| if args: | if args: |
| Line 1022 class ZSQLExtendFolder(Folder,Persistent | Line 1125 class ZSQLExtendFolder(Folder,Persistent |
| qs_temp=[] | qs_temp=[] |
| if _useRequest: | |
| for a in self.REQUEST.form.keys(): | for a in self.REQUEST.form.keys(): |
| qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a]))) | qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a]))) |
| Line 1038 class ZSQLExtendFolder(Folder,Persistent | Line 1142 class ZSQLExtendFolder(Folder,Persistent |
| addList={} | addList={} |
| for q in qs.split(","): | for q in qs.split(","): |
| if len(q.split("="))<2: | |
| continue | |
| name=re.sub("r'+'"," ",q.split("=")[0].lower()) | name=re.sub("r'+'"," ",q.split("=")[0].lower()) |
| value=q.split("=")[1] | value=q.split("=")[1] |
| value=re.sub(r'\+'," ",value) | value=re.sub(r'\+'," ",value) |
| value=urllib.unquote(value) | value=urllib.unquote(value) |
| Line 1107 class ZSQLExtendFolder(Folder,Persistent | Line 1214 class ZSQLExtendFolder(Folder,Persistent |
| table=urllib.unquote(value) | table=urllib.unquote(value) |
| elif name=="-identify": | elif name=="-identify": |
| identify=urllib.unquote(value) | identify=urllib.unquote(value) |
| identify=identify.split("=")[0]+"="+sql_quote(identify.split("=")[1]) | # old code did identify with lower() which doesn't work for oids |
| #identify="lower("+identify.split("=")[0]+")="+sql_quote(identify.split("=")[1].lower()) | |
| (k,v) = identify.split("=") | |
| identify="%s=%s"%(k,sql_quote(v)) | |
| elif name=="-format": | elif name=="-format": |
| format=urllib.unquote(value) | format=urllib.unquote(value) |
| #elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0): | #elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0): |
| Line 1132 class ZSQLExtendFolder(Folder,Persistent | Line 1242 class ZSQLExtendFolder(Folder,Persistent |
| return True | return True |
| def ZSQLFindIndexed(self,qs="",select="oid,*",storename=None,indexedFields=['data_line'],restrictField='id_text',**argv): | def ZSQLFindIndexed(self,tableList=[],qs="",select="oid,*",storename=None,indexedFields=['data_line'],restrictField='id_text',**argv): |
| """find2""" | """find2""" |
| for index in self.ZopeFind(self,obj_ids=indexedFields): | for index in self.ZopeFind(self,obj_ids=indexedFields): |
| Line 1159 class ZSQLExtendFolder(Folder,Persistent | Line 1269 class ZSQLExtendFolder(Folder,Persistent |
| """search in database""" | """search in database""" |
| def delEmpty(list): | def delEmpty(list): |
| """"loesche leere elemente aus der liste""" | """loesche leere elemente aus der liste""" |
| ret=[] | ret=[] |
| for x in list: | for x in list: |
| splitted=x.split("=") | splitted=x.split("=") |
| Line 1218 class ZSQLExtendFolder(Folder,Persistent | Line 1328 class ZSQLExtendFolder(Folder,Persistent |
| #print "calling Query with",repr(NoQuery) | #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) | 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"] | #print self.REQUEST.SESSION["foundCount"] |
| return ret | return ret |
| def ZSQLFoundCountLen(self,var): | def ZSQLFoundCountLen(self,var): |
| Line 1263 class ZSQLExtendFolder(Folder,Persistent | Line 1375 class ZSQLExtendFolder(Folder,Persistent |
| querys=qs.split(",") | querys=qs.split(",") |
| #which arguments are in the old query string | #which arguments are in the old query string |
| queryList={} | queryList={} |
| for query in querys: | for query in querys: |
| arg=query.split("=")[0] | arg=query.split("=")[0] |
| if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_" | if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_" |
| queryList[arg]=query.split("=")[1] | try: |
| queryList[arg]=urllib.unquote_plus(query.split("=")[1]) | |
| except: | |
| queryList[arg]='' | |
| argList=[] | argList=[] |
| arg="" | arg="" |
| #gehe durch die zu aendernden Argumente | #gehe durch die zu aendernden Argumente |
| for argTmp in argv.keys(): | for argTmp in argv.keys(): |
| arg=argTmp[0:]# sicherstellen, dass der string auh kopiert wird | arg=argTmp[0:]# sicherstellen, dass der string auh kopiert wird |
| if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_" | if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_" |
| Line 1291 class ZSQLExtendFolder(Folder,Persistent | Line 1400 class ZSQLExtendFolder(Folder,Persistent |
| return str | return str |
| def parseQueryString(self,qs,iCT,storemax="no",select=None,nostore=None,storename="foundCount",tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None): | def parseQueryString(self,qs,iCT,storemax="no",select=None,nostore=None,storename="foundCount",tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None): |
| """analysieren den QueryString""" | """analysieren den QueryString""" |
| logging.debug("parseQueryString qs=%s"%qs) | |
| #setzte generische werte | #setzte generische werte |
| Line 1315 class ZSQLExtendFolder(Folder,Persistent | Line 1425 class ZSQLExtendFolder(Folder,Persistent |
| searchFieldsOnly={} | searchFieldsOnly={} |
| queryTemplate=[] | queryTemplate=[] |
| outerjoin="" | outerjoin="" |
| debug=None | |
| if not select: | if not select: |
| select="oid,*" | select="oid,*" |
| Line 1333 class ZSQLExtendFolder(Folder,Persistent | Line 1444 class ZSQLExtendFolder(Folder,Persistent |
| for q in splitted: | for q in splitted: |
| name=re.sub("r'+'"," ",q.split("=")[0].lower()) | name=re.sub("r'+'"," ",q.split("=")[0].lower()) |
| if name=="_debug": | |
| debug=True | |
| try: | try: |
| value=urllib.unquote(q.split("=",1)[1]) | value=urllib.unquote(q.split("=",1)[1]) |
| except: | except: |
| Line 1440 class ZSQLExtendFolder(Folder,Persistent | Line 1554 class ZSQLExtendFolder(Folder,Persistent |
| #something is defined by _op_TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE | #something is defined by _op_TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE |
| elif (not name[0]==iCT) and len(punktsplit)==4: | elif (not name[0]==iCT) and len(punktsplit)==4: |
| if opfields.has_key(name): | if opfields.has_key(name): |
| op=opfields[name] | op=opfields[name] |
| else: | else: |
| op="ct" | op="ct" |
| namealt=name | namealt=name |
| name="LOWER("+punktsplit[1]+")" | name="LOWER("+punktsplit[1]+")" |
| value=value.lower() | value=value.lower() |
| Line 1468 class ZSQLExtendFolder(Folder,Persistent | Line 1584 class ZSQLExtendFolder(Folder,Persistent |
| elif op=="numerical": | elif op=="numerical": |
| term=analyseIntSearch(value) | term=analyseIntSearch(value) |
| tmp=(name+" "+term) | tmp=(namealt+" "+term) # take namealt without LOWER |
| elif op=="grep": | elif op=="grep": |
| tmp=(name+" ~* "+sql_quote(value)) | tmp=(name+" ~* "+sql_quote(value)) |
| elif op=="one": | elif op=="one": |
| Line 1480 class ZSQLExtendFolder(Folder,Persistent | Line 1596 class ZSQLExtendFolder(Folder,Persistent |
| op="all" | op="all" |
| if value!='': #lehre Werte werde nicht hinzugefuegt | |
| searchTmp="""%s in (select %s from %s where %s)"""%(punktsplit[3],punktsplit[2],punktsplit[0],tmp) | searchTmp="""%s in (select %s from %s where %s)"""%(punktsplit[3],punktsplit[2],punktsplit[0],tmp) |
| queryTemplate.append(searchTmp) | queryTemplate.append(searchTmp) |
| Line 1518 class ZSQLExtendFolder(Folder,Persistent | Line 1634 class ZSQLExtendFolder(Folder,Persistent |
| elif op=="numerical": | elif op=="numerical": |
| term=analyseIntSearch(value) | term=analyseIntSearch(value) |
| tmp=(name+" "+term) | tmp=(namealt+" "+term) # take namealt without LOWER |
| elif op=="grep": | elif op=="grep": |
| tmp=(name+" ~* "+sql_quote(value)) | tmp=(name+" ~* "+sql_quote(value)) |
| elif op=="one": | elif op=="one": |
| Line 1530 class ZSQLExtendFolder(Folder,Persistent | Line 1646 class ZSQLExtendFolder(Folder,Persistent |
| op="all" | op="all" |
| if (not tableExt) or (namealt.split('.')[0]==tableExt): | if (value!='') and ((not tableExt) or (namealt.split('.')[0]==tableExt)): #keine leeren werde und keine auschluss |
| if searchFields.has_key(namealt): | if searchFields.has_key(namealt): |
| searchFields[namealt]+=lopfields.get(name,'OR')+" "+tmp | searchFields[namealt]+=lopfields.get(name,'OR')+" "+tmp |
| searchFieldsOnly[namealt]+=lopfields.get(name,'OR')+" "+value | searchFieldsOnly[namealt]+=lopfields.get(name,'OR')+" "+value |
| Line 1616 class ZSQLExtendFolder(Folder,Persistent | Line 1732 class ZSQLExtendFolder(Folder,Persistent |
| self.REQUEST.SESSION[storename]['searchFieldsOnly']=searchFieldsOnly | self.REQUEST.SESSION[storename]['searchFieldsOnly']=searchFieldsOnly |
| if debug: | |
| logging.error("ZSQLSimpleSearch %s"%query) | |
| if not NoQuery: | if not NoQuery: |
| return self.ZSQLQuery(query) | return self.ZSQLQuery(query) |
| Line 1798 class ZSQLExtendFolder(Folder,Persistent | Line 1916 class ZSQLExtendFolder(Folder,Persistent |
| return "<a href='%s'>%s</a>"%(self.REQUEST['URL']+"?"+newquerystring,html) | return "<a href='%s'>%s</a>"%(self.REQUEST['URL']+"?"+newquerystring,html) |
| def pydev_settrace(self): | |
| """do settrace to start debugging""" | |
| import pydevd | |
| pydevd.settrace() | |
| manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals()) | manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals()) |
| Line 2111 def manage_addZSQLBibliography(self, id, | Line 2233 def manage_addZSQLBibliography(self, id, |