Changeset 3392

Show
Ignore:
Timestamp:
09/20/2007 06:15:59 AM (1 year ago)
Author:
ed
Message:

Refined the auto-quoting to work with any keywords that need to be ignored for quoting purposes, such as 'asc' and 'desc' in 'order by' clauses, or 'as' in field/table aliases.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dabo/db/dBackend.py

    r3372 r3392  
    226226 
    227227 
    228     def encloseNames(self, exp, autoQuote=True): 
     228    def encloseNames(self, exp, autoQuote=True, keywords=None): 
    229229        """When table/field names contain spaces, this will safely enclose them 
    230230        in quotes or whatever delimiter is appropriate for the backend, unless 
    231         autoQuote is False, in which case it leaves things untouched. 
     231        autoQuote is False, in which case it leaves things untouched. If there are 
     232        keywords that are part of the expression that should not be enclosed 
     233        within the field name, pass them as a tuple to the keywords parameter. 
    232234        """ 
    233235        if autoQuote: 
    234             # First separate any alias structures, e.g., 'foo as bar'. 
    235             parts = re.split(r"\s+as\s+", exp) 
     236            if keywords is None: 
     237                parts = [exp] 
     238                subs = lowkeys = tuple() 
     239            else: 
     240                # First separate any keywords: e.g., 'foo as bar'. 
     241                pat = re.compile(r"(\b%s\b)" % r"\b|\b".join(keywords), re.I) 
     242                parts = pat.split(exp) 
     243                subs = tuple(pat.findall(exp)) 
     244                lowkeys = [k.lower() for k in keywords] 
    236245            delim = self.nameEnclosureChar 
    237246            def encPart(part): 
    238                 qtd = [delim + pt + delim for pt in part.split(".") if pt] 
     247                qtd = [delim + pt.strip() + delim for pt in part.split(".") if pt] 
    239248                return ".".join(qtd) 
    240             exp = " as ".join([encPart(pt) for pt in parts]) 
    241         return exp 
     249            exp = " %s ".join([encPart(pt) for pt in parts 
     250                    if pt.lower() not in lowkeys]) 
     251        return exp % subs 
    242252     
    243253     
     
    247257        # If exp is a function, don't do anything special about spaces. 
    248258        if not self.functionPat.match(exp): 
    249             exp = self.encloseNames(exp, autoQuote=autoQuote
     259            exp = self.encloseNames(exp, autoQuote=autoQuote, keywords=("as",)
    250260        if alias: 
    251             alias = self.encloseNames(alias, autoQuote=autoQuote
     261            alias = self.encloseNames(alias, autoQuote=autoQuote, keywords=("as",)
    252262            exp = "%(exp)s as %(alias)s" % locals() 
    253263        # Give the backend-specific code a chance to update the format 
     
    258268    def addFrom(self, clause, exp, autoQuote=True): 
    259269        """ Add a table to the sql statement.""" 
    260         exp = self.encloseNames(exp, autoQuote=autoQuote
     270        exp = self.encloseNames(exp, autoQuote=autoQuote, keywords=("as",)
    261271        indent = len("select ") * " " 
    262272        return self.addWithSep(clause, exp, sep=",\n%s" % indent) 
     
    265275    def addJoin(self, tbl, joinCondition, exp, joinType=None, autoQuote=True): 
    266276        """ Add a joined table to the sql statement.""" 
    267         tbl = self.encloseNames(tbl, autoQuote=autoQuote
     277        tbl = self.encloseNames(tbl, autoQuote=autoQuote, keywords=("as",)
    268278        joinType = self.formatJoinType(joinType) 
    269279        indent = len("select ") * " " 
     
    288298    def addOrderBy(self, clause, exp, autoQuote=True): 
    289299        """ Add an expression to the order-by clause.""" 
    290         exp = self.encloseNames(exp, autoQuote=autoQuote
     300        exp = self.encloseNames(exp, autoQuote=autoQuote, keywords=("asc", "desc")
    291301        indent = len("select ") * " " 
    292302        return self.addWithSep(clause, exp, sep=",\n%s" % indent)