]>
git.saurik.com Git - cyql.git/blob - __init__.py
47f54fd19972e4a9f2e09a25e1430fab5e826247
1 from __future__
import absolute_import
2 from __future__
import division
3 from __future__
import print_function
4 from __future__
import unicode_literals
6 from future_builtins
import ascii
, filter, hex, map, oct, zip
11 from contextlib
import contextmanager
14 import psycopg2
.extras
17 psycopg2
.extensions
.register_type(psycopg2
.extensions
.UNICODE
)
18 psycopg2
.extensions
.register_type(psycopg2
.extensions
.UNICODEARRAY
)
20 class connect(object):
21 def __init__(self
, dsn
):
23 if 'cache' in options
:
38 self
.driver
= psycopg2
.connect(**options
)
40 except psycopg2
.OperationalError
, e
:
45 self
.driver
.autocommit
= True
47 # XXX: all of my databases default to this...
49 # self.driver.set_client_encoding('UNICODE')
54 hstore
= cache
['hstore']
56 hstore
= psycopg2
.extras
.HstoreAdapter
.get_oids(self
.driver
)
59 cache
['hstore'] = hstore
63 psycopg2
.extras
.register_hstore(self
.driver
, globally
=False, unicode=True, oid
=hstore
)
64 except psycopg2
.ProgrammingError
, e
:
76 def __exit__(self
, type, value
, traceback
):
80 self
.driver
.autocommit
= False
86 self
.driver
.rollback()
90 cursor
= self
.driver
.cursor(cursor_factory
=psycopg2
.extras
.DictCursor
)
97 def execute(self
, statement
, depth
=0, context
=None):
98 # two frames, accounting for execute() and @contextmanager
99 frame
= inspect
.currentframe(depth
+ 2)
101 with self
.cursor() as cursor
:
103 f_locals
= frame
.f_locals
106 context
= dict(**f_locals
)
110 percent
= statement
.find('%', start
)
114 next
= statement
[percent
+ 1]
116 start
= statement
.index(')', percent
+ 2) + 2
117 assert statement
[start
- 1] == 's'
119 start
= statement
.index('}', percent
+ 2)
120 assert statement
[start
+ 1] == 's'
121 code
= statement
[percent
+ 2:start
]
123 if f_globals
== None:
124 f_globals
= frame
.f_globals
126 key
= '__cyql__%i' % (percent
,)
127 # XXX: compile() in the frame's context
128 context
[key
] = eval(code
, f_globals
, f_locals
)
130 statement
= '%s%%(%s)%s' % (statement
[0:percent
], key
, statement
[start
+ 1:])
131 start
= percent
+ len(key
) + 4
132 elif next
in ('%', 's'):
137 cursor
.execute(statement
, context
)
146 def transact(self
, synchronous_commit
=True):
147 self
.driver
.autocommit
= False
149 with self
.cursor() as cursor
:
150 if not synchronous_commit
:
151 cursor
.execute('set local synchronous_commit = off')
156 self
.driver
.rollback()
159 self
.driver
.autocommit
= True
161 def one_(self
, statement
, context
=None):
162 with self
.execute(statement
, 2, context
) as cursor
:
163 one
= cursor
.fetchone()
167 assert cursor
.fetchone() == None
170 def __call__(self
, procedure
, *parameters
):
171 with self
.execute(statement
, 1) as cursor
:
172 return cursor
.callproc(procedure
, *parameters
)
174 def run(self
, statement
, context
=None):
175 with self
.execute(statement
, 1, context
) as cursor
:
176 return cursor
.rowcount
179 def set(self
, statement
):
180 with self
.execute(statement
, 2) as cursor
:
183 def all(self
, statement
, context
=None):
184 with self
.execute(statement
, 1, context
) as cursor
:
185 return cursor
.fetchall()
187 def one(self
, statement
, context
=None):
188 return self
.one_(statement
, context
)
190 def has(self
, statement
):
191 exists
, = self
.one_('select exists(%s)' % (statement
,))
196 def replaced(*args
, **kw
):
197 with connect(dsn
) as sql
:
198 return method(*args
, sql
=sql
, **kw
)
203 def transact(dsn
, *args
, **kw
):
204 with connect(dsn
) as connection
:
205 with connection
.transact(*args
, **kw
):
209 def slap_(sql, table, keys, values, path):
212 csr.execute('savepoint iou')
214 both = dict(keys, **values)
218 insert into %s (%s) values (%s)
222 ', '.join(['%s' for key in fields])
224 except psycopg2.IntegrityError, e:
225 csr.execute('rollback to savepoint iou')
228 update %s set %s where %s
233 for key in values.keys()]),
236 for key in keys.keys()])
237 ), values.values() + keys.values())
239 return path_(csr, path)