228 # shutdown flag |
227 # shutdown flag |
229 self.shutting_down = None |
228 self.shutting_down = None |
230 # sources (additional sources info in the system database) |
229 # sources (additional sources info in the system database) |
231 self.system_source = self.get_source('native', 'system', |
230 self.system_source = self.get_source('native', 'system', |
232 config.system_source_config.copy()) |
231 config.system_source_config.copy()) |
233 self.sources_by_uri = {'system': self.system_source} |
|
234 # querier helper, need to be created after sources initialization |
232 # querier helper, need to be created after sources initialization |
235 self.querier = querier.QuerierHelper(self, self.schema) |
233 self.querier = querier.QuerierHelper(self, self.schema) |
236 # cache eid -> type |
234 # cache eid -> type |
237 self._type_cache = {} |
235 self._type_cache = {} |
238 # the hooks manager |
236 # the hooks manager |
293 # call init_creating so that for instance native source can |
291 # call init_creating so that for instance native source can |
294 # configurate tsearch according to postgres version |
292 # configurate tsearch according to postgres version |
295 self.system_source.init_creating() |
293 self.system_source.init_creating() |
296 else: |
294 else: |
297 self._init_system_source() |
295 self._init_system_source() |
298 self.init_sources_from_database() |
|
299 if 'CWProperty' in self.schema: |
296 if 'CWProperty' in self.schema: |
300 self.vreg.init_properties(self.properties()) |
297 self.vreg.init_properties(self.properties()) |
301 # 4. close initialization connection set and reopen fresh ones for |
298 # 4. close initialization connection set and reopen fresh ones for |
302 # proper initialization |
299 # proper initialization |
303 self.cnxsets.close() |
300 self.cnxsets.close() |
304 self.cnxsets = _CnxSetPool(self.system_source, pool_size) |
301 self.cnxsets = _CnxSetPool(self.system_source, pool_size) |
305 # 5. call instance level initialisation hooks |
302 # 5. call instance level initialisation hooks |
306 self.hm.call_hooks('server_startup', repo=self) |
303 self.hm.call_hooks('server_startup', repo=self) |
|
304 |
|
305 @property |
|
306 def sources_by_uri(self): |
|
307 mapping = {'system': self.system_source} |
|
308 mapping.update((sourceent.name, source) |
|
309 for sourceent, source in self._sources()) |
|
310 return mapping |
|
311 |
|
312 @property |
|
313 def sources_by_eid(self): |
|
314 mapping = {self.system_source.eid: self.system_source} |
|
315 mapping.update((sourceent.eid, source) |
|
316 for sourceent, source in self._sources()) |
|
317 return mapping |
|
318 |
|
319 def _sources(self): |
|
320 if self.config.quick_start: |
|
321 return |
|
322 with self.internal_cnx() as cnx: |
|
323 for sourceent in cnx.execute( |
|
324 'Any S, SN, SA, SC WHERE S is_instance_of CWSource, ' |
|
325 'S name SN, S type SA, S config SC, S name != "system"').entities(): |
|
326 source = self.get_source(sourceent.type, sourceent.name, |
|
327 sourceent.host_config, sourceent.eid) |
|
328 if self.config.source_enabled(source): |
|
329 # call source's init method to complete their initialisation if |
|
330 # needed (for instance looking for persistent configuration using an |
|
331 # internal session, which is not possible until connections sets have been |
|
332 # initialized) |
|
333 source.init(True, sourceent) |
|
334 else: |
|
335 source.init(False, sourceent) |
|
336 source.set_schema(self.schema) |
|
337 yield sourceent, source |
|
338 self._clear_source_defs_caches() |
307 |
339 |
308 # internals ############################################################### |
340 # internals ############################################################### |
309 |
341 |
310 def _init_system_source(self): |
342 def _init_system_source(self): |
311 if self.config.quick_start: |
343 if self.config.quick_start: |
315 sourceent = cnx.execute( |
347 sourceent = cnx.execute( |
316 'Any S, SA, SC WHERE S is_instance_of CWSource,' |
348 'Any S, SA, SC WHERE S is_instance_of CWSource,' |
317 ' S name "system", S type SA, S config SC' |
349 ' S name "system", S type SA, S config SC' |
318 ).one() |
350 ).one() |
319 self.system_source.eid = sourceent.eid |
351 self.system_source.eid = sourceent.eid |
320 self.sources_by_eid[sourceent.eid] = self.system_source |
|
321 self.system_source.init(True, sourceent) |
352 self.system_source.init(True, sourceent) |
322 |
|
323 def init_sources_from_database(self): |
|
324 if self.config.quick_start: |
|
325 return |
|
326 with self.internal_cnx() as cnx: |
|
327 # FIXME: sources should be ordered (add_entity priority) |
|
328 for sourceent in cnx.execute( |
|
329 'Any S, SN, SA, SC WHERE S is_instance_of CWSource, ' |
|
330 'S name SN, S type SA, S config SC, S name != "system"').entities(): |
|
331 self.add_source(sourceent) |
|
332 |
|
333 def add_source(self, sourceent): |
|
334 try: |
|
335 source = self.get_source(sourceent.type, sourceent.name, |
|
336 sourceent.host_config, sourceent.eid) |
|
337 except RuntimeError: |
|
338 if self.config.repairing: |
|
339 self.exception('cant setup source %s, skipped', sourceent.name) |
|
340 return |
|
341 raise |
|
342 self.sources_by_eid[sourceent.eid] = source |
|
343 self.sources_by_uri[sourceent.name] = source |
|
344 if self.config.source_enabled(source): |
|
345 # call source's init method to complete their initialisation if |
|
346 # needed (for instance looking for persistent configuration using an |
|
347 # internal session, which is not possible until connections sets have been |
|
348 # initialized) |
|
349 source.init(True, sourceent) |
|
350 else: |
|
351 source.init(False, sourceent) |
|
352 self._clear_source_defs_caches() |
|
353 |
|
354 def remove_source(self, uri): |
|
355 source = self.sources_by_uri.pop(uri) |
|
356 del self.sources_by_eid[source.eid] |
|
357 self._clear_source_defs_caches() |
|
358 |
353 |
359 def get_source(self, type, uri, source_config, eid=None): |
354 def get_source(self, type, uri, source_config, eid=None): |
360 # set uri and type in source config so it's available through |
355 # set uri and type in source config so it's available through |
361 # source_defs() |
356 # source_defs() |
362 source_config['uri'] = uri |
357 source_config['uri'] = uri |
369 # trigger full reload of all appobjects |
364 # trigger full reload of all appobjects |
370 self.vreg.set_schema(schema) |
365 self.vreg.set_schema(schema) |
371 else: |
366 else: |
372 self.vreg._set_schema(schema) |
367 self.vreg._set_schema(schema) |
373 self.querier.set_schema(schema) |
368 self.querier.set_schema(schema) |
374 for source in self.sources_by_uri.values(): |
369 self.system_source.set_schema(schema) |
375 source.set_schema(schema) |
|
376 self.schema = schema |
370 self.schema = schema |
377 |
371 |
378 def deserialize_schema(self): |
372 def deserialize_schema(self): |
379 """load schema from the database""" |
373 """load schema from the database""" |
380 from cubicweb.server.schemaserial import deserialize_schema |
374 from cubicweb.server.schemaserial import deserialize_schema |