[FIX] addons: defer module data cleanup at end of install/update and avoid loading same module twice
lp bug: https://launchpad.net/bugs/699732 fixed bzr revid: odo@openerp.com-20110107123603-ehyymz30jqzhky20
This commit is contained in:
parent
51e8237ca3
commit
58c3542d11
|
@ -610,18 +610,14 @@ class MigrationManager(object):
|
|||
|
||||
log = logging.getLogger('init')
|
||||
|
||||
def load_module_graph(cr, graph, status=None, perform_checks=True, skip_cleanup=False, **kwargs):
|
||||
def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, **kwargs):
|
||||
"""Migrates+Updates or Installs all module nodes from ``graph``
|
||||
:param graph: graph of module nodes to load
|
||||
:param status: status dictionary for keeping track of progress
|
||||
:param perform_checks: whether module descriptors should be checked for validity (prints warnings
|
||||
for same cases, and even raise osv_except if certificate is invalid)
|
||||
:param skip_cleanup: whether the auto-cleanup of records should be executed (unlinks any object that
|
||||
appears to be from one of the updated modules, but have not been loaded during
|
||||
last loading (i.e. records that seem to have been removed from the module).
|
||||
This is best left disabled when loading stand-alone modules that could contain
|
||||
records from dependent modules (i.e. other modules have put records in their
|
||||
namespace)
|
||||
:param skip_modules: optional list of module names (packages) which have previously been loaded and can be skipped
|
||||
:return: list of modules that were installed or updated
|
||||
"""
|
||||
def process_sql_file(cr, fp):
|
||||
queries = fp.read().split(';')
|
||||
|
@ -707,18 +703,16 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_cleanup=
|
|||
status = {}
|
||||
|
||||
status = status.copy()
|
||||
package_todo = []
|
||||
processed_modules = []
|
||||
statusi = 0
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
|
||||
migrations = MigrationManager(cr, graph)
|
||||
|
||||
has_updates = False
|
||||
modobj = None
|
||||
|
||||
logger.notifyChannel('init', netsvc.LOG_DEBUG, 'loading %d packages..' % len(graph))
|
||||
|
||||
for package in graph:
|
||||
if skip_modules and package.name in skip_modules:
|
||||
continue
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'module %s: loading objects' % package.name)
|
||||
migrations.migrate_module(package, 'pre')
|
||||
register_class(package.name)
|
||||
|
@ -732,6 +726,9 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_cleanup=
|
|||
m = package.name
|
||||
mid = package.id
|
||||
|
||||
if skip_modules and m in skip_modules:
|
||||
continue
|
||||
|
||||
if modobj is None:
|
||||
modobj = pool.get('ir.module.module')
|
||||
|
||||
|
@ -746,7 +743,6 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_cleanup=
|
|||
mode = 'init'
|
||||
|
||||
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
|
||||
has_updates = True
|
||||
for kind in ('init', 'update'):
|
||||
if package.state=='to upgrade':
|
||||
# upgrading the module information
|
||||
|
@ -765,7 +761,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_cleanup=
|
|||
# as there is no rollback.
|
||||
load_test(cr, m, idref, mode)
|
||||
|
||||
package_todo.append(package.name)
|
||||
processed_modules.append(package.name)
|
||||
|
||||
migrations.migrate_module(package, 'post')
|
||||
|
||||
|
@ -785,16 +781,9 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_cleanup=
|
|||
|
||||
statusi += 1
|
||||
|
||||
cr.execute('select model from ir_model where state=%s', ('manual',))
|
||||
for model in cr.dictfetchall():
|
||||
pool.get('ir.model').instanciate(cr, 1, model['model'], {})
|
||||
|
||||
if not skip_cleanup:
|
||||
# Cleanup orphan records
|
||||
pool.get('ir.model.data')._process_end(cr, 1, package_todo)
|
||||
cr.commit()
|
||||
|
||||
return has_updates
|
||||
return processed_modules
|
||||
|
||||
def _check_module_names(cr, module_names):
|
||||
mod_names = set(module_names)
|
||||
|
@ -826,23 +815,30 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
force = []
|
||||
if force_demo:
|
||||
force.append('demo')
|
||||
|
||||
# This is a brand new pool, just created in pooler.get_db_and_pool()
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
|
||||
try:
|
||||
processed_modules = []
|
||||
report = tools.assertion_report()
|
||||
# NOTE: Try to also load the modules that have been marked as uninstallable previously...
|
||||
STATES_TO_LOAD = ['installed', 'to upgrade', 'uninstallable']
|
||||
if 'base' in tools.config['update']:
|
||||
cr.execute("update ir_module_module set state=%s where name=%s", ('to upgrade', 'base'))
|
||||
|
||||
# STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
|
||||
graph = create_graph(cr, ['base'], force)
|
||||
if not graph:
|
||||
logger.notifyChannel('init', netsvc.LOG_CRITICAL, 'module base cannot be loaded! (hint: verify addons-path)')
|
||||
raise osv.osv.except_osv(_('Could not load base module'), _('module base cannot be loaded! (hint: verify addons-path)'))
|
||||
has_updates = load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report, skip_cleanup=True)
|
||||
processed_modules.extend(load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report))
|
||||
|
||||
if tools.config['load_language']:
|
||||
for lang in tools.config['load_language'].split(','):
|
||||
tools.load_language(cr, lang)
|
||||
|
||||
# STEP 2: Mark other modules to be loaded/updated
|
||||
if update_module:
|
||||
modobj = pool.get('ir.module.module')
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'updating modules list')
|
||||
|
@ -867,6 +863,8 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
|
||||
STATES_TO_LOAD += ['to install']
|
||||
|
||||
|
||||
# STEP 3: Load marked modules (skipping base which was done in STEP 1)
|
||||
loop_guardrail = 0
|
||||
while True:
|
||||
loop_guardrail += 1
|
||||
|
@ -884,10 +882,15 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
break
|
||||
|
||||
logger.notifyChannel('init', netsvc.LOG_DEBUG, 'Updating graph with %d more modules' % (len(module_list)))
|
||||
r = load_module_graph(cr, graph, status, report=report)
|
||||
has_updates = has_updates or r
|
||||
processed_modules.extend(load_module_graph(cr, graph, status, report=report, skip_modules=processed_modules))
|
||||
|
||||
# STEP 4: Finish and cleanup
|
||||
if processed_modules:
|
||||
# load custom models
|
||||
cr.execute('select model from ir_model where state=%s', ('manual',))
|
||||
for model in cr.dictfetchall():
|
||||
pool.get('ir.model').instanciate(cr, 1, model['model'], {})
|
||||
|
||||
if has_updates:
|
||||
cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""")
|
||||
for (model, name) in cr.fetchall():
|
||||
model_obj = pool.get(model)
|
||||
|
@ -910,6 +913,9 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
else:
|
||||
logger.notifyChannel('init', netsvc.LOG_WARNING, "Model %s is referenced but not present in the orm pool!" % model)
|
||||
|
||||
# Cleanup orphan records
|
||||
pool.get('ir.model.data')._process_end(cr, 1, processed_modules)
|
||||
|
||||
if report.get_report():
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, report)
|
||||
|
||||
|
|
Loading…
Reference in New Issue