--- ZSQLExtend/ZSQLExtend.py 2007/08/09 15:09:27 1.119 +++ ZSQLExtend/ZSQLExtend.py 2009/02/04 09:10:45 1.129 @@ -127,7 +127,15 @@ class ZSQLExtendFolder(Folder,Persistent """quote str for sql""" 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): """normalize a field, d.h. entfernt alle diakritischen Zeichen und ersetzt diese durch den Grundbuchstaben in einer Spalte einer Tabelle @@ -364,7 +372,7 @@ class ZSQLExtendFolder(Folder,Persistent ''' 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 table: name of the table the xml shall be imported into (may be comma-separated list) @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. @@ -389,46 +397,54 @@ class ZSQLExtendFolder(Folder,Persistent 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.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 - RESPONSE.setHeader("Content-Type","text/plain; charset=utf-8") - RESPONSE.write("Import FMPXML file...\n\n") - 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 + + tablelist=table.split(',') + logging.debug("tablelist: %s" %tablelist) + #table=tables + + for t in tablelist : + logging.debug("table: %s" %table) + options=Options() + options.dsn=dsn + options.table=t + options.filename=filename + options.update_fields=update_fields + options.id_field=id_field + options.sync_mode=sync_mode + options.lc_names=lc_names + options.replace_table=replace + options.keep_fields=keep_fields + options.ascii_db=ascii_db + options.replace_table=replace + options.backup_table=backup + options.debug=debug + + if RESPONSE and log_to_response: + # set up logging to response as plain text + 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 - importFMPXML(options) + importFMPXML(options) + + + if RESPONSE and log_to_response: + loghandler.flush() + RESPONSE.write("\n\n DONE!") + + elif RESPONSE and redirect_url: + RESPONSE.redirect(redirect_url) + os.remove(filename) - - if RESPONSE and log_to_response: - loghandler.flush() - RESPONSE.write("\n\n DONE!") - return - - if RESPONSE and redirect_url: - RESPONSE.redirect(redirect_url) def generateIndex(self,field,index_name,table,RESPONSE=None): @@ -474,6 +490,27 @@ class ZSQLExtendFolder(Folder,Persistent """ 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): """suche relative haufigkeiten (experimental)""" ret={} @@ -543,9 +580,9 @@ class ZSQLExtendFolder(Folder,Persistent @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))) + #logging.debug("formatascii str=%s url=%s"%(repr(str),repr(url))) - if not str: + if not str: return "" str=str.rstrip().lstrip() @@ -626,6 +663,7 @@ class ZSQLExtendFolder(Folder,Persistent @param _value: String der gesucht werden soll, gesucht wird nach allen Worten des Strings, die durch " "-getrennt sind. @param _idField: Feld mit id fŸr die identifikation gleicher EintrŠge @param _additionalStatement: (optional) Zusaetzliches SQL Statement, dass zwischen dem ersten "select from" und dem ersten "where" eingegefŸgt wird. + @param _subselectAddition: (optiona) Zusaetliche SQL Statement die hinter das select statement der subselects eingefuegt werde. @param _select: (optional) Alternativer Wert fŸr den ersten SELECT Aufruf. @param _storename: (optional) Name fuer die Zwischenspeicherung von Werten in der Session """ @@ -837,7 +875,7 @@ class ZSQLExtendFolder(Folder,Persistent #print "INLINE:",argv 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]))) #return [] ret = self.parseQueryString(string.join(qs,","),"_",storename=storename) @@ -1000,18 +1038,19 @@ 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""" - if args: + 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]))) + if _useRequest: + for a in self.REQUEST.form.keys(): + qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a]))) qs=string.join(qs_temp,",") @@ -1026,7 +1065,10 @@ class ZSQLExtendFolder(Folder,Persistent addList={} for q in qs.split(","): + if len(q.split("="))<2: + continue name=re.sub("r'+'"," ",q.split("=")[0].lower()) + value=q.split("=")[1] value=re.sub(r'\+'," ",value) value=urllib.unquote(value) @@ -1101,10 +1143,10 @@ class ZSQLExtendFolder(Folder,Persistent #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))) + if value=="": + changeList.append("\""+name+"\"=null") + else: + changeList.append("\""+name+"\"="+sql_quote(urllib.unquote(value))) changeString=string.join(changeList,",") @@ -1247,30 +1289,25 @@ class ZSQLExtendFolder(Folder,Persistent """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] + queryList[arg]=urllib.unquote_plus(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 "_" @@ -1282,6 +1319,7 @@ class ZSQLExtendFolder(Folder,Persistent 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""" @@ -1465,7 +1503,7 @@ class ZSQLExtendFolder(Folder,Persistent elif op=="numerical": term=analyseIntSearch(value) - tmp=(name+" "+term) + tmp=(namealt+" "+term) # take namealt without LOWER elif op=="grep": tmp=(name+" ~* "+sql_quote(value)) elif op=="one": @@ -1515,7 +1553,7 @@ class ZSQLExtendFolder(Folder,Persistent elif op=="numerical": term=analyseIntSearch(value) - tmp=(name+" "+term) + tmp=(namealt+" "+term) # take namealt without LOWER elif op=="grep": tmp=(name+" ~* "+sql_quote(value)) elif op=="one":