Diff for /ZSQLExtend/ZSQLExtend.py between versions 1.101 and 1.136

version 1.101, 2007/02/01 14:48:59 version 1.136, 2010/09/22 08:57:26
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
   
Line 19  import os.path Line 18  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 56  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 99  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 118  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 222  class ZSQLExtendFolder(Folder,Persistent Line 272  class ZSQLExtendFolder(Folder,Persistent
         for fieldName in fieldNames:          for fieldName in fieldNames:
             if type(fieldName) is UnicodeType:              if type(fieldName) is UnicodeType:
                 fieldName=fieldName.encode('utf-8')                  fieldName=fieldName.encode('utf-8')
             logging.LOG("update xml: fieldname",logging.INFO,repr(fieldName))                                   logging.info("update xml: fieldname",logging.INFO,repr(fieldName))                     
             if fieldName.lower() not in columns:              if fieldName.lower() not in columns:
                                   
                 if create:# table does not exist therefore create with one column                  if create:# table does not exist therefore create with one column
Line 232  class ZSQLExtendFolder(Folder,Persistent Line 282  class ZSQLExtendFolder(Folder,Persistent
                     qstr="""alter table %s add %s %s"""                      qstr="""alter table %s add %s %s"""
                                   
                 self.ZSQLSimpleSearch(qstr%(table,fieldName,'text'))                  self.ZSQLSimpleSearch(qstr%(table,fieldName,'text'))
                 logging.LOG("update xsd: fieldname add",logging.INFO,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):      def importXMLFileAccess(self,table,container,data=None,identify=None,filename=None,RESPONSE=None):
Line 246  class ZSQLExtendFolder(Folder,Persistent Line 296  class ZSQLExtendFolder(Folder,Persistent
         '''          '''
         from xml.dom.pulldom import parseString,parse          from xml.dom.pulldom import parseString,parse
                   
         logging.LOG("import xml",logging.INFO,"called")          logger("import xml",logging.INFO,"called")
         #fh=file("/tmp/fmpxml.xml")          #fh=file("/tmp/fmpxml.xml")
         import bz2          import bz2
         import base64          import base64
Line 255  class ZSQLExtendFolder(Folder,Persistent Line 305  class ZSQLExtendFolder(Folder,Persistent
         if data:          if data:
           data=bz2.decompress(base64.decodestring(data))            data=bz2.decompress(base64.decodestring(data))
                   
           logging.LOG("import xml",logging.INFO,"received file")            logger("import xml",logging.INFO,"received file")
           doc=parseString(data)            doc=parseString(data)
           logging.LOG("import xml",logging.INFO,"parsed file")            logger("import xml",logging.INFO,"parsed file")
   
         elif filename:          elif filename:
           fh=file(filename)            fh=file(filename)
           doc=parse(fh)            doc=parse(fh)
           logging.LOG("import xml",logging.INFO,"parsed file")            logger("import xml",logging.INFO,"parsed file")
         while 1:          while 1:
             node=doc.getEvent()              node=doc.getEvent()
   
Line 285  class ZSQLExtendFolder(Folder,Persistent Line 335  class ZSQLExtendFolder(Folder,Persistent
                         field=dataSet[identify]                          field=dataSet[identify]
   
                         searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field)                          searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field)
                         logging.LOG("import xml",logging.INFO,searchStr)                          logger("import xml",logging.INFO,searchStr)
                         search=self.ZSQLSimpleSearch(searchStr)                          search=self.ZSQLSimpleSearch(searchStr)
                         if search:                          if search:
                             update=True                              update=True
Line 299  class ZSQLExtendFolder(Folder,Persistent Line 349  class ZSQLExtendFolder(Folder,Persistent
                         field=dataSet[identify]                          field=dataSet[identify]
                                       
                         queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field)                          queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field)
                         logging.LOG("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()])
                                       
                                                   
                         queryStr="""INSERT INTO %s  (%s) VALUES (%s)"""%(table,fields,values)                          queryStr="""INSERT INTO %s  (%s) VALUES (%s)"""%(table,fields,values)
                         self.ZSQLSimpleSearch(queryStr)                          self.ZSQLSimpleSearch(queryStr)
                         logging.LOG("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)  
                         logging.LOG("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)  
                         logging.LOG("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)  
                         logging.LOG("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'))  
                       
                     logging.LOG("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:  
                         logging.LOG("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'))  
                             logging.LOG("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))  
             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          tfilehd,filename=tempfile.mkstemp()
             if node[1].nodeName == 'METADATA':          tfile=os.fdopen(tfilehd,'w')
                 doc.expandNode(node[1])          logging.info("importXMLFileFMP: importing %s"%uploadfile)
                       for c in uploadfile.read():
                 names=node[1].getElementsByTagName('FIELD')              tfile.write(c)
           tfile.close()  
                 for name in names:          
                     fn = name.getAttribute('NAME')          from importFMPXML import importFMPXML
                     fieldNames.append(fn)          
                           if not dsn:
                 if update_fields is None:              dsn=self.getConnectionObj().connection_string
                     # update all fields          
                     update_fields = fieldNames          logging.debug("dsn: %s"%dsn)
                           logging.debug("table: %s"%table)
                 zLOG.LOG("fmpxml fieldnames:",zLOG.INFO,repr(fieldNames))          logging.debug("update_fields: %s"%update_fields)
                 # get list of fields in db table          logging.debug("id_field: %s"%id_field)
                 qstr="""select attname from pg_attribute, pg_class where attrelid = pg_class.oid and relname = '%s'"""          logging.debug("sync_mode: %s"%sync_mode)
                 columns=[x.attname for x in self.ZSQLSimpleSearch(qstr%table)]          logging.debug("lc_names: %s"%lc_names)
                           logging.debug("keep_fields: %s"%keep_fields)
                 # adjust db table to fields in XML and fieldlist          logging.debug("ascii_db: %s"%ascii_db)
                 for fieldName in fieldNames:          logging.debug("replace: %s"%replace)
                     zLOG.LOG("fmpxml fieldname:",zLOG.INFO,repr(fieldName))                               logging.debug("backup: %s"%backup)
                     if (fieldName not in columns) and (fieldName in update_fields):          logging.debug("debug: %s"%debug)
                         qstr="""alter table %s add %s %s"""          logging.debug("log_to_response: %s"%log_to_response)
                         self.ZSQLSimpleSearch(qstr%(table,fieldName,'text'))          logging.debug("RESPONSE: %s"%repr(RESPONSE))
                         zLOG.LOG("fmpxml add field:",zLOG.INFO,qstr%(table,fieldName,'text'))  
                                   tablelist=table.split(',')
             # ROW tags (in RESULTSET tag) hold data          logging.debug("tablelist: %s"%tablelist)
             elif node[1].nodeName == 'ROW':          #table=tables
                 rowcnt += 1          
           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)  
                     #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()      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 496  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 543  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 556  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 586  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,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
Line 655  class ZSQLExtendFolder(Folder,Persistent Line 597  class ZSQLExtendFolder(Folder,Persistent
             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 619  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 663  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=="":          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 750  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 766  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 813  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 827  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.
           @param selected (optional): Wert der ausgewaehlt sein soll.
           @param linelen: (optional) maximale laenge eines Eintrages 
                       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 814  class ZSQLExtendFolder(Folder,Persistent Line 854  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 not linelen:  
   
               if linelen and fieldValue and (len(fieldValue) > string.atoi(linelen)):
                   displayValue = fieldValue[:string.atoi(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 896  class ZSQLExtendFolder(Folder,Persistent Line 937  class ZSQLExtendFolder(Folder,Persistent
         else:          else:
             storename="foundCount"              storename="foundCount"
                           
       
   
         if args:          if args:
             argTmp=args              argTmp=args
         else:          else:
Line 907  class ZSQLExtendFolder(Folder,Persistent Line 946  class ZSQLExtendFolder(Folder,Persistent
         #print "INLINE:",argv          #print "INLINE:",argv
         for a in argTmp.keys():          for a in argTmp.keys():
         aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_"          aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_"
         qs.append(aFiltered+"="+urllib.quote(str(argTmp[a])))  
                           
               if type(argTmp[a]) is ListType: # ein parameter zweimal
                       value=""
                       #TODO find a better solution, currently only the last non empty entry is used.
                       for x in argTmp[a]:
                           if x:
                               value=x
               else:
                  try:
                   value=str(argTmp[a])
                  except:
                   value=utf8ify(argTmp[a])
                   
               qs.append(aFiltered+"="+urllib.quote(value))
               logging.debug("InlineSearch:"+string.join(qs,","))
                                   
         #return []            #return []  
   
Line 927  class ZSQLExtendFolder(Folder,Persistent Line 979  class ZSQLExtendFolder(Folder,Persistent
         try:          try:
             self.getConnectionObj().manage_close_connection()              self.getConnectionObj().manage_close_connection()
         except:          except:
             logging.LOG("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2])              logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2])
         try:          try:
             self.getConnectionObj().manage_open_connection()              self.getConnectionObj().manage_open_connection()
         except:          except:
             logging.LOG("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"""          """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 944  class ZSQLExtendFolder(Folder,Persistent Line 996  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:
                         logging.LOG("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()
                     except:                      except:
                         logging.LOG("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2])                          logger("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2])
   
     def getConnectionObj(self):      def getConnectionObj(self):
         if hasattr(self,'connection_id'):          if hasattr(self,'connection_id'):
Line 1000  class ZSQLExtendFolder(Folder,Persistent Line 1060  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 1010  class ZSQLExtendFolder(Folder,Persistent Line 1070  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 1026  class ZSQLExtendFolder(Folder,Persistent Line 1087  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 1055  class ZSQLExtendFolder(Folder,Persistent Line 1119  class ZSQLExtendFolder(Folder,Persistent
         else:          else:
             return True              return True
                   
     def ZSQLChange(self,format=None,RESPONSE=None,USE_FORM=None,**argv):      def ZSQLChange(self,format=None,RESPONSE=None,USE_FORM=None,args=None,**argv):
         """change entries"""          """change entries"""
         #qs=self.REQUEST['QUERY_STRING']          #qs=self.REQUEST['QUERY_STRING']
         # very bad hack          # very bad hack
Line 1067  class ZSQLExtendFolder(Folder,Persistent Line 1131  class ZSQLExtendFolder(Folder,Persistent
                 qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))                  qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))
   
                   
           if args:
               arg_tmp=args
           else:
               arg_tmp=argv
                   
         for field in argv.keys():          for field in arg_tmp.keys():
                                   
                    if field[0]=="_":                     if field[0]=="_":
                        fieldTmp="-"+field[1:]                         fieldTmp="-"+field[1:]
                    else:                     else:
                        fieldTmp=field                         fieldTmp=field
                                                 
                    qs_temp.append("%s=%s"%(fieldTmp,argv[field]))                     qs_temp.append("%s=%s"%(fieldTmp,arg_tmp[field]))
                   
                   
         changeList=[]          changeList=[]
                   logging.info("ZSQLChange qs_temp: %s"%repr(qs_temp))
         for q in qs_temp:          for q in qs_temp:
                 
             name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))              name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))
Line 1091  class ZSQLExtendFolder(Folder,Persistent Line 1159  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 1105  class ZSQLExtendFolder(Folder,Persistent Line 1176  class ZSQLExtendFolder(Folder,Persistent
         changeString=string.join(changeList,",")          changeString=string.join(changeList,",")
   
         queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)          queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)
         logging.LOG("ZSQLExtend",logging.INFO,"CHANGE: "+queryString)          logger("ZSQLExtend",logging.INFO,"CHANGE: "+queryString)
   
         self.ZSQLSimpleSearch(queryString)          self.ZSQLSimpleSearch(queryString)
                   
Line 1116  class ZSQLExtendFolder(Folder,Persistent Line 1187  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 1139  class ZSQLExtendFolder(Folder,Persistent Line 1210  class ZSQLExtendFolder(Folder,Persistent
           
               
           
     def ZSQLFind(self,qs="",select="oid,*",storename=None,tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None,**argv):      def ZSQLFind(self,qs="",select="oid,*",storename="foundCount",tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None,**argv):
         """search in database"""          """search in database"""
   
         def delEmpty(list):          def delEmpty(list):
Line 1191  class ZSQLExtendFolder(Folder,Persistent Line 1262  class ZSQLExtendFolder(Folder,Persistent
   
         qs=string.join(delEmpty(qs.split(",")),",")          qs=string.join(delEmpty(qs.split(",")),",")
   
         if storename:  
             """store"""  
         else:  
             storename="foundCount"  
   
         #store query for further usage          #store query for further usage
           #TODO: erste der beiden ist ueberfluessig
         self.REQUEST.SESSION['query']=qs          self.REQUEST.SESSION['query']=qs
           if not self.REQUEST.SESSION.has_key(storename):
                   self.REQUEST.SESSION[storename]={}
                   
           self.REQUEST.SESSION[storename]['qs']=qs
           
   
         #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"]
                   
Line 1210  class ZSQLExtendFolder(Folder,Persistent Line 1284  class ZSQLExtendFolder(Folder,Persistent
     def ZSQLFoundCountLen(self,var):      def ZSQLFoundCountLen(self,var):
         return len(var)          return len(var)
                           
     def ZSQLFoundCount(self,qs="",select="*",storename=None):      def ZSQLFoundCount(self,qs="",select="*",storename="foundCount"):
           
        ##  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']          return self.REQUEST.SESSION[storename]['count']
   
     def ZSQLRangeStart(self,storename=None):      def ZSQLRangeStart(self,storename="foundCount"):
           
         if storename:  
             """store"""  
         else:  
             storename="foundCount"  
                   
         return int(self.REQUEST.SESSION[storename]['rangeStart'])+1          return int(self.REQUEST.SESSION[storename]['rangeStart'])+1
           
     def ZSQLRangeSize(self,storename=None):      def ZSQLRangeSize(self,storename="foundCount"):
           
         if storename:  
             """store"""  
         else:  
             storename="foundCount"  
                           
         return self.REQUEST.SESSION[storename]['rangeSize']          return self.REQUEST.SESSION[storename]['rangeSize']
   
     def ZSQLRangeEnd(self,storename=None):      def ZSQLRangeEnd(self,storename="foundCount"):
           
         if storename:  
             """store"""  
         else:  
             storename="foundCount"  
                   
         return str(min(int(self.REQUEST.SESSION[storename]['rangeEnd']),int(self.REQUEST.SESSION[storename]['count'])))          return str(min(int(self.REQUEST.SESSION[storename]['rangeEnd']),int(self.REQUEST.SESSION[storename]['count'])))
   
     def ZSQLNewQuery(self,linkText,storename=None,**argv):      def ZSQLNewQuery(self,linkText,storename="foundCount",**argv):
         """suche neu"""          """suche neu"""
         return self.ZSQLNewSearch(linkText,storename,url=self.REQUEST['URL'],args=argv)          return self.ZSQLNewSearch(linkText,storename,url=self.REQUEST['URL'],args=argv)
           
     def ZSQLNewSearch(self,linkText,storename=None,url=None,args=None,**argv):      def ZSQLNewSearch(self,linkText,storename="foundCount",url=None,args=None,**argv):
         """suche mit alten parametern bis auf die in argv getauschten"""          """suche mit alten parametern bis auf die in argv getauschten"""
         str = self.ZSQLNewSearchURL(storename, url, args, **argv)          str = self.ZSQLNewSearchURL(storename, url, args, **argv)
         return """<a href="%s"> %s</a>"""%(str,linkText)          return """<a href="%s"> %s</a>"""%(str,linkText)
                   
   
     def ZSQLNewSearchURL(self, storename=None,url=None,args=None,**argv):      def ZSQLNewSearchURL(self, storename="foundCount",url=None,args=None,**argv):
         """suche mit alten parametern bis auf die in argv getauschten"""          """suche mit alten parametern bis auf die in argv getauschten"""
                   
         if storename:   
             """store"""    
         else:  
             storename="foundCount"  
         qs=self.REQUEST.SESSION[storename]['qs']  
   
         if args:          if args:
             argv=args              argv=args
                           
           #get the old queries
           qs=self.REQUEST.SESSION[storename]['qs']
         querys=qs.split(",")          querys=qs.split(",")
           
           #which arguments are in the old query string
           queryList={}
           for query in querys:
               arg=query.split("=")[0]
               if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_"
               try:
                   queryList[arg]=urllib.unquote_plus(query.split("=")[1])
               except:
                   queryList[arg]=''   
                   
         argList=[]          argList=[]
         arg=""          arg=""
         queryList=[x.split("=")[0] for x in querys]          #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
               if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_"            
                           
                           queryList[arg]=argv[argTmp]
             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:          if url:
             str=url+"?"+"&".join(newquery)              str=url+"?"+urllib.urlencode(queryList)
         else:          else:
             str="ZSQLSearch?"+"&".join(newquery)              str="ZSQLSearch?"+urllib.urlencode(queryList)
                   
         return str          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):      
       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"""
                   
                   
Line 1340  class ZSQLExtendFolder(Folder,Persistent Line 1369  class ZSQLExtendFolder(Folder,Persistent
         searchFields={}          searchFields={}
         searchFieldsOnly={}          searchFieldsOnly={}
         queryTemplate=[]          queryTemplate=[]
           outerjoin=""
           debug=None
                   
         if not select:          if not select:
             select="oid,*"              select="oid,*"
Line 1358  class ZSQLExtendFolder(Folder,Persistent Line 1389  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 1396  class ZSQLExtendFolder(Folder,Persistent Line 1430  class ZSQLExtendFolder(Folder,Persistent
                           
                       
             name=re.sub("r'+'"," ",q.split("=")[0].lower())              name=re.sub("r'+'"," ",q.split("=")[0].lower())
              
             try:              try:
                 value=urllib.unquote(q.split("=",1)[1])                  value=urllib.unquote(q.split("=",1)[1])
               
             except:              except:
                 value=""                  value=""
                           
Line 1425  class ZSQLExtendFolder(Folder,Persistent Line 1461  class ZSQLExtendFolder(Folder,Persistent
                 skip="OFFSET "+str(value)                  skip="OFFSET "+str(value)
                 rangeStart=str(value)                  rangeStart=str(value)
             elif name==iCT+"join":              elif name==iCT+"join":
                   
                 whereList.append(value)                  whereList.append(value)
               elif name==iCT+"outerjoin":
                   
                   outerjoin=value
             elif name==iCT+"sort":              elif name==iCT+"sort":
                 sortstrs=[]                  sortstrs=[]
            
                 for word in value.split(','):                  for word in value.split(','):
                     wordstr=word.lstrip().rstrip()                      wordstr=word.lstrip().rstrip()
                     if sortAllFields:                      if sortAllFields:
Line 1458  class ZSQLExtendFolder(Folder,Persistent Line 1499  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:
Line 1486  class ZSQLExtendFolder(Folder,Persistent Line 1528  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 1498  class ZSQLExtendFolder(Folder,Persistent Line 1540  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 1507  class ZSQLExtendFolder(Folder,Persistent Line 1549  class ZSQLExtendFolder(Folder,Persistent
   
                 #print "OP",op,name                  #print "OP",op,name
                 value=value.lower()                  value=value.lower()
                   
                 tmp=""                  tmp=""
                 if opfields.has_key(name):                  if opfields.has_key(name):
                     op=opfields[name]                      op=opfields[name]
Line 1535  class ZSQLExtendFolder(Folder,Persistent Line 1578  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 1547  class ZSQLExtendFolder(Folder,Persistent Line 1590  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 1580  class ZSQLExtendFolder(Folder,Persistent Line 1623  class ZSQLExtendFolder(Folder,Persistent
                                   
         #print "QE",table          #print "QE",table
         #print (select,table,where,sort,maxstr,skip)          #print (select,table,where,sort,maxstr,skip)
         query="SELECT %s FROM %s %s %s %s %s"%(select,table,where,sort,maxstr,skip)          query="SELECT %s FROM %s %s %s %s %s %s"%(select,table,outerjoin,where,sort,maxstr,skip)
   
         if not nostore=="yes":          if not nostore=="yes":
                           
             self.REQUEST.SESSION['qs']=opfields              self.REQUEST.SESSION['qs']=opfields
         #print "IAMHERE again:", query          #print "IAMHERE again:", query
   
         if storename and (not NoQuery):          if not NoQuery:
   
             query2="SELECT count(*) FROM %s %s"%(table,where)              query2="SELECT count(*) FROM %s %s"%(table,where)
                           
Line 1612  class ZSQLExtendFolder(Folder,Persistent Line 1655  class ZSQLExtendFolder(Folder,Persistent
   
                 self.REQUEST.SESSION[storename]['queryString2']=query2                  self.REQUEST.SESSION[storename]['queryString2']=query2
                 if self.ZSQLSimpleSearch(query2):                  if self.ZSQLSimpleSearch(query2):
           
                     self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count                      self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count
                 else:                  else:
                     self.REQUEST.SESSION[storename]['count']=0                      self.REQUEST.SESSION[storename]['count']=0
Line 1619  class ZSQLExtendFolder(Folder,Persistent Line 1663  class ZSQLExtendFolder(Folder,Persistent
                           
                           
             self.REQUEST.SESSION[storename]['rangeStart']=rangeStart              self.REQUEST.SESSION[storename]['rangeStart']=rangeStart
             if limit=="all":              
               
               self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count']
               
               if (limit=="all") or (limit==int(limit)):
                 self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count']                  self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count']
             else:              else:
                 self.REQUEST.SESSION[storename]['rangeEnd']=int(rangeStart)+int(limit)                  self.REQUEST.SESSION[storename]['rangeEnd']=int(rangeStart)+int(limit)
Line 1628  class ZSQLExtendFolder(Folder,Persistent Line 1676  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 1650  class ZSQLExtendFolder(Folder,Persistent Line 1700  class ZSQLExtendFolder(Folder,Persistent
     def ZSQLQuery(self,query,debug=None):      def ZSQLQuery(self,query,debug=None):
         """query"""          """query"""
         if debug:          if debug:
             logging.LOG("ZSQLQuery", logging.INFO, query)              logger("ZSQLQuery", logging.INFO, query)
                           
         return self.ZSQLSimpleSearch(query)          return self.ZSQLSimpleSearch(query)
   
Line 1712  class ZSQLExtendFolder(Folder,Persistent Line 1762  class ZSQLExtendFolder(Folder,Persistent
             limit=1              limit=1
             newRangeStart=0              newRangeStart=0
                           
         if newRangeStart>=self.REQUEST.SESSION[storename]['count']:          if (newRangeStart>=self.REQUEST.SESSION[storename]['count']) or (self.REQUEST.SESSION[storename]['count']==self.REQUEST.SESSION[storename]['rangeEnd']):
             #newRangeStart=self.REQUEST.SESSION[storename]['count']-1              #newRangeStart=self.REQUEST.SESSION[storename]['count']-1
             return ""              return ""
                   
Line 1810  class ZSQLExtendFolder(Folder,Persistent Line 1860  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):
     def prevLink_old(self,html):          """do settrace to start debugging"""
         """prev link"""          import pydevd
         if self.REQUEST['QUERY_STRING']=="":          pydevd.settrace()
             qs=self.REQUEST.SESSION['query']  
         else:  
             qs=self.REQUEST['QUERY_STRING']  
         max=re.search(r'max\=(.*)\,',qs.lower())  
         offset=re.search(r'offset\=(.*)\,',qs.lower())  
         if not offset:  
             offsetnew=0  
         else:  
             offsetnew=int(offset)-max  
             if offsetnew<0:  
                 offsetnew=0  
         queries=string.split(qs,",")  
         newquery=[]  
         if offset:  
             for query in queries:  
                 if query.split("=")[0].lower()=="offset":  
                     query="-offset=%i"%offsetnew  
                 newquery.append(query)  
                 newquerystring=string.join(newquery,"&")  
         else:  
             queries.append("-offset=%i"%offsetnew)  
             newquerystring=string.join(queries,"&")  
         return "<a href='%s'>%s</a>"%(self.actualPath()+"?"+newquerystring,html)  
           
     def nextLink_old(self,html):  
         """prev link"""  
         if self.REQUEST['QUERY_STRING']=="":  
             qs=self.REQUEST.SESSION['query']  
         else:  
             qs=self.REQUEST['QUERY_STRING']  
         max=re.search(r'max\=(.*)\,',qs.lower())  
       
         offset=re.search(r'offset\=(.*)\,',qs.lower())  
         if not offset:  
             offsetnew=1  
         else:  
             offsetnew=int(offset)+int(max)  
             if offsetnew<0:  
                 offsetnew=0  
         queries=string.split(qs,",")  
         newquery=[]  
         if offset:  
             for query in queries:  
   
                 if query.split("=")[0].lower()=="-offset":  
                     query="-offset=%i"%offsetnew  
                 newquery.append(query)  
                 newquerystring=string.join(newquery,"&")  
         else:  
             queries.append("-offset=%i"%offsetnew)  
             newquerystring=string.join(queries,"&")  
           
         return "<a href='%s'>%s</a>"%(self.actualPath()+"?"+newquerystring,html)  
                   
           
 manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals())  manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals())
Line 2180  def manage_addZSQLBibliography(self, id, Line 2177  def manage_addZSQLBibliography(self, id,
   
           
   
       
   

Removed from v.1.101  
changed lines
  Added in v.1.136


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>