diff options
Diffstat (limited to 'sqlplain/sql_support.py')
-rw-r--r-- | sqlplain/sql_support.py | 91 |
1 files changed, 0 insertions, 91 deletions
diff --git a/sqlplain/sql_support.py b/sqlplain/sql_support.py deleted file mode 100644 index 357a14a..0000000 --- a/sqlplain/sql_support.py +++ /dev/null @@ -1,91 +0,0 @@ -import re, inspect -from decorator import FunctionMaker - -class _SymbolReplacer(object): - """ - A small internal class to parse SQL templates with names arguments. - Returns the names of the arguments and the template interpolated with - a placeholder. Used by get_args_templ. - """ - STRING_OR_COMMENT = re.compile(r"('[^']*'|--.*\n)") - SYMBOL = re.compile(r"(?<!:):(\w+)") # a name prefixed by colons - - def __init__(self, placeholder): - self.placeholder = placeholder - self.replaced = [] - self.found = set() - - def get_args_templ(self, templ): - argnames = [] - def repl(mo): - "Replace named args with placeholders" - argname = mo.group(1) - if argname in argnames: - raise NameError('Duplicate argument %r in SQL template' - % argname) - argnames.append(argname) - return self.placeholder or mo.group() - out = [] - for i, chunk in enumerate(self.STRING_OR_COMMENT.split(templ)): - if i % 2 == 0: # real sql code - chunk = self.SYMBOL.sub(repl, chunk) - out.append(chunk) - return argnames, ''.join(out) - -templ_cache = {} - -# used in .execute and do -def get_args_templ(templ, placeholder=None): - # this is small hack instead of a full featured SQL parser - """ - Take a SQL template and replace named arguments with the placeholder, except - in strings and comments. Return the replaced arguments and the new - template. The results are cached. - - >>> args, templ = get_args_templ('INSERT INTO book (:title, :author)') - >>> print args - ['title', 'author'] - >>> print templ - INSERT INTO book (:title, :author) - >>> print get_args_templ('INSERT INTO book (:title, :author)', '?')[1] - INSERT INTO book (?, ?) - """ - if (templ, placeholder) in templ_cache: - return templ_cache[templ, placeholder] - argnames, new_templ = _SymbolReplacer(placeholder).get_args_templ(templ) - templ_cache[templ, placeholder] = argnames, new_templ - return argnames, new_templ - -def do(templ, name='sqlquery', defaults=None, scalar=False, ntuple=None): - """ - Compile a SQL query template down to a Python function with attributes - __source__, argnames defaults, scalar, ntuple. defaults is a tuple. - """ - argnames = ', '.join(get_args_templ(templ)[0]) - if argnames: - argnames += ',' - src = '''def %(name)s(conn, %(argnames)s): - return conn.execute(templ, (%(argnames)s), scalar=scalar, ntuple=ntuple) - ''' % locals() - fn = FunctionMaker( - name=name, signature=argnames, defaults=defaults, doc=templ).make( - src, dict(templ=templ, scalar=scalar, ntuple=ntuple), addsource=True) - comment = '# ntuple = %s\n# scalar = %s\n# templ=\n%s\n' % ( - ntuple, scalar, '\n'.join('## ' + ln for ln in templ.splitlines())) - fn.__source__ = '%s\n%s' % (comment, fn.__source__) - fn.templ = templ - fn.argnames = argnames - fn.defaults = defaults - fn.scalar = scalar - fn.ntuple = ntuple - return fn - -def spec(fn, clause, argnames=None, defaults=None, ntuple=None): - "Add a clause to an SQL Template function" - return do(fn.templ + clause, argnames = argnames or fn.argnames, - defaults=defaults or fn.defaults, - scalar=fn.scalar, ntuple=ntuple or fn.ntuple) - - -if __name__ == '__main__': - import doctest; doctest.testmod() |