credativ team mailing list archive
-
credativ team
-
Mailing list archive
-
Message #04831
[Merge] lp:~therp-nl/openupgrade-server/6.1-use_orm into lp:openupgrade-server
Stefan Rijnhart (Therp) has proposed merging lp:~therp-nl/openupgrade-server/6.1-use_orm into lp:openupgrade-server.
Requested reviews:
OpenUpgrade Committers (openupgrade-committers)
For more details, see:
https://code.launchpad.net/~therp-nl/openupgrade-server/6.1-use_orm/+merge/105196
This merge constitutes the refactoring of the database layout analysis and the inclusion of the analysis files for 6.1, as described here:
https://lists.launchpad.net/openupgrade-drivers/msg00001.html
--
https://code.launchpad.net/~therp-nl/openupgrade-server/6.1-use_orm/+merge/105196
Your team OpenUpgrade Committers is requested to review the proposed merge of lp:~therp-nl/openupgrade-server/6.1-use_orm into lp:openupgrade-server.
=== modified file 'openerp/addons/base/ir/ir_model.py'
--- openerp/addons/base/ir/ir_model.py 2012-02-09 08:38:28 +0000
+++ openerp/addons/base/ir/ir_model.py 2012-05-09 12:37:19 +0000
@@ -32,6 +32,8 @@
from tools.translate import _
import pooler
+from openerp.openupgrade import openupgrade_log
+
_logger = logging.getLogger(__name__)
def _get_fields_type(self, cr, uid, context=None):
@@ -675,6 +677,10 @@
return super(ir_model_data,self).unlink(cr, uid, ids, context=context)
def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False, context=None):
+ #OpenUpgrade: log entry (used in csv import)
+ if xml_id:
+ openupgrade_log.log_xml_id(cr, module, xml_id)
+
model_obj = self.pool.get(model)
if not context:
context = {}
=== added file 'openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt'
--- openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt 1970-01-01 00:00:00 +0000
+++ openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt 2012-05-09 12:37:19 +0000
@@ -0,0 +1,178 @@
+---base---
+base / ir.actions.act_window / menus (char) : DEL
+base / ir.actions.act_window / target (selection) : selection_keys is now '['current', 'inline', 'new']' ('['current', 'new']')
+base / ir.actions.act_window.view / view_mode (selection) : selection_keys is now '['calendar', 'form', 'gantt', 'graph', 'kanban', 'tree']' ('['calendar', 'form', 'gantt', 'graph', 'tree']')
+base / ir.actions.client / name (char) : NEW required: required
+base / ir.actions.client / params_store (binary) : NEW
+base / ir.actions.client / tag (char) : NEW required: required
+base / ir.actions.client / type (char) : NEW required: required, req_default: ir.actions.client
+base / ir.actions.client / usage (char) : NEW
+base / ir.actions.todo / category_id (many2one) : NEW relation: ir.actions.todo.category
+base / ir.actions.todo / restart (selection) : DEL required: required, selection_keys: ['always', 'never', 'onskip'], req_default: onskip
+base / ir.actions.todo / state (selection) : selection_keys is now '['done', 'open']' ('['cancel', 'done', 'open', 'skip']')
+base / ir.actions.todo / type (selection) : NEW required: required, selection_keys: ['automatic', 'manual', 'once'], req_default: manual
+base / ir.actions.todo.category / name (char) : NEW required: required
+base / ir.actions.todo.category / sequence (integer) : NEW
+base / ir.actions.todo.category / wizards_ids (one2many) : NEW relation: ir.actions.todo
+base / ir.mail_server / name (char) : NEW required: required
+base / ir.mail_server / sequence (integer) : NEW
+base / ir.mail_server / smtp_debug (boolean) : NEW
+base / ir.mail_server / smtp_encryption (selection) : NEW required: required, selection_keys: ['none', 'ssl', 'starttls'], req_default: none
+base / ir.mail_server / smtp_host (char) : NEW required: required
+base / ir.mail_server / smtp_pass (char) : NEW
+base / ir.mail_server / smtp_port (integer) : NEW required: required, req_default: 25
+base / ir.mail_server / smtp_user (char) : NEW
+base / ir.model.fields / serialization_field_id (many2one): NEW relation: ir.model.fields
+base / ir.module.category / description (text) : NEW
+base / ir.module.category / module_ids (one2many) : NEW relation: ir.module.module
+base / ir.module.category / sequence (integer) : NEW
+base / ir.module.category / visible (boolean) : NEW
+base / ir.module.module / application (boolean) : NEW
+base / ir.module.module / auto_install (boolean) : NEW
+base / ir.module.module / complexity (selection) : NEW selection_keys: ['easy', 'expert', 'normal']
+base / ir.module.module / icon (char) : NEW
+base / ir.module.module / sequence (integer) : NEW
+base / ir.module.module / web (boolean) : DEL
+base / ir.sequence / implementation (selection) : NEW required: required, selection_keys: ['no_gap', 'standard'], req_default: standard
+base / ir.translation / module (char) : DEL
+base / ir.translation / xml_id (char) : DEL
+base / ir.ui.view / type (selection) : selection_keys is now '['calendar', 'diagram', 'form', 'gantt', 'graph', 'kanban', 'mdx', 'search', 'tree']' ('['calendar', 'diagram', 'form', 'gantt', 'graph', 'mdx', 'search', 'tree']')
+base / ir.ui.view.custom / ref_id (many2one) : now required
+base / ir.ui.view.custom / user_id (many2one) : now required
+base / ir.values / key (selection) : now required, default = action
+base / ir.values / meta (text) : DEL
+base / ir.values / model (char) : now required
+base / ir.values / name (char) : now required
+base / ir.values / object (boolean) : DEL
+base / res.bank / code (char) : module is now 'l10n_ch' ('base')
+base / res.company / bank_ids (one2many) : NEW relation: res.partner.bank
+base / res.company / company_registry (char) : NEW
+base / res.company / name (char) : now a function
+base / res.company / paper_format (selection) : NEW required: required, selection_keys: ['a4', 'us_letter'], req_default: a4
+base / res.company / rml_footer2 (char) : now a function
+base / res.country / address_format (text) : NEW
+base / res.currency / position (selection) : NEW selection_keys: ['after', 'before']
+base / res.currency.rate / currency_rate_type_id (many2one): NEW relation: res.currency.rate.type
+base / res.currency.rate.type / name (char) : NEW required: required
+base / res.groups / category_id (many2one) : NEW relation: ir.module.category
+base / res.groups / implied_ids (many2many) : NEW relation: res.groups
+base / res.partner / color (integer) : NEW
+base / res.partner.address / color (integer) : NEW
+base / res.partner.bank / acc_number (char) : now required
+base / res.partner.bank / bank_bic (char) : NEW
+base / res.partner.bank / bank_name (char) : NEW
+base / res.partner.bank / company_id (many2one) : NEW relation: res.company
+base / res.partner.bank / footer (boolean) : NEW
+base / res.partner.bank.type / format_layout (text) : NEW
+base / res.users / address_id (many2one) : DEL relation: res.partner.address
+base / res.users / email (char) : DEL
+base / res.users / id (integer) : NEW
+base / res.users / user_email (char) : not a function anymore
+deleted xml-id of model ir.actions.act_window: base.act_values_form
+deleted xml-id of model ir.actions.act_window: base.action_config_simple_view_form
+deleted xml-id of model ir.actions.act_window: base.action_config_user_form
+deleted xml-id of model ir.actions.act_window: base.action_view_base_module_upgrade_window
+deleted xml-id of model ir.actions.act_window: base.res_partner_canal-act
+deleted xml-id of model ir.actions.server: base.action_start_configurator
+deleted xml-id of model ir.actions.todo: base.config_wizard_simple_view
+deleted xml-id of model ir.actions.todo: base.config_wizard_step_user
+deleted xml-id of model ir.actions.wizard: base.wizard_server_action_create
+deleted xml-id of model ir.model.access: base.access_ir_ui_view_custom_group_system
+deleted xml-id of model ir.model.access: base.access_ir_values_group_erp_manager
+deleted xml-id of model ir.model.access: base.access_res_partner_canal_group_partner_manager
+deleted xml-id of model ir.model.access: base.access_res_partner_canal_group_user
+deleted xml-id of model ir.ui.menu: base.menu_crm_config_lead
+deleted xml-id of model ir.ui.menu: base.menu_res_partner_canal-act
+deleted xml-id of model ir.ui.menu: base.menu_view_base_module_configuration
+deleted xml-id of model ir.ui.menu: base.menu_view_base_module_import
+deleted xml-id of model ir.ui.view: base.res_partner_canal-view
+deleted xml-id of model ir.ui.view: base.res_partner_canal-view-tree
+deleted xml-id of model ir.ui.view: base.values_view_form
+deleted xml-id of model ir.ui.view: base.values_view_tree
+deleted xml-id of model ir.ui.view: base.view_confirm_simple_view_form
+deleted xml-id of model ir.ui.view: base.view_users_configuration_form
+deleted xml-id of model ir.ui.view_sc: base.ir_ui_view_sc_configuration
+deleted xml-id of model ir.values: base.action_todo_config
+deleted xml-id of model res.currency.rate: base.rateVEB
+deleted xml-id of model res.currency: base.VEB
+deleted xml-id of model res.partner.bank.type.field: base.bank_normal_field
+deleted xml-id of model res.partner.bank.type.field: base.bank_normal_field_contry
+new xml-id of model ir.actions.act_window.view: base.action_values_defaults_form_view
+new xml-id of model ir.actions.act_window.view: base.action_values_defaults_tree_view
+new xml-id of model ir.actions.act_window: base.act_values_form_defaults
+new xml-id of model ir.actions.act_window: base.action_currency_rate_type_form
+new xml-id of model ir.actions.act_window: base.action_ir_mail_server_list
+new xml-id of model ir.actions.act_window: base.action_res_partner_bank_account_form
+new xml-id of model ir.actions.act_window: base.action_res_partner_bank_type_form
+new xml-id of model ir.actions.act_window: base.bank_account_update
+new xml-id of model ir.actions.act_window: base.ir_config_list_action
+new xml-id of model ir.actions.report.xml: base.preview_report
+new xml-id of model ir.actions.todo.category: base.category_administration_config
+new xml-id of model ir.actions.todo.category: base.category_sales_management_config
+new xml-id of model ir.actions.todo.category: base.category_tools_customization_config
+new xml-id of model ir.mail_server: base.ir_mail_server_localhost0
+new xml-id of model ir.model.access: base.access_ir_actions_client
+new xml-id of model ir.model.access: base.access_ir_actions_todo_category
+new xml-id of model ir.model.access: base.access_ir_mail_server_all
+new xml-id of model ir.model.access: base.access_res_currency_rate_type_group_all
+new xml-id of model ir.module.category: base.module_category_account_voucher
+new xml-id of model ir.module.category: base.module_category_accounting_and_finance
+new xml-id of model ir.module.category: base.module_category_administration
+new xml-id of model ir.module.category: base.module_category_customer_relationship_management
+new xml-id of model ir.module.category: base.module_category_hidden
+new xml-id of model ir.module.category: base.module_category_human_resources
+new xml-id of model ir.module.category: base.module_category_knowledge_management
+new xml-id of model ir.module.category: base.module_category_localization
+new xml-id of model ir.module.category: base.module_category_localization_account_charts
+new xml-id of model ir.module.category: base.module_category_manufacturing
+new xml-id of model ir.module.category: base.module_category_marketing
+new xml-id of model ir.module.category: base.module_category_point_of_sale
+new xml-id of model ir.module.category: base.module_category_project_management
+new xml-id of model ir.module.category: base.module_category_purchase_management
+new xml-id of model ir.module.category: base.module_category_report_designer
+new xml-id of model ir.module.category: base.module_category_sales_management
+new xml-id of model ir.module.category: base.module_category_specific_industry_applications
+new xml-id of model ir.module.category: base.module_category_tools
+new xml-id of model ir.module.category: base.module_category_usability
+new xml-id of model ir.module.category: base.module_category_warehouse_management
+new xml-id of model ir.rule: base.ir_ui_view_custom_personal
+new xml-id of model ir.rule: base.ir_values_default_rule
+new xml-id of model ir.ui.menu: base.ir_config_menu
+new xml-id of model ir.ui.menu: base.menu_action_res_partner_bank_form
+new xml-id of model ir.ui.menu: base.menu_action_res_partner_bank_typeform
+new xml-id of model ir.ui.menu: base.menu_email
+new xml-id of model ir.ui.menu: base.menu_mail_servers
+new xml-id of model ir.ui.menu: base.menu_values_form_defaults
+new xml-id of model ir.ui.view: base.contacts_kanban_view
+new xml-id of model ir.ui.view: base.ir_actions_todo_category_form
+new xml-id of model ir.ui.view: base.ir_actions_todo_category_tree
+new xml-id of model ir.ui.view: base.ir_mail_server_form
+new xml-id of model ir.ui.view: base.ir_mail_server_list
+new xml-id of model ir.ui.view: base.module_view_kanban
+new xml-id of model ir.ui.view: base.res_partner_kanban_view
+new xml-id of model ir.ui.view: base.user_groups_view
+new xml-id of model ir.ui.view: base.values_view_form_defaults
+new xml-id of model ir.ui.view: base.view_currency_rate_type_form
+new xml-id of model ir.ui.view: base.view_currency_rate_type_search
+new xml-id of model ir.ui.view: base.view_currency_search
+new xml-id of model ir.ui.view: base.view_ir_config_form
+new xml-id of model ir.ui.view: base.view_ir_config_list
+new xml-id of model ir.ui.view: base.view_ir_config_search
+new xml-id of model ir.ui.view: base.view_ir_mail_server_search
+new xml-id of model ir.ui.view: base.view_partner_bank_search
+new xml-id of model res.country: base.ax
+new xml-id of model res.country: base.bl
+new xml-id of model res.country: base.bq
+new xml-id of model res.country: base.cw
+new xml-id of model res.country: base.gg
+new xml-id of model res.country: base.im
+new xml-id of model res.country: base.je
+new xml-id of model res.country: base.mf
+new xml-id of model res.country: base.ps
+new xml-id of model res.country: base.ss
+new xml-id of model res.country: base.sx
+new xml-id of model res.currency.rate: base.rateUYU
+new xml-id of model res.currency.rate: base.rateVEF
+new xml-id of model res.currency: base.UYU
+new xml-id of model res.currency: base.VEF
+new xml-id of model res.partner.bank.type.field: base.bank_normal_field_bic
=== added file 'openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt'
--- openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt 1970-01-01 00:00:00 +0000
+++ openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt 2012-05-09 12:37:19 +0000
@@ -0,0 +1,248 @@
+---general---
+# 5021 fields matched,
+# Direct match: 4708
+# Found in other module: 6
+# Found with different name: 0
+# Found with different type: 1
+# In obsolete models: 306
+# New columns: 646
+# Not matched: 187
+new model account.asset.asset
+new model account.asset.category
+new model account.asset.depreciation.line
+new model account.asset.history
+new model account.bank.statement.line.global
+new model account.coda.comm.type
+new model account.coda.trans.category
+new model account.coda.trans.code
+new model account.coda.trans.type
+new model account.financial.report
+new model account.treasury.report
+new model analytic.user.funct.grid
+new model asset.asset.report
+new model coda.bank.account
+new model coda.bank.statement
+new model coda.bank.statement.line
+new model crm.case.channel
+new model crm.partner.report.assign
+new model edi.document
+new model fetchmail.server
+new model google.import.message
+new model hr.contribution.register
+new model hr.payslip.input
+new model hr.payslip.run
+new model hr.payslip.worked_days
+new model hr.recruitment.source
+new model hr.rule.input
+new model hr.salary.rule
+new model hr.salary.rule.category
+new model import.sugarcrm
+new model ir.actions.client
+new model ir.actions.todo.category
+new model ir.mail_server
+new model l10n_br_account.cst
+new model l10n_br_account.cst.template
+new model mail.thread
+new model pos.category
+new model project.task.history
+new model project.task.history.cumulative
+new model project.user.allocation
+new model res.currency.rate.type
+new model res.partner.activation
+new model res.partner.location
+new model res.portal
+new model res.portal.widget
+obsolete model account.report_libroiva
+obsolete model analytic_user_funct_grid
+obsolete model base_report_creator.report
+obsolete model base_report_creator.report.fields
+obsolete model base_report_creator.report.filter
+obsolete model board.note
+obsolete model board.note.type
+obsolete model company.contribution
+obsolete model company.contribution.line
+obsolete model document.directory.ics.fields
+obsolete model email.server
+obsolete model email.template
+obsolete model email_template.account
+obsolete model email_template.mailbox
+obsolete model hr.allounce.deduction.categoty
+obsolete model hr.contibution.register
+obsolete model hr.contibution.register.line
+obsolete model hr.contract.wage.type
+obsolete model hr.contract.wage.type.period
+obsolete model hr.employee.marital.status
+obsolete model hr.passport
+obsolete model hr.payroll.advice
+obsolete model hr.payroll.advice.line
+obsolete model hr.payroll.register
+obsolete model hr.payslip.account.move
+obsolete model hr.payslip.line.line
+obsolete model mailgate.message
+obsolete model mailgate.thread
+obsolete model mrp.production.order
+obsolete model project.resource.allocation
+obsolete model report.account.invoice.product
+obsolete model res.partner.canal
+obsolete model res.partner.job
+ERROR: module not in list of installed modules:
+---project_caldav---
+project_caldav / project.task / alarm_id (many2one) : DEL relation: res.alarm
+project_caldav / project.task / allday (boolean) : DEL
+project_caldav / project.task / attendee_ids (many2many) : DEL relation: calendar.attendee
+project_caldav / project.task / base_calendar_alarm_id (many2one): DEL relation: calendar.alarm
+project_caldav / project.task / base_calendar_url (char) : DEL
+project_caldav / project.task / byday (selection) : DEL selection_keys: ['-1', '1', '2', '3', '4', '5']
+project_caldav / project.task / class (selection) : DEL selection_keys: ['confidential', 'private', 'public']
+project_caldav / project.task / count (integer) : DEL
+project_caldav / project.task / day (integer) : DEL
+project_caldav / project.task / duration (integer) : DEL
+project_caldav / project.task / edit_all (boolean) : DEL
+project_caldav / project.task / end_date (date) : DEL
+project_caldav / project.task / end_type (selection) : DEL selection_keys: ['count', 'end_date', 'forever']
+project_caldav / project.task / exdate (text) : DEL
+project_caldav / project.task / exrule (char) : DEL
+project_caldav / project.task / fr (boolean) : DEL
+project_caldav / project.task / freq (selection) : DEL selection_keys: ['None', 'daily', 'hourly', 'monthly', 'weekly', 'yearly']
+project_caldav / project.task / interval (integer) : DEL
+project_caldav / project.task / location (char) : DEL
+project_caldav / project.task / mo (boolean) : DEL
+project_caldav / project.task / month_list (selection) : DEL selection_keys: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+project_caldav / project.task / organizer (char) : DEL
+project_caldav / project.task / organizer_id (many2one) : DEL relation: res.users
+project_caldav / project.task / recurrency (boolean) : DEL
+project_caldav / project.task / recurrent_id (datetime) : DEL
+project_caldav / project.task / recurrent_uid (integer) : DEL
+project_caldav / project.task / rrule_type (selection) : DEL selection_keys: ['daily', 'monthly', 'none', 'weekly', 'yearly']
+project_caldav / project.task / sa (boolean) : DEL
+project_caldav / project.task / select1 (selection) : DEL selection_keys: ['date', 'day']
+project_caldav / project.task / show_as (selection) : DEL selection_keys: ['busy', 'free']
+project_caldav / project.task / su (boolean) : DEL
+project_caldav / project.task / th (boolean) : DEL
+project_caldav / project.task / tu (boolean) : DEL
+project_caldav / project.task / vtimezone (selection) : DEL selection_keys: function
+project_caldav / project.task / we (boolean) : DEL
+project_caldav / project.task / week_list (selection) : DEL selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE']
+project_caldav / project.task / write_date (datetime) : DEL
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_0
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_1
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_10
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_11
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_12
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_13
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_14
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_15
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_16
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_17
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_18
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_19
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_2
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_20
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_21
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_22
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_226
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_23
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_24
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_25
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_27
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_28
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_29
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_3
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_30
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_31
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_32
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_33
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_34
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_35
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_36
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_37
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_38
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_4
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_5
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_6
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_7
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_8
+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_9
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_1
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_10
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_11
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_2
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_3
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_4
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_5
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_6
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_7
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_8
+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_9
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_1
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_10
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_11
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_2
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_3
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_4
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_5
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_6
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_7
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_8
+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_9
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_1
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_10
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_11
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_12
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_13
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_14
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_15
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_16
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_17
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_18
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_19
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_2
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_3
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_4
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_5
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_7
+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_9
+deleted xml-id of model basic.calendar.lines: caldav.calendar_lines_alarm2
+deleted xml-id of model basic.calendar.lines: caldav.calendar_lines_attendee2
+deleted xml-id of model basic.calendar.lines: caldav.calendar_lines_todo
+deleted xml-id of model basic.calendar.lines: project_caldav.basic_calendar_lines_attendee0
+deleted xml-id of model basic.calendar.lines: project_caldav.basic_calendar_lines_valarm0
+deleted xml-id of model basic.calendar.lines: project_caldav.basic_calendar_lines_vtodo0
+deleted xml-id of model basic.calendar: caldav.basic_calendar2
+deleted xml-id of model basic.calendar: project_caldav.basic_calendar_tasks0
+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form
+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form1
+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form2
+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form3
+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form4
+ERROR: module not in list of installed modules:
+---base_report_creator---
+deleted xml-id of model ir.actions.act_window: base_report_creator.action_report_menu_create
+deleted xml-id of model ir.actions.act_window: base_report_creator.base_report_creator_action
+deleted xml-id of model ir.actions.wizard: base_report_creator.wizard_set_filter_fields
+deleted xml-id of model ir.model.access: base_report_creator.access_base_report_creator_report
+deleted xml-id of model ir.model.access: base_report_creator.access_base_report_creator_report_fields
+deleted xml-id of model ir.model.access: base_report_creator.access_base_report_creator_report_filter
+deleted xml-id of model ir.ui.menu: base.menu_custom_reports
+deleted xml-id of model ir.ui.view: base.view_model_fields_tree
+deleted xml-id of model ir.ui.view: base_report_creator.base_report_creator_form
+deleted xml-id of model ir.ui.view: base_report_creator.base_report_creator_tree
+deleted xml-id of model ir.ui.view: base_report_creator.view_report_filter
+deleted xml-id of model ir.ui.view: base_report_creator.view_report_menu_create
+ERROR: module not in list of installed modules:
+---document_ics---
+document_ics / crm.meeting / code (char) : DEL
+document_ics / document.directory.content / fname_field (char) : DEL
+document_ics / document.directory.content / ics_domain (char) : DEL
+document_ics / document.directory.content / ics_field_ids (one2many) : DEL relation: document.directory.ics.fields
+document_ics / document.directory.content / obj_iterate (boolean) : DEL
+document_ics / document.directory.content / object_id (many2one) : DEL relation: ir.model
+deleted xml-id of model document.directory.content.type: document_ics.ics
+deleted xml-id of model ir.actions.act_window: document_ics.action_view_document_ics_config_directories
+deleted xml-id of model ir.actions.todo: document_ics.config_wizard_step_case_section_menu
+deleted xml-id of model ir.model.access: document_ics.access_document_directory_ics_fields_all
+deleted xml-id of model ir.model.access: document_ics.access_document_directory_ics_fields_manager
+deleted xml-id of model ir.ui.view: document_ics.view_document_directory_form
+deleted xml-id of model ir.ui.view: document_ics.view_document_directory_form_1
+deleted xml-id of model ir.ui.view: document_ics.view_document_ics_config_directories
+deleted xml-id of model ir.ui.view: document_ics.view_meeting_inherit_form
=== added directory 'openerp/addons/openupgrade_records'
=== added file 'openerp/addons/openupgrade_records/__init__.py'
--- openerp/addons/openupgrade_records/__init__.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/__init__.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,2 @@
+import model
+import lib
=== added file 'openerp/addons/openupgrade_records/__openerp__.py'
--- openerp/addons/openupgrade_records/__openerp__.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/__openerp__.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+
+{
+ 'name': 'OpenUpgrade Records',
+ 'version': '0.2',
+ 'category': 'Normal',
+ 'description': """Allow OpenUpgrade records to be
+stored in the database and compare with other servers.
+
+This module depends on OpenERP client lib:
+
+ easy_install openerp-client-lib
+
+""",
+ 'author': 'OpenUpgrade Community',
+ 'maintainer': 'OpenUpgrade Community',
+ 'contributors': ['Therp BV'],
+ 'website': 'https://launchpad.net/~openupgrade-committers',
+ 'depends': [],
+ 'init_xml': [],
+ 'update_xml': [
+ 'view/openupgrade_record.xml',
+ 'view/comparison_config.xml',
+ 'view/analysis_wizard.xml',
+ 'view/generate_records_wizard.xml',
+ 'view/install_all_wizard.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'demo_xml': [
+ ],
+ 'test': [
+ ],
+ 'installable': True,
+ 'auto_install': False,
+ 'external_dependencies': {
+ 'python' : ['openerplib'],
+ },
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'openerp/addons/openupgrade_records/__terp__.py'
--- openerp/addons/openupgrade_records/__terp__.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/__terp__.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+
+{
+ 'name': 'OpenUpgrade Records',
+ 'version': '0.2',
+ 'category': 'Normal',
+ 'description': """Allow OpenUpgrade records to be
+stored in the database and compare with other servers.
+
+This module depends on OpenERP client lib:
+
+ easy_install openerp-client-lib
+
+""",
+ 'author': 'OpenUpgrade Community',
+ 'maintainer': 'OpenUpgrade Community',
+ 'contributors': ['Therp BV'],
+ 'website': 'https://launchpad.net/~openupgrade-committers',
+ 'depends': [],
+ 'init_xml': [],
+ 'update_xml': [
+ 'view/openupgrade_record.xml',
+ 'view/comparison_config.xml',
+ 'view/analysis_wizard.xml',
+ 'view/generate_records_wizard.xml',
+ 'view/install_all_wizard.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'demo_xml': [
+ ],
+ 'test': [
+ ],
+ 'installable': True,
+ 'auto_install': False,
+ 'external_dependencies': {
+ 'python' : ['openerplib'],
+ },
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added directory 'openerp/addons/openupgrade_records/lib'
=== added file 'openerp/addons/openupgrade_records/lib/__init__.py'
--- openerp/addons/openupgrade_records/lib/__init__.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/lib/__init__.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,2 @@
+import apriori
+import compare
=== renamed file 'openerp/openupgrade/changes.py' => 'openerp/addons/openupgrade_records/lib/apriori.py'
=== renamed file 'openerp/openupgrade/process-csv.py' => 'openerp/addons/openupgrade_records/lib/compare.py'
--- openerp/openupgrade/process-csv.py 2012-02-15 22:19:54 +0000
+++ openerp/addons/openupgrade_records/lib/compare.py 2012-05-09 12:37:19 +0000
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
##############################################################################
#
@@ -20,21 +19,21 @@
#
##############################################################################
-USAGE = """
-
- Standalone runnable to analyse two progressive datase layouts from the
- OpenUpgrade server.
-
- Usage: %(name)s <old.csv> <new.csv>
-
-"""
-
-import sys, copy, csv, re
-import changes
+#####################################################################
+# library providing a function to analyse two progressive database
+# layouts from the OpenUpgrade server.
+#####################################################################
+
+import copy
+
+try:
+ from openerp.addons.openupgrade_records.lib import apriori
+except ImportError:
+ from openupgrade_records.lib import apriori
keys = [
'module',
- 'operation',
+ 'mode',
'model',
'field',
'type',
@@ -46,168 +45,196 @@
'inherits',
]
-def readfile(file):
- fields = []
- readfile = csv.reader(open(file, 'rb'), delimiter=',', quotechar='"')
- for row in readfile:
- if len(row) != len(keys):
- print "Skip line %s (%s)" % (row, len(row))
- continue
- col = 0
- field = {}
- for key in keys:
- field[key] = row[col]
- col += 1
- field['matched'] = False
- fields.append(field)
- return fields
-
-def equal(dicta, dictb, ignore):
- ka = dicta.keys()
- kb = dictb.keys()
- kbstatic = dictb.keys()
- for keyset in [ ka, kb, kbstatic ]:
- for k in ignore:
- keyset.remove(k)
- for k in ka:
- if k not in kbstatic:
- return False
- if dicta[k] != dictb[k]:
- return False
- kb.remove(k)
- if kb:
- return False
- return True
-
-def compare(dict_old, dict_new, fields):
+def module_map(module):
+ return apriori.renamed_modules.get(
+ module, module)
+
+def compare_records(dict_old, dict_new, fields):
+ """
+ Check equivalence of two OpenUpgrade field representations
+ with respect to the keys in the 'fields' arguments.
+ Take apriori knowledge into account for mapped modules or
+ model names.
+ Return True of False.
+ """
for field in fields:
if field == 'module':
- if (changes.renamed_modules.get(dict_old[field], dict_old[field]) != dict_new[field]):
+ if (module_map(dict_old[field]) != dict_new[field]):
return False
elif field == 'model':
- if (changes.renamed_models.get(dict_old[field], dict_old[field]) != dict_new[field]):
+ if (apriori.renamed_models.get(
+ dict_old[field], dict_old[field]) != dict_new[field]):
return False
else:
if dict_old[field] != dict_new[field]:
return False
return True
-def search(item, dict, fields):
- for i in dict:
- if not compare(item, i, fields):
+def search(item, item_list, fields):
+ """
+ Find a match of a dictionary in a list of similar dictionaries
+ with respect to the keys in the 'fields' arguments.
+ Return the item if found or None.
+ """
+ for i in item_list:
+ if not compare_records(item, i, fields):
continue
return i
return None
-def fieldprint(old, new, field='NOT SPECIFIED', text=None):
-# repr = 'module %s, model %s, field %s (%s)' % (old['module'], old['model'], old['field'], old['type'])
+def fieldprint(old, new, field, text, reprs):
fieldrepr = "%s (%s)" % (old['field'], old['type'])
- repr = '%s / %s / %s' % (old['module'].ljust(12), old['model'].ljust(24), fieldrepr.ljust(30))
+ repr = '%s / %s / %s' % (
+ old['module'].ljust(12), old['model'].ljust(24), fieldrepr.ljust(30))
if text:
- print "%s: %s" % (repr, text)
+ reprs.setdefault(module_map(old['module']), []).append(
+ "%s: %s" % (repr, text))
else:
- print "%s: %s is now \'%s\' ('%s')" % (repr, field, new[field], old[field])
+ reprs.setdefault(module_map(old['module']), []).append(
+ "%s: %s is now \'%s\' ('%s')" % (
+ repr, field, new[field], old[field]))
-def report_generic(new, old, attrs):
+def report_generic(new, old, attrs, reprs):
for attr in attrs:
if attr == 'required':
if old[attr] != new['required'] and new['required']:
text = "now required"
- if column['req_default']:
- text += ', default = %s' % column['req_default']
- fieldprint(old, new, text=text)
+ if new['req_default']:
+ text += ', default = %s' % new['req_default']
+ fieldprint(old, new, None, text, reprs)
elif attr == 'isfunction':
if old['isfunction'] != new['isfunction']:
if new['isfunction']:
text = "now a function"
else:
text = "not a function anymore"
- fieldprint(old, new, text=text)
+ fieldprint(old, new, None, text, reprs)
else:
if old[attr] != new[attr]:
- fieldprint(old, new, attr)
-
-if len(sys.argv) != 3:
- print USAGE % {'name': sys.argv[0]}
- exit(1)
-
-k5 = readfile(sys.argv[1])
-k6 = readfile(sys.argv[2])
-
-origlen = len(k5)
-
-models6 = set([ column['model'] for column in k6 ])
-models5 = set([ column['model'] for column in k5 ])
-
-matched_direct = 0
-matched_other_module = 0
-matched_other_type = 0
-matched_other_name = 0
-in_obsolete_models = 0
-
-obsolete_models = []
-for model in models5:
- if model not in models6:
- obsolete_models.append(model)
- print '# obsolete model %s' % model
-
-for column in copy.copy(k5):
- if column['model'] in obsolete_models:
- k5.remove(column)
- in_obsolete_models += 1
-
-for model in models6:
- if model not in models5:
- print '# new model %s' % model
-
-def match(match_fields, report_fields, warn=False):
- count = 0
- for column in copy.copy(k5):
- found = search(column, k6, match_fields)
+ fieldprint(old, new, attr, None, reprs)
+
+def compare_sets(old_records, new_records):
+ """
+ Compare a set of OpenUpgrade field representations.
+ Try to match the equivalent fields in both sets.
+ Return a textual representation of changes in a dictionary with
+ module names as keys. Special case is the 'general' key
+ which contains overall remarks and matching statistics.
+ """
+ reprs = {'general': []}
+
+ for record in old_records + new_records:
+ record['matched'] = False
+ origlen = len(old_records)
+ new_models = set([ column['model'] for column in new_records ])
+ old_models = set([ column['model'] for column in old_records ])
+
+ matched_direct = 0
+ matched_other_module = 0
+ matched_other_type = 0
+ matched_other_name = 0
+ in_obsolete_models = 0
+
+ obsolete_models = []
+ for model in old_models:
+ if model not in new_models:
+ obsolete_models.append(model)
+ reprs['general'].append('obsolete model %s' % model)
+
+ for column in copy.copy(old_records):
+ if column['model'] in obsolete_models:
+ old_records.remove(column)
+ in_obsolete_models += 1
+
+ for model in new_models:
+ if model not in old_models:
+ reprs['general'].append('new model %s' % model)
+
+ def match(match_fields, report_fields, warn=False):
+ count = 0
+ for column in copy.copy(old_records):
+ found = search(column, new_records, match_fields)
+ if found:
+ if warn:
+ pass
+ #print "Tentatively"
+ report_generic(found, column, report_fields, reprs)
+ old_records.remove(column)
+ new_records.remove(found)
+ count += 1
+ return count
+
+ matched_direct = match(
+ ['module', 'mode', 'model', 'field'],
+ ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
+
+ # other module, same type and operation
+ matched_other_module = match(
+ ['mode', 'model', 'field', 'type'],
+ ['module', 'relation', 'selection_keys', 'inherits', 'isfunction', 'required'])
+
+ # other module, same operation, other type
+ matched_other_type = match(
+ ['mode', 'model', 'field'],
+ ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
+
+ # fields with other names
+ #matched_other_name = match(
+ # ['module', 'type', 'relation'],
+ # ['field', 'relation', 'type', 'selection_keys',
+ # 'inherits', 'isfunction', 'required'], warn=True)
+
+ printkeys = [
+ 'relation', 'required', 'selection_keys',
+ 'req_default', 'inherits', 'mode'
+ ]
+ for column in old_records:
+ # we do not care about removed function fields
+ if not column['isfunction']:
+ if column['mode'] == 'create':
+ column['mode'] = ''
+ fieldprint(
+ column, None, None, "DEL " + ", ".join(
+ [k + ': ' + str(column[k]) for k in printkeys if column[k]]
+ ), reprs)
+
+ for column in new_records:
+ # we do not care about newly added function fields
+ if not column['isfunction']:
+ if column['mode'] == 'create':
+ column['mode'] = ''
+ fieldprint(
+ column, None, None, "NEW " + ", ".join(
+ [k + ': ' + str(column[k]) for k in printkeys if column[k]]
+ ), reprs)
+
+ for line in [
+ "# %d fields matched," % (origlen - len(old_records)),
+ "# Direct match: %d" % matched_direct,
+ "# Found in other module: %d" % matched_other_module,
+ "# Found with different type: %d" % matched_other_type,
+ "# Found with different name: %d" % matched_other_name,
+ "# In obsolete models: %d" % in_obsolete_models,
+ "# Not matched: %d" % len(old_records),
+ "# New columns: %d" % len(new_records),
+ ]:
+ reprs['general'].append(line)
+ return reprs
+
+def compare_xml_sets(old_records, new_records):
+ reprs = {}
+ match_fields = ['module', 'model', 'name']
+ for column in copy.copy(old_records):
+ found = search(column, new_records, match_fields)
if found:
- if warn:
- print "Tentatively"
- report_generic(found, column, report_fields)
- k5.remove(column)
- k6.remove(found)
- count += 1
- return count
-
-matched_direct = match(['module', 'operation', 'model', 'field'],
- ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
-
-# other module, same type and operation
-matched_other_module = match(['operation', 'model', 'field', 'type'],
- ['module', 'relation', 'selection_keys', 'inherits', 'isfunction', 'required'])
-
-# other module, same operation, other type
-matched_other_type = match(['operation', 'model', 'field'],
- ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
-
-# fields with other names
-#matched_other_name = match(['module', 'type', 'relation'],
-# ['field', 'relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'], warn=True)
-
-printkeys = ['relation', 'required', 'selection_keys', 'req_default', 'inherits', 'operation']
-for column in k5:
- # we do not care about removed function fields
- if not column['isfunction']:
- if column['operation'] == 'create':
- column['operation'] = ''
- fieldprint(column, None, text="DEL " + ", ".join([k + ': ' + str(column[k]) for k in printkeys if column[k]]))
-
-for column in k6:
- # we do not care about newly added function fields
- if not column['isfunction']:
- if column['operation'] == 'create':
- column['operation'] = ''
- fieldprint(column, None, text="NEW " + ", ".join([k + ': ' + str(column[k]) for k in printkeys if column[k]]))
-
-print "# %d fields matched," % (origlen - len(k5))
-print "# Direct match: %d" % matched_direct
-print "# Found in other module: %d" % matched_other_module
-print "# Found with different type: %d" % matched_other_type
-print "# Found with different name: %d" % matched_other_name
-print "# In obsolete models: %d" % in_obsolete_models
-print "# Not matched: %d" % len(k5)
-print "# New columns: %d" % len(k6)
+ old_records.remove(column)
+ new_records.remove(found)
+ for entry in sorted(
+ old_records, key=lambda k: '%s%s' % (k['model'].ljust(128), k['name'])):
+ reprs.setdefault(module_map(entry['module']), []).append(
+ 'deleted xml-id of model %s: %s' % (entry['model'], entry['name']))
+ for entry in sorted(
+ new_records, key=lambda k: '%s%s' % (k['model'].ljust(128), k['name'])):
+ reprs.setdefault(module_map(entry['module']), []).append(
+ 'new xml-id of model %s: %s' % (entry['model'], entry['name']))
+ return reprs
=== added directory 'openerp/addons/openupgrade_records/model'
=== added file 'openerp/addons/openupgrade_records/model/__init__.py'
--- openerp/addons/openupgrade_records/model/__init__.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/model/__init__.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,6 @@
+import openupgrade_record
+import comparison_config
+import analysis_wizard
+import generate_records_wizard
+import install_all_wizard
+
=== added file 'openerp/addons/openupgrade_records/model/analysis_wizard.py'
--- openerp/addons/openupgrade_records/model/analysis_wizard.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/model/analysis_wizard.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import os
+from osv import osv, fields
+
+try:
+ from openerp.addons.openupgrade_records.lib import compare
+ from openerp.openupgrade_records.lib import apriori
+ from openerp.addons import get_module_path
+except ImportError:
+ from openupgrade_records.lib import compare
+ from openupgrade_records.lib import apriori
+ from addons import get_module_path
+
+class openupgrade_analysis_wizard(osv.osv_memory):
+ _name = 'openupgrade.analysis.wizard'
+ _description = 'OpenUpgrade Analysis Wizard'
+ _columns = {
+ 'server_config': fields.many2one(
+ 'openupgrade.comparison.config',
+ 'Configuration', required=True),
+ 'state': fields.selection(
+ [('init', 'Init'), ('ready', 'Ready')], 'State',
+ readonly=True),
+ 'log': fields.text('Log'),
+ 'write': fields.boolean(
+ 'Write files',
+ help='Write analysis files to the module directories'
+ ),
+ }
+ _defaults = {
+ 'state': lambda *a: 'init',
+ 'write': lambda *a: True,
+ }
+
+ def get_communication(self, cr, uid, ids, context=None):
+ """
+ Retrieve both sets of database representations,
+ perform the comparison and register the resulting
+ change set
+ """
+ def write_file(
+ module, version, contents, filename='openupgrade_analysis.txt'):
+ module_path = get_module_path(module)
+ if not module_path:
+ return "ERROR: could not find module path:\n"
+ full_path = os.path.join(
+ module_path, 'migrations', version)
+ if not os.path.exists(full_path):
+ try:
+ os.makedirs(full_path)
+ except os.error:
+ return "ERROR: could not create migrations directory:\n"
+ logfile = os.path.join(full_path, filename)
+ try:
+ f = open(logfile, 'w')
+ except Exception:
+ return "ERROR: could not open file %s for writing:\n" % logfile
+ f.write(contents)
+ f.close()
+ return None
+
+ wizard = self.browse(cr, uid, ids[0], context=context)
+ # Retrieve connection and access methods
+ conf_obj = self.pool.get('openupgrade.comparison.config')
+ connection = conf_obj.get_connection(
+ cr, uid, [wizard.server_config.id], context=context)
+ remote_record_obj = connection.get_model('openupgrade.record')
+ local_record_obj = self.pool.get('openupgrade.record')
+
+ # Retrieve field representations and compare
+ remote_records = remote_record_obj.field_dump(context)
+ local_records = local_record_obj.field_dump(cr, uid, context)
+ res = compare.compare_sets(remote_records, local_records)
+
+ # Retrieve xml id representations and compare
+ fields = ['module', 'model', 'name']
+ local_xml_record_ids = local_record_obj.search(
+ cr, uid, [('type', '=', 'xmlid')])
+ remote_xml_record_ids = remote_record_obj.search(
+ [('type', '=', 'xmlid')])
+ local_xml_records = [
+ dict([(field, x[field]) for field in fields])
+ for x in local_record_obj.read(
+ cr, uid, local_xml_record_ids, fields)
+ ]
+ remote_xml_records = [
+ dict([(field, x[field]) for field in fields])
+ for x in remote_record_obj.read(
+ remote_xml_record_ids, fields)
+ ]
+ res_xml = compare.compare_xml_sets(
+ remote_xml_records, local_xml_records)
+
+ # reorder and output the result
+ keys = list(set(res.keys() + res_xml.keys()))
+ keys.remove('general')
+ keys = ['general'] + keys
+ module_obj = self.pool.get('ir.module.module')
+ module_ids = module_obj.search(
+ cr, uid, [('state', '=', 'installed')])
+ modules = dict([(x['name'], x) for x in module_obj.read(cr, uid, module_ids)])
+ general = ''
+ for key in keys:
+ contents = "---%s---\n" % key
+ if key in res:
+ contents += '\n'.join([unicode(line) for line in sorted(res[key])])
+ if res[key]:
+ contents += '\n'
+ if key in res_xml:
+ contents += '\n'.join([unicode(line) for line in sorted(res_xml[key])])
+ if res_xml[key]:
+ contents += '\n'
+ if key == 'general':
+ general += contents
+ continue
+ if key not in modules:
+ general += (
+ "ERROR: module not in list of installed modules:\n"
+ + contents)
+ continue
+ if wizard.write:
+ error = write_file(
+ key, modules[key]['installed_version'], contents)
+ if error:
+ general += error
+ general += contents
+ else:
+ general += contents
+
+ # Store the general log in as many places as possible ;-)
+ if wizard.write and 'base' in modules:
+ write_file(
+ 'base', modules['base']['installed_version'], general,
+ 'openupgrade_general_log.txt')
+ self.pool.get('openupgrade.comparison.config').write(
+ cr, uid, wizard.server_config.id,
+ {'last_log': general})
+ self.write(cr, uid, ids, {'state': 'ready', 'log': general})
+
+ result = {
+ 'name': self._description,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'openupgrade.analysis.wizard',
+ 'domain': [],
+ 'context': context,
+ 'type': 'ir.actions.act_window',
+ #'target': 'new',
+ 'res_id': ids[0],
+ }
+ return result
+
+openupgrade_analysis_wizard()
+
=== added file 'openerp/addons/openupgrade_records/model/comparison_config.py'
--- openerp/addons/openupgrade_records/model/comparison_config.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/model/comparison_config.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import osv, fields
+import openerplib
+from tools.translate import _
+
+class openupgrade_comparison_config(osv.osv):
+ _name = 'openupgrade.comparison.config'
+ _columns = {
+ 'name': fields.char('Name', size=64),
+ 'server': fields.char('Server', size=64, required=True),
+ 'port': fields.integer('Port', required=True),
+ 'protocol': fields.selection(
+ [('http://', 'XML-RPC')],
+ # ('https://', 'XML-RPC Secure')], not supported by libopenerp
+ 'Protocol', required=True),
+ 'database': fields.char('Database', size=64, required=True),
+ 'username': fields.char('Username', size=24, required=True),
+ 'password': fields.char('Password', size=24, required=True, password=True),
+ 'last_log': fields.text('Last log'),
+ }
+ _defaults = {
+ 'port': lambda *a: 8069,
+ 'protocol': lambda *a: 'http://',
+ }
+
+ def get_connection(self, cr, uid, ids, context=None):
+ if not ids:
+ raise osv.except_osv(
+ _("Cannot connect"), _("Invalid id passed."))
+ conf = self.read(cr, uid, ids[0], context=None)
+ return openerplib.get_connection(
+ hostname=conf['server'],
+ database=conf['database'],
+ login=conf['username'],
+ password=conf['password'],
+ port=conf['port'],
+ )
+
+ def test_connection(self, cr, uid, ids, context=None):
+ try:
+ connection = self.get_connection(cr, uid, [ids[0]], context)
+ user_model = connection.get_model("res.users")
+ ids = user_model.search([("login", "=", "admin")])
+ user_info = user_model.read(ids[0], ["name"])
+ except Exception, e:
+ raise osv.except_osv(
+ _("Connection failed."), unicode(e))
+ raise osv.except_osv(
+ _("Connection succesful."),
+ _("%s is connected.") % user_info["name"]
+ )
+
+ def analyze(self, cr, uid, ids, context=None):
+ """
+ Run the analysis wizard
+ """
+ wizard_obj = self.pool.get('openupgrade.analysis.wizard')
+ wizard_id = wizard_obj.create(
+ cr, uid, {'server_config': ids[0]}, context)
+ result = {
+ 'name': wizard_obj._description,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'openupgrade.analysis.wizard',
+ 'domain': [],
+ 'context': context,
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'res_id': wizard_id,
+ 'nodestroy': True,
+ }
+ return result
+
+openupgrade_comparison_config()
=== added file 'openerp/addons/openupgrade_records/model/generate_records_wizard.py'
--- openerp/addons/openupgrade_records/model/generate_records_wizard.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/model/generate_records_wizard.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import os
+from osv import osv, fields
+import pooler
+try:
+ from openerp.openupgrade import openupgrade_tools
+except ImportError:
+ from openupgrade import openupgrade_tools
+
+class generate_records_wizard(osv.osv_memory):
+ _name = 'openupgrade.generate.records.wizard'
+ _description = 'OpenUpgrade Generate Records Wizard'
+ _columns = {
+ 'state': fields.selection([('init', 'init'), ('ready', 'ready')], 'State'),
+ }
+ _defaults = {
+ 'state': lambda *a: 'init',
+ }
+
+ def generate(self, cr, uid, ids, context=None):
+ """
+ Main wizard step. Make sure that all modules are up-to-date,
+ then reinitialize all installed modules.
+ Equivalent of running the server with '-d <database> --init all'
+
+ The goal of this is to fill the records table.
+
+ TODO: update module list and versions, then update all modules?
+ """
+ # Truncate the records table
+ if (openupgrade_tools.table_exists(cr, 'openupgrade_attribute') and
+ openupgrade_tools.table_exists(cr, 'openupgrade_record')):
+ cr.execute(
+ 'TRUNCATE openupgrade_attribute, openupgrade_record;'
+ )
+
+ # Need to get all modules in state 'installed'
+ module_obj = self.pool.get('ir.module.module')
+ module_ids = module_obj.search(
+ cr, uid, [('state', 'in', ['to install', 'to upgrade'])])
+ if module_ids:
+ cr.commit()
+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ # Did we succeed above?
+ module_ids = module_obj.search(
+ cr, uid, [('state', 'in', ['to install', 'to upgrade'])])
+ if module_ids:
+ modules = module_obj.read(
+ cr, uid, module_ids, ['name'], context=context)
+ raise except_osv(
+ "Cannot reliably generate records",
+ ("Cannot seem to install or upgrade modules " +
+ ', '.join([x['name'] for x in modules])))
+ # Now reinitialize all installed modules
+ module_ids = module_obj.search(
+ cr, uid, [('state', '=', 'installed')])
+ module_obj.write(
+ cr, uid, module_ids, {'state': 'to install'})
+ cr.commit()
+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ self.write(cr, uid, ids, {'state': 'ready'})
+ # and we are done
+ return True
+
+generate_records_wizard()
+
=== added file 'openerp/addons/openupgrade_records/model/install_all_wizard.py'
--- openerp/addons/openupgrade_records/model/install_all_wizard.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/model/install_all_wizard.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import time
+import os
+from osv import osv, fields
+import pooler
+
+class install_all_wizard(osv.osv_memory):
+ _name = 'openupgrade.install.all.wizard'
+ _description = 'OpenUpgrade Install All Wizard'
+ _columns = {
+ 'state': fields.selection([('init', 'init'), ('ready', 'ready')], 'State', readonly=True),
+ 'to_install': fields.integer('Number of modules to install', readonly=True),
+ }
+ _defaults = {
+ 'state': lambda *a: 'init',
+ }
+
+
+ def default_get(self, cr, uid, fields, context=None):
+ """
+ Update module list and retrieve the number
+ of installable modules
+ """
+ res = super(install_all_wizard, self).default_get(
+ cr, uid, fields, context=None)
+ module_obj = self.pool.get('ir.module.module')
+ update, add = module_obj.update_list(cr, uid,)
+ print "%s modules added" % add
+ module_ids = module_obj.search(
+ cr, uid, [('state', 'not in', ['installed', 'uninstallable', 'unknown'])])
+ res.update(
+ {'to_install': module_ids and len(module_ids) or False}
+ )
+ return res
+
+ def quirk_fiscalyear(self, cr, uid, ids, context=None):
+ """
+ Install account module first and create a fiscal year,
+ in order to prevent "No fiscal year defined" exception
+ during an upgrade or reinstallation of the account module.
+
+ Refer to account_fiscalyear.find(), which is called as
+ a default function by the orm upon module upgrade.
+ """
+ module_obj = self.pool.get('ir.module.module')
+ pool = self.pool
+ # Retrieve status of the account module
+ account_module_id = module_obj.search(
+ cr, uid, [('name', '=', 'account')], context=context)[0]
+ state = module_obj.read(
+ cr, uid, account_module_id, ['state'], context=context)['state']
+ if state != 'installed':
+ # Cancel installation of other modules
+ module_ids = module_obj.search(
+ cr, uid, [('state', '=', 'to install')])
+ module_obj.write(cr, uid, module_ids, {'state': 'uninstalled'})
+ # Mark the module and its dependencies
+ module_obj.button_install(cr, uid, [account_module_id])
+ # Install account module
+ cr.commit()
+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ # get or create today's fiscal year
+ fy_obj = pool.get('account.fiscalyear')
+ if not fy_obj.find(cr, uid, False, exception=False, context=context):
+ fy_obj.create(cr, uid, {
+ 'name': time.strftime('%Y'),
+ 'code': time.strftime('%Y'),
+ 'date_start': "%s-01-01" % time.strftime('%Y'),
+ 'date_stop': "%s-12-31" % time.strftime('%Y'),
+ })
+
+ def install_all(self, cr, uid, ids, context=None):
+ """
+ Main wizard step. Set all installable modules to install
+ and actually install them.
+ """
+ module_obj = self.pool.get('ir.module.module')
+ module_ids = module_obj.search(
+ cr, uid, [('state', 'not in', ['installed', 'uninstallable', 'unknown'])])
+ if module_ids:
+ module_obj.write(
+ cr, uid, module_ids, {'state': 'to install'})
+ cr.commit()
+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ self.write(cr, uid, ids, {'state': 'ready'})
+ return True
+
+install_all_wizard()
+
=== added file 'openerp/addons/openupgrade_records/model/openupgrade_record.py'
--- openerp/addons/openupgrade_records/model/openupgrade_record.py 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/model/openupgrade_record.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module Copyright (C) 2012 OpenUpgrade community
+# https://launchpad.net/~openupgrade-committers
+#
+# Contributors:
+# Therp BV <http://therp.nl>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import osv, fields
+
+# Cannot use forward references in 6.0
+class openupgrade_record(osv.osv):
+ _name = 'openupgrade.record'
+openupgrade_record()
+
+class openupgrade_attribute(osv.osv):
+ _name = 'openupgrade.attribute'
+ _rec_name = 'attribute_id'
+ _columns = {
+ 'name': fields.char(
+ 'Name', size=24,
+ readonly=True,
+ ),
+ 'value': fields.char(
+ 'Value',
+ size=4096,
+ readonly=True,
+ ),
+ 'record_id': fields.many2one(
+ 'openupgrade.record', ondelete='CASCADE',
+ readonly=True,
+ ),
+ }
+openupgrade_attribute()
+
+class openupgrade_record(osv.osv):
+ _inherit = 'openupgrade.record'
+
+ _columns = {
+ 'name': fields.char('Name', size=256, readonly=True),
+ 'module': fields.char('Module', size=128, readonly=True),
+ 'model': fields.char('Model', size=128, readonly=True),
+ 'field': fields.char('Field', size=128, readonly=True),
+ 'mode': fields.selection(
+ [('create', 'Create'), ('modify', 'Modify')],
+ 'Mode',
+ help='Set to Create if a field is newly created '
+ 'in this module. If this module modifies an attribute of an '
+ 'exting field, set to Modify.',
+ readonly=True,
+ ),
+ 'type': fields.selection(
+ [('field', 'Field'), ('xmlid', 'XML ID')],
+ 'Type',
+ readonly=True,
+ ),
+ 'attribute_ids': fields.one2many(
+ 'openupgrade.attribute', 'record_id', 'Attributes',
+ readonly=True,
+ ),
+ }
+ def field_dump(self, cr, uid, context=None):
+ keys = [
+ 'module',
+ 'mode',
+ 'model',
+ 'field',
+ 'type',
+ 'isfunction',
+ 'relation',
+ 'required',
+ 'selection_keys',
+ 'req_default',
+ 'inherits',
+ ]
+
+ template = dict([(x, False) for x in keys])
+ ids = self.search(cr, uid, [('type', '=', 'field')], context=context)
+ records = self.browse(cr, uid, ids, context=context)
+ data = []
+ for record in records:
+ repr = template.copy()
+ repr.update({
+ 'module': record.module,
+ 'model': record.model,
+ 'field': record.field,
+ 'mode': record.mode,
+ })
+ repr.update(
+ dict([(x.name, x.value) for x in record.attribute_ids]))
+ data.append(repr)
+ return data
+
+openupgrade_record()
=== added directory 'openerp/addons/openupgrade_records/security'
=== added file 'openerp/addons/openupgrade_records/security/ir.model.access.csv'
--- openerp/addons/openupgrade_records/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/security/ir.model.access.csv 2012-05-09 12:37:19 +0000
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_openupgrade_record","openupgrade.record all","model_openupgrade_record",,1,0,0,0
+"access_openupgrade_attribute","openupgrade.attribute all","model_openupgrade_attribute",,1,0,0,0
=== added directory 'openerp/addons/openupgrade_records/view'
=== added file 'openerp/addons/openupgrade_records/view/analysis_wizard.xml'
--- openerp/addons/openupgrade_records/view/analysis_wizard.xml 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/view/analysis_wizard.xml 2012-05-09 12:37:19 +0000
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record id="view_openupgrade_analysis_wizard_form" model="ir.ui.view">
+ <field name="name">view.openupgrade.analysis_wizard.form</field>
+ <field name="model">openupgrade.analysis.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="OpenUpgrade Analysis Wizard">
+ <field name="server_config" readonly="1"/>
+ <field name="state"/>
+ <field name="log" colspan="4"
+ attrs="{'invisible': [('state', '!=', 'ready')]}"/>
+ <field name="write"
+ attrs="{'readonly': [('state', '!=', 'init')]}"/>
+ <button icon="gtk-close"
+ special="cancel"
+ string="Close"
+ />
+ <button icon="gtk-ok"
+ string="Create"
+ name="get_communication"
+ type="object"
+ states="init"
+ />
+ </form>
+ </field>
+ </record>
+ </data>
+</openerp>
=== added file 'openerp/addons/openupgrade_records/view/comparison_config.xml'
--- openerp/addons/openupgrade_records/view/comparison_config.xml 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/view/comparison_config.xml 2012-05-09 12:37:19 +0000
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record id="view_openupgrade_comparison_config_tree" model="ir.ui.view">
+ <field name="name">view.openupgrade.comparison_config.tree</field>
+ <field name="model">openupgrade.comparison.config</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="OpenUpgrade Comparison Config">
+ <field name="name" select="1"/>
+ <field name="protocol"/>
+ <field name="server" select="1"/>
+ <field name="port" select="1"/>
+ <field name="database" select="1"/>
+ </tree>
+ </field>
+ </record>
+ <record id="view_openupgrade_comparison_config_form" model="ir.ui.view">
+ <field name="name">view.openupgrade.comparison_config.form</field>
+ <field name="model">openupgrade.comparison.config</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="OpenUpgrade Comparison Config">
+ <field name="name"/>
+ <field name="protocol"/>
+ <field name="server"/>
+ <field name="port"/>
+ <field name="database"/>
+ <field name="username"/>
+ <field name="password" password="1"/>
+ <button
+ name="test_connection"
+ string="Test Connection"
+ type="object" icon="gtk-network"
+ colspan="2"
+ />
+ <newline/>
+ <button
+ name="analyze"
+ string="Perform Analysis"
+ type="object" icon="gtk-execute"
+ colspan="2"
+ />
+ <separator string="Last log" colspan="4"/>
+ <field name="last_log" nolabel="1" colspan="4"/>
+ </form>
+ </field>
+ </record>
+ <record id="action_openupgrade_comparison_config_tree" model="ir.actions.act_window">
+ <field name="name">OpenUpgrade Comparison Configs</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">openupgrade.comparison.config</field>
+ <field name="view_type">form</field>
+ </record>
+ <menuitem
+ action="action_openupgrade_comparison_config_tree"
+ id="menu_openupgrade_comparison_config"
+ name="Comparison Configurations"
+ parent="menu_openupgrade"
+ />
+ </data>
+</openerp>
=== added file 'openerp/addons/openupgrade_records/view/generate_records_wizard.xml'
--- openerp/addons/openupgrade_records/view/generate_records_wizard.xml 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/view/generate_records_wizard.xml 2012-05-09 12:37:19 +0000
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record id="view_openupgrade_generate_records_wizard_form" model="ir.ui.view">
+ <field name="name">view.openupgrade.generate_records_wizard.form</field>
+ <field name="model">openupgrade.generate.records.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="OpenUpgrade Generate Records Wizard">
+ <group states="init" colspan="4">
+ <label string="This will reinitialize all the modules installed on this database. Do not continue if you use this database in production."
+ />
+ <button icon="gtk-close"
+ special="cancel"
+ string="Cancel"
+ />
+ <button icon="gtk-ok"
+ string="Continue"
+ name="generate"
+ type="object"
+ />
+ </group>
+ <group states="ready" colspan="4">
+ <label string="Modules initialized and records created"
+ />
+ <field name="state" invisible="1"/>
+ <button icon="gtk-close"
+ special="cancel"
+ string="Close"
+ />
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record id="action_generate_records" model="ir.actions.act_window">
+ <field name="name">Generate Records</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">openupgrade.generate.records.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form,tree</field>
+ <field name="target">new</field>
+ </record>
+
+ <menuitem name="Generate Records"
+ id="menu_openupgrade_generate_records"
+ parent="menu_openupgrade"
+ action="action_generate_records"
+ sequence="15"/>
+
+ </data>
+</openerp>
=== added file 'openerp/addons/openupgrade_records/view/install_all_wizard.xml'
--- openerp/addons/openupgrade_records/view/install_all_wizard.xml 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/view/install_all_wizard.xml 2012-05-09 12:37:19 +0000
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <record id="view_openupgrade_install_all_wizard_form" model="ir.ui.view">
+ <field name="name">view.openupgrade.install_all_wizard.form</field>
+ <field name="model">openupgrade.install.all.wizard</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="OpenUpgrade Install All Modules Wizard">
+ <group states="init" colspan="4">
+ <label string="This will install all modules on the database. Do not continue if you use this database in production." colspan="4"
+ />
+ <field name="to_install"/>
+ <newline/>
+ <button icon="gtk-close"
+ special="cancel"
+ string="Cancel"
+ />
+ <button icon="gtk-ok"
+ string="Continue"
+ name="install_all"
+ type="object"
+ />
+ </group>
+ <group states="ready" colspan="4">
+ <label string="Modules installed"
+ />
+ <field name="state" invisible="1"/>
+ <button icon="gtk-close"
+ special="cancel"
+ string="Close"
+ />
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record id="action_install_all" model="ir.actions.act_window">
+ <field name="name">Install All Modules</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">openupgrade.install.all.wizard</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form,tree</field>
+ <field name="target">new</field>
+ </record>
+
+ <menuitem name="Install All Modules"
+ id="menu_openupgrade_install_all"
+ parent="menu_openupgrade"
+ action="action_install_all"
+ sequence="14"/>
+
+ </data>
+</openerp>
=== added file 'openerp/addons/openupgrade_records/view/openupgrade_record.xml'
--- openerp/addons/openupgrade_records/view/openupgrade_record.xml 1970-01-01 00:00:00 +0000
+++ openerp/addons/openupgrade_records/view/openupgrade_record.xml 2012-05-09 12:37:19 +0000
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+ <!-- Top level menu under 'Database structure' -->
+ <menuitem
+ id="menu_openupgrade"
+ name="OpenUpgrade Development"
+ parent="base.menu_administration"
+ sequence="99"
+ />
+ <record id="view_openupgrade_record_tree" model="ir.ui.view">
+ <field name="name">view.openupgrade.record.tree</field>
+ <field name="model">openupgrade.record</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="OpenUpgrade Records">
+ <field name="module" select="1"/>
+ <field name="model" select="1"/>
+ <field name="field" select="1"/>
+ <field name="name" select="1"/>
+ <field name="type" select="1"/>
+ <field name="mode" select="1"/>
+ </tree>
+ </field>
+ </record>
+ <record id="view_openupgrade_record_form" model="ir.ui.view">
+ <field name="name">view.openupgrade.record.form</field>
+ <field name="model">openupgrade.record</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="OpenUpgrade Record">
+ <field name="module" select="1"/>
+ <field name="model" select="1"/>
+ <field name="field" select="1"/>
+ <field name="name" select="1"/>
+ <field name="type" select="1"/>
+ <field name="mode" select="1"/>
+ <separator string="Attributes" colspan="4"/>
+ <field name="attribute_ids" mode="tree,form" nolabel="1" colspan="4">
+ <tree string="Attributes">
+ <field name="name"/>
+ <field name="value"/>
+ </tree>
+ <form string="Attribute">
+ <field name="name"/>
+ <field name="value"/>
+ </form>
+ </field>
+ </form>
+ </field>
+ </record>
+ <record id="action_openupgrade_record_tree" model="ir.actions.act_window">
+ <field name="name">OpenUpgrade Records</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">openupgrade.record</field>
+ <field name="view_type">form</field>
+ </record>
+ <menuitem
+ action="action_openupgrade_record_tree"
+ id="menu_openupgrade_records"
+ name="Records"
+ parent="menu_openupgrade"
+ />
+ </data>
+</openerp>
=== modified file 'openerp/modules/loading.py'
--- openerp/modules/loading.py 2012-03-09 14:44:43 +0000
+++ openerp/modules/loading.py 2012-05-09 12:37:19 +0000
@@ -66,6 +66,15 @@
_logger = logging.getLogger(__name__)
+### OpenUpgrade
+def table_exists(cr, table):
+ """ Check whether a certain table or view exists """
+ cr.execute(
+ 'SELECT count(relname) FROM pg_class WHERE relname = %s',
+ (table,))
+ return cr.fetchone()[0] == 1
+### End of OpenUpgrade
+
def open_openerp_namespace():
# See comment for open_openerp_namespace.
if openerp.conf.deprecation.open_openerp_namespace:
@@ -144,8 +153,6 @@
finally:
fp.close()
- fields_logger = logging.getLogger('OpenUpgrade_FIELD')
- xmlid_logger = logging.getLogger('OpenUpgrade_XMLID')
local_registry = {}
def get_repr(properties, type='val'):
"""
@@ -180,24 +187,12 @@
if isinstance(model, osv.orm.TransientModel):
return
+ model_registry = local_registry.setdefault(
+ model._name, {})
if model._inherits:
- properties = {
- 'model': model._name,
- 'field': '_inherits',
- 'type': '',
- 'isfunction': '',
- 'relation': '',
- 'required': '',
- 'selection_keys': '',
- 'req_default': '',
- 'inherits': unicode(model._inherits),
- }
- local_registry[get_repr(properties, 'key')] = get_repr(
- properties)
- for k,v in model._columns.items():
- properties = {
- 'model': model._name,
- 'field': k,
+ model_registry['_inherits'] = {'_inherits': unicode(model._inherits)}
+ for k, v in model._columns.items():
+ properties = {
'type': v._type,
'isfunction': (
isinstance(v, osv.fields.function) and 'function' or ''),
@@ -224,45 +219,70 @@
else:
properties['req_default'] = unicode(
model._defaults[k])
- local_registry[get_repr(properties, 'key')] = get_repr(
- properties)
+ for key, value in properties.items():
+ if value:
+ model_registry.setdefault(k, {})[key] = value
- def compare_registries():
+ def get_record_id(cr, module, model, field, mode):
+ """
+ OpenUpgrade: get or create the id from the record table matching
+ the key parameter values
+ """
+ cr.execute(
+ "SELECT id FROM openupgrade_record "
+ "WHERE module = %s AND model = %s AND "
+ "field = %s AND mode = %s AND type = %s",
+ (module, model, field, mode, 'field')
+ )
+ record = cr.fetchone()
+ if record:
+ return record[0]
+ cr.execute(
+ "INSERT INTO openupgrade_record "
+ "(module, model, field, mode, type) "
+ "VALUES (%s, %s, %s, %s, %s)",
+ (module, model, field, mode, 'field')
+ )
+ cr.execute(
+ "SELECT id FROM openupgrade_record "
+ "WHERE module = %s AND model = %s AND "
+ "field = %s AND mode = %s AND type = %s",
+ (module, model, field, mode, 'field')
+ )
+ return cr.fetchone()[0]
+
+ def compare_registries(cr, module):
"""
OpenUpgrade: Compare the local registry with the global registry,
log any differences and merge the local registry with
the global one.
"""
- for key in sorted(local_registry.keys()):
- if key in registry:
- if registry[key] != local_registry[key]:
- fields_logger.info(
- '"%s","modify",%s,%s',
- package.name, key, local_registry[key])
- else:
- fields_logger.info(
- '"%s","create",%s,%s',
- package.name, key, local_registry[key])
- registry[key] = local_registry[key]
-
- def log_xmlids(cr, package_name):
- """
- OpenUpgrade: Log all XMLID's owned by this package.
- TODO: other modules can really easily add items that 'belong' to
- another module. Needs deeper digging in the load_data methods.
-
- Need to pass the cursor, as the one passed to the upper method is
- closed by now.
- """
- cr.execute(
- 'select model, name from ir_model_data where module=%s '
- 'order by model, name', (package_name,))
- for res in cr.fetchall():
- xmlid_logger.info(
- ','.join([
- "\"" + string.replace(property, '\"', '\'') + "\""
- for property in (res[0], res[1], package_name)
- ]))
+ if not table_exists(cr, 'openupgrade_record'):
+ return
+ for model, fields in local_registry.items():
+ registry.setdefault(model, {})
+ for field, attributes in fields.items():
+ old_field = registry[model].setdefault(field, {})
+ mode = old_field and 'modify' or 'create'
+ record_id = False
+ for key, value in attributes.items():
+ if key not in old_field or old_field[key] != value:
+ if not record_id:
+ record_id = get_record_id(
+ cr, module, model, field, mode)
+ cr.execute(
+ "SELECT id FROM openupgrade_attribute "
+ "WHERE name = %s AND value = %s AND "
+ "record_id = %s",
+ (key, value, record_id)
+ )
+ if not cr.fetchone():
+ cr.execute(
+ "INSERT INTO openupgrade_attribute "
+ "(name, value, record_id) VALUES (%s, %s, %s)",
+ (key, value, record_id)
+ )
+ old_field[key] = value
if status is None:
status = {}
@@ -294,11 +314,10 @@
loaded_modules.append(package.name)
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
# OpenUpgrade: add this module's models to the registry
- fields_logger.info('module %s', package.name)
local_registry = {}
for model in models:
log_model(model)
- compare_registries()
+ compare_registries(cr, package.name)
init_module_models(cr, package.name, models)
@@ -364,7 +383,6 @@
if hasattr(package, kind):
delattr(package, kind)
- log_xmlids(cr, package.name) # OpenUpgrade
cr.commit()
# mark new res_log records as read
=== modified file 'openerp/openupgrade/__init__.py'
--- openerp/openupgrade/__init__.py 2012-01-15 11:39:02 +0000
+++ openerp/openupgrade/__init__.py 2012-05-09 12:37:19 +0000
@@ -1,1 +0,0 @@
-import openupgrade
=== added file 'openerp/openupgrade/doc/source/analyse.rst'
--- openerp/openupgrade/doc/source/analyse.rst 1970-01-01 00:00:00 +0000
+++ openerp/openupgrade/doc/source/analyse.rst 2012-05-09 12:37:19 +0000
@@ -0,0 +1,29 @@
+How to run your own analysis
+============================
+If you do need to run your own analysis, you need to perform the following
+steps (the awkward processing of the server log file is now obsolete).
+
+* Set up two OpenUpgrade servers of subsequent OpenERP releases
+
+* On both instances, install a database without demo data and
+ install the *openupgrade_records* module, which is included in the
+ OpenUpgrade server distribution. This will add a menu
+ *OpenUpgrade Development* to the Administration menu.
+
+* On both instances, install the modules that you need to write migration
+ scripts for, or alternatively select *Install All Modules* from the
+ Development menu.
+
+* On both instances: from the development menu, select the *Generate Records*
+ option.
+
+* On the target instance (this is the more recent version): from the
+ Development menu, select the *Comparison Config* option and
+ create a new config to connect to the other instance. In the config's
+ form, click on *Perform Analysis*.
+
+Note that in many of the operations above you may get a client timeout or a
+concurrent access error even if the operation completes successfully. You
+should be able to assertain a succesful operation by verifying that all
+modules involved are in an installed state and the analysis files in the
+module directories have an appropriate modification time.
=== modified file 'openerp/openupgrade/doc/source/analysis.rst'
--- openerp/openupgrade/doc/source/analysis.rst 2012-02-15 22:19:54 +0000
+++ openerp/openupgrade/doc/source/analysis.rst 2012-05-09 12:37:19 +0000
@@ -1,20 +1,22 @@
Database analysis
+++++++++++++++++
-In this chapter you will find more information on how you can review the
-differences between databases that
-different versions of OpenERP generate, using a module based perspective.
+Database analysis files are now included in the openupgrade-addons
+distribution, so if you need to develop migration scripts for the
+standard modules you do not need to run the analysis process yourself.
+You can find the analysis file in the module's migrations directory
+under the current version, in a file called openupgrade_analysis.txt
-The process of migrating a module from OpenERP 5 to OpenERP 6.0 is the same as
-migrating a module from OpenERP 6.0 to OpenERP 6.1, but the OpenERP log file is
-formatted slightly different in 6.1, so it needs to be processed accordingly.
+The analysis of the base module is included in the openupgrade-server
+distribution. This module includes an additional file,
+openupgrade_general_log.txt. This file contains some statistics as well
+as the analysis records of modules that could not be found in the target
+release of OpenERP.
.. toctree::
:maxdepth: 2
- install5
- install6
- install61
+ analyse
xmlids
format
strategies
=== removed file 'openerp/openupgrade/doc/source/install5.rst'
--- openerp/openupgrade/doc/source/install5.rst 2012-02-14 09:55:11 +0000
+++ openerp/openupgrade/doc/source/install5.rst 1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-Step 1: Setup OpenERP 5 database
-================================
-
-Install the openupgrade server version 5. Configure logging to file.
-Create a new database. Install the module that you want to write an upgrade
-script for.
-Stop the openupgrade server version 5
-Delete the server log file.
-Start the openupgrade server with -u all -d <database> --stop-after-init
-
-Extract a csv file with the database layout per module, using the following
-command::
-
- grep OpenUpgrade_FIELD <server-5.log> |cut -d \: -f 5- | sort > server-5.csv
-
-Extract a text file with the XML IDs created per module, using the following
-command::
-
- grep OpenUpgrade_XMLID <server-5.log> |cut -d \: -f 5- | sort > xmlids-5.txt
-
=== removed file 'openerp/openupgrade/doc/source/install6.rst'
--- openerp/openupgrade/doc/source/install6.rst 2012-02-14 09:55:11 +0000
+++ openerp/openupgrade/doc/source/install6.rst 1970-01-01 00:00:00 +0000
@@ -1,28 +0,0 @@
-Step 2: Setup OpenERP 6 database
-================================
-
-Next, we repeat the process for version 6.
-
-Install the openupgrade server version 6. Configure logging to file.
-Create a new database. Install the module that you want to write an upgrade
-script for.
-Stop the openupgrade server version 6
-Delete the server log file.
-Start the openupgrade server with -u all -d <database> --stop-after-init
-
-Extract a csv file with the database layout per module, using the following
-command::
-
- grep OpenUpgrade_FIELD <server-6.log> |cut -d \: -f 5- | sort > server-6.csv
-
-Extract a text file with the XML IDs created per module, using the following
-command::
-
- grep OpenUpgrade_XMLID <server-6.log> |cut -d \: -f 5- | sort > xmlids-6.txt
-
-Perform a rough matching mechanism on the csv files:
-
- /path/to/openupgrade-server/bin/openupgrade/process-csv.py server-5.csv server-6.csv
-
-Save the results as a starting point for your work. See below for a description
-of the output.
=== removed file 'openerp/openupgrade/doc/source/install61.rst'
--- openerp/openupgrade/doc/source/install61.rst 2012-02-17 15:05:04 +0000
+++ openerp/openupgrade/doc/source/install61.rst 1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-Step 2: Setup OpenERP 6.1 database
-==================================
-
-To extract the necessary information for OpenERP 6.1, install the openupgrade
-server version 6.1. Configure logging to file.
-Create a new database. Install the module that you want to write an upgrade
-script for.
-Stop the openupgrade server version 6.1
-Delete the server log file.
-Start the openupgrade server with -u all -d <database> --stop-after-init
-
-Extract a csv file with the database layout per module, using the following
-command::
-
- grep OpenUpgrade_FIELD <server-6.1.log> |cut -d \ -f 7- | sort > server-6.1.csv
-
-Extract a text file with the XML IDs created per module, using the following
-command (note that this is slightly different from previous server versions)::
-
- grep OpenUpgrade_XMLID <server-6.1.log> |cut -d \ -f 7- | sort > xmlids-6.1.txt
-
-Perform a rough matching mechanism on the csv files:
-
- /path/to/openupgrade-server/bin/openupgrade/process-csv.py old-server.csv new-server.csv
-
-Save the results as a starting point for your work. See below for a description
-of the output.
=== modified file 'openerp/openupgrade/doc/source/modules60-61.rst'
--- openerp/openupgrade/doc/source/modules60-61.rst 2012-03-01 09:13:40 +0000
+++ openerp/openupgrade/doc/source/modules60-61.rst 2012-05-09 12:37:19 +0000
@@ -56,7 +56,7 @@
+------------------------------+------------------------------+
|base_calendar | Done |
+------------------------------+------------------------------+
-|base_contact | |
+|base_contact | Done |
+------------------------------+------------------------------+
|base_crypt | Nothing to do |
+------------------------------+------------------------------+
=== modified file 'openerp/openupgrade/doc/source/status.rst'
--- openerp/openupgrade/doc/source/status.rst 2012-03-01 09:13:40 +0000
+++ openerp/openupgrade/doc/source/status.rst 2012-05-09 12:37:19 +0000
@@ -16,3 +16,9 @@
* Documentation for developers and users. You are currently reading it. The documentation is maintained in the latest server branch. Status: always to be improved upon!
+.. toctree::
+ :maxdepth: 2
+
+ modules60-61
+
+
=== modified file 'openerp/openupgrade/doc/source/xmlids.rst'
--- openerp/openupgrade/doc/source/xmlids.rst 2012-02-15 22:19:54 +0000
+++ openerp/openupgrade/doc/source/xmlids.rst 2012-05-09 12:37:19 +0000
@@ -1,15 +1,14 @@
XML IDs
========
-Create a diff file of the XML IDs between the two database versions:
-
- diff xmlids-5.txt xmlids-6.txt > xmlids.diff
-
-This will give you a clear overview of the resources that are created by the
-modules. If you accidentally created the analysis from databases containing
+The OpenUpgrade analysis files give a representation of the XML IDs that a
+module defines, in comparison with the previous release of the module.
+
+Note, that if you run your own analysis on databases containing
demo data, you will get a lot of noise here.
XML IDs which do not occur in the updated version of all installed modules
-will be removed automatically by the OpenERP server.
+will be removed automatically by the OpenERP server, if they do not have
+the noupdate attribute.
You can ignore most entries here, most notably
@@ -63,4 +62,3 @@
[1] You might want to use this information to semi-automatically audit any manual
customizations. This subject falls out of scope of this project for now)
-
=== modified file 'openerp/openupgrade/openupgrade.py'
--- openerp/openupgrade/openupgrade.py 2012-03-06 22:36:49 +0000
+++ openerp/openupgrade/openupgrade.py 2012-05-09 12:37:19 +0000
@@ -4,11 +4,12 @@
import pooler
import logging
import tools
+import openupgrade_tools
logger = logging.getLogger('OpenUpgrade')
__all__ = [
- 'load_xml',
+ 'load_data',
'rename_columns',
'rename_tables',
'drop_columns',
@@ -61,7 +62,9 @@
finally:
fp.close()
+# for backwards compatibility
load_xml = load_data
+table_exists = openupgrade_tools.table_exists
def rename_columns(cr, column_spec):
"""
@@ -212,13 +215,6 @@
logger.warn('No rows affected for query "%s"', query)
return res
-def table_exists(cr, table):
- """ Check whether a certain table or view exists """
- cr.execute(
- 'SELECT count(relname) FROM pg_class WHERE relname = %s',
- (table,))
- return cr.fetchone()[0] == 1
-
def column_exists(cr, table, column):
""" Check whether a certain column exists """
cr.execute(
=== added file 'openerp/openupgrade/openupgrade_log.py'
--- openerp/openupgrade/openupgrade_log.py 1970-01-01 00:00:00 +0000
+++ openerp/openupgrade/openupgrade_log.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+from openupgrade_tools import table_exists
+
+def log_xml_id(cr, module, xml_id):
+ """
+ Log xml_ids at load time in the records table.
+ Called from openerp/tools/convert.py:xml_import._test_xml_id()
+
+ # Catcha's
+ - The module needs to be loaded with 'init', or the calling method
+ won't be called. This can be brought about by installing the
+ module or updating the 'state' field of the module to 'to install'
+ or call the server with '--init <module>' and the database argument.
+
+ - Do you get the right results immediately when installing the module?
+ No, sorry. This method retrieves the model from the ir_model_table, but when
+ the xml id is encountered for the first time, this method is called
+ before the item is present in this table. Therefore, you will not
+ get any meaningful results until the *second* time that you 'init'
+ the module.
+
+ - The good news is that the openupgrade_records module that comes
+ with this distribution allows you to deal with all of this with
+ one click on the menu item Settings -> Customizations ->
+ Database Structure -> OpenUpgrade -> Generate Records
+
+ - You cannot reinitialize the modules in your production database
+ and expect to keep working on it happily ever after. Do not perform
+ this routine on your production database.
+
+ :param module: The module that contains the xml_id
+ :param xml_id: the xml_id, with or without 'module.' prefix
+ """
+ if not table_exists(cr, 'openupgrade_record'):
+ return
+ if not '.' in xml_id:
+ xml_id = '%s.%s' % (module, xml_id)
+ cr.execute(
+ "SELECT model FROM ir_model_data "
+ "WHERE module = %s AND name = %s",
+ xml_id.split('.'))
+ record = cr.fetchone()
+ if not record:
+ print "Cannot find xml_id %s" % xml_id
+ return
+ else:
+ cr.execute(
+ "SELECT id FROM openupgrade_record "
+ "WHERE module=%s AND model=%s AND name=%s AND type=%s",
+ (module, record[0], xml_id, 'xmlid'))
+ if not cr.fetchone():
+ cr.execute(
+ "INSERT INTO openupgrade_record "
+ "(module, model, name, type) values(%s, %s, %s, %s)",
+ (module, record[0], xml_id, 'xmlid'))
+
=== added file 'openerp/openupgrade/openupgrade_tools.py'
--- openerp/openupgrade/openupgrade_tools.py 1970-01-01 00:00:00 +0000
+++ openerp/openupgrade/openupgrade_tools.py 2012-05-09 12:37:19 +0000
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+def table_exists(cr, table):
+ """ Check whether a certain table or view exists """
+ cr.execute(
+ 'SELECT count(relname) FROM pg_class WHERE relname = %s',
+ (table,))
+ return cr.fetchone()[0] == 1
+
=== modified file 'openerp/tools/convert.py'
--- openerp/tools/convert.py 2012-03-02 11:28:34 +0000
+++ openerp/tools/convert.py 2012-05-09 12:37:19 +0000
@@ -62,6 +62,8 @@
unsafe_eval = eval
from safe_eval import safe_eval as eval
+from openerp.openupgrade import openupgrade_log
+
class ConvertError(Exception):
def __init__(self, doc, orig_excpt):
self.d = doc
@@ -256,6 +258,7 @@
if len(id) > 64:
_logger.error('id: %s is to long (max: 64)', id)
+ openupgrade_log.log_xml_id(self.cr, self.module, xml_id)
def _tag_delete(self, cr, rec, data_node=None):
d_model = rec.get("model",'')
=== modified file 'openerp/tools/sql.py'
--- openerp/tools/sql.py 2009-10-20 10:52:23 +0000
+++ openerp/tools/sql.py 2012-05-09 12:37:19 +0000
@@ -22,7 +22,8 @@
def drop_view_if_exists(cr, viewname):
cr.execute("select count(1) from pg_class where relkind=%s and relname=%s", ('v', viewname,))
if cr.fetchone()[0]:
- cr.execute("DROP view %s" % (viewname,))
+ # OpenUpgrade: add CASCADE
+ cr.execute("DROP view %s CASCADE" % (viewname,))
cr.commit()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
Follow ups