forked from OCA/server-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ADD] allow creating missing indexes and purging properties (OCA#736)
* [ADD] allow creating missing indexes * [FIX] tests; installation * [ADD] allow purging properties * [ADD] missing file * [ADD] test purging properties * [ADD] missing parent_id for menu entry * [FIX] don't delete too many and wrong properties
- Loading branch information
Showing
9 changed files
with
329 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Therp BV <http://therp.nl> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
from ..identifier_adapter import IdentifierAdapter | ||
from openerp import api, fields, models | ||
|
||
|
||
class CreateIndexesLine(models.TransientModel): | ||
_inherit = 'cleanup.purge.line' | ||
_name = 'cleanup.create_indexes.line' | ||
|
||
purged = fields.Boolean('Created') | ||
wizard_id = fields.Many2one('cleanup.create_indexes.wizard') | ||
field_id = fields.Many2one('ir.model.fields', required=True) | ||
|
||
@api.multi | ||
def purge(self): | ||
tables = set() | ||
for field in self.mapped('field_id'): | ||
model = self.env[field.model] | ||
name = '%s_%s_index' % (model._table, field.name) | ||
self.env.cr.execute( | ||
'create index %s ON %s (%s)', | ||
( | ||
IdentifierAdapter(name, quote=False), | ||
IdentifierAdapter(model._table), | ||
IdentifierAdapter(field.name), | ||
), | ||
) | ||
tables.add(model._table) | ||
for table in tables: | ||
self.env.cr.execute( | ||
'analyze %s', (IdentifierAdapter(model._table),) | ||
) | ||
self.write({ | ||
'purged': True, | ||
}) | ||
|
||
|
||
class CreateIndexesWizard(models.TransientModel): | ||
_inherit = 'cleanup.purge.wizard' | ||
_name = 'cleanup.create_indexes.wizard' | ||
_description = 'Create indexes' | ||
|
||
purge_line_ids = fields.One2many( | ||
'cleanup.create_indexes.line', 'wizard_id', | ||
) | ||
|
||
@api.multi | ||
def find(self): | ||
for field in self.env['ir.model.fields'].search([ | ||
('index', '=', True), | ||
]): | ||
if field.model not in self.env.registry: | ||
continue | ||
model = self.env[field.model] | ||
name = '%s_%s_index' % (model._table, field.name) | ||
self.env.cr.execute( | ||
'select indexname from pg_indexes ' | ||
'where indexname=%s and tablename=%s', | ||
(name, model._table) | ||
) | ||
if self.env.cr.rowcount: | ||
continue | ||
|
||
self.env.cr.execute( | ||
'select a.attname ' | ||
'from pg_attribute a ' | ||
'join pg_class c on a.attrelid=c.oid ' | ||
'join pg_tables t on t.tablename=c.relname ' | ||
'where attname=%s and c.relname=%s', | ||
(field.name, model._table,) | ||
) | ||
if not self.env.cr.rowcount: | ||
continue | ||
|
||
yield (0, 0, { | ||
'name': '%s.%s' % (field.model, field.name), | ||
'field_id': field.id, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Therp BV <http://therp.nl> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
from openerp import api, models, fields | ||
REASON_DUPLICATE = 1 | ||
REASON_DEFAULT = 2 | ||
|
||
|
||
class CleanupPurgeLineProperty(models.TransientModel): | ||
_inherit = 'cleanup.purge.line' | ||
_name = 'cleanup.purge.line.property' | ||
_description = 'Purge properties' | ||
|
||
wizard_id = fields.Many2one( | ||
'cleanup.purge.wizard.property', 'Purge Wizard', readonly=True) | ||
property_id = fields.Many2one('ir.property') | ||
reason = fields.Selection([ | ||
(REASON_DUPLICATE, 'Duplicated property'), | ||
(REASON_DEFAULT, 'Same value as default'), | ||
]) | ||
|
||
@api.multi | ||
def purge(self): | ||
"""Delete properties""" | ||
self.write({'purged': True}) | ||
return self.mapped('property_id').unlink() | ||
|
||
|
||
class CleanupPurgeWizardProperty(models.TransientModel): | ||
_inherit = 'cleanup.purge.wizard' | ||
_name = 'cleanup.purge.wizard.property' | ||
_description = 'Purge properties' | ||
|
||
@api.model | ||
def find(self): | ||
""" | ||
Search property records which are duplicated or the same as the default | ||
""" | ||
result = [] | ||
default_properties = self.env['ir.property'].search([ | ||
('res_id', '=', False), | ||
]) | ||
handled_field_ids = [] | ||
for prop in default_properties: | ||
if prop.fields_id.id in handled_field_ids: | ||
continue | ||
domain = [ | ||
('id', '!=', prop.id), | ||
('fields_id', '=', prop.fields_id.id), | ||
# =? explicitly tests for None or False, not falsyness | ||
('value_float', '=?', prop.value_float or False), | ||
('value_integer', '=?', prop.value_integer or False), | ||
('value_text', '=?', prop.value_text or False), | ||
('value_binary', '=?', prop.value_binary or False), | ||
('value_reference', '=?', prop.value_reference or False), | ||
('value_datetime', '=?', prop.value_datetime or False), | ||
] | ||
if prop.company_id: | ||
domain.append(('company_id', '=', prop.company_id.id)) | ||
else: | ||
domain.extend([ | ||
'|', | ||
('company_id', '=', False), | ||
( | ||
'company_id', 'in', self.env['res.company'].search([ | ||
( | ||
'id', 'not in', default_properties.filtered( | ||
lambda x: x.company_id and | ||
x.fields_id == prop.fields_id | ||
).ids, | ||
) | ||
]).ids | ||
), | ||
]) | ||
|
||
for redundant_property in self.env['ir.property'].search(domain): | ||
result.append({ | ||
'name': '%s@%s: %s' % ( | ||
prop.name, prop.res_id, prop.get_by_record(prop) | ||
), | ||
'property_id': redundant_property.id, | ||
'reason': REASON_DEFAULT, | ||
}) | ||
handled_field_ids.append(prop.fields_id.id) | ||
self.env.cr.execute( | ||
''' | ||
with grouped_properties(ids, cnt) as ( | ||
select array_agg(id), count(*) | ||
from ir_property group by res_id, company_id, fields_id | ||
) | ||
select ids from grouped_properties where cnt > 1 | ||
''' | ||
) | ||
for ids, in self.env.cr.fetchall(): | ||
# odoo uses the first property found by search | ||
for prop in self.env['ir.property'].search([ | ||
('id', 'in', ids) | ||
])[1:]: | ||
result.append({ | ||
'name': '%s@%s: %s' % ( | ||
prop.name, prop.res_id, prop.get_by_record(prop) | ||
), | ||
'property_id': prop.id, | ||
'reason': REASON_DUPLICATE, | ||
}) | ||
|
||
return result | ||
|
||
purge_line_ids = fields.One2many( | ||
'cleanup.purge.line.property', 'wizard_id', 'Properties to purge') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<odoo> | ||
<record id="cleanup_create_indexes_wizard_view_form" model="ir.ui.view"> | ||
<field name="model">cleanup.create_indexes.wizard</field> | ||
<field name="inherit_id" ref="form_purge_wizard" /> | ||
<field name="mode">primary</field> | ||
<field name="arch" type="xml"> | ||
<button name="purge_all" position="attributes"> | ||
<attribute name="string">Create all</attribute> | ||
</button> | ||
<button name="purge" position="attributes"> | ||
<attribute name="string">Create</attribute> | ||
</button> | ||
</field> | ||
</record> | ||
|
||
<record id="cleanup_create_indexes_wizard_action" model="ir.actions.server"> | ||
<field name="name">Create missing indexes</field> | ||
<field name="type">ir.actions.server</field> | ||
<field name="state">code</field> | ||
<field name="model_id" ref="database_cleanup.model_cleanup_create_indexes_wizard" /> | ||
<field name="code">action = self.get_wizard_action(cr, uid, context=context)</field> | ||
</record> | ||
|
||
<record id="cleanup_create_indexes_line_view_tree" model="ir.ui.view"> | ||
<field name="model">cleanup.create_indexes.line</field> | ||
<field name="inherit_id" ref="tree_purge_line" /> | ||
<field name="mode">primary</field> | ||
<field name="arch" type="xml"> | ||
<button name="purge" position="attributes"> | ||
<attribute name="string">Create this index</attribute> | ||
<attribute name="icon">gtk-add</attribute> | ||
</button> | ||
</field> | ||
</record> | ||
|
||
<record id="cleanup_create_indexes_line_action" model="ir.actions.server"> | ||
<field name="name">Create</field> | ||
<field name="type">ir.actions.server</field> | ||
<field name="state">code</field> | ||
<field name="model_id" ref="database_cleanup.model_cleanup_create_indexes_line" /> | ||
<field name="code">self.purge(cr, uid, context.get('active_ids', []), context)</field> | ||
</record> | ||
|
||
<record id="cleanup_create_indexes_line_action_value" model="ir.values"> | ||
<field name="name">Create indexes</field> | ||
<field name="key">action</field> | ||
<field name="key2">client_action_multi</field> | ||
<field name="model">cleanup.create_indexes.line</field> | ||
<field name="value" eval="'ir.actions.server,%d' % ref('database_cleanup.cleanup_create_indexes_line_action')" /> | ||
</record> | ||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<openerp> | ||
<data> | ||
<record id="purge_property_view" model="ir.ui.view"> | ||
<field name="model">cleanup.purge.wizard.property</field> | ||
<field name="inherit_id" ref="form_purge_wizard" /> | ||
<field name="mode">primary</field> | ||
<field name="arch" type="xml"> | ||
<data /> | ||
</field> | ||
</record> | ||
|
||
<record id="action_purge_property" model="ir.actions.server"> | ||
<field name="name">Purge properties</field> | ||
<field name="type">ir.actions.server</field> | ||
<field name="state">code</field> | ||
<field name="model_id" ref="database_cleanup.model_cleanup_purge_wizard_property" /> | ||
<field name="code">action = self.get_wizard_action(cr, uid, context=context)</field> | ||
</record> | ||
|
||
<record id="purge_property_line_tree" model="ir.ui.view"> | ||
<field name="model">cleanup.purge.line.property</field> | ||
<field name="inherit_id" ref="tree_purge_line" /> | ||
<field name="mode">primary</field> | ||
<field name="arch" type="xml"> | ||
<field name="name" position="after"> | ||
<field name="reason" /> | ||
</field> | ||
</field> | ||
</record> | ||
|
||
<record id="action_purge_property_line" model="ir.actions.server"> | ||
<field name="name">Purge</field> | ||
<field name="type">ir.actions.server</field> | ||
<field name="state">code</field> | ||
<field name="model_id" ref="database_cleanup.model_cleanup_purge_line_property" /> | ||
<field name="code">self.purge(cr, uid, context.get('active_ids', []), context)</field> | ||
</record> | ||
|
||
<record id="action_purge_property_line_value" model="ir.values"> | ||
<field name="name">Purge</field> | ||
<field name="key">action</field> | ||
<field name="key2">client_action_multi</field> | ||
<field name="model">cleanup.purge.line.property</field> | ||
<field name="value" eval="'ir.actions.server,%d' % ref('database_cleanup.action_purge_property_line')" /> | ||
</record> | ||
|
||
</data> | ||
</openerp> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters