]>
Commit | Line | Data |
---|---|---|
1 | from __future__ import unicode_literals | |
2 | from __future__ import print_function | |
3 | ||
4 | import inspect | |
5 | import os | |
6 | ||
7 | from contextlib import contextmanager | |
8 | ||
9 | import psycopg2 | |
10 | import psycopg2.extras | |
11 | import psycopg2.pool | |
12 | ||
13 | psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) | |
14 | ||
15 | class connection(object): | |
16 | def __init__(self, driver): | |
17 | self.driver = driver | |
18 | ||
19 | @contextmanager | |
20 | def cursor(self): | |
21 | try: | |
22 | cursor = self.driver.cursor(cursor_factory=psycopg2.extras.DictCursor) | |
23 | yield cursor | |
24 | finally: | |
25 | cursor.close() | |
26 | ||
27 | @contextmanager | |
28 | def execute(self, statement, depth=0): | |
29 | with self.cursor() as cursor: | |
30 | # two frames, accounting for execute() and @contextmanager | |
31 | locals = inspect.currentframe(depth + 2).f_locals | |
32 | try: | |
33 | cursor.execute(statement.format(**locals), locals) | |
34 | finally: | |
35 | del locals | |
36 | yield cursor | |
37 | ||
38 | @contextmanager | |
39 | def transact(self, synchronous_commit=True): | |
40 | with self.cursor() as cursor: | |
41 | if not synchronous_commit: | |
42 | cursor.execute('set local synchronous_commit = off') | |
43 | ||
44 | try: | |
45 | yield transaction(self) | |
46 | self.driver.commit() | |
47 | except: | |
48 | self.driver.rollback() | |
49 | raise | |
50 | ||
51 | class transaction(object): | |
52 | def __init__(self, connection): | |
53 | self.connection = connection | |
54 | ||
55 | def pull(self, statement): | |
56 | with self.connection.execute(statement, 1) as cursor: | |
57 | return cursor.fetchall() | |
58 | ||
59 | def yank(self, statement): | |
60 | with self.connection.execute(statement, 1) as cursor: | |
61 | rows = cursor.fetchall() | |
62 | return rows[0] if len(rows) != 0 else None | |
63 | ||
64 | def push(self, statement): | |
65 | with self.connection.execute(statement, 1) as cursor: | |
66 | pass | |
67 | ||
68 | @contextmanager | |
69 | def connect(dsn): | |
70 | attempt = 0 | |
71 | while True: | |
72 | try: | |
73 | driver = psycopg2.connect(**dsn) | |
74 | break | |
75 | except psycopg2.OperationalError, e: | |
76 | if attempt == 2: | |
77 | raise e | |
78 | attempt = attempt + 1 | |
79 | ||
80 | try: | |
81 | driver.set_client_encoding('UNICODE') | |
82 | yield connection(driver) | |
83 | finally: | |
84 | driver.close() | |
85 | ||
86 | def connected(dsn): | |
87 | def wrapped(method): | |
88 | def replaced(*args, **kw): | |
89 | with connect(dsn) as connection: | |
90 | return method(connection, *args, **kw) | |
91 | return replaced | |
92 | return wrapped | |
93 | ||
94 | @contextmanager | |
95 | def transact(dsn, **args): | |
96 | with connect(dsn) as connection: | |
97 | with connection.transact(**args) as cursor: | |
98 | yield cursor | |
99 | ||
100 | """ | |
101 | def slap_(sql, table, keys, values, path): | |
102 | csr = sql.cursor() | |
103 | try: | |
104 | csr.execute('savepoint iou') | |
105 | try: | |
106 | both = dict(keys, **values) | |
107 | fields = both.keys() | |
108 | ||
109 | csr.execute(''' | |
110 | insert into %s (%s) values (%s) | |
111 | ''' % ( | |
112 | table, | |
113 | ', '.join(fields), | |
114 | ', '.join(['%s' for key in fields]) | |
115 | ), both.values()) | |
116 | except psycopg2.IntegrityError, e: | |
117 | csr.execute('rollback to savepoint iou') | |
118 | ||
119 | csr.execute(''' | |
120 | update %s set %s where %s | |
121 | ''' % ( | |
122 | table, | |
123 | ', '.join([ | |
124 | key + ' = %s' | |
125 | for key in values.keys()]), | |
126 | ' and '.join([ | |
127 | key + ' = %s' | |
128 | for key in keys.keys()]) | |
129 | ), values.values() + keys.values()) | |
130 | ||
131 | return path_(csr, path) | |
132 | finally: | |
133 | csr.close() | |
134 | """ |