150 skip_relations, skip_entities) |
150 skip_relations, skip_entities) |
151 return stmts |
151 return stmts |
152 |
152 |
153 |
153 |
154 _SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION = re.compile('^(?!(sql|pg)_)').match |
154 _SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION = re.compile('^(?!(sql|pg)_)').match |
|
155 |
|
156 |
155 def sql_drop_all_user_tables(driver_or_helper, sqlcursor): |
157 def sql_drop_all_user_tables(driver_or_helper, sqlcursor): |
156 """Return ths sql to drop all tables found in the database system.""" |
158 """Return ths sql to drop all tables found in the database system.""" |
157 if not getattr(driver_or_helper, 'list_tables', None): |
159 if not getattr(driver_or_helper, 'list_tables', None): |
158 dbhelper = db.get_db_helper(driver_or_helper) |
160 dbhelper = db.get_db_helper(driver_or_helper) |
159 else: |
161 else: |
160 dbhelper = driver_or_helper |
162 dbhelper = driver_or_helper |
161 |
163 |
162 cmds = [dbhelper.sql_drop_sequence('entities_id_seq')] |
164 stmts = [dbhelper.sql_drop_sequence('entities_id_seq')] |
163 # for mssql, we need to drop views before tables |
165 # for mssql, we need to drop views before tables |
164 if hasattr(dbhelper, 'list_views'): |
166 if hasattr(dbhelper, 'list_views'): |
165 cmds += ['DROP VIEW %s;' % name |
167 stmts += ['DROP VIEW %s;' % name |
166 for name in filter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, dbhelper.list_views(sqlcursor))] |
168 for name in filter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, |
167 cmds += ['DROP TABLE %s;' % name |
169 dbhelper.list_views(sqlcursor))] |
168 for name in filter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, dbhelper.list_tables(sqlcursor))] |
170 stmts += ['DROP TABLE %s;' % name |
169 return '\n'.join(cmds) |
171 for name in filter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, |
|
172 dbhelper.list_tables(sqlcursor))] |
|
173 return stmts |
170 |
174 |
171 |
175 |
172 class ConnectionWrapper(object): |
176 class ConnectionWrapper(object): |
173 """handle connection to the system source, at some point associated to a |
177 """handle connection to the system source, at some point associated to a |
174 :class:`Session` |
178 :class:`Session` |
197 # bad state. Replace it by a new one. |
201 # bad state. Replace it by a new one. |
198 self.reconnect() |
202 self.reconnect() |
199 |
203 |
200 def close(self, i_know_what_i_do=False): |
204 def close(self, i_know_what_i_do=False): |
201 """close all connections in the set""" |
205 """close all connections in the set""" |
202 if i_know_what_i_do is not True: # unexpected closing safety belt |
206 if i_know_what_i_do is not True: # unexpected closing safety belt |
203 raise RuntimeError('connections set shouldn\'t be closed') |
207 raise RuntimeError('connections set shouldn\'t be closed') |
204 try: |
208 try: |
205 self.cu.close() |
209 self.cu.close() |
206 self.cu = None |
210 self.cu = None |
207 except Exception: |
211 except Exception: |
214 |
218 |
215 # internals ############################################################### |
219 # internals ############################################################### |
216 |
220 |
217 def cnxset_freed(self): |
221 def cnxset_freed(self): |
218 """connections set is being freed from a session""" |
222 """connections set is being freed from a session""" |
219 pass # no nothing by default |
223 pass # no nothing by default |
220 |
224 |
221 def reconnect(self): |
225 def reconnect(self): |
222 """reopen a connection for this source or all sources if none specified |
226 """reopen a connection for this source or all sources if none specified |
223 """ |
227 """ |
224 try: |
228 try: |
265 def cnx(self): |
269 def cnx(self): |
266 if self._cnx is None: |
270 if self._cnx is None: |
267 self._cnx = self._source.get_connection() |
271 self._cnx = self._source.get_connection() |
268 self._cu = self._cnx.cursor() |
272 self._cu = self._cnx.cursor() |
269 return self._cnx |
273 return self._cnx |
|
274 |
270 @cnx.setter |
275 @cnx.setter |
271 def cnx(self, value): |
276 def cnx(self, value): |
272 self._cnx = value |
277 self._cnx = value |
273 |
278 |
274 @property |
279 @property |
275 def cu(self): |
280 def cu(self): |
276 if self._cnx is None: |
281 if self._cnx is None: |
277 self._cnx = self._source.get_connection() |
282 self._cnx = self._source.get_connection() |
278 self._cu = self._cnx.cursor() |
283 self._cu = self._cnx.cursor() |
279 return self._cu |
284 return self._cu |
|
285 |
280 @cu.setter |
286 @cu.setter |
281 def cu(self, value): |
287 def cu(self, value): |
282 self._cu = value |
288 self._cu = value |
283 |
289 |
284 |
290 |
432 if atype in converters: |
438 if atype in converters: |
433 # It is easier to modify preprocess_entity rather |
439 # It is easier to modify preprocess_entity rather |
434 # than add_entity (native) as this behavior |
440 # than add_entity (native) as this behavior |
435 # may also be used for update. |
441 # may also be used for update. |
436 value = converters[atype](value) |
442 value = converters[atype](value) |
437 elif atype == 'Password': # XXX could be done using a TYPE_CONVERTERS callback |
443 elif atype == 'Password': # XXX could be done using a TYPE_CONVERTERS callback |
438 # if value is a Binary instance, this mean we got it |
444 # if value is a Binary instance, this mean we got it |
439 # from a query result and so it is already encrypted |
445 # from a query result and so it is already encrypted |
440 if isinstance(value, Binary): |
446 if isinstance(value, Binary): |
441 value = value.getvalue() |
447 value = value.getvalue() |
442 else: |
448 else: |
443 value = crypt_password(value) |
449 value = crypt_password(value) |
444 value = self._binary(value) |
450 value = self._binary(value) |
445 elif isinstance(value, Binary): |
451 elif isinstance(value, Binary): |
446 value = self._binary(value.getvalue()) |
452 value = self._binary(value.getvalue()) |
447 attrs[SQL_PREFIX+str(attr)] = value |
453 attrs[SQL_PREFIX + str(attr)] = value |
448 attrs[SQL_PREFIX+'eid'] = entity.eid |
454 attrs[SQL_PREFIX + 'eid'] = entity.eid |
449 return attrs |
455 return attrs |
450 |
456 |
451 # these are overridden by set_log_methods below |
457 # these are overridden by set_log_methods below |
452 # only defining here to prevent pylint from complaining |
458 # only defining here to prevent pylint from complaining |
453 info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None |
459 info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None |
454 |
460 |
455 set_log_methods(SQLAdapterMixIn, getLogger('cubicweb.sqladapter')) |
461 set_log_methods(SQLAdapterMixIn, getLogger('cubicweb.sqladapter')) |
456 |
462 |
457 |
463 |
458 # connection initialization functions ########################################## |
464 # connection initialization functions ########################################## |
508 _install_sqlite_querier_patch() |
514 _install_sqlite_querier_patch() |
509 |
515 |
510 class group_concat(object): |
516 class group_concat(object): |
511 def __init__(self): |
517 def __init__(self): |
512 self.values = set() |
518 self.values = set() |
|
519 |
513 def step(self, value): |
520 def step(self, value): |
514 if value is not None: |
521 if value is not None: |
515 self.values.add(value) |
522 self.values.add(value) |
|
523 |
516 def finalize(self): |
524 def finalize(self): |
517 return ', '.join(text_type(v) for v in self.values) |
525 return ', '.join(text_type(v) for v in self.values) |
518 |
526 |
519 cnx.create_aggregate("GROUP_CONCAT", 1, group_concat) |
527 cnx.create_aggregate("GROUP_CONCAT", 1, group_concat) |
520 |
528 |
534 def limit_size2(text, maxsize): |
542 def limit_size2(text, maxsize): |
535 return _limit_size(text, maxsize) |
543 return _limit_size(text, maxsize) |
536 cnx.create_function("TEXT_LIMIT_SIZE", 2, limit_size2) |
544 cnx.create_function("TEXT_LIMIT_SIZE", 2, limit_size2) |
537 |
545 |
538 from logilab.common.date import strptime |
546 from logilab.common.date import strptime |
|
547 |
539 def weekday(ustr): |
548 def weekday(ustr): |
540 try: |
549 try: |
541 dt = strptime(ustr, '%Y-%m-%d %H:%M:%S') |
550 dt = strptime(ustr, '%Y-%m-%d %H:%M:%S') |
542 except: |
551 except: |
543 dt = strptime(ustr, '%Y-%m-%d') |
552 dt = strptime(ustr, '%Y-%m-%d') |
544 # expect sunday to be 1, saturday 7 while weekday method return 0 for |
553 # expect sunday to be 1, saturday 7 while weekday method return 0 for |
545 # monday |
554 # monday |
546 return (dt.weekday() + 1) % 7 |
555 return (dt.weekday() + 1) % 7 |
547 cnx.create_function("WEEKDAY", 1, weekday) |
556 cnx.create_function("WEEKDAY", 1, weekday) |
548 |
557 |