Example #1
0
    def sql_sub_vars(self, sql, args):
        """Extract $XYZ-style variables from the `sql` query.
        """
        names = set()
        values = []
        missing_args = []

        def add_value(aname):
            names.add(aname)
            try:
                arg = args[aname]
                # support one level of indirection (e.g. for $USER)
                if arg.startswith('$'):
                    arg = arg[1:]
                    if not arg.startswith('$'):  # $$ quotes for $
                        arg = args[arg]
            except KeyError:
                arg = args[str(aname)] = ''
                missing_args.append(aname)
            values.append(arg)

        # simple parameter substitution outside literal
        def repl(match):
            add_value(match.group(1))
            return '%s'

        # inside a literal break it and concatenate with the parameter
        def repl_literal(expr, db):
            parts = sub_vars_re.split(expr[1:-1])
            if len(parts) == 1:
                return expr
            params = parts[1::2]
            parts = ["'%s'" % p for p in parts]
            parts[1::2] = ['%s'] * len(params)
            for param in params:
                add_value(param)
            return db.concat(*parts)

        sql_io = io.StringIO()

        # break SQL into literals and non-literals to handle replacing
        # variables within them with query parameters
        with self.env.db_query as db:
            for expr in re.split("('(?:[^']|(?:''))*')", sql):
                if expr.startswith("'"):
                    sql_io.write(repl_literal(expr, db))
                else:
                    sql_io.write(sub_vars_re.sub(repl, expr))

        # Remove arguments that don't appear in the SQL query
        for name in set(args) - names:
            del args[name]
        return sql_io.getvalue(), values, missing_args
Example #2
0
    def sql_sub_vars(self, sql, args, db=None):
        """Extract $XYZ-style variables from the `sql` query.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        names = set()
        values = []
        missing_args = []

        def add_value(aname):
            names.add(aname)
            try:
                arg = args[aname]
            except KeyError:
                arg = args[str(aname)] = ""
                missing_args.append(aname)
            values.append(arg)

        # simple parameter substitution outside literal
        def repl(match):
            add_value(match.group(1))
            return "%s"

        # inside a literal break it and concatenate with the parameter
        def repl_literal(expr):
            parts = sub_vars_re.split(expr[1:-1])
            if len(parts) == 1:
                return expr
            params = parts[1::2]
            parts = ["'%s'" % p for p in parts]
            parts[1::2] = ["%s"] * len(params)
            for param in params:
                add_value(param)
            return self.env.get_read_db().concat(*parts)

        sql_io = StringIO()

        # break SQL into literals and non-literals to handle replacing
        # variables within them with query parameters
        for expr in re.split("('(?:[^']|(?:''))*')", sql):
            if expr.startswith("'"):
                sql_io.write(repl_literal(expr))
            else:
                sql_io.write(sub_vars_re.sub(repl, expr))

        # Remove arguments that don't appear in the SQL query
        for name in set(args) - names:
            del args[name]
        return sql_io.getvalue(), values, missing_args
Example #3
0
    def sql_sub_vars(self, sql, args, db=None):
        """Extract $XYZ-style variables from the `sql` query.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        names = set()
        values = []
        missing_args = []

        def add_value(aname):
            names.add(aname)
            try:
                arg = args[aname]
            except KeyError:
                arg = args[str(aname)] = ''
                missing_args.append(aname)
            values.append(arg)

        # simple parameter substitution outside literal
        def repl(match):
            add_value(match.group(1))
            return '%s'

        # inside a literal break it and concatenate with the parameter
        def repl_literal(expr):
            parts = sub_vars_re.split(expr[1:-1])
            if len(parts) == 1:
                return expr
            params = parts[1::2]
            parts = ["'%s'" % p for p in parts]
            parts[1::2] = ['%s'] * len(params)
            for param in params:
                add_value(param)
            return self.env.get_read_db().concat(*parts)

        sql_io = StringIO()

        # break SQL into literals and non-literals to handle replacing
        # variables within them with query parameters
        for expr in re.split("('(?:[^']|(?:''))*')", sql):
            if expr.startswith("'"):
                sql_io.write(repl_literal(expr))
            else:
                sql_io.write(sub_vars_re.sub(repl, expr))

        # Remove arguments that don't appear in the SQL query
        for name in set(args) - names:
            del args[name]
        return sql_io.getvalue(), values, missing_args