cursor.close()
@contextmanager
- def execute(self, statement, depth=0, context=None):
+ def execute(self, statement, depth=0):
+ # two frames, accounting for execute() and @contextmanager
+ frame = inspect.currentframe(depth + 2)
+
with self.cursor() as cursor:
- # two frames, accounting for execute() and @contextmanager
- locals = inspect.currentframe(depth + 2).f_locals
- try:
- if context == None:
- context = locals
- cursor.execute(statement.format(**locals), context)
- finally:
- del locals
+ f_globals = None
+
+ f_locals = frame.f_locals
+ context = dict(**f_locals)
+
+ start = 0
+ while True:
+ percent = statement.find('%', start)
+ if percent == -1:
+ break
+
+ next = statement[percent + 1]
+ if next == '(':
+ start = statement.index(')', percent + 2) + 2
+ elif next == '{':
+ start = statement.index('}', percent + 2)
+ code = statement[percent + 2:start]
+
+ if f_globals == None:
+ f_globals = frame.f_globals
+
+ key = '__cyql__%i' % (percent,)
+ # XXX: compile() in the frame's context
+ context[key] = eval(code, f_globals, f_locals)
+
+ statement = '%s%%(%s)s%s' % (statement[0:percent], key, statement[start + 1:])
+ start = percent + len(key) + 4
+ elif next == '%':
+ start = percent + 2
+ else:
+ assert False
+
+ cursor.execute(statement, context)
+
+ del context
+ del f_locals
+ del f_globals
+
yield cursor
@contextmanager
with self.execute(statement, 1) as cursor:
return cursor.callproc(procedure, *parameters)
- def run(self, statement, locals=None):
- with self.execute(statement, 1, locals) as cursor:
+ def run(self, statement):
+ with self.execute(statement, 1) as cursor:
return cursor.rowcount
@contextmanager