cubicweb/server/repository.py
changeset 11774 51c160677afe
parent 11767 432f87a63057
child 11811 f09efeead7f9
equal deleted inserted replaced
11773:054a947b5415 11774:51c160677afe
   177         self.system_source = self.get_source('native', 'system',
   177         self.system_source = self.get_source('native', 'system',
   178                                              config.system_source_config.copy())
   178                                              config.system_source_config.copy())
   179         self.sources_by_uri = {'system': self.system_source}
   179         self.sources_by_uri = {'system': self.system_source}
   180         # querier helper, need to be created after sources initialization
   180         # querier helper, need to be created after sources initialization
   181         self.querier = querier.QuerierHelper(self, self.schema)
   181         self.querier = querier.QuerierHelper(self, self.schema)
   182         # cache eid -> (type, extid)
   182         # cache eid -> type
   183         self._type_extid_cache = {}
   183         self._type_cache = {}
   184         # cache extid -> eid
       
   185         # open some connection sets
   184         # open some connection sets
   186         if config.init_cnxset_pool:
   185         if config.init_cnxset_pool:
   187             self.init_cnxset_pool()
   186             self.init_cnxset_pool()
   188         # the hooks manager
   187         # the hooks manager
   189         self.hm = hook.HooksManager(self.vreg)
   188         self.hm = hook.HooksManager(self.vreg)
   712     # data sources handling ###################################################
   711     # data sources handling ###################################################
   713     # * correspondance between eid and type
   712     # * correspondance between eid and type
   714     # * correspondance between eid and local id (i.e. specific to a given source)
   713     # * correspondance between eid and local id (i.e. specific to a given source)
   715 
   714 
   716     def clear_caches(self, eids):
   715     def clear_caches(self, eids):
   717         etcache = self._type_extid_cache
   716         etcache = self._type_cache
   718         rqlcache = self.querier._rql_cache
   717         rqlcache = self.querier._rql_cache
   719         for eid in eids:
   718         for eid in eids:
   720             try:
   719             try:
   721                 etype, extid = etcache.pop(int(eid))  # may be a string in some cases
   720                 etype = etcache.pop(int(eid))  # may be a string in some cases
   722                 rqlcache.pop(('%s X WHERE X eid %s' % (etype, eid),), None)
   721                 rqlcache.pop(('%s X WHERE X eid %s' % (etype, eid),), None)
   723             except KeyError:
   722             except KeyError:
   724                 etype = None
   723                 etype = None
   725             rqlcache.pop(('Any X WHERE X eid %s' % eid,), None)
   724             rqlcache.pop(('Any X WHERE X eid %s' % eid,), None)
   726             self.system_source.clear_eid_cache(eid, etype)
   725             self.system_source.clear_eid_cache(eid, etype)
   727 
   726 
   728     def type_and_extid_from_eid(self, eid, cnx):
   727     def type_from_eid(self, eid, cnx):
   729         """Return the type and extid of the entity with id `eid`."""
   728         """Return the type of the entity with id `eid`"""
   730         try:
   729         try:
   731             eid = int(eid)
   730             eid = int(eid)
   732         except ValueError:
   731         except ValueError:
   733             raise UnknownEid(eid)
   732             raise UnknownEid(eid)
   734         try:
   733         try:
   735             return self._type_extid_cache[eid]
   734             return self._type_cache[eid]
   736         except KeyError:
   735         except KeyError:
   737             etype, extid = self.system_source.eid_type_extid(cnx, eid)
   736             etype = self.system_source.eid_type(cnx, eid)
   738             self._type_extid_cache[eid] = (etype, extid)
   737             self._type_cache[eid] = etype
   739             return etype, extid
   738             return etype
   740 
       
   741     def type_from_eid(self, eid, cnx):
       
   742         """Return the type of the entity with id `eid`"""
       
   743         return self.type_and_extid_from_eid(eid, cnx)[0]
       
   744 
   739 
   745     def querier_cache_key(self, cnx, rql, args, eidkeys):
   740     def querier_cache_key(self, cnx, rql, args, eidkeys):
   746         cachekey = [rql]
   741         cachekey = [rql]
   747         for key in sorted(eidkeys):
   742         for key in sorted(eidkeys):
   748             try:
   743             try:
   755             cachekey.append(etype)
   750             cachekey.append(etype)
   756             # ensure eid is correctly typed in args
   751             # ensure eid is correctly typed in args
   757             args[key] = int(args[key])
   752             args[key] = int(args[key])
   758         return tuple(cachekey)
   753         return tuple(cachekey)
   759 
   754 
   760     def add_info(self, cnx, entity, source, extid=None):
   755     def add_info(self, cnx, entity, source):
   761         """add type and source info for an eid into the system table,
   756         """add type and source info for an eid into the system table,
   762         and index the entity with the full text index
   757         and index the entity with the full text index
   763         """
   758         """
   764         # begin by inserting eid/type/source/extid into the entities table
   759         # begin by inserting eid/type/source into the entities table
   765         hook.CleanupNewEidsCacheOp.get_instance(cnx).add_data(entity.eid)
   760         hook.CleanupNewEidsCacheOp.get_instance(cnx).add_data(entity.eid)
   766         self.system_source.add_info(cnx, entity, source, extid)
   761         self.system_source.add_info(cnx, entity, source)
   767 
   762 
   768     def _delete_cascade_multi(self, cnx, entities):
   763     def _delete_cascade_multi(self, cnx, entities):
   769         """same as _delete_cascade but accepts a list of entities with
   764         """same as _delete_cascade but accepts a list of entities with
   770         the same etype and belonging to the same source.
   765         the same etype and belonging to the same source.
   771         """
   766         """
   802                             raise
   797                             raise
   803                         self.exception('error while cascading delete for entity %s. RQL: %s',
   798                         self.exception('error while cascading delete for entity %s. RQL: %s',
   804                                        entities, rql)
   799                                        entities, rql)
   805 
   800 
   806     def init_entity_caches(self, cnx, entity, source):
   801     def init_entity_caches(self, cnx, entity, source):
   807         """add entity to connection entities cache and repo's extid cache.
   802         """Add entity to connection entities cache and repo's cache."""
   808         Return entity's ext id if the source isn't the system source.
       
   809         """
       
   810         cnx.set_entity_cache(entity)
   803         cnx.set_entity_cache(entity)
   811         if source.uri == 'system':
   804         self._type_cache[entity.eid] = entity.cw_etype
   812             extid = None
       
   813         else:
       
   814             extid = source.get_extid(entity)
       
   815         self._type_extid_cache[entity.eid] = (entity.cw_etype, extid)
       
   816         return extid
       
   817 
   805 
   818     def glob_add_entity(self, cnx, edited):
   806     def glob_add_entity(self, cnx, edited):
   819         """add an entity to the repository
   807         """add an entity to the repository
   820 
   808 
   821         the entity eid should originally be None and a unique eid is assigned to
   809         the entity eid should originally be None and a unique eid is assigned to
   827         entity.cw_edited = edited
   815         entity.cw_edited = edited
   828         source = self.system_source
   816         source = self.system_source
   829         # allocate an eid to the entity before calling hooks
   817         # allocate an eid to the entity before calling hooks
   830         entity.eid = self.system_source.create_eid(cnx)
   818         entity.eid = self.system_source.create_eid(cnx)
   831         # set caches asap
   819         # set caches asap
   832         extid = self.init_entity_caches(cnx, entity, source)
   820         self.init_entity_caches(cnx, entity, source)
   833         if server.DEBUG & server.DBG_REPO:
   821         if server.DEBUG & server.DBG_REPO:
   834             print('ADD entity', self, entity.cw_etype, entity.eid, edited)
   822             print('ADD entity', self, entity.cw_etype, entity.eid, edited)
   835         prefill_entity_caches(entity)
   823         prefill_entity_caches(entity)
   836         self.hm.call_hooks('before_add_entity', cnx, entity=entity)
   824         self.hm.call_hooks('before_add_entity', cnx, entity=entity)
   837         relations = preprocess_inlined_relations(cnx, entity)
   825         relations = preprocess_inlined_relations(cnx, entity)
   838         edited.set_defaults()
   826         edited.set_defaults()
   839         if cnx.is_hook_category_activated('integrity'):
   827         if cnx.is_hook_category_activated('integrity'):
   840             edited.check(creation=True)
   828             edited.check(creation=True)
   841         self.add_info(cnx, entity, source, extid)
   829         self.add_info(cnx, entity, source)
   842         try:
   830         try:
   843             source.add_entity(cnx, entity)
   831             source.add_entity(cnx, entity)
   844         except (UniqueTogetherError, ViolatedConstraint) as exc:
   832         except (UniqueTogetherError, ViolatedConstraint) as exc:
   845             userhdlr = cnx.vreg['adapters'].select(
   833             userhdlr = cnx.vreg['adapters'].select(
   846                 'IUserFriendlyError', cnx, entity=entity, exc=exc)
   834                 'IUserFriendlyError', cnx, entity=entity, exc=exc)