File:  [Repository] / ZSQLExtend / ZSQLExtend.py
Revision 1.112: download - view: text, annotated - select for diffs - revision graph
Thu Apr 19 20:29:59 2007 UTC (17 years, 1 month ago) by dwinter
Branches: MAIN
CVS tags: HEAD
multsearch

from OFS.Folder import Folder
from Acquisition import Implicit
from Globals import DTMLFile,package_home,Persistent
import urllib
import re
import string
#from pyPgSQL import libpq
from AccessControl import getSecurityManager,Unauthorized
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from Products.PageTemplates.PageTemplateFile import PageTemplateFile

from Products.ZSQLMethods.SQL import SQLConnectionIDs
from xml.sax.saxutils import escape
from types import *
import Shared.DC.ZRDB.DA
import logging
import os.path
import os
import copy
import unicodedata
import tempfile
import sys

#ersetzt logging
def logger(txt,method,txt2):
    """logging""" 
    logging.info(txt+ txt2)


from OFS.SimpleItem import SimpleItem

def getTextFromNode(nodename):
    """get the cdata content of a node"""
    if nodename is None:
        return ""
    nodelist=nodename.childNodes
    rc = ""
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
           rc = rc + node.data
    return rc

def analyseIntSearch(word):
    #analyse integer searches

    splitted=word.split("-")

    if len(splitted)==1:
        return "="+splitted[0]
    
    if splitted[0]=="":
        return "< "+splitted[1]

    if splitted[1]=='':
        return "> "+splitted[0]
    else:
        return "BETWEEN "+splitted[0]+" AND "+splitted[1]

        

def sql_quote(v):
    # quote dictionary
    quote_dict = {"\'": "''", "\\": "\\\\"}
    for dkey in quote_dict.keys():
        if string.find(v, dkey) >= 0:
            v=string.join(string.split(v,dkey),quote_dict[dkey])
    return "'%s'" % v

def showSQLConnectionIDs(self):
    return SQLConnectionIDs(self)

class Options:
    """options class"""
    
class ZSQLIndex(SimpleItem):
    """index"""
    meta_type="ZSQLIndex"
    
    def __init__(self,index,id,table=''):
        self.index=[x for x in index]
        self.id=id
        self.table=table
        
    def setIndex(self,index):
        self.index=[x for x in index]
        
    def getIndex(self):
        return self.index

class ZSQLExtendFolder(Folder,Persistent, Implicit):
    """Folder"""
    meta_type="ZSQLExtendFolder"
    
    def ZSQLQuote(self,str):
        """quote str for sql"""
        return sql_quote(str)
    
    
    def normalizeField(self,table,fieldname, newFieldName=None,mode="alter", RESPONSE=None):
        """normalize a field"""
        import unicodedata
        
        if not newFieldName:
            newFieldName=fieldname+"_normal"
            
        def normal(str):
            if str:
                return unicodedata.normalize('NFKD', str.decode('utf-8')).encode('ASCII', 'ignore')
            else:
                return ""
        if mode=="create": # create the field
            qstr="""alter table %s add %s %s"""
            self.ZSQLSimpleSearch(qstr%(table,newFieldName,'text'))
        
        qstr="select oid,%s from %s"%(fieldname,table)
        for result in self.ZSQLSimpleSearch(qstr):
            qstr="update %s set %s = %s where oid = %s"

            self.ZSQLSimpleSearch(qstr%(table,newFieldName,self.ZSQLQuote(normal(getattr(result,fieldname))),result.oid))
        
    def importAccessModell(self,configFileName,RESPONSE=None):
        """import tables from access
        @param configFileName: xml-configfile
        """
        from Ft.Xml import Parse
        fh=file(configFileName)

        doc=Parse(fh)
        
        x=doc.xpath("//pathToFolder/@path")
        
        
        if not (len(x)==1): # tag ist nich eineindeutig
            return False
        
        pathToFolder=x[0].value
        
        for db in doc.xpath("//db"):
            
            containers=db.xpath("./@container")
            identifiers=db.xpath("./@identify")
            

            if not (len(containers)==1):
                return False
            else:
                container=containers[0].value
            
            if not (len(identifiers)==1):
                identifier=None
            else:
                identifier=identifiers[0].value
            
            self.xsdToTable(container.lower(),container,modus="drop",filename=os.path.join(pathToFolder,container.lower()+".xsd"))
            self.importXMLFileAccess(container.lower(),container,filename=os.path.join(pathToFolder,container.lower()+".xml"),identify=identifier)
            
        return "<html><body>DONE</body></html>"
     
    def xsdToTable(self,table,elementNameForTable,modus="update", filename=None,data=None,RESPONSE=None):
        """reads an xsd file an creates the columns of a table out of its structure
        @param table: name of the table the xml shall be imported into
        @param elementNameForTable: must be a element of type complex type. the element of the sequence in the complex type
                                    define the columns of the table >table<
        @param data (optional): data to be imported
    
        @param filename (optional) or filename
        @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes.
        @param RESPONSE: (optional)
 
        """
        #from xml.dom.minidom import parseString,parse
        
        from Ft.Xml import Parse
        logger("import xsd",logging.INFO,"called")
        #fh=file("/tmp/fmpxml.xml")
        import bz2
        import base64
        
        
        ret=""
        if data:
          data=bz2.decompress(base64.decodestring(data))
        
          #logger("import xsd",logging.INFO,"received file")
          doc=Parse(data)
          #logger("import xsd",logging.INFO,"parsed file")
        
        elif filename:
          fh=file(filename)
          txt=fh.read()
          
          doc=Parse(txt)
          #logger("import xsd",logging.INFO,"parsed file")
        
        
        Nss={'xsd':'http://www.w3.org/2001/XMLSchema'}
        definingSequence=doc.xpath("""//xsd:element[@name='%s']/xsd:complexType/xsd:sequence/xsd:element/@name"""%elementNameForTable,explicitNss=Nss)
        
        fieldNames=[x.value for x in definingSequence]
        
        
        
        #check if table exists
        
        qstr="""select relname from pg_class where relname = '%s'"""%table
        if not(self.ZSQLSimpleSearch(qstr)) or (len (self.ZSQLSimpleSearch(qstr))<1): # if not the create the table
            columns=[]
            create=True    
        else:
            create=False
            
            logger("update xsd: fieldnames",logging.INFO,repr(fieldNames))                       
            qstr="""select attname from pg_attribute, pg_class where attrelid = pg_class.oid and relname = '%s' """
            columns=[x.attname for x in self.ZSQLSimpleSearch(qstr%table)]            
        
        
        if (modus=="drop") and (not create): #table shall be deleted, therefore it should exist (not create)
            print "drop"
            qstr="""DROP TABLE %s """
            self.ZSQLSimpleSearch(qstr%table)
            columns=[]
            create=True
        
        for fieldName in fieldNames:
            if type(fieldName) is UnicodeType:
                fieldName=fieldName.encode('utf-8')
            logging.info("update xml: fieldname",logging.INFO,repr(fieldName))                     
            if fieldName.lower() not in columns:
                
                if create:# table does not exist therefore create with one column
                    qstr="""create table %s (%s %s)"""
                    create=False
                else:# otherwise add the field
                    qstr="""alter table %s add %s %s"""
                
                self.ZSQLSimpleSearch(qstr%(table,fieldName,'text'))
                logger("update xsd: fieldname add",logging.INFO,qstr%(table,fieldName,'text'))                       
   

    def importXMLFileAccess(self,table,container,data=None,identify=None,filename=None,RESPONSE=None):
        '''
        Import XML file in access format into the table
        @param table: name of the table the xml shall be imported into
        @param containerTagName: XML-Tag which describes a dataset
        @param data: data to be imported
        @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes.
        @param RESPONSE: (optional)
        '''
        from xml.dom.pulldom import parseString,parse
        
        logger("import xml",logging.INFO,"called")
        #fh=file("/tmp/fmpxml.xml")
        import bz2
        import base64
        
        ret=""
        if data:
          data=bz2.decompress(base64.decodestring(data))
        
          logger("import xml",logging.INFO,"received file")
          doc=parseString(data)
          logger("import xml",logging.INFO,"parsed file")

        elif filename:
          fh=file(filename)
          doc=parse(fh)
          logger("import xml",logging.INFO,"parsed file")
        while 1:
            node=doc.getEvent()

            if node is None:
                break;
            else:
                if node[1].nodeName.lower()==container.lower(): # make everything case insensitive
                    doc.expandNode(node[1])
                    
                    dataSet={}
                    for col in node[1].childNodes:
                        if col.nodeType is col.ELEMENT_NODE: 
                            data=col.nodeName
                            dataSet[data]=getTextFromNode(col)

                    update=False
                    
                    if identify:

                        field=dataSet[identify]

                        searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field)
                        logger("import xml",logging.INFO,searchStr)
                        search=self.ZSQLSimpleSearch(searchStr)
                        if search:
                            update=True
                    
                    if update:
                        tmp=[]
                        for fieldName in dataSet.keys():
                            tmp.append("""%s = %s"""%(fieldName,self.ZSQLQuote(dataSet[fieldName])))
                        setStr=",".join(tmp)

                        field=dataSet[identify]
                  
                        queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field)
                        logger("update xml",logging.INFO,queryStr)
                        self.ZSQLSimpleSearch(queryStr)
                        ret+="ud: %s \n"%field
                    else:

                       
                        fields=",".join(dataSet.keys())
                        values=",".join([""" %s """%self.ZSQLQuote(dataSet[x]) for x in dataSet.keys()])
                  
                        
                        queryStr="""INSERT INTO %s  (%s) VALUES (%s)"""%(table,fields,values)
                        self.ZSQLSimpleSearch(queryStr)
                        logger("update xml",logging.INFO,queryStr)
                        
                        
                        
          
        return ret
        
    
    def importXMLFile(self,table,containerTagName,fieldNames,data=None,identify=None,filename=None,RESPONSE=None):
        #TODO: finish importXMLFile
        '''
        Import XML file into the table
        @param table: name of the table the xml shall be imported into
        @param containerTagName: XML-Tag which describes a dataset
        @param file: xmlfile handle
        @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes.
        @param RESPONSE: (optional)
        '''
        ret=""
        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,dsn=None,uploadfile=None,update_fields=None,id_field=None,sync_mode=False,replace=False,redirect_url=None,ascii_db=False,RESPONSE=None):
        '''
        Import FileMaker XML file (FMPXMLRESULT format) into the table.
        @param dsn: database connection string
        @param table: name of the table the xml shall be imported into
        @param uploadfile: xmlfile file
        @param update_fields: (optional) list of fields to update; default is to create all fields
        @param id_field: (optional) field which uniquely identifies an entry for updating purposes.
        @param sync_mode: (optional) really synchronise, i.e. delete entries not in XML file
        @param RESPONSE: (optional)
        @param redirect_url: (optional) url for redirecting after the upload is done
        '''
        
        tfilehd,filename=tempfile.mkstemp()
        tfile=os.fdopen(tfilehd,'w')
        logging.error("import %s"%uploadfile)
        for c in uploadfile.read():
            tfile.write(c)
        tfile.close()  
        
        from importFMPXML import importFMPXML
        
        if not dsn:
            dsn=self.getConnectionObj().connection_string
            
        options=Options()
        options.dsn=dsn
        options.table=table
        options.filename=filename
        options.update_fields=update_fields
        options.id_field=id_field
        options.sync_mode=sync_mode
        options.replace_table=replace
        options.lc_names=True
	options.ascii_db=ascii_db
        importFMPXML(options)
        
        os.remove(filename)
        
        if RESPONSE and redirect_url:
            RESPONSE.redirect(redirect_url)
            
    def generateIndex(self,field,index_name,table,RESPONSE=None):
        """erzeuge index aus feld"""
        index={}
        founds=self.ZSQLSimpleSearch("""SELECT %s,oid FROM %s LIMIT 2000"""%(field,table))

        for found in founds:
            tmp=getattr(found,field,None)
            if tmp:
                strings=tmp.split(" ")
                for string in strings:
                    if index.get(string):
                        index[string].append(found.oid)
                    else:
                        index[string]=[found.oid]
                    RESPONSE.write(string+"\n")
            
        if not hasattr(self,index_name):
            obj=ZSQLIndex(index,index_name,table)
            self._setObject(index_name,obj)
                    
        self._getOb(index_name).setIndex(index)
        
    def getIndex(self,index_name):
        """getIndex"""
        founds=self.ZopeFind(self,obj_ids=[index_name])
        
        return founds[0][1].getIndex()
    
            
    def testneu(self):
        """test"""
        relStatement="""period like '%s%%'"""
        statement="select * from cdli_cat"
        wherePart="museum_no like 'VAT%'"
        classes=['Uruk III','Uruk IV']
        return self.searchRel(relStatement,statement,wherePart,classes)

    def URLquote(self,txt):
        """urlquote"""
        return urllib.quote(txt)
    
    def searchRel(self,relStatement,statement,wherePart,classes):
        """suche relative haufigkeiten"""
        ret={}
        allRecords=len(self.ZSQLSimpleSearch(statement + " where "+wherePart))
        
        for oneclass in classes:
            ret[oneclass]=len(self.ZSQLSimpleSearch(statement + " where ("+wherePart+") and "+ relStatement%oneclass))
        
        return (ret,allRecords)
                  
    def content_html(self):
        """template fuer content"""
        
        try:
            obj=getattr(self,"ZSQLBibliography_template")
            return obj()
        except:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ZSQLBibliography_template_standard.zpt'),content_type='text/html').__of__(self)
            pt.content_type="text/html"
            
            return pt()

        
    def getWeight(self):
        """getLabe"""
        try:
            return self.weight
        except:
            return ""

    def getLabel(self):
        """getLabe"""
        try:
            return self.label
        except:
            return ""

    def getDescription(self):
        """getLabe"""
        try:
            return self.description
        except:
            return ""

    manage_options=Folder.manage_options+(
        {'label':'Main Config','action':'changeZSQLExtendForm'},
       )

    def changeZSQLExtendForm(self):
        """change folder config"""
        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeZSQLExtendForm.zpt')).__of__(self)
        return pt()


    def changeZSQLExtend(self,label,description,weight=0,REQUEST=None,connection_id=None):
        """change it"""
        self.connection_id=connection_id
        self.weight=weight
        self.label=label
        self.description=description
        
        if REQUEST is not None:
            return self.manage_main(self, REQUEST)

    def formatAscii(self,str,url=None):
        """ersetze ascii umbrueche durch <br>"""
        #url=None
        str=str.rstrip().lstrip()
        
        if url and str:
            
            retStr=""
            words=str.split("\n")
            
            for word in words:
                strUrl=url%word
                #print "str",strUrl
                retStr+="""<a href="%s">%s</a><br/>"""%(strUrl,word)
            str=retStr
        if str:
            return re.sub(r"[\n]","<br/>",str)
        else:
            return ""
        
    def getSAttribute(self,obj,atribute,pref=''):
        """get Attribute or emptystring"""
        
        #print "obj",obj
        try:
            return pref+getattr(obj,atribute)
        except:
            return ""
        
    def getS(self,str):
        """make none to empty string"""
        if str:
            return str
        else:
            return ""

    def actualPath(self,url=None):
        """path"""

        if self.REQUEST['HTTP_X_FORWARDED_SERVER']=='':
            host=self.REQUEST['HTTP_HOST']
        else:
            host=self.REQUEST['HTTP_X_FORWARDED_SERVER']
        if not url:
                return "http://"+host+self.REQUEST['PATH_TRANSLATED']
        else:
                temp=self.REQUEST[url].split("/")
                temp[2]=host
                return string.join(temp,"/")

    def getRequest(self):
        """request"""
        return self.REQUEST

    def lowerEnd(self,path):
        """oinly for demo"""
        return os.path.splitext(path)[0]+".jpg"
        
    def ZSQLisEmpty(self,field):
        """Teste ob Treffer leer"""
        #print "field",field
        if not field:
            return 1
        if field.strip()=="":
            return 1
        return 0

    def ZSQLMultiSearch(self,_table,_searchField,_value,_idField,_additionalStatement="",_select=None,_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 zurŸck, d.h. es wird die "und" suche realisiert, 
        z.B. fŸr simplesearch ueber mehrere Felder
        """
        if _storename:
            """store"""
        else:
            _storename="foundCount"
            
        queries=[]
        #baue jede einzelne abfrage
        splitted=_value.split(" ")
        if not _select:
            _select=_idField
            
        queries.append("select %s from  %s %s where %s like '%%%s%%'"%(_select,_table,_additionalStatement,_searchField,splitted[0]))
        
        if len(splitted)>1:
            for v in splitted[1:]:
                queries.append("select %s from  %s where %s like '%%%s%%'"%(_idField,_table,_searchField,v))
                
        q=" and %s in ("%_idField
        query=q.join(queries) # nun baue sie zusammen
        for i in range(len(queries)-1):
            query+=")" #noch die klammern schliessen
        
        
        if _additionalStatement:
            query=query+" "
        
        logging.info("ZSQLSimple: %s"%query)
        retT=self.ZSQLSimpleSearch(query)
        logging.info("ZSQLSimple: %s"%retT)
        
        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())
        
        
            
        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=""):
        """return HTML Fragment with search options"""
        
        ret="""<select name="-op_%s">
        <option value="bw">begins with</option>                 <!-- begins with / beginnt mit, "Wort*" -->
        <option value="ew">ends with</option>
        <option value="ct" selected>contains</option>                   <!-- contains / enthaellt, "Wort" -->
    <option value="eq">equals</option>                          <!-- equals / ist, =Wort -->
</select>"""%fieldname
        return ret

    def ZSQLSelectionFromCRList(self,fieldname,listField,boxType="checkbox",checked=None):
        """generate select options from a cr seperated list"""
        fields=listField.split("\n")
        ret=""
        for field in fields:
            if checked and (field in checked.split("\n")):
                ret+="""<input name="%s" type="%s" value="%s" checked>%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
            else:
                ret+="""<input name="%s" type="%s" value="%s">%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
        return ret

    def ZSQLSelectionFromSearchList(self,fieldname,results,fieldnameResult,boxType="checkbox",checked=None):
        """generate select options from a cr seperated list"""

        ret=""
        if not results: return ""
        
        for result in results:
            field=getattr(result,fieldnameResult)
            if field:
                if checked and (getattr(result,fieldnameResult) in checked.split("\n")):
                    ret+="""<input name="%s" type="%s" value="%s" checked>%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
                else:
                    ret+="""<input name="%s" type="%s" value="%s">%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
        return ret


    def ZSQLOptionsFromCRList(self,fieldname,listField, multiple='',start=None,startValue=None,size=None,selected=None):
        """generate select oprions form a cr seperated list"""
        fields=listField.split("\n")
        if size:
            ret="""<select name="%s" %s size="%s" >
            """%(fieldname,multiple,size)

        else:
            ret="""<select name="%s" %s >
            """%(fieldname,multiple)
        if start:
            if start==' ':
                start=''
                if not startValue:
                    startValue=start
                    
            ret+="""<option value="%s" >%s</option>"""%(startValue,start)
        for field in fields:
            if selected and (field in selected.split("\n")):
                 ret+="""<option selected value="%s">%s</option>"""%(field.encode('utf-8'),field.encode('utf-8'))
            else:
                 ret+="""<option value="%s">%s</option>"""%(field.encode('utf-8'),field.encode('utf-8'))
        ret+="""</select>"""
        return ret

    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
        es wird
        <select name=fieldname mutiple>
        <option value=startValue>start</option>
        <option value=result.fieldName>result.fieldValue</option>
        erzeugt.
        
        @param fieldname: Name fuer name-wert im select-tag
        @param results: Resultobject einer SQL-suche
        @param fieldName: Name des Feldes, das als value in den option-tag geschrieben werden soll.
        @param valueName: (optional) Name des Feldes, dass als im option-tag ausgegeben wird, default wert ist valueName=fieldName
        @param start: (optional) falls zusaetzliches option tag erzeugt werden soll, gibt start an was im option tag steht
        @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:
            valueName=fieldName
        if size:
            ret="""<select name="%s" %s size="%s" %s>
            """%(fieldname,multiple,size,additionalSelect)
        else:
            ret="""<select name="%s" %s %s>
            """%(fieldname,multiple,additionalSelect)
        if start:
            if start==' ':
                        start=''
            
            if not startValue:
                    startValue=start
            
            if clear:
                ret+="""<option selected value="%s" >%s</option>"""%(startValue,start)
            else:
                ret+="""<option value="%s" >%s</option>"""%(startValue,start)
                
        for result in results:
            field=getattr(result,fieldName)
            fieldValue=getattr(result,valueName)
         
            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:
    
                    ret+="""<option value="%s" selected>%s</option>"""%(field,displayValue)
                else:
                    ret+="""<option value="%s">%s</option>"""%(field,displayValue)

        ret+="""</select>"""
        return ret

            
    def ZSQLInlineSearchU(self,storename=None,args=None,**argv):
        """one element if exists"""
        qs=[]
        if storename:
            """store"""
            storename=storename
        else:
            storename="foundCount"
            
        if args:
            argTmp=args
        else:
            argTmp=argv


        #print "INLINE:",argv
        for a in argTmp.keys():
	    aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_"
            qs.append(aFiltered+"="+urllib.quote(str(argTmp[a])))
        #return []  
        ret = self.parseQueryString(string.join(qs,","),"_",storename=storename)

        try:
            return ret[0]
        except:
            return None
     
     
    def ZSQLSequentialSearch(self,_fieldlist,_searchTerm,storename=None,args=None,**argv):
        """get a list of tuples (fields,searchoptions,table) to search the searchTerm in, returns dictionary. """
        #print "do search with:",_fieldlist,_searchTerm,storename,args,argv
        ret={} 
        if args:
            argTmp=args
        else:
            argTmp=argv

        for field in _fieldlist:

            argTmp2=copy.deepcopy(argTmp)
            argTmp2[field[0]]=_searchTerm
            argTmp2['_op_'+field[0]]=field[1]
            argTmp2['_table']=field[2]
            
            ret[field[0]]=(self.ZSQLInlineSearch(storename=storename,args=argTmp2),field[3],field[4],field[5],field[6])
        
        return ret
    
    
    def ZSQLInlineSearch(self,storename=None,args=None,**argv):
        """inlinesearch"""
       
        qs=[]
        if storename:
            """store"""
        else:
            storename="foundCount"
            
    

        if args:
            argTmp=args
        else:
            argTmp=argv


        #print "INLINE:",argv
        for a in argTmp.keys():
            aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_"
      
            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:
               
                value=str(argTmp[a])
            qs.append(aFiltered+"="+urllib.quote(value))
            
                
        #return []  

        return self.parseQueryString(string.join(qs,","),"_",storename=storename)

    def ZSQLInlineSearch2(self,query):
        """inlinesearch"""
        qs=[]
        
        #print "INLINE:",query
        return self.ZSQLSimpleSearch(query)
    

    def ZSQLResetConnection(self):
        """reset the connectione"""
        try:
            self.getConnectionObj().manage_close_connection()
        except:
            logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2])
        try:
            self.getConnectionObj().manage_open_connection()
        except:
            logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2])

    def ZSQLSimpleSearch(self,query=None,max_rows=1000000):
        """simple search"""
        logging.error("ZSQLSimpleSearch X %s"%query)
        #print query
        if not query:
            query=self.query
        
        
        if (hasattr(self,"_v_searchSQL") and (self._v_searchSQL == None)) or (not hasattr(self,"_v_searchSQL")):
            
            self._v_searchSQL=Shared.DC.ZRDB.DA.DA("_v_searchSQL","_v_searchSQL",self.getConnectionObj().getId(),"var","<dtml-var var>")
            
            self._v_searchSQL.max_rows_=max_rows
            try:
                logging.error("I am here")
                t=self._v_searchSQL.__call__(var=query)
                logging.error("I am here %s"%t)
                return t
            except :
                logger("ZSQLSimpleSearch ERROR1",logging.ERROR, '%s %s'%sys.exc_info()[:2])
                if sys.exc_info()[0]=="Database Error":
                    try:
                        self.getConnectionObj().manage_open_connection()
                    except:
                        logger("ZSQLSimpleSearch ERROR2",logging.ERROR, '%s %s'%sys.exc_info()[:2])
        else:
            try:

                self._v_searchSQL.max_rows_=max_rows
                
                return self._v_searchSQL.__call__(var=query)
            except :
                logger("ZSQLSimpleSearch ERROR2",logging.ERROR, '%s %s'%sys.exc_info()[:2])
                if sys.exc_info()[0]=="Database Error":
                    try:
                        self.getConnectionObj().manage_open_connection()
                    except:
                        logger("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2])

    def getConnectionObj(self):
        if hasattr(self,'connection_id'):
            return getattr(self,self.connection_id)
       
                    
    def ZSQLSimpleSearch2(self,query=None):
        """ returrn SQLSearch"""
       
        if not query:
            query=self.query
        if getattr(self,'_v_search',None):
            
            return self._v_search(var=query)
        
        if hasattr(self,'search') and (self.search.meta_type=="Z SQL Method"):
            self._v_search=self.search
            return self.search(var=query)
        else:
            if hasattr(self.aq_parent.aq_parent,'search') and (self.aq_parent.aq_parent.search.meta_type=="Z SQL Method"):
                self._v_search=self.aq_parent.aq_parent.search
                return self.aq_parent.aq_parent.search(var=query)
            else:
                search=self.ZopeFind(self,obj_metatypes=["Z SQL Method"],search_sub=1)
                if search:
                    self._v_search=search[0][1]
                    return search[0][1](var=query)
                else:
                    return []
    
        
        
    def ZSQLAdd(self,format=None,RESPONSE=None,args=None,**argv):
        """Neuer Eintrag"""
            
	if args:
            argTmp=args
        else:
            argTmp=argv

        qs_temp=[]
    
        for a in self.REQUEST.form.keys():
            qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))

        qs=string.join(qs_temp,",")
        
        for field in argTmp.keys():
                   if field[0]=="_":
                       fieldTmp="-"+field[1:]
                   else:
                       fieldTmp=field
                       
                   qs+=",%s=%s"%(fieldTmp,argTmp[field])
        
        
        addList={}
        for q in qs.split(","):
            name=re.sub("r'+'"," ",q.split("=")[0].lower())
            value=q.split("=")[1]
            value=re.sub(r'\+'," ",value)
            value=urllib.unquote(value) 
            if name=="-table":
                table=urllib.unquote(value)
            elif name=="-format":
                format=urllib.unquote(value)
            elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0):
                addList[urllib.unquote(name)]=urllib.unquote(value)

        keyList=[]
        valueList=[]
        for x in addList.keys():
            keyList.append("\""+x+"\"")
            valueList.append(sql_quote(addList[x]))

        keyString=string.join(keyList,",")
        valueString=string.join(valueList,",")
        
        queryString="INSERT INTO %s (%s) VALUES (%s)"%(table,keyString,valueString)

        self.ZSQLSimpleSearch(queryString)
        
        if RESPONSE and format:
            return RESPONSE.redirect(format)
        else:
            return True
        
    def ZSQLChange(self,format=None,RESPONSE=None,USE_FORM=None,args=None,**argv):
        """change entries"""
        #qs=self.REQUEST['QUERY_STRING']
        # very bad hack

        qs_temp=[]
        if USE_FORM or RESPONSE:
            for a in self.REQUEST.form.keys():
        
                qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))

        
        if args:
            arg_tmp=args
        else:
            arg_tmp=argv
            
        for field in arg_tmp.keys():
                
                   if field[0]=="_":
                       fieldTmp="-"+field[1:]
                   else:
                       fieldTmp=field
                       
                   qs_temp.append("%s=%s"%(fieldTmp,arg_tmp[field]))
        
        
        changeList=[]
        logging.info("ZSQLChange qs_temp: %s"%repr(qs_temp))
        for q in qs_temp:
       
            name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))
            value="=".join(q.split("=")[1:])
            value=re.sub(r'\+'," ",value)
            value=urllib.unquote(value)
         
            if name=="-table":
                    table=urllib.unquote(value)
            elif name=="-identify":
                identify=urllib.unquote(value)
                identify="lower("+identify.split("=")[0]+")="+sql_quote(identify.split("=")[1].lower())
            elif name=="-format":
                format=urllib.unquote(value)
            #elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0):
            elif (not (name[0]=="-" or name[0]=="_")):

		if value=="":
	                changeList.append("\""+name+"\"=null")
		else:
                	changeList.append("\""+name+"\"="+sql_quote(urllib.unquote(value)))
                
        changeString=string.join(changeList,",")

        queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)
        logger("ZSQLExtend",logging.INFO,"CHANGE: "+queryString)

        self.ZSQLSimpleSearch(queryString)
        
        
        if RESPONSE and format:
            return RESPONSE.redirect(format)
        else:
            return True
   

    def ZSQLFindIndexed(self,tableList=[],qs="",select="oid,*",storename=None,indexedFields=['data_line'],restrictField='id_text',**argv):
        """find2"""
        
        for index in self.ZopeFind(self,obj_ids=indexedFields):
            txt=argv.get(index[0],None)
            if txt:
                oids=index[1].getIndex()[txt]
                
        search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv)
     
        search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv)
        return search2
    
    def ZSQLFind2(self,qs="",select="oid,*",storename=None,tableList=['cdli_translit','cdli_cat'],restrictField='id_text',**argv):
        """find2"""
        
        search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv)
     
        search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv)
        return search2
    
      
    
    def ZSQLFind(self,qs="",select="oid,*",storename="foundCount",tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None,**argv):
        """search in database"""

        def delEmpty(list):
            """"loesche leere elemente aus der liste"""
            ret=[]
            for x in list:
                splitted=x.split("=")
                if (len(splitted)>1) and not (splitted[1]==' '):
                    ret.append(x)
            return ret

        if qs=="":
           #kein querystring ubergeben 
           if self.REQUEST['QUERY_STRING']:
               qs=self.REQUEST['QUERY_STRING']

               qs=string.join(qs.split("&"),",")

               for field in argv.keys():
                   if field[0]=="_":
                       fieldTmp="-"+field[1:]
                   else:
                       fieldTmp=field
                       
                   qs+=",%s=%s"%(fieldTmp,argv[field])
                   
           else:

               qs=self.REQUEST.SESSION.get('query','')
               
               for field in argv.keys():
                   if field[0]=="_":
                       fieldTmp="-"+field[1:]
                   else:
                       fieldTmp=field
                   
                   qs+=",%s=%s"%(fieldTmp,argv[field])

         

        else:
            self.REQUEST['QUERY_STRING']=qs

            qs=string.join(qs.split("&"),",")
            
        
        
        qs=re.sub("\\+"," ",qs)#TODO: Austauschen da Leerzeichen bei http-get durch + ersetzt wird, generell sollte alles auf post umgeschrieben werden. vom search formular.

        qs=string.join(delEmpty(qs.split(",")),",")


        #store query for further usage
        #TODO: erste der beiden ist ueberfluessig
        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)

        ret=self.parseQueryString(qs,"-",select=select,storemax="yes",storename=storename,tableExt=tableExt,NoQuery=NoQuery,NoLimit=NoLimit,restrictField=restrictField,restrictConnect=restrictConnect,filter=filter)
        #print self.REQUEST.SESSION["foundCount"]
        

        
        return ret

    def ZSQLFoundCountLen(self,var):
        return len(var)
            
    def ZSQLFoundCount(self,qs="",select="*",storename="foundCount"):
                
        return self.REQUEST.SESSION[storename]['count']

    def ZSQLRangeStart(self,storename="foundCount"):
      
        return int(self.REQUEST.SESSION[storename]['rangeStart'])+1
    
    def ZSQLRangeSize(self,storename="foundCount"):
        
        return self.REQUEST.SESSION[storename]['rangeSize']

    def ZSQLRangeEnd(self,storename="foundCount"):
   
        return str(min(int(self.REQUEST.SESSION[storename]['rangeEnd']),int(self.REQUEST.SESSION[storename]['count'])))

    def ZSQLNewQuery(self,linkText,storename="foundCount",**argv):
        """suche neu"""
        return self.ZSQLNewSearch(linkText,storename,url=self.REQUEST['URL'],args=argv)
    
    def ZSQLNewSearch(self,linkText,storename="foundCount",url=None,args=None,**argv):
        """suche mit alten parametern bis auf die in argv getauschten"""
        str = self.ZSQLNewSearchURL(storename, url, args, **argv)
        return """<a href="%s"> %s</a>"""%(str,linkText)
        

    def ZSQLNewSearchURL(self, storename="foundCount",url=None,args=None,**argv):
        """suche mit alten parametern bis auf die in argv getauschten"""
        if args:
            argv=args
                
        #get the old queries
        qs=self.REQUEST.SESSION[storename]['qs']
        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]=query.split("=")[1]
            except:
                queryList[arg]=''   
                
        argList=[]
        arg=""
        
        
        
        #gehe durch die zu aendernden Argumente
        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]

        if url:
            str=url+"?"+urllib.urlencode(queryList)
        else:
            str="ZSQLSearch?"+urllib.urlencode(queryList)
        
        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):
        """analysieren den QueryString"""
       
       
        #setzte generische werte
        
        lop="AND" # standardsuche mit and
        max="ALL" #standard alle auswaehlen
        maxstr=""
        whereList=[]
        sort=""
        op="bw"
        opfields={}
        lopfields={} #Verknuepfung bei mehrfachauswahl von einem feld
        sortfields={} #order of sortfields
        diacritics={} #diacritische zeichen, falls "no", dann werden diese fuer das feld gefiltert.
        sortAllFields=None
        skip=""
        rangeStart=0
        limit=0
        searchFields={}
        searchFieldsOnly={}
        queryTemplate=[]
        outerjoin=""
        debug=None
        
        if not select:
            select="oid,*"

        #check for op 
        splitted=qs.split(",")

        if tableExt:
            table=tableExt

        if restrictField:
                    select=restrictField
        
        
        #erster durchgang suche operatoren    
        for q in splitted:
            
                name=re.sub("r'+'"," ",q.split("=")[0].lower())
                if name=="_debug":
                    debug=True
                    
                try:
                    value=urllib.unquote(q.split("=",1)[1])
                except:
                    value=""
                #print "Hi",name[0:3],q
                if name[0:3]==iCT+"op":
                    op=value

                    field=name[4:]
                    opfields[field]=op

                if name[0:4]==iCT+"lop":
                    lop=value

                    field=name[5:]
                    lopfields[field]=lop
                    
                if name[0:11]==iCT+"diacritics":
                    field=name[12:]
                    diacritics[field]=value
                    
                if name[0:10]==iCT+"sortorder":
                    #sort=value
                    
                    field=name[11:]
                    sortAllFields=None
                    #no field selected
                    if field=="":
                        sortAllFields=value
                    else:
                        sortfields[field]=value
                        
        #zweiter durchgang analysiere felder
        for q in qs.split(","):
       
            
          
            name=re.sub("r'+'"," ",q.split("=")[0].lower())
           
            try:
                value=urllib.unquote(q.split("=",1)[1])
            
            except:
                value=""
            
            punktsplit=name.split(".")   #sonderfall feld mit punkten(tabelle.suchFeld.ausgewaehltesFeld,feldinoriginal), d.h. suche in anderer tabelle:                      
         
            #analysiere alle anderen faelle
            
            if diacritics.get(name,'yes')=='no':
                """filter diacritische zeichen"""
                value=unicodedata.normalize('NFKD', value.decode('utf-8')).encode('ASCII', 'ignore')
                
            if name==iCT+"lop":
                lop=value
            elif name==iCT+"table":
                if not tableExt: 
                    table=value
            elif name==iCT+"select":
                if not restrictField:
                    select=value
            elif name==iCT+"max":
                if not NoLimit:
                    maxstr="LIMIT "+str(value)
                    limit=str(value)
            elif name==iCT+"skip":
                skip="OFFSET "+str(value)
                rangeStart=str(value)
            elif name==iCT+"join":
                
                whereList.append(value)
            elif name==iCT+"outerjoin":
                
                outerjoin=value
            elif name==iCT+"sort":
                sortstrs=[]
         
                for word in value.split(','):
                    wordstr=word.lstrip().rstrip()
                    if sortAllFields:
                        order=sortAllFields
                    else:
                        order=sortfields.get(wordstr,'ASC')
                        
                    if not (wordstr == ""):
                        sortstrs.append(wordstr+" "+order)
                if len(sortstrs)>0:
                    sort="ORDER BY "+string.join(sortstrs,',')
                    
                    
            elif name==iCT+"token":
                if not nostore=="yes":
                    self.REQUEST.SESSION['token']=value

            elif name==iCT+"op":
                op=value


            #sonderfall Name hat das Format: 
            #TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE_-table
            #i.e. erzeugt wird
            #das Statement 
            #WHERE IDENTIFIER_IN_TABELLE in (select * from SELECT_FIELD
            #where LOWER(SUCHFELD_IN_DIESER_TABELLE) something  value)
            #something is defined by _op_TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE
            
            elif (not name[0]==iCT) and len(punktsplit)==4:
                
                if opfields.has_key(name):
                    op=opfields[name]
                else:
                    op="ct"
                namealt=name
                name="LOWER("+punktsplit[1]+")" 
                value=value.lower()
                if op=="ct":
                    tmp=(name+" LIKE "+sql_quote("%"+value+"%"))
                elif op=="gt":
                    tmp=(name+">"+sql_quote(value))
                elif op=="lt":
                    tmp=(name+"<"+sql_quote(value))
                elif op=="eq":
                    tmp=(name+"="+sql_quote(value))
                elif op=="bw":
                    tmp=(name+" LIKE "+sql_quote(value+"%"))
                elif op=="ew":
                    tmp=(name+" LIKE "+sql_quote("%"+value))
                elif op=="all":
                    tmps=[]
                    for word in value.split(" "):
                        tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
                        
                    tmp=string.join(tmps,' AND ')

                elif op=="numerical":
                    term=analyseIntSearch(value)
                    tmp=(name+" "+term)
                elif op=="grep":
                    tmp=(name+" ~* "+sql_quote(value))
                elif op=="one":
                    tmps=[]
                    for word in value.split(" "):
                        tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
                        
                    tmp=string.join(tmps,' OR ')

                op="all"

                if value!='': #lehre Werte werde nicht hinzugefuegt
                    searchTmp="""%s in (select %s from %s where %s)"""%(punktsplit[3],punktsplit[2],punktsplit[0],tmp)

                    queryTemplate.append(searchTmp)
                
            elif (not name[0]==iCT) and (not len(value)==0):

                #print "OP",op,name
                value=value.lower()
                
                tmp=""
                if opfields.has_key(name):
                    op=opfields[name]
                else:
                    op="ct"
                namealt=name
                name="LOWER("+name+")"    
                if op=="ct":
                    tmp=(name+" LIKE "+sql_quote("%"+value+"%"))
                elif op=="gt":
                    tmp=(name+">"+sql_quote(value))
                elif op=="lt":
                    tmp=(name+"<"+sql_quote(value))
                elif op=="eq":
                    tmp=(name+"="+sql_quote(value))
                elif op=="bw":
                    tmp=(name+" LIKE "+sql_quote(value+"%"))
                elif op=="ew":
                    tmp=(name+" LIKE "+sql_quote("%"+value))
                elif op=="all":
                    tmps=[]
                    for word in value.split(" "):
                        tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
                        
                    tmp=string.join(tmps,' AND ')

                elif op=="numerical":
                    term=analyseIntSearch(value)
                    tmp=(name+" "+term)
                elif op=="grep":
                    tmp=(name+" ~* "+sql_quote(value))
                elif op=="one":
                    tmps=[]
                    for word in value.split(" "):
                        tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
                        
                    tmp=string.join(tmps,' OR ')

                op="all"

                if (value!='') and ((not tableExt) or (namealt.split('.')[0]==tableExt)): #keine leeren werde und keine auschluss
                    if searchFields.has_key(namealt):
                        searchFields[namealt]+=lopfields.get(name,'OR')+" "+tmp
                        searchFieldsOnly[namealt]+=lopfields.get(name,'OR')+" "+value
                    else: 
                        searchFields[namealt]=tmp
                        searchFieldsOnly[namealt]=value


        whereList=["("+searchFields[x]+")" for x in searchFields.keys()]
        whereList+=queryTemplate
        
        if len(whereList)>0:
            if filter:
                whereStr="("+string.join(whereList," "+lop+" ")+") AND "+filter
            else:
                whereStr=string.join(whereList," "+lop+" ")
            where="WHERE "+whereStr
        else:
            if filter:
                where="WHERE "+filter
            else:
                where=""

        if restrictConnect:

            if len(where)==0:
                where="WHERE "+restrictConnect[0]+" in ("+restrictConnect[1]+")"
            else:
                where+="and "+restrictConnect[0]+" in ("+restrictConnect[1]+")"
                
        #print "QE",table
        #print (select,table,where,sort,maxstr,skip)
        query="SELECT %s FROM %s %s %s %s %s %s"%(select,table,outerjoin,where,sort,maxstr,skip)

        if not nostore=="yes":
            
            self.REQUEST.SESSION['qs']=opfields
        #print "IAMHERE again:", query

        if not NoQuery:

            query2="SELECT count(*) FROM %s %s"%(table,where)
            
            #print "QUERYSTRING:",self.REQUEST.SESSION[storename]['queryString2']
            if not self.REQUEST.SESSION.has_key(storename):
                self.REQUEST.SESSION[storename]={}

            self.REQUEST.SESSION[storename]['qs']=qs #sichere Querystring
        
            if self.REQUEST.SESSION[storename].has_key('queryString2'):
        
                if not self.REQUEST.SESSION[storename]['queryString2']==query2:
                    #print "HOOOOO",storename
                    self.REQUEST.SESSION[storename]['queryString2']=query2
                    try:
                        self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count
                    except:
                        self.REQUEST.SESSION[storename]['count']=0
                    #print "QUERY",query2,"::::",self.REQUEST.SESSION[storename]['queryString2']
                
            else:
        
                self.REQUEST.SESSION[storename]['queryString2']=query2
                if self.ZSQLSimpleSearch(query2):
        
                    self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count
                else:
                    self.REQUEST.SESSION[storename]['count']=0
                #print "QUERYNEW",self.REQUEST.SESSION[storename]['queryString2']
            
            
            self.REQUEST.SESSION[storename]['rangeStart']=rangeStart
            
            
            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']
            else:
                self.REQUEST.SESSION[storename]['rangeEnd']=int(rangeStart)+int(limit)
            self.REQUEST.SESSION[storename]['rangeSize']=limit
            self.REQUEST.SESSION[storename]['searchFields']=searchFields

            self.REQUEST.SESSION[storename]['searchFieldsOnly']=searchFieldsOnly
    
        if debug:
            logging.error("ZSQLSimpleSearch %s"%query)
        if not NoQuery:
                
            return self.ZSQLQuery(query)
        else:

            return query

    def ZSQLUniqueQuery(self,value,returns):
        """unique relation"""
        if returns:
            statement="""select %s from %s where %s = '%s' """%(returns[1],returns[0],returns[2],value)
            founds=self.ZSQLSimpleSearch(statement)
            if founds:
                return getattr(founds[0],returns[1])
            else:
                return value
        else:
            return value
        
    def ZSQLQuery(self,query,debug=None):
        """query"""
        if debug:
            logger("ZSQLQuery", logging.INFO, query)
       
        return self.ZSQLSimpleSearch(query)

    
    def ZSQLSearch(self):
        """To be done"""
           
        formatfile=self.REQUEST['URL1'] #generisch redirect zur gleichen url
      
        #zerlege querystring in key value paare
        #TODO: check if this is really necessary, use argv**
        
        rq=self.REQUEST['QUERY_STRING']
        querys=rq.split("&")
        for querytemp in querys: #zerg
            query=querytemp.split("=")
            
            try:
                if query[0].lower()=="-format":
                    formatfile=query[1]
            except:
                pass

        #sichern
        self.REQUEST.SESSION['query']=string.join(self.REQUEST['QUERY_STRING'].split("&"),",")
        self.REQUEST.SESSION['come_from_search']="yes"
        
        return self.REQUEST.RESPONSE.redirect(urllib.unquote(formatfile)+"?"+rq)

    
    def ZSQLint(self,string):
        try:

            return(int(string))
        except:
            return 0

    def getZSQLSearchFieldsList(self,storename="foundCount"):
        """get searchfieldList"""
        #print self.REQUEST.SESSION[storename]['searchFields'].keys()
        return  self.REQUEST.SESSION[storename]['searchFieldsOnly'].keys()

    def getZSQLSearchFields(self,field,storename="foundCount"):
        """get searchfield"""
        #print "SF",self.REQUEST.SESSION[storename]['searchFields']
        
        return  self.REQUEST.SESSION[storename]['searchFieldsOnly'][field]

                                                
    def nextLink(self,html,storename="foundCount"):
        """nextLink"""

        try:
            limit=self.REQUEST.SESSION[storename]['rangeSize']
            if int(limit)==0 :
                limit="1"
            newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])+int(limit)
        except:
            limit=1
            newRangeStart=0
            
        if (newRangeStart>=self.REQUEST.SESSION[storename]['count']) or (self.REQUEST.SESSION[storename]['count']==self.REQUEST.SESSION[storename]['rangeEnd']):
            #newRangeStart=self.REQUEST.SESSION[storename]['count']-1
            return ""
        
        #create new query string
        
        if self.REQUEST['QUERY_STRING']=="":
            qs=self.REQUEST.SESSION['query']
            
            queries=string.split(qs,",")[0:]
            
            
        else:
            qs=self.REQUEST['QUERY_STRING']
            queries=string.split(qs,"&")[0:]
            
            
            
        newquery=[]

        skipFound=0
        
        for query in queries:
                        
            if query[0]=="_" : query="-"+query[1:]
            
            if query.split("=")[0].lower()=="-skip":

                skipFound=1
                query="-skip=%i"%newRangeStart
            newquery.append(query)

        if skipFound==0 :
            query="-skip=%i"%newRangeStart
            newquery.append(query)
                
        newquerystring=string.join(newquery,"&")
        return "<a href='%s'>%s</a>"%(self.REQUEST['URL']+"?"+newquerystring,html)

            
        
    def prevLink(self,html,storename="foundCount"):
        """prev link"""

        try:
            limit=self.REQUEST.SESSION[storename]['rangeSize']
            if int(limit)==0 :
                limit="1"
            newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])-int(limit)
        except:
            limit=1
            newRangeStart=0
        if newRangeStart <0:
            return ""

        #print "limit",limit,newRangeStart,int(self.REQUEST.SESSION[storename]['rangeStart'])
        
        if newRangeStart<0:
                newRangeStart=0

        #create new query string
        
        if self.REQUEST['QUERY_STRING']=="":
            qs=self.REQUEST.SESSION['query']
            #qs=re.sub(r'_','-',qs) #aendern fuer query
            queries=string.split(qs,",")
            
            
        else:
            qs=self.REQUEST['QUERY_STRING']
            queries=string.split(qs,"&")
            
            
            
        newquery=[]
        
        skipFound=0

        for query in queries:
            #print query.split("=")[0]

            if query[0]=="_" : query[0]="-"
            
            if query.split("=")[0].lower()=="-skip":
                #print"HI"
                query="-skip=%i"%newRangeStart
                skipFound=1
            newquery.append(query)

        if skipFound==0 :
            query="-skip=%i"%newRangeStart
            newquery.append(query)
            
        newquerystring=string.join(newquery,"&")

        return "<a href='%s'>%s</a>"%(self.REQUEST['URL']+"?"+newquerystring,html)


    
 
manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals())

def manage_addZSQLExtendFolder(self, id, title='', label='', description='',
                     createPublic=0,
                     createUserF=0,
                     connection_id=None,
                     REQUEST=None):
    """Add a new Folder object with id *id*.

    If the 'createPublic' and 'createUserF' parameters are set to any true
    value, an 'index_html' and a 'UserFolder' objects are created respectively
    in the new folder.
    """
    
    
    ob=ZSQLExtendFolder()
    ob.id=str(id)
    ob.title=title
    self._setObject(id, ob)
    ob=self._getOb(id)
    setattr(ob,'label',label)
    setattr(ob,'description',description)
    setattr(ob,'connection_id',connection_id)
    
    checkPermission=getSecurityManager().checkPermission

    if createUserF:
        if not checkPermission('Add User Folders', ob):
            raise Unauthorized, (
                  'You are not authorized to add User Folders.'
                  )
        ob.manage_addUserFolder()

    if createPublic:
        if not checkPermission('Add Page Templates', ob):
            raise Unauthorized, (
                  'You are not authorized to add Page Templates.'
                  )
        ob.manage_addProduct['PageTemplates'].manage_addPageTemplate(
            id='index_html', title='')

    if REQUEST is not None:
        return self.manage_main(self, REQUEST, update_menu=1)



class ZSQLBibliography(Folder,ZSQLExtendFolder):
    """Bibliography"""
    meta_type="ZSQLBibliography"
    def getLabel(self):
        try:
            return self.label
        except:
            return ""

    def getDescription(self):
        try:
            return self.description
        except:
            return ""
            
    def changeZSQLBibliographyForm(self):
        """change folder config"""
        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeZSQLBibliographyForm.zpt')).__of__(self)
        return pt()


    def content_html(self):
        """template fuer content"""
        
        try:
            obj=getattr(self,"ZSQLBibliography_template")
            return obj()
        except:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ZSQLBibliography_template_standard.zpt')).__of__(self)
            pt.content_type="text/html"
            return pt()

    def changeZSQLBibliography(self,tableName,label,description,connection_id=None,REQUEST=None):
        """change it"""
        self.connection_id=connection_id
        self.tableName=tableName
        self.label=label
        self.description=description
        
        if REQUEST is not None:
            return self.manage_main(self, REQUEST)

    manage_options=Folder.manage_options+(
        {'label':'Main Config','action':'changeZSQLBibliographyForm'},
        {'label':'Generate RDF Template','action':'generateRDFTemplate'},
        {'label':'Generate XML Template','action':'generateXMLTemplate'},
       )


    def getFieldLabel(self,fields,field):
        """get labels"""
        try:
            ret =fields[0][field]
            if ret == "":
                return field
            else:
                return ret
        except:
            return field
        
    def getFieldValue(self,found,field):
        """get value"""
        try:
            ret=getattr(found,field)
            if ret == "":
                return None
            else:
                return ret
        except:
            return None

    def findTagsFromMapping(self,referenceType):
        """gib hash mit label -> generic zurueck"""
        self.referencetypes=self.ZopeFind(self.standardMD)
        bibdata={}
        retdata={}
        fieldlist=self.standardMD.fieldList
        
        for referenceTypeF in self.referencetypes:
                #print referenceType,referenceTypeF[1].title
                if referenceTypeF[1].title == referenceType: 
                        bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields
                        bibdata['data']=referenceTypeF[1]
                        self.fields=bibdata[referenceType]
                        for field in fieldlist:
                            if referenceTypeF[1].getValue(field)[0]==None:
                                retdata[field]=field
                            else:
                                retdata[field]=referenceTypeF[1].getValue(field)[0]

        return retdata,fieldlist
        
    def findLabelsFromMapping(self,referenceType):
        """gib hash mit label -> generic zurueck"""
        self.referencetypes=self.ZopeFind(self.standardMD)
        bibdata={}
        retdata={}
        fieldlist=self.standardMD.fieldList
        
        for referenceTypeF in self.referencetypes:
                #print referenceType,referenceTypeF[1].title
                if referenceTypeF[1].title == referenceType: 
                        bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields
                        bibdata['data']=referenceTypeF[1]
                        self.fields=bibdata[referenceType]
                        for field in fieldlist:
                            retdata[field]=referenceTypeF[1].getValue(field)[1]

        return retdata,fieldlist

    def createRDFTag(self,tag,content,namespace="cdli"):
        """create RDF"""
        if content:
            tag=namespace+":"+tag
            if (type(content) is StringType) or (type(content) is UnicodeType):
                ret=""" <%s>%s</%s>"""%(tag,escape(content),tag)
            else:
                ret=""" <%s>%s</%s>"""%(tag,content,tag)
            return ret.decode('latin-1')
        else:
            return ""
    
    def createIndexTag(self,tag,content):
        """create tag"""
        
        if content:
            if (type(content) is StringType) or (type(content) is UnicodeType):
                ret=""" <%s>%s</%s>"""%(tag,escape(content),tag)
            else:
                ret=""" <%s>%s</%s>"""%(tag,content,tag)
            return ret.decode('latin-1')

        else:
            return ""
    
    def getXML2(self):
        """crate index meta"""

        fn=os.path.splitext(self.REQUEST['fn'])[0]+"."
        self.REQUEST['fn']=fn

        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record2.xml')).__of__(self)
        pt.content_type="text/xml"
        return pt()


    def generateRDFTemplate(self,REQUEST=None):
        """generateRDFtemplate"""
        zt=ZopePageTemplate('record.rdf')
        self._setObject('record.rdf',zt)
        default_content_fn = os.path.join(package_home(globals()),
                                          'zpt','record.rdf')
        text = open(default_content_fn).read()
        zt.pt_edit(text, 'text/xml')


        if REQUEST is not None:
            return self.manage_main(self, REQUEST)

    def generateXMLTemplate(self,REQUEST=None):
        """generateXMLtemplate"""
        zt=ZopePageTemplate('record.xml')
        self._setObject('record.xml',zt)
        default_content_fn = os.path.join(package_home(globals()),
                                          'zpt','record.xml')
        text = open(default_content_fn).read()
        zt.pt_edit(text, 'text/xml')


        if REQUEST is not None:
            return self.manage_main(self, REQUEST)
    def getMetaDataRDF(self):
        """crate index meta"""
        find=self.ZopeFind(self,obj_ids=["record.rdf"])
        if not find:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record.rdf')).__of__(self)
            pt.content_type="text/xml"
            return pt()
        else:
            return find[0][1]()

    def getMetaDataXML(self):
        """crate index meta"""
        find=self.ZopeFind(self,obj_ids=["record.xml"])
        if not find:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record.xml')).__of__(self)
            pt.content_type="text/xml"
            return pt()
        else:
            return find[0][1]()


    def getMetaDatasXML(self):
        """index"""
        # check if the request's host part was OK
        http_host = self.REQUEST['HTTP_HOST']
        host_port = self.REQUEST['SERVER_PORT']
        fix_host = None
        if http_host and http_host.rfind(host_port) == -1:
            #print "HTTP_HOST needs fixing!"
            fix_host = http_host + ":" + host_port
        
        ret="""<?xml version="1.0" ?>
                     <index>"""
        for found in self.ZSQLSimpleSearch("select oid from %s limit ALL"%self.tableName):
            base_url = self.absolute_url()
            if fix_host:
                #print "replacing ", http_host, " by ", fix_host
                base_url = string.replace(base_url, http_host, fix_host, 1)
                
            link=base_url+"/"+"record.html?oid=%i"%found.oid
            metalink=base_url+"/"+"getMetaDataXML?oid=%i"%found.oid
            
            ret+="""<resource resourceLink="%s" metaLink="%s"/>\n"""%(link,metalink)
            
        return ret+"\n</index>"

    
manage_addZSQLBibliographyForm=DTMLFile('ZSQLBibliographyAdd', globals())

def manage_addZSQLBibliography(self, id, tableName,label,description,title='',
                     createPublic=0,
                     createUserF=0,
                     connection_id=None,
                     REQUEST=None):
    """Add a new Folder object with id *id*.

    If the 'createPublic' and 'createUserF' parameters are set to any true
    value, an 'index_html' and a 'UserFolder' objects are created respectively
    in the new folder.
    """
    
    
    ob=ZSQLBibliography()
    ob.id=str(id)
    ob.title=title
    self._setObject(id, ob)
    ob=self._getOb(id)
    setattr(ob,'tableName',tableName)
    setattr(ob,'label',label)
    setattr(ob,'description',description)
    setattr(ob,'connection_id',connection_id)
    
    checkPermission=getSecurityManager().checkPermission

    if createUserF:
        if not checkPermission('Add User Folders', ob):
            raise Unauthorized, (
                  'You are not authorized to add User Folders.'
                  )
        ob.manage_addUserFolder()

    if createPublic:
        if not checkPermission('Add Page Templates', ob):
            raise Unauthorized, (
                  'You are not authorized to add Page Templates.'
                  )
        ob.manage_addProduct['PageTemplates'].manage_addPageTemplate(
            id='index_html', title='')

    if REQUEST is not None:
        return self.manage_main(self, REQUEST, update_menu=1)

    

    

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