From 5ca0f64b4e80e9d01fe231bbd75bf9c686a7b44f Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 11 May 2011 16:47:54 +0200 Subject: [PATCH] [REF] moved init_db from tools.misc to modules.db. bzr revid: vmt@openerp.com-20110511144754-m06exg4dsn2jbdgz --- openerp/modules/__init__.py | 18 +++-- openerp/modules/db.py | 112 ++++++++++++++++++++++++++++++++ openerp/service/web_services.py | 3 +- openerp/tools/misc.py | 69 -------------------- 4 files changed, 127 insertions(+), 75 deletions(-) create mode 100644 openerp/modules/db.py diff --git a/openerp/modules/__init__.py b/openerp/modules/__init__.py index a07248f786f..2db494754eb 100644 --- a/openerp/modules/__init__.py +++ b/openerp/modules/__init__.py @@ -50,6 +50,8 @@ from cStringIO import StringIO import logging +import openerp.modules.db + logger = netsvc.Logger() _ad = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'addons') # default addons path (base) @@ -417,6 +419,8 @@ def upgrade_graph(graph, cr, module_list, force=None): len_graph = len(graph) for module in module_list: # This will raise an exception if no/unreadable descriptor file. + # NOTE The call to load_information_from_description_file is already + # done by db.initialize, so it is possible to not do it again here. info = load_information_from_description_file(module) if info['installable']: packages.append((module, info)) # TODO directly a dict, like in get_modules_with_version @@ -504,9 +508,13 @@ def load_module(module_name): fm[0].close() -def register_class(m): - """ - Register module named m, if not already registered +def register_module_classes(m): + """ Register module named m, if not already registered. + + This will load the module and register all of its models. (Actually, the + explicit constructor call of each of the models inside the module will + register them.) + """ def log(e): @@ -773,7 +781,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= continue logger.notifyChannel('init', netsvc.LOG_INFO, 'module %s: loading objects' % package.name) migrations.migrate_module(package, 'pre') - register_class(package.name) + register_module_classes(package.name) models = pool.instanciate(package.name, cr) if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): init_module_models(cr, package.name, models) @@ -869,7 +877,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): cr.execute("SELECT relname FROM pg_class WHERE relkind='r' AND relname='ir_module_module'") if len(cr.fetchall())==0: logger.notifyChannel("init", netsvc.LOG_INFO, "init db") - tools.init_db(cr) + openerp.modules.db.initialize(cr) tools.config["init"]["all"] = 1 tools.config['update']['all'] = 1 if not tools.config['without_demo']: diff --git a/openerp/modules/db.py b/openerp/modules/db.py new file mode 100644 index 00000000000..261b39ffb31 --- /dev/null +++ b/openerp/modules/db.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# Copyright (C) 2010 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import openerp.modules + +def initialize(cr): + """ Initialize a database with for the ORM. + + This executes base/base.sql, creates the ir_module_categories (taken + from each module descriptor file), and creates the ir_module_module + and ir_model_data entries. + + """ + f = openerp.modules.get_module_resource('base', 'base.sql') + base_sql_file = openerp.tools.misc.file_open(f) + try: + cr.execute(base_sql_file.read()) + cr.commit() + finally: + base_sql_file.close() + + for i in openerp.modules.get_modules(): + mod_path = openerp.modules.get_module_path(i) + if not mod_path: + continue + + # This will raise an exception if no/unreadable descriptor file. + info = openerp.modules.load_information_from_description_file(i) + + if not info: + continue + categories = info['category'].split('/') + category_id = create_categories(cr, categories) + + if info['installable']: + if info['active']: + state = 'to install' + else: + state = 'uninstalled' + else: + state = 'uninstallable' + + cr.execute('INSERT INTO ir_module_module \ + (author, website, name, shortdesc, description, \ + category_id, state, certificate, web, license) \ + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id', ( + info['author'], + info['website'], i, info['name'], + info['description'], category_id, state, info['certificate'], + info['web'], + info['license'])) + id = cr.fetchone()[0] + cr.execute('INSERT INTO ir_model_data \ + (name,model,module, res_id, noupdate) VALUES (%s,%s,%s,%s,%s)', ( + 'module_meta_information', 'ir.module.module', i, id, True)) + dependencies = info['depends'] + for d in dependencies: + cr.execute('INSERT INTO ir_module_module_dependency \ + (module_id,name) VALUES (%s, %s)', (id, d)) + cr.commit() + +def create_categories(cr, categories): + """ Create the ir_module_category entries for some categories. + + categories is a list of strings forming a single category with its + parent categories, like ['Grand Parent', 'Parent', 'Child']. + + Return the database id of the (last) category. + + """ + p_id = None + while categories: + if p_id is not None: + cr.execute('SELECT id \ + FROM ir_module_category \ + WHERE name=%s AND parent_id=%s', (categories[0], p_id)) + else: + cr.execute('SELECT id \ + FROM ir_module_category \ + WHERE name=%s AND parent_id IS NULL', (categories[0],)) + c_id = cr.fetchone() + if not c_id: + cr.execute('INSERT INTO ir_module_category \ + (name, parent_id) \ + VALUES (%s, %s) RETURNING id', (categories[0], p_id)) + c_id = cr.fetchone()[0] + else: + c_id = c_id[0] + p_id = c_id + categories = categories[1:] + return p_id + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 3b0d0ef7320..8806e1b4f99 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -35,6 +35,7 @@ import openerp.pooler as pooler import openerp.release as release import openerp.sql_db as sql_db import openerp.tools as tools +import openerp.modules import locale import logging from cStringIO import StringIO @@ -92,7 +93,7 @@ class db(netsvc.ExportService): try: serv.actions[id]['progress'] = 0 cr = sql_db.db_connect(db_name).cursor() - tools.init_db(cr) + openerp.modules.db.initialize(cr) tools.config['lang'] = lang cr.commit() cr.close() diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index fd31bc14f20..f232dd4ceac 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -69,75 +69,6 @@ _logger = logging.getLogger('tools') # We include the *Base ones just in case, currently they seem to be subclasses of the _* ones. SKIPPED_ELEMENT_TYPES = (etree._Comment, etree._ProcessingInstruction, etree.CommentBase, etree.PIBase) -# initialize a database with base/base.sql -def init_db(cr): - import openerp.modules as addons - f = addons.get_module_resource('base', 'base.sql') - base_sql_file = file_open(f) - try: - cr.execute(base_sql_file.read()) - cr.commit() - finally: - base_sql_file.close() - - for i in addons.get_modules(): - mod_path = addons.get_module_path(i) - if not mod_path: - continue - - # This will raise an exception if no/unreadable descriptor file. - info = addons.load_information_from_description_file(i) - - if not info: - continue - categs = info['category'].split('/') - p_id = None - while categs: - if p_id is not None: - cr.execute('SELECT id \ - FROM ir_module_category \ - WHERE name=%s AND parent_id=%s', (categs[0], p_id)) - else: - cr.execute('SELECT id \ - FROM ir_module_category \ - WHERE name=%s AND parent_id IS NULL', (categs[0],)) - c_id = cr.fetchone() - if not c_id: - cr.execute('INSERT INTO ir_module_category \ - (name, parent_id) \ - VALUES (%s, %s) RETURNING id', (categs[0], p_id)) - c_id = cr.fetchone()[0] - else: - c_id = c_id[0] - p_id = c_id - categs = categs[1:] - - if info['installable']: - if info['active']: - state = 'to install' - else: - state = 'uninstalled' - else: - state = 'uninstallable' - cr.execute('INSERT INTO ir_module_module \ - (author, website, name, shortdesc, description, \ - category_id, state, certificate, web, license) \ - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id', ( - info['author'], - info['website'], i, info['name'], - info['description'], p_id, state, info['certificate'], - info['web'], - info['license'])) - id = cr.fetchone()[0] - cr.execute('INSERT INTO ir_model_data \ - (name,model,module, res_id, noupdate) VALUES (%s,%s,%s,%s,%s)', ( - 'module_meta_information', 'ir.module.module', i, id, True)) - dependencies = info['depends'] - for d in dependencies: - cr.execute('INSERT INTO ir_module_module_dependency \ - (module_id,name) VALUES (%s, %s)', (id, d)) - cr.commit() - def find_in_path(name): try: return which(name)