1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import string
27 import sys
28 import sql_types
29 from spacewalk.common import usix
30
31
33 """ Create a dictionary from a row description and its values. """
34 data = {}
35 if not names:
36 raise AttributeError("Class initialization requires a description hash")
37 if row is None:
38 return data
39 for x in range(len(names)):
40 name, value = __oci_name_value(names[x], row[x])
41 data[name] = value
42 return data
43
44
46 """ Extract the name, value pair needed by ociDict function. """
47
48 name, dbitype, dsize, dbsize, prec, scale, nullok = names
49 name = name.lower()
50 return name, value
51
52
53
56
57
58
60
61 - def __init__(self, errno, errmsg, *args):
62 self.errno = errno
63 (self.errmsg, errmsg) = string.split(errmsg, '\n', 1)
64 SQLError.__init__(self, self.errno, self.errmsg, errmsg, *args)
65
66
67
69
70 - def __init__(self, db, errno, errmsg, *args):
71 self.db = db
72 self.errno = errno
73 self.errmsg = errmsg
74 SQLError.__init__(self, errno, errmsg, db, *args)
75
76
77
79
81 self.db = db
82 self.errmsg = errmsg
83 SQLError.__init__(self, errmsg, db, *args)
84
85
88
89
91
92 """ A class to implement generic SQL Cursor operations. """
93
94
95
96
97 _cursor_cache = {}
98
99 - def __init__(self, dbh=None, sql=None, force=None):
100 self.sql = sql
101 self.dbh = dbh
102
103 self.reparsed = 0
104 self._real_cursor = None
105 self._dbh_id = id(dbh)
106
107 self.description = None
108
109 if self._dbh_id not in self._cursor_cache:
110 self._cursor_cache[self._dbh_id] = {}
111
112
113 self._real_cursor = self._prepare(force=force)
114
116 raise NotImplementedError()
117
119 if self.sql:
120
121 _h = self._cursor_cache[self._dbh_id]
122 if not force and self.sql in _h:
123 return _h[self.sql]
124 cursor = self._prepare_sql()
125 if self.sql:
126 _h[self.sql] = cursor
127 return cursor
128
129 - def prepare(self, sql, force=None):
130 """
131 Prepares the current statement.
132
133 Must be called prior to execute even if the underlying database driver
134 does not support an explicit prepare before execution.
135 """
136 if sql is None:
137 raise Exception("XXX Unable to prepare None")
138 self.sql = sql
139 self._real_cursor = self._prepare(force=force)
140
141 - def update_blob(self, table_name, column_name, where_clause,
142 data, **kwargs):
143 """
144 Abstraction for the update of a blob column which can vary wildly
145 between different database implementations.
146 """
147 raise NotImplementedError()
148
152
154 """
155 Execute a query multiple times with different data sets.
156
157 Call with keyword arguments mapping to ordered lists.
158 i.e. cursor.executemany(id=[1, 2], name=["Bill", "Mary"])
159 """
160 return self._execute_wrapper(self._executemany, *p, **kw)
161
163 """
164 Uses executemany but chops the incoming dict into chunks for each
165 call.
166
167 When attempting to execute bulk operations with a lot of rows in the
168 arrays,
169 Oracle may occasionally lock (probably the oracle client library).
170 I noticed this previously with the import code. -- misa
171 This function executes bulk operations in smaller chunks
172 dict is supposed to be the dictionary that we normally apply to
173 statement.execute.
174 """
175 ret = 0
176 start_chunk = 0
177 while 1:
178 subdict = {}
179 for k, arr in dict.items():
180 subarr = arr[start_chunk:start_chunk + chunk_size]
181 if not subarr:
182
183 return ret
184 subdict[k] = subarr
185 ret = ret + self.executemany(**subdict)
186 start_chunk = start_chunk + chunk_size
187
188
189 return ret
190
192 """
193 Database specific execute wrapper. Mostly used just to catch DB
194 exceptions and wrap them.
195
196 Must be subclasses by database specific drivers.
197 """
198 raise NotImplementedError()
199
206
208 raise NotImplementedError()
209
211 """ Database specific execution of the query. """
212 raise NotImplementedError()
213
214
215
216
217
220
222 rows = self._real_cursor.fetchall()
223 return rows
224
226 """
227 Return a dictionary for the row returned mapping column name to
228 it's value.
229 """
230 ret = ociDict(self.description, self._real_cursor.fetchone())
231
232 if len(ret) == 0:
233 return None
234 return ret
235
237 """
238 Fetch all rows as a list of dictionaries.
239 """
240 rows = self._real_cursor.fetchall()
241
242 ret = []
243 for x in rows:
244 d = ociDict(self.description, x)
245 if len(d) > 0:
246 ret.append(d)
247 if ret == []:
248 return None
249 return ret
250
252 if type(val) in (usix.ListType, usix.TupleType):
253 return 1
254 return 0
255
256
258
259 """
260 Class for calling out to stored procedures.
261
262 Written to behave very much like a Python function in that these
263 Procedure objects are "callable".
264
265 See database specific implementations for more details.
266 """
267
271
276
277
279
280 """
281 Base class for handling database operations.
282
283 Inherited from by the backend specific classes for Oracle, PostgreSQL, etc.
284 """
285 _procedure_class = Procedure
286 TimestampFromTicks = None
287
290
292 """ Opens a connection to the database. """
293 raise NotImplementedError()
294
296 """ Check that this connection is still valid. """
297
298
299 raise NotImplementedError()
300
302 """ Prepare an SQL statement. """
303 raise NotImplementedError()
304
306 """ Commit changes """
307 raise NotImplementedError()
308
310 """Return a pointer to a callable instance for a given stored
311 procedure.
312 The return value is a (possibly modified) copy of the arguments passed
313 in. see cx_Oracle's Cursor.callproc for more details"""
314 return self._procedure_class(name, None)
315
316 return self._procedure_class(name, None)
317
319 """
320 Return a pointer to a callable instance for a given stored
321 function.
322
323 The return value is the return value of the function.
324 One has to properly define the return type for the function, since
325 usually the database drivers do not allow for auto-discovery.
326 See cx_Oracle's Cursor.callfunc for more details.
327 """
328 if not isinstance(ret_type, sql_types.DatabaseDataType):
329 raise SQLError("Invalid return type specified", ret_type)
330 return self._function(name, ret_type)
331
333 raise NotImplementedError()
334
336 "set a transaction point to which we can rollback to"
337 pass
338
340 "rollback changes, optionally to a previously set transaction point"
341 pass
342
344 "Close the connection"
345 pass
346
348 "return an empty Cursor object"
349 return Cursor()
350
352 "Fix environment variables (to be redefined in subclasses)"
353 pass
354
356 "Reads a lob's contents"
357 return None
358
359 - def is_connected_to(self, backend, host, port, username, password,
360 database, sslmode):
361 """
362 Check if this database matches the given connection parameters.
363 """
364 raise NotImplementedError()
365
366 - def Date(self, year, month, day):
367 "Returns a Date object"
368 raise NotImplementedError()
369
371 "Returns a Date object"
372 raise NotImplementedError()
373
374
375
376
377
379
381 self.statement = statement
382
384 return "<%s instance at %s; statement=%s" % (
385 self.__class__, id(self), self.statement)
386
388 return self.statement
389