You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
5.5 KiB

11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # This module copyright (C) 2014 Therp BV (<http://therp.nl>).
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as
  9. # published by the Free Software Foundation, either version 3 of the
  10. # License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. ##############################################################################
  21. from openerp.osv import orm, fields
  22. from openerp.tools.translate import _
  23. class CleanupPurgeLineTable(orm.TransientModel):
  24. _inherit = 'cleanup.purge.line'
  25. _name = 'cleanup.purge.line.table'
  26. _columns = {
  27. 'wizard_id': fields.many2one(
  28. 'cleanup.purge.wizard.table', 'Purge Wizard', readonly=True),
  29. }
  30. def purge(self, cr, uid, ids, context=None):
  31. """
  32. Unlink tables upon manual confirmation.
  33. """
  34. lines = self.browse(cr, uid, ids, context=context)
  35. tables = [line.name for line in lines]
  36. for line in lines:
  37. if line.purged:
  38. continue
  39. # Retrieve constraints on the tables to be dropped
  40. # This query is referenced in numerous places
  41. # on the Internet but credits probably go to Tom Lane
  42. # in this post http://www.postgresql.org/\
  43. # message-id/22895.1226088573@sss.pgh.pa.us
  44. # Only using the constraint name and the source table,
  45. # but I'm leaving the rest in for easier debugging
  46. cr.execute(
  47. """
  48. SELECT conname, confrelid::regclass, af.attname AS fcol,
  49. conrelid::regclass, a.attname AS col
  50. FROM pg_attribute af, pg_attribute a,
  51. (SELECT conname, conrelid, confrelid,conkey[i] AS conkey,
  52. confkey[i] AS confkey
  53. FROM (select conname, conrelid, confrelid, conkey,
  54. confkey, generate_series(1,array_upper(conkey,1)) AS i
  55. FROM pg_constraint WHERE contype = 'f') ss) ss2
  56. WHERE af.attnum = confkey AND af.attrelid = confrelid AND
  57. a.attnum = conkey AND a.attrelid = conrelid
  58. AND confrelid::regclass = '%s'::regclass;
  59. """ % line.name)
  60. for constraint in cr.fetchall():
  61. if constraint[3] in tables:
  62. self.logger.info(
  63. 'Dropping constraint %s on table %s (to be dropped)',
  64. constraint[0], constraint[3])
  65. cr.execute(
  66. "ALTER TABLE %s DROP CONSTRAINT %s" % (
  67. constraint[3], constraint[0]))
  68. self.logger.info(
  69. 'Dropping table %s', line.name)
  70. cr.execute("DROP TABLE \"%s\"" % (line.name,))
  71. line.write({'purged': True})
  72. cr.commit()
  73. return True
  74. class CleanupPurgeWizardTable(orm.TransientModel):
  75. _inherit = 'cleanup.purge.wizard'
  76. _name = 'cleanup.purge.wizard.table'
  77. def default_get(self, cr, uid, fields, context=None):
  78. res = super(CleanupPurgeWizardTable, self).default_get(
  79. cr, uid, fields, context=context)
  80. if 'name' in fields:
  81. res['name'] = _('Purge tables')
  82. return res
  83. def find(self, cr, uid, context=None):
  84. """
  85. Search for tables that cannot be instantiated.
  86. Ignore views for now.
  87. """
  88. model_ids = self.pool['ir.model'].search(cr, uid, [], context=context)
  89. # Start out with known tables with no model
  90. known_tables = ['wkf_witm_trans']
  91. for model in self.pool['ir.model'].browse(
  92. cr, uid, model_ids, context=context):
  93. model_pool = self.pool.get(model.model)
  94. if not model_pool:
  95. continue
  96. known_tables.append(model_pool._table)
  97. known_tables += [
  98. column._sql_names(model_pool)[0]
  99. for column in model_pool._columns.values()
  100. if (column._type == 'many2many' and
  101. hasattr(column, '_rel')) # unstored function fields of
  102. # type m2m don't have _rel
  103. ]
  104. # Cannot pass table names as a psycopg argument
  105. known_tables_repr = ",".join(
  106. [("'%s'" % table) for table in known_tables])
  107. cr.execute(
  108. """
  109. SELECT table_name FROM information_schema.tables
  110. WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
  111. AND table_name NOT IN (%s)""" % known_tables_repr)
  112. res = [(0, 0, {'name': row[0]}) for row in cr.fetchall()]
  113. if not res:
  114. raise orm.except_orm(
  115. _('Nothing to do'),
  116. _('No orphaned tables found'))
  117. return res
  118. _columns = {
  119. 'purge_line_ids': fields.one2many(
  120. 'cleanup.purge.line.table',
  121. 'wizard_id', 'Tables to purge'),
  122. }