@@ -98,16 +98,44 @@ def module_installed(cr, module):
98
98
return modules_installed (cr , module )
99
99
100
100
101
- def uninstall_module (cr , module ):
101
+ def module_dependencies (cr , module ):
102
+ """Get dependencies of given module.
103
+
104
+ :param str module: name of the module
105
+ :return: list names of the dependencies
106
+ :rtype: list(str)
107
+ """
108
+ cr .execute (
109
+ """
110
+ SELECT m.name
111
+ FROM ir_module_module m
112
+ INNER JOIN ir_module_module_dependency d ON d.module_id = m.id
113
+ WHERE d.name = %s
114
+ """ ,
115
+ [module ],
116
+ )
117
+ return [name for (name ,) in cr .fetchall ()]
118
+
119
+
120
+ def uninstall_module (cr , module , with_dependencies = False ):
102
121
"""
103
122
Uninstall and remove all records owned by a module.
104
123
105
124
:param str module: name of the module to uninstall
125
+ :param bool with_dependencies: whether to also remove dependencies of the module
126
+ :return: set of uninstalled module names
127
+ :rtype: set(str)
106
128
"""
129
+ result = set ()
107
130
cr .execute ("SELECT id FROM ir_module_module WHERE name=%s" , (module ,))
108
131
(mod_id ,) = cr .fetchone () or [None ]
109
132
if not mod_id :
110
- return
133
+ return result
134
+
135
+ if with_dependencies :
136
+ dependencies = module_dependencies (cr , module )
137
+ for dep in dependencies :
138
+ result .union (uninstall_module (cr , dep , with_dependencies = with_dependencies ))
111
139
112
140
# delete constraints only owned by this module
113
141
cr .execute (
@@ -219,14 +247,18 @@ def uninstall_module(cr, module):
219
247
if table_exists (cr , "ir_translation" ):
220
248
cr .execute ("DELETE FROM ir_translation WHERE module=%s" , [module ])
221
249
cr .execute ("UPDATE ir_module_module SET state='uninstalled' WHERE name=%s" , (module ,))
250
+ return result | {module }
222
251
223
252
224
- def uninstall_theme (cr , theme , base_theme = None ):
253
+ def uninstall_theme (cr , theme , base_theme = None , with_dependencies = False ):
225
254
"""
226
255
Uninstall a theme module and remove it from websites.
227
256
228
257
:param str theme: name of the theme module to uninstall
229
258
:param str or None base_theme: if not `None`, unload first this base theme
259
+ :param bool with_dependencies: whether to also remove dependencies of the theme
260
+ :return: set of uninstalled module names
261
+ :rtype: set(str)
230
262
231
263
.. warning::
232
264
@@ -238,7 +270,7 @@ def uninstall_theme(cr, theme, base_theme=None):
238
270
cr .execute ("SELECT id FROM ir_module_module WHERE name=%s AND state in %s" , [theme , INSTALLED_MODULE_STATES ])
239
271
(theme_id ,) = cr .fetchone () or [None ]
240
272
if not theme_id :
241
- return
273
+ return None
242
274
243
275
env_ = env (cr )
244
276
IrModuleModule = env_ ["ir.module.module" ]
@@ -253,17 +285,20 @@ def uninstall_theme(cr, theme, base_theme=None):
253
285
for website in websites :
254
286
IrModuleModule ._theme_remove (website )
255
287
flush (env_ ["base" ])
256
- uninstall_module (cr , theme )
288
+ return uninstall_module (cr , theme , with_dependencies = with_dependencies )
257
289
258
290
259
- def remove_module (cr , module ):
291
+ def remove_module (cr , module , with_dependencies = False ):
260
292
"""
261
293
Completely remove a module.
262
294
263
295
This operation is equivalent to uninstall and removal of *all* references to
264
296
the module - no trace of it is left in the database.
265
297
266
298
:param str module: name of the module to remove
299
+ :param bool with_dependencies: whether to also remove dependencies of the module
300
+ :return: set of uninstalled module names
301
+ :rtype: set(str)
267
302
268
303
.. warning::
269
304
Since this function removes *all* data associated to the module. Ensure to
@@ -273,15 +308,17 @@ def remove_module(cr, module):
273
308
# module need to be currently installed and running as deletions
274
309
# are made using orm.
275
310
276
- uninstall_module (cr , module )
277
- cr .execute ("DELETE FROM ir_module_module_dependency WHERE name=%s" , (module ,))
278
- cr .execute ("DELETE FROM ir_module_module WHERE name=%s RETURNING id" , (module ,))
311
+ result = uninstall_module (cr , module , with_dependencies = with_dependencies )
312
+ names = list (result )
313
+ cr .execute ("DELETE FROM ir_module_module_dependency WHERE name = ANY(%s)" , (names ,))
314
+ cr .execute ("DELETE FROM ir_module_module WHERE name = ANY(%s) RETURNING id" , (names ,))
279
315
if cr .rowcount :
280
- [mod_id ] = cr .fetchone ()
281
- cr .execute ("DELETE FROM ir_model_data WHERE model='ir.module.module' AND res_id=%s" , [mod_id ])
316
+ ids = [id_ for (id_ ,) in cr .fetchall ()]
317
+ cr .execute ("DELETE FROM ir_model_data WHERE model='ir.module.module' AND res_id = ANY(%s)" , (ids ,))
318
+ return result
282
319
283
320
284
- def remove_theme (cr , theme , base_theme = None ):
321
+ def remove_theme (cr , theme , base_theme = None , with_dependencies = False ):
285
322
"""
286
323
Uninstall a theme module.
287
324
@@ -290,12 +327,14 @@ def remove_theme(cr, theme, base_theme=None):
290
327
291
328
See :func:`remove_module` and :func:`uninstall_theme`.
292
329
"""
293
- uninstall_theme (cr , theme , base_theme = base_theme )
294
- cr .execute ("DELETE FROM ir_module_module_dependency WHERE name=%s" , (theme ,))
295
- cr .execute ("DELETE FROM ir_module_module WHERE name=%s RETURNING id" , (theme ,))
330
+ result = uninstall_theme (cr , theme , base_theme = base_theme , with_dependencies = with_dependencies )
331
+ themes = list (result )
332
+ cr .execute ("DELETE FROM ir_module_module_dependency WHERE name = ANY(%s)" , (themes ,))
333
+ cr .execute ("DELETE FROM ir_module_module WHERE name = ANY(%s) RETURNING id" , (themes ,))
296
334
if cr .rowcount :
297
- [mod_id ] = cr .fetchone ()
298
- cr .execute ("DELETE FROM ir_model_data WHERE model='ir.module.module' AND res_id=%s" , [mod_id ])
335
+ ids = [id_ for (id_ ,) in cr .fetchall ()]
336
+ cr .execute ("DELETE FROM ir_model_data WHERE model='ir.module.module' AND res_id = ANY(%s)" , (ids ,))
337
+ return result
299
338
300
339
301
340
def _update_view_key (cr , old , new ):
0 commit comments