|
@ -85,18 +85,21 @@ class CleanupPurgeWizardColumn(orm.TransientModel): |
|
|
res['name'] = _('Purge columns') |
|
|
res['name'] = _('Purge columns') |
|
|
return res |
|
|
return res |
|
|
|
|
|
|
|
|
def get_orphaned_columns(self, cr, uid, model_pool, context=None): |
|
|
|
|
|
|
|
|
def get_orphaned_columns(self, cr, uid, model_pools, context=None): |
|
|
""" |
|
|
""" |
|
|
From openobject-server/openerp/osv/orm.py |
|
|
From openobject-server/openerp/osv/orm.py |
|
|
Iterate on the database columns to identify columns |
|
|
Iterate on the database columns to identify columns |
|
|
of fields which have been removed |
|
|
of fields which have been removed |
|
|
""" |
|
|
""" |
|
|
columns = [ |
|
|
|
|
|
c for c in model_pool._columns |
|
|
|
|
|
if not (isinstance(model_pool._columns[c], fields.function) |
|
|
|
|
|
and not model_pool._columns[c].store)] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
columns = list(set([ |
|
|
|
|
|
column for model_pool in model_pools |
|
|
|
|
|
for column in model_pool._columns |
|
|
|
|
|
if not (isinstance(model_pool._columns[column], fields.function) |
|
|
|
|
|
and not model_pool._columns[column].store) |
|
|
|
|
|
])) |
|
|
columns += orm.MAGIC_COLUMNS |
|
|
columns += orm.MAGIC_COLUMNS |
|
|
columns += self.blacklist.get(model_pool._table, []) |
|
|
|
|
|
|
|
|
columns += self.blacklist.get(model_pools[0]._table, []) |
|
|
|
|
|
|
|
|
cr.execute("SELECT a.attname" |
|
|
cr.execute("SELECT a.attname" |
|
|
" FROM pg_class c, pg_attribute a" |
|
|
" FROM pg_class c, pg_attribute a" |
|
@ -106,26 +109,37 @@ class CleanupPurgeWizardColumn(orm.TransientModel): |
|
|
" AND pg_catalog.format_type(a.atttypid, a.atttypmod)" |
|
|
" AND pg_catalog.format_type(a.atttypid, a.atttypmod)" |
|
|
" NOT IN ('cid', 'tid', 'oid', 'xid')" |
|
|
" NOT IN ('cid', 'tid', 'oid', 'xid')" |
|
|
" AND a.attname NOT IN %s", |
|
|
" AND a.attname NOT IN %s", |
|
|
(model_pool._table, False, tuple(columns))), |
|
|
|
|
|
|
|
|
(model_pools[0]._table, False, tuple(columns))), |
|
|
return [column[0] for column in cr.fetchall()] |
|
|
return [column[0] for column in cr.fetchall()] |
|
|
|
|
|
|
|
|
def find(self, cr, uid, context=None): |
|
|
def find(self, cr, uid, context=None): |
|
|
""" |
|
|
""" |
|
|
Search for columns that are not in the corresponding model. |
|
|
Search for columns that are not in the corresponding model. |
|
|
|
|
|
|
|
|
|
|
|
Group models by table to prevent false positives for columns |
|
|
|
|
|
that are only in some of the models sharing the same table. |
|
|
|
|
|
Example of this is 'sale_id' not being a field of stock.picking.in |
|
|
""" |
|
|
""" |
|
|
res = [] |
|
|
res = [] |
|
|
model_pool = self.pool['ir.model'] |
|
|
model_pool = self.pool['ir.model'] |
|
|
model_ids = model_pool.search(cr, uid, [], context=context) |
|
|
model_ids = model_pool.search(cr, uid, [], context=context) |
|
|
line_pool = self.pool['cleanup.purge.line.column'] |
|
|
line_pool = self.pool['cleanup.purge.line.column'] |
|
|
|
|
|
|
|
|
|
|
|
# mapping of tables to tuples (model id, [pool1, pool2, ...]) |
|
|
|
|
|
table2model = {} |
|
|
|
|
|
|
|
|
for model in model_pool.browse(cr, uid, model_ids, context=context): |
|
|
for model in model_pool.browse(cr, uid, model_ids, context=context): |
|
|
model_pool = self.pool.get(model.model) |
|
|
model_pool = self.pool.get(model.model) |
|
|
if not model_pool or not model_pool._auto: |
|
|
if not model_pool or not model_pool._auto: |
|
|
continue |
|
|
continue |
|
|
|
|
|
table2model.setdefault(model_pool._table, (model.id, []))[1].append(model_pool) |
|
|
|
|
|
|
|
|
|
|
|
for table, model_spec in table2model.iteritems(): |
|
|
for column in self.get_orphaned_columns( |
|
|
for column in self.get_orphaned_columns( |
|
|
cr, uid, model_pool, context=context): |
|
|
|
|
|
|
|
|
cr, uid, model_spec[1], context=context): |
|
|
res.append((0, 0, { |
|
|
res.append((0, 0, { |
|
|
'name': column, |
|
|
'name': column, |
|
|
'model_id': model.id})) |
|
|
|
|
|
|
|
|
'model_id': model_spec[0]})) |
|
|
if not res: |
|
|
if not res: |
|
|
raise orm.except_orm( |
|
|
raise orm.except_orm( |
|
|
_('Nothing to do'), |
|
|
_('Nothing to do'), |
|
|