[IMP] the module graph is updated and loaded until there are modules to load.
[IMP] log the extra database columns only when all modules are loaded bzr revid: christophe@tinyerp.com-20090129095937-izrx5s4qac1dmapj
This commit is contained in:
parent
04ad5bba04
commit
f3bd6582fc
|
@ -274,11 +274,13 @@ def get_modules():
|
||||||
|
|
||||||
|
|
||||||
def create_graph(module_list, force=None):
|
def create_graph(module_list, force=None):
|
||||||
if not force:
|
|
||||||
force = []
|
|
||||||
graph = Graph()
|
graph = Graph()
|
||||||
packages = []
|
return upgrade_graph(graph, module_list, force)
|
||||||
|
|
||||||
|
def upgrade_graph(graph, module_list, force=None):
|
||||||
|
if force is None:
|
||||||
|
force = []
|
||||||
|
packages = []
|
||||||
for module in module_list:
|
for module in module_list:
|
||||||
try:
|
try:
|
||||||
mod_path = get_module_path(module)
|
mod_path = get_module_path(module)
|
||||||
|
@ -556,7 +558,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs):
|
||||||
|
|
||||||
migrations = MigrationManager(cr, graph)
|
migrations = MigrationManager(cr, graph)
|
||||||
|
|
||||||
check_rules = False
|
has_updates = False
|
||||||
modobj = None
|
modobj = None
|
||||||
|
|
||||||
for package in graph:
|
for package in graph:
|
||||||
|
@ -579,7 +581,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs):
|
||||||
idref = {}
|
idref = {}
|
||||||
status['progress'] = (float(statusi)+0.4) / len(graph)
|
status['progress'] = (float(statusi)+0.4) / len(graph)
|
||||||
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
|
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
|
||||||
check_rules = True
|
has_updates = True
|
||||||
init_module_objects(cr, m, modules)
|
init_module_objects(cr, m, modules)
|
||||||
for kind in ('init', 'update'):
|
for kind in ('init', 'update'):
|
||||||
for filename in package.data.get('%s_xml' % kind, []):
|
for filename in package.data.get('%s_xml' % kind, []):
|
||||||
|
@ -614,6 +616,8 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs):
|
||||||
cr.execute('update ir_module_module set demo=%s where id=%s', (True, mid))
|
cr.execute('update ir_module_module set demo=%s where id=%s', (True, mid))
|
||||||
package_todo.append(package.name)
|
package_todo.append(package.name)
|
||||||
|
|
||||||
|
migrations.migrate_module(package, 'post')
|
||||||
|
|
||||||
if modobj:
|
if modobj:
|
||||||
ver = release.major_version + '.' + package.data.get('version', '1.0')
|
ver = release.major_version + '.' + package.data.get('version', '1.0')
|
||||||
# Set new modules and dependencies
|
# Set new modules and dependencies
|
||||||
|
@ -622,24 +626,24 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs):
|
||||||
# Update translations for all installed languages
|
# Update translations for all installed languages
|
||||||
modobj.update_translations(cr, 1, [mid], None)
|
modobj.update_translations(cr, 1, [mid], None)
|
||||||
cr.commit()
|
cr.commit()
|
||||||
|
|
||||||
|
package.state = 'installed'
|
||||||
|
for kind in ('init', 'demo', 'update'):
|
||||||
|
if hasattr(package, kind):
|
||||||
|
delattr(package, kind)
|
||||||
|
|
||||||
migrations.migrate_module(package, 'post')
|
|
||||||
|
|
||||||
statusi += 1
|
statusi += 1
|
||||||
|
|
||||||
if perform_checks and check_rules:
|
|
||||||
cr.execute("""select model,name from ir_model where id not in (select model_id from ir_model_access)""")
|
|
||||||
for (model, name) in cr.fetchall():
|
|
||||||
logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name))
|
|
||||||
|
|
||||||
|
|
||||||
cr.execute('select model from ir_model where state=%s', ('manual',))
|
cr.execute('select model from ir_model where state=%s', ('manual',))
|
||||||
for model in cr.dictfetchall():
|
for model in cr.dictfetchall():
|
||||||
pool.get('ir.model').instanciate(cr, 1, model['model'], {})
|
pool.get('ir.model').instanciate(cr, 1, model['model'], {})
|
||||||
|
|
||||||
pool.get('ir.model.data')._process_end(cr, 1, package_todo)
|
pool.get('ir.model.data')._process_end(cr, 1, package_todo)
|
||||||
cr.commit()
|
cr.commit()
|
||||||
|
|
||||||
|
return has_updates
|
||||||
|
|
||||||
def load_modules(db, force_demo=False, status=None, update_module=False):
|
def load_modules(db, force_demo=False, status=None, update_module=False):
|
||||||
if not status:
|
if not status:
|
||||||
|
@ -652,9 +656,11 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
||||||
pool = pooler.get_pool(cr.dbname)
|
pool = pooler.get_pool(cr.dbname)
|
||||||
try:
|
try:
|
||||||
report = tools.assertion_report()
|
report = tools.assertion_report()
|
||||||
|
STATES_TO_LOAD = ['installed', 'to upgrade']
|
||||||
|
graph = create_graph(['base'], force)
|
||||||
|
has_updates = False
|
||||||
if update_module:
|
if update_module:
|
||||||
basegraph = create_graph(['base'], force)
|
has_updates = load_module_graph(cr, graph, status, perform_checks=False, report=report)
|
||||||
load_module_graph(cr, basegraph, status, perform_checks=False, report=report)
|
|
||||||
|
|
||||||
modobj = pool.get('ir.module.module')
|
modobj = pool.get('ir.module.module')
|
||||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'updating modules list')
|
logger.notifyChannel('init', netsvc.LOG_INFO, 'updating modules list')
|
||||||
|
@ -673,20 +679,31 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
||||||
modobj.button_upgrade(cr, 1, ids)
|
modobj.button_upgrade(cr, 1, ids)
|
||||||
|
|
||||||
cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
|
cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
|
||||||
cr.execute("select name from ir_module_module where state in ('installed', 'to install', 'to upgrade')")
|
|
||||||
else:
|
STATES_TO_LOAD += ['to install']
|
||||||
cr.execute("select name from ir_module_module where state in ('installed', 'to upgrade')")
|
|
||||||
module_list = [name for (name,) in cr.fetchall()]
|
while True:
|
||||||
graph = create_graph(module_list, force)
|
cr.execute("SELECT name from ir_module_module WHERE state in (%s)" % ','.join(['%s']*len(STATES_TO_LOAD)), STATES_TO_LOAD)
|
||||||
|
|
||||||
# the 'base' module has already been updated
|
module_list = [name for (name,) in cr.fetchall() if name not in graph]
|
||||||
base = graph['base']
|
if not module_list:
|
||||||
base.state = 'installed'
|
break
|
||||||
for kind in ('init', 'demo', 'update'):
|
|
||||||
if hasattr(base, kind):
|
upgrade_graph(graph, module_list, force)
|
||||||
delattr(base, kind)
|
r = load_module_graph(cr, graph, status, report=report)
|
||||||
|
has_updates = has_updates or r
|
||||||
|
|
||||||
load_module_graph(cr, graph, status, report=report)
|
if has_updates:
|
||||||
|
cr.execute("""select model,name from ir_model where id not in (select model_id from ir_model_access)""")
|
||||||
|
for (model, name) in cr.fetchall():
|
||||||
|
logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name))
|
||||||
|
|
||||||
|
cr.execute("SELECT model from ir_model")
|
||||||
|
for (model,) in cr.fetchall():
|
||||||
|
obj = pool.get(model)
|
||||||
|
if obj:
|
||||||
|
obj._check_removed_columns(cr, log=True)
|
||||||
|
|
||||||
if report.get_report():
|
if report.get_report():
|
||||||
logger.notifyChannel('init', netsvc.LOG_INFO, report)
|
logger.notifyChannel('init', netsvc.LOG_INFO, report)
|
||||||
|
|
||||||
|
@ -697,7 +714,6 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
||||||
if update_module:
|
if update_module:
|
||||||
cr.execute("select id,name from ir_module_module where state=%s", ('to remove',))
|
cr.execute("select id,name from ir_module_module where state=%s", ('to remove',))
|
||||||
for mod_id, mod_name in cr.fetchall():
|
for mod_id, mod_name in cr.fetchall():
|
||||||
pool = pooler.get_pool(cr.dbname)
|
|
||||||
cr.execute('select model,res_id from ir_model_data where noupdate=%s and module=%s order by id desc', (False, mod_name,))
|
cr.execute('select model,res_id from ir_model_data where noupdate=%s and module=%s order by id desc', (False, mod_name,))
|
||||||
for rmod, rid in cr.fetchall():
|
for rmod, rid in cr.fetchall():
|
||||||
uid = 1
|
uid = 1
|
||||||
|
@ -722,7 +738,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
||||||
else:
|
else:
|
||||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'removed %d unused menus' % (cr.rowcount,))
|
logger.notifyChannel('init', netsvc.LOG_INFO, 'removed %d unused menus' % (cr.rowcount,))
|
||||||
|
|
||||||
cr.execute("update ir_module_module set state=%s where state in ('to remove')", ('uninstalled', ))
|
cr.execute("update ir_module_module set state=%s where state=%s", ('uninstalled', 'to remove',))
|
||||||
cr.commit()
|
cr.commit()
|
||||||
finally:
|
finally:
|
||||||
cr.close()
|
cr.close()
|
||||||
|
|
|
@ -1176,6 +1176,8 @@ class orm_template(object):
|
||||||
self.pool.get(table).write_string(cr, uid, id, langs, vals, context)
|
self.pool.get(table).write_string(cr, uid, id, langs, vals, context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _check_removed_columns(self, cr, log=False):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
class orm_memory(orm_template):
|
class orm_memory(orm_template):
|
||||||
_protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count']
|
_protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count']
|
||||||
|
@ -1359,6 +1361,10 @@ class orm_memory(orm_template):
|
||||||
'id': id
|
'id': id
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _check_removed_columns(self, cr, log=False):
|
||||||
|
# nothing to check in memory...
|
||||||
|
pass
|
||||||
|
|
||||||
class orm(orm_template):
|
class orm(orm_template):
|
||||||
_sql_constraints = []
|
_sql_constraints = []
|
||||||
|
@ -1411,6 +1417,26 @@ class orm(orm_template):
|
||||||
if (val<>False) or (type(val)<>bool):
|
if (val<>False) or (type(val)<>bool):
|
||||||
cr.execute(update_query, (ss[1](val), key))
|
cr.execute(update_query, (ss[1](val), key))
|
||||||
|
|
||||||
|
def _check_removed_columns(self, cr, log=False):
|
||||||
|
logger = netsvc.Logger()
|
||||||
|
# iterate on the database columns to drop the NOT NULL constraints
|
||||||
|
# of fields which were required but have been removed (or will be added by another module)
|
||||||
|
columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)]
|
||||||
|
columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns
|
||||||
|
cr.execute("SELECT a.attname, a.attnotnull"
|
||||||
|
" FROM pg_class c, pg_attribute a"
|
||||||
|
" WHERE c.relname=%%s"
|
||||||
|
" AND c.oid=a.attrelid"
|
||||||
|
" AND a.attisdropped=%%s"
|
||||||
|
" AND pg_catalog.format_type(a.atttypid, a.atttypmod) NOT IN ('cid', 'tid', 'oid', 'xid')"
|
||||||
|
" AND a.attname NOT IN (%s)" % ",".join(['%s']*len(columns)),
|
||||||
|
[self._table, False] + columns)
|
||||||
|
for column in cr.dictfetchall():
|
||||||
|
if log:
|
||||||
|
logger.notifyChannel("orm", netsvc.LOG_DEBUG, "column %s is in the table %s but not in the corresponding object %s" % (column['attname'], self._table, self._name))
|
||||||
|
if column['attnotnull']:
|
||||||
|
cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, column['attname']))
|
||||||
|
|
||||||
def _auto_init(self, cr, context={}):
|
def _auto_init(self, cr, context={}):
|
||||||
store_compute = False
|
store_compute = False
|
||||||
logger = netsvc.Logger()
|
logger = netsvc.Logger()
|
||||||
|
@ -1456,24 +1482,8 @@ class orm(orm_template):
|
||||||
if not cr.rowcount:
|
if not cr.rowcount:
|
||||||
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k]))
|
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k]))
|
||||||
cr.commit()
|
cr.commit()
|
||||||
|
|
||||||
# iterate on the database columns to drop the NOT NULL constraints
|
self._check_removed_columns(cr, log=False)
|
||||||
# of fields which were required but have been removed
|
|
||||||
columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)]
|
|
||||||
columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns
|
|
||||||
cr.execute("SELECT a.attname, a.attnotnull"
|
|
||||||
" FROM pg_class c, pg_attribute a"
|
|
||||||
" WHERE c.relname=%%s"
|
|
||||||
" AND c.oid=a.attrelid"
|
|
||||||
" AND a.attisdropped=%%s"
|
|
||||||
" AND pg_catalog.format_type(a.atttypid, a.atttypmod) NOT IN ('cid', 'tid', 'oid', 'xid')"
|
|
||||||
" AND a.attname NOT IN (%s)" % ",".join(['%s']*len(columns)),
|
|
||||||
[self._table, False] + columns)
|
|
||||||
for column in cr.dictfetchall():
|
|
||||||
# TODO display this information only when all modules are loaded
|
|
||||||
logger.notifyChannel("orm", netsvc.LOG_DEBUG, "column %s is in the table %s but not in the corresponding object %s" % (column['attname'], self._table, self._name))
|
|
||||||
if column['attnotnull']:
|
|
||||||
cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, column['attname']))
|
|
||||||
|
|
||||||
# iterate on the "object columns"
|
# iterate on the "object columns"
|
||||||
todo_update_store = []
|
todo_update_store = []
|
||||||
|
|
Loading…
Reference in New Issue