141 self._running_threads = [] |
141 self._running_threads = [] |
142 # initial schema, should be build or replaced latter |
142 # initial schema, should be build or replaced latter |
143 self.schema = CubicWebSchema(config.appid) |
143 self.schema = CubicWebSchema(config.appid) |
144 # querier helper, need to be created after sources initialization |
144 # querier helper, need to be created after sources initialization |
145 self.querier = QuerierHelper(self, self.schema) |
145 self.querier = QuerierHelper(self, self.schema) |
|
146 # should we reindex in changes? |
|
147 self.do_fti = not config['delay-full-text-indexation'] |
146 # sources |
148 # sources |
147 self.sources = [] |
149 self.sources = [] |
148 self.sources_by_uri = {} |
150 self.sources_by_uri = {} |
149 # FIXME: store additional sources info in the system database ? |
151 # FIXME: store additional sources info in the system database ? |
150 # FIXME: sources should be ordered (add_entity priority) |
152 # FIXME: sources should be ordered (add_entity priority) |
208 # close initialization pool and reopen fresh ones for proper |
210 # close initialization pool and reopen fresh ones for proper |
209 # initialization now that we know cubes |
211 # initialization now that we know cubes |
210 self._get_pool().close(True) |
212 self._get_pool().close(True) |
211 for i in xrange(config['connections-pool-size']): |
213 for i in xrange(config['connections-pool-size']): |
212 self._available_pools.put_nowait(ConnectionsPool(self.sources)) |
214 self._available_pools.put_nowait(ConnectionsPool(self.sources)) |
213 |
215 |
214 # internals ############################################################### |
216 # internals ############################################################### |
215 |
217 |
216 def get_source(self, uri, source_config): |
218 def get_source(self, uri, source_config): |
217 source_config['uri'] = uri |
219 source_config['uri'] = uri |
218 return get_source(source_config, self.schema, self) |
220 return get_source(source_config, self.schema, self) |
775 if source.uri != uri: |
777 if source.uri != uri: |
776 # eid not from the given source |
778 # eid not from the given source |
777 raise UnknownEid(eid) |
779 raise UnknownEid(eid) |
778 return extid |
780 return extid |
779 |
781 |
780 def extid2eid(self, source, lid, etype, session=None, insert=True): |
782 def extid2eid(self, source, lid, etype, session=None, insert=True, |
|
783 recreate=False): |
781 """get eid from a local id. An eid is attributed if no record is found""" |
784 """get eid from a local id. An eid is attributed if no record is found""" |
782 cachekey = (str(lid), source.uri) |
785 cachekey = (str(lid), source.uri) |
783 try: |
786 try: |
784 return self._extid_cache[cachekey] |
787 return self._extid_cache[cachekey] |
785 except KeyError: |
788 except KeyError: |
790 reset_pool = True |
793 reset_pool = True |
791 eid = self.system_source.extid2eid(session, source, lid) |
794 eid = self.system_source.extid2eid(session, source, lid) |
792 if eid is not None: |
795 if eid is not None: |
793 self._extid_cache[cachekey] = eid |
796 self._extid_cache[cachekey] = eid |
794 self._type_source_cache[eid] = (etype, source.uri, lid) |
797 self._type_source_cache[eid] = (etype, source.uri, lid) |
|
798 if recreate: |
|
799 entity = source.before_entity_insertion(session, lid, etype, eid) |
|
800 entity._cw_recreating = True |
|
801 if source.should_call_hooks: |
|
802 self.hm.call_hooks('before_add_entity', etype, session, entity) |
|
803 # XXX add fti op ? |
|
804 source.after_entity_insertion(session, lid, entity) |
|
805 if source.should_call_hooks: |
|
806 self.hm.call_hooks('after_add_entity', etype, session, entity) |
795 if reset_pool: |
807 if reset_pool: |
796 session.reset_pool() |
808 session.reset_pool() |
797 return eid |
809 return eid |
798 if not insert: |
810 if not insert: |
799 return |
811 return |
836 self.system_source.add_info(session, entity, source, extid) |
848 self.system_source.add_info(session, entity, source, extid) |
837 if complete: |
849 if complete: |
838 entity.complete(entity.e_schema.indexable_attributes()) |
850 entity.complete(entity.e_schema.indexable_attributes()) |
839 session.add_query_data('neweids', entity.eid) |
851 session.add_query_data('neweids', entity.eid) |
840 # now we can update the full text index |
852 # now we can update the full text index |
841 FTIndexEntityOp(session, entity=entity) |
853 if self.do_fti: |
|
854 FTIndexEntityOp(session, entity=entity) |
842 CleanupEidTypeCacheOp(session) |
855 CleanupEidTypeCacheOp(session) |
843 |
856 |
844 def delete_info(self, session, eid): |
857 def delete_info(self, session, eid): |
845 self._prepare_delete_info(session, eid) |
858 self._prepare_delete_info(session, eid) |
846 self._delete_info(session, eid) |
859 self._delete_info(session, eid) |
904 if not source.support_relation(rtype, 1): |
917 if not source.support_relation(rtype, 1): |
905 raise RTypeNotSupportedBySources(rtype) |
918 raise RTypeNotSupportedBySources(rtype) |
906 else: |
919 else: |
907 source = subjsource |
920 source = subjsource |
908 return source |
921 return source |
909 |
|
910 @cached |
|
911 def rel_type_sources(self, rtype): |
|
912 return [source for source in self.sources |
|
913 if source.support_relation(rtype) or rtype in source.dont_cross_relations] |
|
914 |
922 |
915 def locate_etype_source(self, etype): |
923 def locate_etype_source(self, etype): |
916 for source in self.sources: |
924 for source in self.sources: |
917 if source.support_entity(etype, 1): |
925 if source.support_entity(etype, 1): |
918 return source |
926 return source |
1002 if not only_inline_rels: |
1010 if not only_inline_rels: |
1003 self.hm.call_hooks('before_update_entity', etype, session, |
1011 self.hm.call_hooks('before_update_entity', etype, session, |
1004 entity) |
1012 entity) |
1005 source.update_entity(session, entity) |
1013 source.update_entity(session, entity) |
1006 if not only_inline_rels: |
1014 if not only_inline_rels: |
1007 if need_fti_update: |
1015 if need_fti_update and self.do_fti: |
1008 # reindex the entity only if this query is updating at least |
1016 # reindex the entity only if this query is updating at least |
1009 # one indexable attribute |
1017 # one indexable attribute |
1010 FTIndexEntityOp(session, entity=entity) |
1018 FTIndexEntityOp(session, entity=entity) |
1011 if source.should_call_hooks: |
1019 if source.should_call_hooks: |
1012 self.hm.call_hooks('after_update_entity', etype, session, |
1020 self.hm.call_hooks('after_update_entity', etype, session, |
1103 nameserver.createGroup(group) |
1111 nameserver.createGroup(group) |
1104 except errors.NamingError: |
1112 except errors.NamingError: |
1105 pass |
1113 pass |
1106 return nameserver |
1114 return nameserver |
1107 |
1115 |
|
1116 # multi-sources planner helpers ########################################### |
|
1117 |
|
1118 @cached |
|
1119 def rel_type_sources(self, rtype): |
|
1120 return [source for source in self.sources |
|
1121 if source.support_relation(rtype) |
|
1122 or rtype in source.dont_cross_relations] |
|
1123 |
|
1124 @cached |
|
1125 def can_cross_relation(self, rtype): |
|
1126 return [source for source in self.sources |
|
1127 if source.support_relation(rtype) |
|
1128 and rtype in source.cross_relations] |
|
1129 |
|
1130 @cached |
|
1131 def is_multi_sources_relation(self, rtype): |
|
1132 return any(source for source in self.sources |
|
1133 if not source is self.system_source |
|
1134 and source.support_relation(rtype)) |
|
1135 |
1108 |
1136 |
1109 def pyro_unregister(config): |
1137 def pyro_unregister(config): |
1110 """unregister the repository from the pyro name server""" |
1138 """unregister the repository from the pyro name server""" |
1111 nshost, nsgroup = config['pyro-ns-host'], config['pyro-ns-group'] |
1139 nshost, nsgroup = config['pyro-ns-host'], config['pyro-ns-group'] |
1112 appid = config['pyro-id'] or config.appid |
1140 appid = config['pyro-id'] or config.appid |