server/session.py
changeset 9024 701b19785f1d
parent 9023 67f242261dd3
child 9025 768eb9a6a2db
equal deleted inserted replaced
9023:67f242261dd3 9024:701b19785f1d
   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 
  1356     def closed(self):
  1351     def closed(self):
  1357         return not hasattr(self, '_cnxs')
  1352         return not hasattr(self, '_cnxs')
  1358 
  1353 
  1359     # transaction data/operations management ##################################
  1354     # transaction data/operations management ##################################
  1360 
  1355 
  1361     transaction_data = cnx_attr('data')
  1356     transaction_data = cnx_attr('transaction_data')
  1362     pending_operations = cnx_attr('pending_operations')
  1357     pending_operations = cnx_attr('pending_operations')
  1363     pruned_hooks_cache = cnx_attr('pruned_hooks_cache')
  1358     pruned_hooks_cache = cnx_attr('pruned_hooks_cache')
  1364     add_operation      = cnx_meth('add_operation')
  1359     add_operation      = cnx_meth('add_operation')
  1365 
  1360 
  1366     # undo support ############################################################
  1361     # undo support ############################################################
  1370 
  1365 
  1371     def transaction_uuid(self, set=True):
  1366     def transaction_uuid(self, set=True):
  1372         try:
  1367         try:
  1373             return self._cnx.transaction_uuid(set=set)
  1368             return self._cnx.transaction_uuid(set=set)
  1374         except KeyError:
  1369         except KeyError:
  1375             self._cnx.data['tx_uuid'] = uuid = uuid4().hex
  1370             self._cnx.transaction_data['tx_uuid'] = uuid = uuid4().hex
  1376             self.repo.system_source.start_undoable_transaction(self, uuid)
  1371             self.repo.system_source.start_undoable_transaction(self, uuid)
  1377             return uuid
  1372             return uuid
  1378 
  1373 
  1379     # querier helpers #########################################################
  1374     # querier helpers #########################################################
  1380 
  1375