408 self.running_dbapi_query = True |
408 self.running_dbapi_query = True |
409 # internal (root) session |
409 # internal (root) session |
410 self.is_internal_session = session.is_internal_session |
410 self.is_internal_session = session.is_internal_session |
411 |
411 |
412 #: dict containing arbitrary data cleared at the end of the transaction |
412 #: dict containing arbitrary data cleared at the end of the transaction |
413 self.data = {} |
413 self.transaction_data = {} |
414 #: ordered list of operations to be processed on commit/rollback |
414 #: ordered list of operations to be processed on commit/rollback |
415 self.pending_operations = [] |
415 self.pending_operations = [] |
416 #: (None, 'precommit', 'postcommit', 'uncommitable') |
416 #: (None, 'precommit', 'postcommit', 'uncommitable') |
417 self.commit_state = None |
417 self.commit_state = None |
418 |
418 |
435 self.undo_actions = config['undo-enabled'] |
435 self.undo_actions = config['undo-enabled'] |
436 |
436 |
437 # RQLRewriter are not thread safe |
437 # RQLRewriter are not thread safe |
438 self._rewriter = rewriter |
438 self._rewriter = rewriter |
439 |
439 |
440 @property |
|
441 def transaction_data(self): |
|
442 return self.data |
|
443 |
|
444 |
|
445 def clear(self): |
440 def clear(self): |
446 """reset internal data""" |
441 """reset internal data""" |
447 self.data = {} |
442 self.transaction_data = {} |
448 #: ordered list of operations to be processed on commit/rollback |
443 #: ordered list of operations to be processed on commit/rollback |
449 self.pending_operations = [] |
444 self.pending_operations = [] |
450 #: (None, 'precommit', 'postcommit', 'uncommitable') |
445 #: (None, 'precommit', 'postcommit', 'uncommitable') |
451 self.commit_state = None |
446 self.commit_state = None |
452 self.pruned_hooks_cache = {} |
447 self.pruned_hooks_cache = {} |
499 self.repo._free_cnxset(cnxset) |
494 self.repo._free_cnxset(cnxset) |
500 |
495 |
501 |
496 |
502 # Entity cache management ################################################# |
497 # Entity cache management ################################################# |
503 # |
498 # |
504 # The connection entity cache as held in cnx.data it is removed at end the |
499 # The connection entity cache as held in cnx.transaction_data it is removed at end the |
505 # end of the connection (commit and rollback) |
500 # end of the connection (commit and rollback) |
506 # |
501 # |
507 # XXX connection level caching may be a pb with multiple repository |
502 # XXX connection level caching may be a pb with multiple repository |
508 # instances, but 1. this is probably not the only one :$ and 2. it may be |
503 # instances, but 1. this is probably not the only one :$ and 2. it may be |
509 # an acceptable risk. Anyway we could activate it or not according to a |
504 # an acceptable risk. Anyway we could activate it or not according to a |
510 # configuration option |
505 # configuration option |
511 |
506 |
512 def set_entity_cache(self, entity): |
507 def set_entity_cache(self, entity): |
513 """Add `entity` to the connection entity cache""" |
508 """Add `entity` to the connection entity cache""" |
514 ecache = self.data.setdefault('ecache', {}) |
509 ecache = self.transaction_data.setdefault('ecache', {}) |
515 ecache.setdefault(entity.eid, entity) |
510 ecache.setdefault(entity.eid, entity) |
516 |
511 |
517 def entity_cache(self, eid): |
512 def entity_cache(self, eid): |
518 """get cache entity for `eid`""" |
513 """get cache entity for `eid`""" |
519 return self.data['ecache'][eid] |
514 return self.transaction_data['ecache'][eid] |
520 |
515 |
521 def cached_entities(self): |
516 def cached_entities(self): |
522 """return the whole entity cache""" |
517 """return the whole entity cache""" |
523 return self.data.get('ecache', {}).values() |
518 return self.transaction_data.get('ecache', {}).values() |
524 |
519 |
525 def drop_entity_cache(self, eid=None): |
520 def drop_entity_cache(self, eid=None): |
526 """drop entity from the cache |
521 """drop entity from the cache |
527 |
522 |
528 If eid is None, the whole cache is dropped""" |
523 If eid is None, the whole cache is dropped""" |
529 if eid is None: |
524 if eid is None: |
530 self.data.pop('ecache', None) |
525 self.transaction_data.pop('ecache', None) |
531 else: |
526 else: |
532 del self.data['ecache'][eid] |
527 del self.transaction_data['ecache'][eid] |
533 |
528 |
534 # Tracking of entity added of removed in the transaction ################## |
529 # Tracking of entity added of removed in the transaction ################## |
535 # |
530 # |
536 # Those are function to allows cheap call from client in other process. |
531 # Those are function to allows cheap call from client in other process. |
537 |
532 |
538 def deleted_in_transaction(self, eid): |
533 def deleted_in_transaction(self, eid): |
539 """return True if the entity of the given eid is being deleted in the |
534 """return True if the entity of the given eid is being deleted in the |
540 current transaction |
535 current transaction |
541 """ |
536 """ |
542 return eid in self.data.get('pendingeids', ()) |
537 return eid in self.transaction_data.get('pendingeids', ()) |
543 |
538 |
544 def added_in_transaction(self, eid): |
539 def added_in_transaction(self, eid): |
545 """return True if the entity of the given eid is being created in the |
540 """return True if the entity of the given eid is being created in the |
546 current transaction |
541 current transaction |
547 """ |
542 """ |
548 return eid in self.data.get('neweids', ()) |
543 return eid in self.transaction_data.get('neweids', ()) |
549 |
544 |
550 # Operation management #################################################### |
545 # Operation management #################################################### |
551 |
546 |
552 def add_operation(self, operation, index=None): |
547 def add_operation(self, operation, index=None): |
553 """add an operation to be executed at the end of the transaction""" |
548 """add an operation to be executed at the end of the transaction""" |
643 |
638 |
644 def ertype_supports_undo(self, ertype): |
639 def ertype_supports_undo(self, ertype): |
645 return self.undo_actions and ertype not in NO_UNDO_TYPES |
640 return self.undo_actions and ertype not in NO_UNDO_TYPES |
646 |
641 |
647 def transaction_uuid(self, set=True): |
642 def transaction_uuid(self, set=True): |
648 uuid = self.data.get('tx_uuid') |
643 uuid = self.transaction_data.get('tx_uuid') |
649 if set and uuid is None: |
644 if set and uuid is None: |
650 raise KeyError |
645 raise KeyError |
651 return uuid |
646 return uuid |
652 |
647 |
653 def transaction_inc_action_counter(self): |
648 def transaction_inc_action_counter(self): |
654 num = self.data.setdefault('tx_action_count', 0) + 1 |
649 num = self.transaction_data.setdefault('tx_action_count', 0) + 1 |
655 self.data['tx_action_count'] = num |
650 self.transaction_data['tx_action_count'] = num |
656 return num |
651 return num |
657 # db-api like interface ################################################### |
652 # db-api like interface ################################################### |
658 |
653 |
659 def source_defs(self): |
654 def source_defs(self): |
660 return self.repo.source_defs() |
655 return self.repo.source_defs() |
1116 # shared data handling ################################################### |
1111 # shared data handling ################################################### |
1117 |
1112 |
1118 def get_shared_data(self, key, default=None, pop=False, txdata=False): |
1113 def get_shared_data(self, key, default=None, pop=False, txdata=False): |
1119 """return value associated to `key` in session data""" |
1114 """return value associated to `key` in session data""" |
1120 if txdata: |
1115 if txdata: |
1121 data = self._cnx.data |
1116 data = self._cnx.transaction_data |
1122 else: |
1117 else: |
1123 data = self.data |
1118 data = self.data |
1124 if pop: |
1119 if pop: |
1125 return data.pop(key, default) |
1120 return data.pop(key, default) |
1126 else: |
1121 else: |
1127 return data.get(key, default) |
1122 return data.get(key, default) |
1128 |
1123 |
1129 def set_shared_data(self, key, value, txdata=False): |
1124 def set_shared_data(self, key, value, txdata=False): |
1130 """set value associated to `key` in session data""" |
1125 """set value associated to `key` in session data""" |
1131 if txdata: |
1126 if txdata: |
1132 self._cnx.data[key] = value |
1127 self._cnx.transaction_data[key] = value |
1133 else: |
1128 else: |
1134 self.data[key] = value |
1129 self.data[key] = value |
1135 |
1130 |
1136 # server-side service call ################################################# |
1131 # server-side service call ################################################# |
1137 |
1132 |