--- ZSQLExtend/ZSQLExtend.py 2005/04/27 19:36:01 1.63
+++ ZSQLExtend/ZSQLExtend.py 2005/11/08 13:37:32 1.71
@@ -17,6 +17,7 @@ import Shared.DC.ZRDB.DA
import zLOG
import os.path
import os
+from OFS.SimpleItem import SimpleItem
def analyseIntSearch(word):
#analyse integer searches
@@ -41,16 +42,87 @@ def sql_quote(v):
quote_dict = {"\'": "''", "\\": "\\\\"}
for dkey in quote_dict.keys():
if string.find(v, dkey) >= 0:
- v=join(split(v,dkey),quote_dict[dkey])
+ v=string.join(string.split(v,dkey),quote_dict[dkey])
return "'%s'" % v
def showSQLConnectionIDs(self):
return SQLConnectionIDs(self)
+class ZSQLIndex(SimpleItem):
+ """index"""
+ meta_type="ZSQLIndex"
+
+ def __init__(self,index,id,table=''):
+ self.index=[x for x in index]
+ self.id=id
+ self.table=table
+
+ def setIndex(self,index):
+ self.index=[x for x in index]
+
+ def getIndex(self):
+ return self.index
+
class ZSQLExtendFolder(Folder,Persistent, Implicit):
"""Folder"""
meta_type="ZSQLExtendFolder"
-
+
+ def importXMLFile(self,table,containerTagName,file,identify=None,RESPONSE=None):
+ #TODO: finish importXMLFile
+ '''
+ Import XML file into the table
+ @param table: name of the table the xml shall be imported into
+ @param containerTagName: XML-Tag which describes a dataset
+ @param file: xmlfile handle
+ @param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes.
+ @param RESPONSE: (optional)
+ '''
+ from xml.dom.pulldom import parseString
+
+ doc=parseString(file.read())
+ while 1:
+ node=doc.getEvent()
+
+ if node is None:
+ break;
+ else:
+ if node[1].nodeName==containerTagName:
+ doc.expandNode(node[1])
+ #fn=node[1].getAttribute("xml:id")
+ #nf=file("xtf/"+fn+".xtf",'w')
+ #nf.write(""""""+node[1].toxml()+"")
+ #print "wrote: %s"%fn
+
+
+ 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))
+ print len(founds)
+ 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%%'"""
@@ -62,6 +134,7 @@ class ZSQLExtendFolder(Folder,Persistent
def URLquote(self,txt):
"""urlquote"""
return urllib.quote(txt)
+
def searchRel(self,relStatement,statement,wherePart,classes):
"""suche relative haufigkeiten"""
ret={}
@@ -229,7 +302,7 @@ class ZSQLExtendFolder(Folder,Persistent
return ret
- def ZSQLOptionsFromCRList(self,fieldname,listField, multiple='',start=None,startValue=None,size=None):
+ 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:
@@ -247,7 +320,10 @@ class ZSQLExtendFolder(Folder,Persistent
ret+=""""""%(startValue,start)
for field in fields:
- ret+=""""""%(field.encode('utf-8'),field.encode('utf-8'))
+ if selected and (field in selected.split("\n")):
+ ret+=""""""%(field.encode('utf-8'),field.encode('utf-8'))
+ else:
+ ret+=""""""%(field.encode('utf-8'),field.encode('utf-8'))
ret+=""""""
return ret
@@ -343,40 +419,50 @@ class ZSQLExtendFolder(Folder,Persistent
"""inlinesearch"""
qs=[]
-
-
#print "INLINE:",query
return self.ZSQLSimpleSearch(query)
-
+
+
def ZSQLSimpleSearch(self,query=None,max_rows=1000000):
"""simple search"""
-
+
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.connection_id,"var","")
+
+ self._v_searchSQL=Shared.DC.ZRDB.DA.DA("_v_searchSQL","_v_searchSQL",self.getConnectionObj().getId(),"var","")
+
self._v_searchSQL.max_rows_=max_rows
try:
+
return self._v_searchSQL.__call__(var=query)
except :
if sys.exc_info()[0]=="Database Error":
try:
- getattr(self,self.connection_id).manage_open_connection()
- except: pass
+ self.getConnectionObj().manage_open_connection()
+ except:
+ zLOG.LOG("ZSQLSimpleSearch",zLOG.ERROR, '%s %s'%sys.exc_info()[:2])
else:
try:
self._v_searchSQL.max_rows_=max_rows
+
return self._v_searchSQL.__call__(var=query)
except :
if sys.exc_info()[0]=="Database Error":
try:
- getattr(self,self.connection_id).manage_open_connection()
- except: pass
+ self.getConnectionObj().manage_open_connection()
+ except:
+ zLOG.LOG("ZSQLSimpleSearch",zLOG.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"""
- #print "hi",query
+
if not query:
query=self.query
if getattr(self,'_v_search',None):
@@ -400,20 +486,36 @@ class ZSQLExtendFolder(Folder,Persistent
- def ZSQLAdd(self):
+ def ZSQLAdd(self,format=None,RESPONSE=None,**argv):
"""Neuer Eintrag"""
- qs=self.REQUEST['QUERY_STRING']
+
+ 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 argv.keys():
+ if field[0]=="_":
+ fieldTmp="-"+field[1:]
+ else:
+ fieldTmp=field
+
+ qs+=",%s=%s"%(fieldTmp,argv[field])
+
+
addList={}
- for q in qs.split("&"):
+ for q in qs.split(","):
name=re.sub("r'+'"," ",q.split("=")[0].lower())
value=q.split("=")[1]
- value=re.sub(r'\+'," ",value)
- value=urllib.unquote(value)
+ value=re.sub(r'\+'," ",value)
+ value=urllib.unquote(value)
if name=="-table":
table=urllib.unquote(value)
elif name=="-format":
format=urllib.unquote(value)
- elif (not name[0]=="-") and (not len(value)==0):
+ elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0):
addList[urllib.unquote(name)]=urllib.unquote(value)
keyList=[]
@@ -426,45 +528,80 @@ class ZSQLExtendFolder(Folder,Persistent
valueString=string.join(valueList,",")
queryString="INSERT INTO %s (%s) VALUES (%s)"%(table,keyString,valueString)
+
self.ZSQLSimpleSearch(queryString)
- return self.REQUEST.RESPONSE.redirect(format)
- def ZSQLChange(self,**argv):
+ if RESPONSE and format:
+ return RESPONSE.redirect(format)
+ else:
+ return True
+
+ def ZSQLChange(self,format=None,RESPONSE=None,USE_FORM=None,**argv):
"""change entries"""
#qs=self.REQUEST['QUERY_STRING']
# very bad hack
+
qs_temp=[]
-
- for a in self.REQUEST.form.keys():
- qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))
+ if USE_FORM or RESPONSE:
+ for a in self.REQUEST.form.keys():
+ qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))
- qs=string.join(qs_temp,"&")
-
-
- #print "CHANGE QS",self.REQUEST
- #return self.REQUEST
+
+
+ for field in argv.keys():
+
+ if field[0]=="_":
+ fieldTmp="-"+field[1:]
+ else:
+ fieldTmp=field
+
+ qs_temp.append("%s=%s"%(fieldTmp,argv[field]))
+
+
changeList=[]
- for q in qs.split("&"):
+
+ for q in qs_temp:
+
name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))
- value=q.split("=")[1]
+ value="=".join(q.split("=")[1:])
value=re.sub(r'\+'," ",value)
- value=urllib.unquote(value)
- if name=="-table":
- table=urllib.unquote(value)
+ value=urllib.unquote(value)
+
+ if name=="-table":
+ table=urllib.unquote(value)
elif name=="-identify":
identify=urllib.unquote(value)
identify=identify.split("=")[0]+"="+sql_quote(identify.split("=")[1])
elif name=="-format":
format=urllib.unquote(value)
- elif (not name[0]=="-") and (not len(value)==0):
+ elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0):
changeList.append("\""+name+"\"="+sql_quote(urllib.unquote(value)))
+
changeString=string.join(changeList,",")
queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)
+
self.ZSQLSimpleSearch(queryString)
- return self.REQUEST.RESPONSE.redirect(format)
-
+
+
+ if RESPONSE and format:
+ return RESPONSE.redirect(format)
+ else:
+ return True
+ def ZSQLFindIndexed(self,qs="",select="oid,*",storename=None,indexedFields=['data_line'],restrictField='id_text',**argv):
+ """find2"""
+
+ for index in self.ZopeFind(self,obj_ids=indexedFields):
+ txt=argv.get(index[0],None)
+ if txt:
+ oids=index[1].getIndex()[txt]
+
+ search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv)
+
+ search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv)
+ return search2
+
def ZSQLFind2(self,qs="",select="oid,*",storename=None,tableList=['cdli_translit','cdli_cat'],restrictField='id_text',**argv):
"""find2"""
@@ -476,9 +613,10 @@ 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):
- """Find"""
+ """search in database"""
def delEmpty(list):
+ """"loesche leere elemente aus der liste"""
ret=[]
for x in list:
splitted=x.split("=")
@@ -486,15 +624,11 @@ class ZSQLExtendFolder(Folder,Persistent
ret.append(x)
return ret
-
-
- #self.REQUEST.SESSION['come_from_search']="no" # zuruecksetzen
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():
@@ -526,7 +660,7 @@ class ZSQLExtendFolder(Folder,Persistent
- qs=re.sub("\\+"," ",qs)# Austauschen da Leerzeichen bei http-get durch + ersetzt wird, generell sollte alles auf post umgeschrieben werden. vom search formular.
+ 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(",")),",")
@@ -654,6 +788,8 @@ class ZSQLExtendFolder(Folder,Persistent
"""analysieren den QueryString"""
+ #setzte generische werte
+
lop="AND" # standardsuche mit and
max="ALL" #standard alle auswaehlen
maxstr=""
@@ -669,21 +805,22 @@ class ZSQLExtendFolder(Folder,Persistent
limit=0
searchFields={}
searchFieldsOnly={}
+ queryTemplate=[]
+
if not select:
select="oid,*"
- #print "Q",nostore,qs
- #check for op
-
-
-
- splitted=qs.split(",")
+ #check for op
+ splitted=qs.split(",")
+ print splitted
if tableExt:
table=tableExt
if restrictField:
select=restrictField
-
+
+
+ #erster durchgang suche operatoren
for q in splitted:
name=re.sub("r'+'"," ",q.split("=")[0].lower())
@@ -714,25 +851,21 @@ class ZSQLExtendFolder(Folder,Persistent
sortAllFields=value
else:
sortfields[field]=value
-
- #print "HI",op,field
- #print opfieldsa
- #now analyse the querystring
-
+
+ #zweiter durchgang analysiere felder
for q in qs.split(","):
- #try:
-
+
name=re.sub("r'+'"," ",q.split("=")[0].lower())
try:
value=urllib.unquote(q.split("=",1)[1])
except:
value=""
- #value=sql_quote(value)
-
-
+ punktsplit=name.split(".") #sonderfall feld mit punkten(tabelle.suchFeld.ausgewaehltesFeld,feldinoriginal), d.h. suche in anderer tabelle:
+
+ #analysiere alle anderen faelle
if name==iCT+"lop":
lop=value
elif name==iCT+"table":
@@ -773,7 +906,53 @@ class ZSQLExtendFolder(Folder,Persistent
op=value
+
+ 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]+")"
+ print "XX",op
+ 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"
+ print punktsplit
+ searchTmp="""%s in (select %s from %s where %s)"""%(punktsplit[3],punktsplit[2],punktsplit[0],tmp)
+ print "got",searchTmp
+ queryTemplate.append(searchTmp)
+
elif (not name[0]==iCT) and (not len(value)==0):
#print "OP",op,name
@@ -828,6 +1007,7 @@ class ZSQLExtendFolder(Folder,Persistent
whereList=["("+searchFields[x]+")" for x in searchFields.keys()]
+ whereList+=queryTemplate
if len(whereList)>0:
if filter:
@@ -851,7 +1031,7 @@ class ZSQLExtendFolder(Folder,Persistent
#print "QE",table
#print (select,table,where,sort,maxstr,skip)
query="SELECT %s FROM %s %s %s %s %s"%(select,table,where,sort,maxstr,skip)
-
+ print query
if not nostore=="yes":
self.REQUEST.SESSION['qs']=opfields
@@ -915,37 +1095,34 @@ class ZSQLExtendFolder(Folder,Persistent
else:
return value
- def ZSQLQuery(self,query):
+ def ZSQLQuery(self,query,debug=None):
"""query"""
-
+ if debug:
+ zLOG.LOG("ZSQLQuery", zLOG.INFO, query)
+
return self.ZSQLSimpleSearch(query)
def ZSQLSearch(self):
"""To be done"""
- rq=self.REQUEST['QUERY_STRING']
-
- querys=rq.split("&")
-
-
+
formatfile=self.REQUEST['URL1'] #generisch redirect zur gleichen url
+
+ #zerlege querystring in key value paare
+ #TODO: check if this is really necessary, use argv**
- for querytemp in querys:
+ 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:
- """nothing"""
+ pass
-
- #print formatfile
-
-
+ #sichern
self.REQUEST.SESSION['query']=string.join(self.REQUEST['QUERY_STRING'].split("&"),",")
self.REQUEST.SESSION['come_from_search']="yes"
@@ -1321,7 +1498,7 @@ class ZSQLBibliography(Folder,ZSQLExtend
else:
return ""
- def getMetaDataXML2(self):
+ def getXML2(self):
"""crate index meta"""
fn=os.path.splitext(self.REQUEST['fn'])[0]+"."