1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 # Copyright (C) 2010-2012 OpenERP s.a. (<http://openerp.com>).
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as
10 # published by the Free Software Foundation, either version 3 of the
11 # License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
23 import openerp.modules
26 _logger = logging.getLogger(__name__)
28 def is_initialized(cr):
29 """ Check if a database has been initialized for the ORM.
31 The database can be initialized with the 'initialize' function below.
34 cr.execute("SELECT relname FROM pg_class WHERE relkind='r' AND relname='ir_module_module'")
35 return len(cr.fetchall()) > 0
38 """ Initialize a database with for the ORM.
40 This executes base/base.sql, creates the ir_module_categories (taken
41 from each module descriptor file), and creates the ir_module_module
42 and ir_model_data entries.
45 f = openerp.modules.get_module_resource('base', 'base.sql')
47 m = "File not found: 'base.sql' (provided by module 'base')."
50 base_sql_file = openerp.tools.misc.file_open(f)
52 cr.execute(base_sql_file.read())
57 for i in openerp.modules.get_modules():
58 mod_path = openerp.modules.get_module_path(i)
62 # This will raise an exception if no/unreadable descriptor file.
63 info = openerp.modules.load_information_from_description_file(i)
67 categories = info['category'].split('/')
68 category_id = create_categories(cr, categories)
70 if info['installable']:
73 state = 'uninstallable'
75 cr.execute('INSERT INTO ir_module_module \
76 (author, website, name, shortdesc, description, \
77 category_id, auto_install, state, web, license, application, icon, sequence, summary) \
78 VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id', (
80 info['website'], i, info['name'],
81 info['description'], category_id,
82 info['auto_install'], state,
85 info['application'], info['icon'],
86 info['sequence'], info['summary']))
88 cr.execute('INSERT INTO ir_model_data \
89 (name,model,module, res_id, noupdate) VALUES (%s,%s,%s,%s,%s)', (
90 'module_'+i, 'ir.module.module', 'base', id, True))
91 dependencies = info['depends']
92 for d in dependencies:
93 cr.execute('INSERT INTO ir_module_module_dependency \
94 (module_id,name) VALUES (%s, %s)', (id, d))
96 # Install recursively all auto-installing modules
98 cr.execute("""SELECT m.name FROM ir_module_module m WHERE m.auto_install AND state != 'to install'
100 SELECT 1 FROM ir_module_module_dependency d JOIN ir_module_module mdep ON (d.name = mdep.name)
101 WHERE d.module_id = m.id AND mdep.state != 'to install'
103 to_auto_install = [x[0] for x in cr.fetchall()]
104 if not to_auto_install: break
105 cr.execute("""UPDATE ir_module_module SET state='to install' WHERE name in %s""", (tuple(to_auto_install),))
109 def create_categories(cr, categories):
110 """ Create the ir_module_category entries for some categories.
112 categories is a list of strings forming a single category with its
113 parent categories, like ['Grand Parent', 'Parent', 'Child'].
115 Return the database id of the (last) category.
121 category.append(categories[0])
122 xml_id = 'module_category_' + ('_'.join(map(lambda x: x.lower(), category))).replace('&', 'and').replace(' ', '_')
123 # search via xml_id (because some categories are renamed)
124 cr.execute("SELECT res_id FROM ir_model_data WHERE name=%s AND module=%s AND model=%s",
125 (xml_id, "base", "ir.module.category"))
129 cr.execute('INSERT INTO ir_module_category \
131 VALUES (%s, %s) RETURNING id', (categories[0], p_id))
132 c_id = cr.fetchone()[0]
133 cr.execute('INSERT INTO ir_model_data (module, name, res_id, model) \
134 VALUES (%s, %s, %s, %s)', ('base', xml_id, c_id, 'ir.module.category'))
138 categories = categories[1:]
141 def has_unaccent(cr):
142 """ Test if the database has an unaccent function.
144 The unaccent is supposed to be provided by the PostgreSQL unaccent contrib
145 module but any similar function will be picked by OpenERP.
148 cr.execute("SELECT proname FROM pg_proc WHERE proname='unaccent'")
149 return len(cr.fetchall()) > 0
151 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: