--- /dev/null
+#from __future__ import unicode_literals
+#from __future__ import print_function
+
+import inspect
+import os
+
+from contextlib import contextmanager
+
+import psycopg2
+import psycopg2.pool
+
+from psycopg2.extras import DictCursor
+
+psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
+
+def Cursor(sql):
+ return sql.cursor(cursor_factory=DictCursor)
+
+class Transaction(object):
+ def __init__(self, connection):
+ self.connection = connection
+
+ def pull(self, statement):
+ locals = inspect.currentframe(1).f_locals
+ cursor = Cursor(self.connection)
+
+ try:
+ cursor.execute(statement.format(**locals), locals)
+ return cursor.fetchall()
+ finally:
+ cursor.close()
+
+ def yank(self, statement):
+ locals = inspect.currentframe(1).f_locals
+ cursor = Cursor(self.connection)
+
+ try:
+ cursor.execute(statement.format(**locals), locals)
+ rows = cursor.fetchall()
+ return rows[0] if len(rows) != 0 else None
+ finally:
+ cursor.close()
+
+ def push(self, statement):
+ locals = inspect.currentframe(1).f_locals
+ cursor = Cursor(self.connection)
+
+ try:
+ cursor.execute(statement.format(**locals), locals)
+ finally:
+ cursor.close()
+
+@contextmanager
+def ConnectSQL(dsn):
+ attempt = 0
+ while True:
+ try:
+ sql = psycopg2.connect(**dsn)
+ break
+ except psycopg2.OperationalError, e:
+ if attempt == 2:
+ raise e
+ attempt = attempt + 1
+
+ try:
+ sql.set_client_encoding('UNICODE')
+
+ @contextmanager
+ def transact():
+ try:
+ yield Transaction(sql)
+ sql.commit()
+ except:
+ sql.rollback()
+ raise
+
+ yield transact
+ finally:
+ sql.close()
+
+def slap_(sql, table, keys, values, path):
+ csr = sql.cursor()
+ try:
+ csr.execute('savepoint iou')
+ try:
+ both = dict(keys, **values)
+ fields = both.keys()
+
+ csr.execute('''
+ insert into %s (%s) values (%s)
+ ''' % (
+ table,
+ ', '.join(fields),
+ ', '.join(['%s' for key in fields])
+ ), both.values())
+ except psycopg2.IntegrityError, e:
+ csr.execute('rollback to savepoint iou')
+
+ csr.execute('''
+ update %s set %s where %s
+ ''' % (
+ table,
+ ', '.join([
+ key + ' = %s'
+ for key in values.keys()]),
+ ' and '.join([
+ key + ' = %s'
+ for key in keys.keys()])
+ ), values.values() + keys.values())
+
+ return path_(csr, path)
+ finally:
+ csr.close()