Merge lp:~therp-nl/openupgrade-server/6.1-use_orm into lp:openupgrade-server/6.1

Proposed by Stefan Rijnhart (Opener)
Status: Merged
Merged at revision: 3977
Proposed branch: lp:~therp-nl/openupgrade-server/6.1-use_orm
Merge into: lp:openupgrade-server/6.1
Diff against target: 2470 lines (+1797/-305)
35 files modified
openerp/addons/base/ir/ir_model.py (+6/-0)
openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt (+178/-0)
openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt (+248/-0)
openerp/addons/openupgrade_records/__init__.py (+2/-0)
openerp/addons/openupgrade_records/__openerp__.py (+63/-0)
openerp/addons/openupgrade_records/__terp__.py (+63/-0)
openerp/addons/openupgrade_records/lib/__init__.py (+2/-0)
openerp/addons/openupgrade_records/lib/compare.py (+174/-147)
openerp/addons/openupgrade_records/model/__init__.py (+6/-0)
openerp/addons/openupgrade_records/model/analysis_wizard.py (+178/-0)
openerp/addons/openupgrade_records/model/comparison_config.py (+98/-0)
openerp/addons/openupgrade_records/model/generate_records_wizard.py (+90/-0)
openerp/addons/openupgrade_records/model/install_all_wizard.py (+113/-0)
openerp/addons/openupgrade_records/model/openupgrade_record.py (+111/-0)
openerp/addons/openupgrade_records/security/ir.model.access.csv (+3/-0)
openerp/addons/openupgrade_records/view/analysis_wizard.xml (+30/-0)
openerp/addons/openupgrade_records/view/comparison_config.xml (+62/-0)
openerp/addons/openupgrade_records/view/generate_records_wizard.xml (+52/-0)
openerp/addons/openupgrade_records/view/install_all_wizard.xml (+54/-0)
openerp/addons/openupgrade_records/view/openupgrade_record.xml (+65/-0)
openerp/modules/loading.py (+73/-55)
openerp/openupgrade/__init__.py (+0/-1)
openerp/openupgrade/doc/source/analyse.rst (+29/-0)
openerp/openupgrade/doc/source/analysis.rst (+11/-9)
openerp/openupgrade/doc/source/install5.rst (+0/-20)
openerp/openupgrade/doc/source/install6.rst (+0/-28)
openerp/openupgrade/doc/source/install61.rst (+0/-27)
openerp/openupgrade/doc/source/modules60-61.rst (+1/-1)
openerp/openupgrade/doc/source/status.rst (+6/-0)
openerp/openupgrade/doc/source/xmlids.rst (+6/-8)
openerp/openupgrade/openupgrade.py (+4/-8)
openerp/openupgrade/openupgrade_log.py (+56/-0)
openerp/openupgrade/openupgrade_tools.py (+8/-0)
openerp/tools/convert.py (+3/-0)
openerp/tools/sql.py (+2/-1)
To merge this branch: bzr merge lp:~therp-nl/openupgrade-server/6.1-use_orm
Reviewer Review Type Date Requested Status
OpenUpgrade Committers Pending
Review via email: mp+105196@code.launchpad.net

Description of the change

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

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/addons/base/ir/ir_model.py'
2--- openerp/addons/base/ir/ir_model.py 2012-02-09 08:38:28 +0000
3+++ openerp/addons/base/ir/ir_model.py 2012-05-09 12:37:19 +0000
4@@ -32,6 +32,8 @@
5 from tools.translate import _
6 import pooler
7
8+from openerp.openupgrade import openupgrade_log
9+
10 _logger = logging.getLogger(__name__)
11
12 def _get_fields_type(self, cr, uid, context=None):
13@@ -675,6 +677,10 @@
14 return super(ir_model_data,self).unlink(cr, uid, ids, context=context)
15
16 def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False, context=None):
17+ #OpenUpgrade: log entry (used in csv import)
18+ if xml_id:
19+ openupgrade_log.log_xml_id(cr, module, xml_id)
20+
21 model_obj = self.pool.get(model)
22 if not context:
23 context = {}
24
25=== added file 'openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt'
26--- openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt 1970-01-01 00:00:00 +0000
27+++ openerp/addons/base/migrations/6.1.1.3/openupgrade_analysis.txt 2012-05-09 12:37:19 +0000
28@@ -0,0 +1,178 @@
29+---base---
30+base / ir.actions.act_window / menus (char) : DEL
31+base / ir.actions.act_window / target (selection) : selection_keys is now '['current', 'inline', 'new']' ('['current', 'new']')
32+base / ir.actions.act_window.view / view_mode (selection) : selection_keys is now '['calendar', 'form', 'gantt', 'graph', 'kanban', 'tree']' ('['calendar', 'form', 'gantt', 'graph', 'tree']')
33+base / ir.actions.client / name (char) : NEW required: required
34+base / ir.actions.client / params_store (binary) : NEW
35+base / ir.actions.client / tag (char) : NEW required: required
36+base / ir.actions.client / type (char) : NEW required: required, req_default: ir.actions.client
37+base / ir.actions.client / usage (char) : NEW
38+base / ir.actions.todo / category_id (many2one) : NEW relation: ir.actions.todo.category
39+base / ir.actions.todo / restart (selection) : DEL required: required, selection_keys: ['always', 'never', 'onskip'], req_default: onskip
40+base / ir.actions.todo / state (selection) : selection_keys is now '['done', 'open']' ('['cancel', 'done', 'open', 'skip']')
41+base / ir.actions.todo / type (selection) : NEW required: required, selection_keys: ['automatic', 'manual', 'once'], req_default: manual
42+base / ir.actions.todo.category / name (char) : NEW required: required
43+base / ir.actions.todo.category / sequence (integer) : NEW
44+base / ir.actions.todo.category / wizards_ids (one2many) : NEW relation: ir.actions.todo
45+base / ir.mail_server / name (char) : NEW required: required
46+base / ir.mail_server / sequence (integer) : NEW
47+base / ir.mail_server / smtp_debug (boolean) : NEW
48+base / ir.mail_server / smtp_encryption (selection) : NEW required: required, selection_keys: ['none', 'ssl', 'starttls'], req_default: none
49+base / ir.mail_server / smtp_host (char) : NEW required: required
50+base / ir.mail_server / smtp_pass (char) : NEW
51+base / ir.mail_server / smtp_port (integer) : NEW required: required, req_default: 25
52+base / ir.mail_server / smtp_user (char) : NEW
53+base / ir.model.fields / serialization_field_id (many2one): NEW relation: ir.model.fields
54+base / ir.module.category / description (text) : NEW
55+base / ir.module.category / module_ids (one2many) : NEW relation: ir.module.module
56+base / ir.module.category / sequence (integer) : NEW
57+base / ir.module.category / visible (boolean) : NEW
58+base / ir.module.module / application (boolean) : NEW
59+base / ir.module.module / auto_install (boolean) : NEW
60+base / ir.module.module / complexity (selection) : NEW selection_keys: ['easy', 'expert', 'normal']
61+base / ir.module.module / icon (char) : NEW
62+base / ir.module.module / sequence (integer) : NEW
63+base / ir.module.module / web (boolean) : DEL
64+base / ir.sequence / implementation (selection) : NEW required: required, selection_keys: ['no_gap', 'standard'], req_default: standard
65+base / ir.translation / module (char) : DEL
66+base / ir.translation / xml_id (char) : DEL
67+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']')
68+base / ir.ui.view.custom / ref_id (many2one) : now required
69+base / ir.ui.view.custom / user_id (many2one) : now required
70+base / ir.values / key (selection) : now required, default = action
71+base / ir.values / meta (text) : DEL
72+base / ir.values / model (char) : now required
73+base / ir.values / name (char) : now required
74+base / ir.values / object (boolean) : DEL
75+base / res.bank / code (char) : module is now 'l10n_ch' ('base')
76+base / res.company / bank_ids (one2many) : NEW relation: res.partner.bank
77+base / res.company / company_registry (char) : NEW
78+base / res.company / name (char) : now a function
79+base / res.company / paper_format (selection) : NEW required: required, selection_keys: ['a4', 'us_letter'], req_default: a4
80+base / res.company / rml_footer2 (char) : now a function
81+base / res.country / address_format (text) : NEW
82+base / res.currency / position (selection) : NEW selection_keys: ['after', 'before']
83+base / res.currency.rate / currency_rate_type_id (many2one): NEW relation: res.currency.rate.type
84+base / res.currency.rate.type / name (char) : NEW required: required
85+base / res.groups / category_id (many2one) : NEW relation: ir.module.category
86+base / res.groups / implied_ids (many2many) : NEW relation: res.groups
87+base / res.partner / color (integer) : NEW
88+base / res.partner.address / color (integer) : NEW
89+base / res.partner.bank / acc_number (char) : now required
90+base / res.partner.bank / bank_bic (char) : NEW
91+base / res.partner.bank / bank_name (char) : NEW
92+base / res.partner.bank / company_id (many2one) : NEW relation: res.company
93+base / res.partner.bank / footer (boolean) : NEW
94+base / res.partner.bank.type / format_layout (text) : NEW
95+base / res.users / address_id (many2one) : DEL relation: res.partner.address
96+base / res.users / email (char) : DEL
97+base / res.users / id (integer) : NEW
98+base / res.users / user_email (char) : not a function anymore
99+deleted xml-id of model ir.actions.act_window: base.act_values_form
100+deleted xml-id of model ir.actions.act_window: base.action_config_simple_view_form
101+deleted xml-id of model ir.actions.act_window: base.action_config_user_form
102+deleted xml-id of model ir.actions.act_window: base.action_view_base_module_upgrade_window
103+deleted xml-id of model ir.actions.act_window: base.res_partner_canal-act
104+deleted xml-id of model ir.actions.server: base.action_start_configurator
105+deleted xml-id of model ir.actions.todo: base.config_wizard_simple_view
106+deleted xml-id of model ir.actions.todo: base.config_wizard_step_user
107+deleted xml-id of model ir.actions.wizard: base.wizard_server_action_create
108+deleted xml-id of model ir.model.access: base.access_ir_ui_view_custom_group_system
109+deleted xml-id of model ir.model.access: base.access_ir_values_group_erp_manager
110+deleted xml-id of model ir.model.access: base.access_res_partner_canal_group_partner_manager
111+deleted xml-id of model ir.model.access: base.access_res_partner_canal_group_user
112+deleted xml-id of model ir.ui.menu: base.menu_crm_config_lead
113+deleted xml-id of model ir.ui.menu: base.menu_res_partner_canal-act
114+deleted xml-id of model ir.ui.menu: base.menu_view_base_module_configuration
115+deleted xml-id of model ir.ui.menu: base.menu_view_base_module_import
116+deleted xml-id of model ir.ui.view: base.res_partner_canal-view
117+deleted xml-id of model ir.ui.view: base.res_partner_canal-view-tree
118+deleted xml-id of model ir.ui.view: base.values_view_form
119+deleted xml-id of model ir.ui.view: base.values_view_tree
120+deleted xml-id of model ir.ui.view: base.view_confirm_simple_view_form
121+deleted xml-id of model ir.ui.view: base.view_users_configuration_form
122+deleted xml-id of model ir.ui.view_sc: base.ir_ui_view_sc_configuration
123+deleted xml-id of model ir.values: base.action_todo_config
124+deleted xml-id of model res.currency.rate: base.rateVEB
125+deleted xml-id of model res.currency: base.VEB
126+deleted xml-id of model res.partner.bank.type.field: base.bank_normal_field
127+deleted xml-id of model res.partner.bank.type.field: base.bank_normal_field_contry
128+new xml-id of model ir.actions.act_window.view: base.action_values_defaults_form_view
129+new xml-id of model ir.actions.act_window.view: base.action_values_defaults_tree_view
130+new xml-id of model ir.actions.act_window: base.act_values_form_defaults
131+new xml-id of model ir.actions.act_window: base.action_currency_rate_type_form
132+new xml-id of model ir.actions.act_window: base.action_ir_mail_server_list
133+new xml-id of model ir.actions.act_window: base.action_res_partner_bank_account_form
134+new xml-id of model ir.actions.act_window: base.action_res_partner_bank_type_form
135+new xml-id of model ir.actions.act_window: base.bank_account_update
136+new xml-id of model ir.actions.act_window: base.ir_config_list_action
137+new xml-id of model ir.actions.report.xml: base.preview_report
138+new xml-id of model ir.actions.todo.category: base.category_administration_config
139+new xml-id of model ir.actions.todo.category: base.category_sales_management_config
140+new xml-id of model ir.actions.todo.category: base.category_tools_customization_config
141+new xml-id of model ir.mail_server: base.ir_mail_server_localhost0
142+new xml-id of model ir.model.access: base.access_ir_actions_client
143+new xml-id of model ir.model.access: base.access_ir_actions_todo_category
144+new xml-id of model ir.model.access: base.access_ir_mail_server_all
145+new xml-id of model ir.model.access: base.access_res_currency_rate_type_group_all
146+new xml-id of model ir.module.category: base.module_category_account_voucher
147+new xml-id of model ir.module.category: base.module_category_accounting_and_finance
148+new xml-id of model ir.module.category: base.module_category_administration
149+new xml-id of model ir.module.category: base.module_category_customer_relationship_management
150+new xml-id of model ir.module.category: base.module_category_hidden
151+new xml-id of model ir.module.category: base.module_category_human_resources
152+new xml-id of model ir.module.category: base.module_category_knowledge_management
153+new xml-id of model ir.module.category: base.module_category_localization
154+new xml-id of model ir.module.category: base.module_category_localization_account_charts
155+new xml-id of model ir.module.category: base.module_category_manufacturing
156+new xml-id of model ir.module.category: base.module_category_marketing
157+new xml-id of model ir.module.category: base.module_category_point_of_sale
158+new xml-id of model ir.module.category: base.module_category_project_management
159+new xml-id of model ir.module.category: base.module_category_purchase_management
160+new xml-id of model ir.module.category: base.module_category_report_designer
161+new xml-id of model ir.module.category: base.module_category_sales_management
162+new xml-id of model ir.module.category: base.module_category_specific_industry_applications
163+new xml-id of model ir.module.category: base.module_category_tools
164+new xml-id of model ir.module.category: base.module_category_usability
165+new xml-id of model ir.module.category: base.module_category_warehouse_management
166+new xml-id of model ir.rule: base.ir_ui_view_custom_personal
167+new xml-id of model ir.rule: base.ir_values_default_rule
168+new xml-id of model ir.ui.menu: base.ir_config_menu
169+new xml-id of model ir.ui.menu: base.menu_action_res_partner_bank_form
170+new xml-id of model ir.ui.menu: base.menu_action_res_partner_bank_typeform
171+new xml-id of model ir.ui.menu: base.menu_email
172+new xml-id of model ir.ui.menu: base.menu_mail_servers
173+new xml-id of model ir.ui.menu: base.menu_values_form_defaults
174+new xml-id of model ir.ui.view: base.contacts_kanban_view
175+new xml-id of model ir.ui.view: base.ir_actions_todo_category_form
176+new xml-id of model ir.ui.view: base.ir_actions_todo_category_tree
177+new xml-id of model ir.ui.view: base.ir_mail_server_form
178+new xml-id of model ir.ui.view: base.ir_mail_server_list
179+new xml-id of model ir.ui.view: base.module_view_kanban
180+new xml-id of model ir.ui.view: base.res_partner_kanban_view
181+new xml-id of model ir.ui.view: base.user_groups_view
182+new xml-id of model ir.ui.view: base.values_view_form_defaults
183+new xml-id of model ir.ui.view: base.view_currency_rate_type_form
184+new xml-id of model ir.ui.view: base.view_currency_rate_type_search
185+new xml-id of model ir.ui.view: base.view_currency_search
186+new xml-id of model ir.ui.view: base.view_ir_config_form
187+new xml-id of model ir.ui.view: base.view_ir_config_list
188+new xml-id of model ir.ui.view: base.view_ir_config_search
189+new xml-id of model ir.ui.view: base.view_ir_mail_server_search
190+new xml-id of model ir.ui.view: base.view_partner_bank_search
191+new xml-id of model res.country: base.ax
192+new xml-id of model res.country: base.bl
193+new xml-id of model res.country: base.bq
194+new xml-id of model res.country: base.cw
195+new xml-id of model res.country: base.gg
196+new xml-id of model res.country: base.im
197+new xml-id of model res.country: base.je
198+new xml-id of model res.country: base.mf
199+new xml-id of model res.country: base.ps
200+new xml-id of model res.country: base.ss
201+new xml-id of model res.country: base.sx
202+new xml-id of model res.currency.rate: base.rateUYU
203+new xml-id of model res.currency.rate: base.rateVEF
204+new xml-id of model res.currency: base.UYU
205+new xml-id of model res.currency: base.VEF
206+new xml-id of model res.partner.bank.type.field: base.bank_normal_field_bic
207
208=== added file 'openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt'
209--- openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt 1970-01-01 00:00:00 +0000
210+++ openerp/addons/base/migrations/6.1.1.3/openupgrade_general_log.txt 2012-05-09 12:37:19 +0000
211@@ -0,0 +1,248 @@
212+---general---
213+# 5021 fields matched,
214+# Direct match: 4708
215+# Found in other module: 6
216+# Found with different name: 0
217+# Found with different type: 1
218+# In obsolete models: 306
219+# New columns: 646
220+# Not matched: 187
221+new model account.asset.asset
222+new model account.asset.category
223+new model account.asset.depreciation.line
224+new model account.asset.history
225+new model account.bank.statement.line.global
226+new model account.coda.comm.type
227+new model account.coda.trans.category
228+new model account.coda.trans.code
229+new model account.coda.trans.type
230+new model account.financial.report
231+new model account.treasury.report
232+new model analytic.user.funct.grid
233+new model asset.asset.report
234+new model coda.bank.account
235+new model coda.bank.statement
236+new model coda.bank.statement.line
237+new model crm.case.channel
238+new model crm.partner.report.assign
239+new model edi.document
240+new model fetchmail.server
241+new model google.import.message
242+new model hr.contribution.register
243+new model hr.payslip.input
244+new model hr.payslip.run
245+new model hr.payslip.worked_days
246+new model hr.recruitment.source
247+new model hr.rule.input
248+new model hr.salary.rule
249+new model hr.salary.rule.category
250+new model import.sugarcrm
251+new model ir.actions.client
252+new model ir.actions.todo.category
253+new model ir.mail_server
254+new model l10n_br_account.cst
255+new model l10n_br_account.cst.template
256+new model mail.thread
257+new model pos.category
258+new model project.task.history
259+new model project.task.history.cumulative
260+new model project.user.allocation
261+new model res.currency.rate.type
262+new model res.partner.activation
263+new model res.partner.location
264+new model res.portal
265+new model res.portal.widget
266+obsolete model account.report_libroiva
267+obsolete model analytic_user_funct_grid
268+obsolete model base_report_creator.report
269+obsolete model base_report_creator.report.fields
270+obsolete model base_report_creator.report.filter
271+obsolete model board.note
272+obsolete model board.note.type
273+obsolete model company.contribution
274+obsolete model company.contribution.line
275+obsolete model document.directory.ics.fields
276+obsolete model email.server
277+obsolete model email.template
278+obsolete model email_template.account
279+obsolete model email_template.mailbox
280+obsolete model hr.allounce.deduction.categoty
281+obsolete model hr.contibution.register
282+obsolete model hr.contibution.register.line
283+obsolete model hr.contract.wage.type
284+obsolete model hr.contract.wage.type.period
285+obsolete model hr.employee.marital.status
286+obsolete model hr.passport
287+obsolete model hr.payroll.advice
288+obsolete model hr.payroll.advice.line
289+obsolete model hr.payroll.register
290+obsolete model hr.payslip.account.move
291+obsolete model hr.payslip.line.line
292+obsolete model mailgate.message
293+obsolete model mailgate.thread
294+obsolete model mrp.production.order
295+obsolete model project.resource.allocation
296+obsolete model report.account.invoice.product
297+obsolete model res.partner.canal
298+obsolete model res.partner.job
299+ERROR: module not in list of installed modules:
300+---project_caldav---
301+project_caldav / project.task / alarm_id (many2one) : DEL relation: res.alarm
302+project_caldav / project.task / allday (boolean) : DEL
303+project_caldav / project.task / attendee_ids (many2many) : DEL relation: calendar.attendee
304+project_caldav / project.task / base_calendar_alarm_id (many2one): DEL relation: calendar.alarm
305+project_caldav / project.task / base_calendar_url (char) : DEL
306+project_caldav / project.task / byday (selection) : DEL selection_keys: ['-1', '1', '2', '3', '4', '5']
307+project_caldav / project.task / class (selection) : DEL selection_keys: ['confidential', 'private', 'public']
308+project_caldav / project.task / count (integer) : DEL
309+project_caldav / project.task / day (integer) : DEL
310+project_caldav / project.task / duration (integer) : DEL
311+project_caldav / project.task / edit_all (boolean) : DEL
312+project_caldav / project.task / end_date (date) : DEL
313+project_caldav / project.task / end_type (selection) : DEL selection_keys: ['count', 'end_date', 'forever']
314+project_caldav / project.task / exdate (text) : DEL
315+project_caldav / project.task / exrule (char) : DEL
316+project_caldav / project.task / fr (boolean) : DEL
317+project_caldav / project.task / freq (selection) : DEL selection_keys: ['None', 'daily', 'hourly', 'monthly', 'weekly', 'yearly']
318+project_caldav / project.task / interval (integer) : DEL
319+project_caldav / project.task / location (char) : DEL
320+project_caldav / project.task / mo (boolean) : DEL
321+project_caldav / project.task / month_list (selection) : DEL selection_keys: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
322+project_caldav / project.task / organizer (char) : DEL
323+project_caldav / project.task / organizer_id (many2one) : DEL relation: res.users
324+project_caldav / project.task / recurrency (boolean) : DEL
325+project_caldav / project.task / recurrent_id (datetime) : DEL
326+project_caldav / project.task / recurrent_uid (integer) : DEL
327+project_caldav / project.task / rrule_type (selection) : DEL selection_keys: ['daily', 'monthly', 'none', 'weekly', 'yearly']
328+project_caldav / project.task / sa (boolean) : DEL
329+project_caldav / project.task / select1 (selection) : DEL selection_keys: ['date', 'day']
330+project_caldav / project.task / show_as (selection) : DEL selection_keys: ['busy', 'free']
331+project_caldav / project.task / su (boolean) : DEL
332+project_caldav / project.task / th (boolean) : DEL
333+project_caldav / project.task / tu (boolean) : DEL
334+project_caldav / project.task / vtimezone (selection) : DEL selection_keys: function
335+project_caldav / project.task / we (boolean) : DEL
336+project_caldav / project.task / week_list (selection) : DEL selection_keys: ['FR', 'MO', 'SA', 'SU', 'TH', 'TU', 'WE']
337+project_caldav / project.task / write_date (datetime) : DEL
338+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_0
339+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_1
340+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_10
341+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_11
342+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_12
343+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_13
344+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_14
345+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_15
346+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_16
347+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_17
348+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_18
349+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_19
350+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_2
351+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_20
352+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_21
353+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_22
354+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_226
355+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_23
356+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_24
357+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_25
358+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_27
359+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_28
360+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_29
361+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_3
362+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_30
363+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_31
364+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_32
365+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_33
366+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_34
367+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_35
368+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_36
369+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_37
370+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_38
371+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_4
372+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_5
373+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_6
374+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_7
375+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_8
376+deleted xml-id of model basic.calendar.fields: project_caldav.basic_calendar_fields_9
377+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_1
378+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_10
379+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_11
380+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_2
381+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_3
382+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_4
383+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_5
384+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_6
385+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_7
386+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_8
387+deleted xml-id of model basic.calendar.fields: project_caldav.map_alarm_9
388+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_1
389+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_10
390+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_11
391+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_2
392+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_3
393+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_4
394+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_5
395+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_6
396+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_7
397+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_8
398+deleted xml-id of model basic.calendar.fields: project_caldav.map_attendee_9
399+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_1
400+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_10
401+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_11
402+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_12
403+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_13
404+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_14
405+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_15
406+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_16
407+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_17
408+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_18
409+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_19
410+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_2
411+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_3
412+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_4
413+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_5
414+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_7
415+deleted xml-id of model basic.calendar.fields: project_caldav.map_todo_9
416+deleted xml-id of model basic.calendar.lines: caldav.calendar_lines_alarm2
417+deleted xml-id of model basic.calendar.lines: caldav.calendar_lines_attendee2
418+deleted xml-id of model basic.calendar.lines: caldav.calendar_lines_todo
419+deleted xml-id of model basic.calendar.lines: project_caldav.basic_calendar_lines_attendee0
420+deleted xml-id of model basic.calendar.lines: project_caldav.basic_calendar_lines_valarm0
421+deleted xml-id of model basic.calendar.lines: project_caldav.basic_calendar_lines_vtodo0
422+deleted xml-id of model basic.calendar: caldav.basic_calendar2
423+deleted xml-id of model basic.calendar: project_caldav.basic_calendar_tasks0
424+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form
425+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form1
426+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form2
427+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form3
428+deleted xml-id of model ir.ui.view: project_caldav.view_project_caldav_task_form4
429+ERROR: module not in list of installed modules:
430+---base_report_creator---
431+deleted xml-id of model ir.actions.act_window: base_report_creator.action_report_menu_create
432+deleted xml-id of model ir.actions.act_window: base_report_creator.base_report_creator_action
433+deleted xml-id of model ir.actions.wizard: base_report_creator.wizard_set_filter_fields
434+deleted xml-id of model ir.model.access: base_report_creator.access_base_report_creator_report
435+deleted xml-id of model ir.model.access: base_report_creator.access_base_report_creator_report_fields
436+deleted xml-id of model ir.model.access: base_report_creator.access_base_report_creator_report_filter
437+deleted xml-id of model ir.ui.menu: base.menu_custom_reports
438+deleted xml-id of model ir.ui.view: base.view_model_fields_tree
439+deleted xml-id of model ir.ui.view: base_report_creator.base_report_creator_form
440+deleted xml-id of model ir.ui.view: base_report_creator.base_report_creator_tree
441+deleted xml-id of model ir.ui.view: base_report_creator.view_report_filter
442+deleted xml-id of model ir.ui.view: base_report_creator.view_report_menu_create
443+ERROR: module not in list of installed modules:
444+---document_ics---
445+document_ics / crm.meeting / code (char) : DEL
446+document_ics / document.directory.content / fname_field (char) : DEL
447+document_ics / document.directory.content / ics_domain (char) : DEL
448+document_ics / document.directory.content / ics_field_ids (one2many) : DEL relation: document.directory.ics.fields
449+document_ics / document.directory.content / obj_iterate (boolean) : DEL
450+document_ics / document.directory.content / object_id (many2one) : DEL relation: ir.model
451+deleted xml-id of model document.directory.content.type: document_ics.ics
452+deleted xml-id of model ir.actions.act_window: document_ics.action_view_document_ics_config_directories
453+deleted xml-id of model ir.actions.todo: document_ics.config_wizard_step_case_section_menu
454+deleted xml-id of model ir.model.access: document_ics.access_document_directory_ics_fields_all
455+deleted xml-id of model ir.model.access: document_ics.access_document_directory_ics_fields_manager
456+deleted xml-id of model ir.ui.view: document_ics.view_document_directory_form
457+deleted xml-id of model ir.ui.view: document_ics.view_document_directory_form_1
458+deleted xml-id of model ir.ui.view: document_ics.view_document_ics_config_directories
459+deleted xml-id of model ir.ui.view: document_ics.view_meeting_inherit_form
460
461=== added directory 'openerp/addons/openupgrade_records'
462=== added file 'openerp/addons/openupgrade_records/__init__.py'
463--- openerp/addons/openupgrade_records/__init__.py 1970-01-01 00:00:00 +0000
464+++ openerp/addons/openupgrade_records/__init__.py 2012-05-09 12:37:19 +0000
465@@ -0,0 +1,2 @@
466+import model
467+import lib
468
469=== added file 'openerp/addons/openupgrade_records/__openerp__.py'
470--- openerp/addons/openupgrade_records/__openerp__.py 1970-01-01 00:00:00 +0000
471+++ openerp/addons/openupgrade_records/__openerp__.py 2012-05-09 12:37:19 +0000
472@@ -0,0 +1,63 @@
473+# -*- coding: utf-8 -*-
474+##############################################################################
475+#
476+# OpenERP, Open Source Management Solution
477+# This module Copyright (C) 2012 OpenUpgrade community
478+# https://launchpad.net/~openupgrade-committers
479+#
480+# Contributors:
481+# Therp BV <http://therp.nl>
482+#
483+# This program is free software: you can redistribute it and/or modify
484+# it under the terms of the GNU Affero General Public License as
485+# published by the Free Software Foundation, either version 3 of the
486+# License, or (at your option) any later version.
487+#
488+# This program is distributed in the hope that it will be useful,
489+# but WITHOUT ANY WARRANTY; without even the implied warranty of
490+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
491+# GNU Affero General Public License for more details.
492+#
493+# You should have received a copy of the GNU Affero General Public License
494+# along with this program. If not, see <http://www.gnu.org/licenses/>.
495+#
496+##############################################################################
497+
498+
499+{
500+ 'name': 'OpenUpgrade Records',
501+ 'version': '0.2',
502+ 'category': 'Normal',
503+ 'description': """Allow OpenUpgrade records to be
504+stored in the database and compare with other servers.
505+
506+This module depends on OpenERP client lib:
507+
508+ easy_install openerp-client-lib
509+
510+""",
511+ 'author': 'OpenUpgrade Community',
512+ 'maintainer': 'OpenUpgrade Community',
513+ 'contributors': ['Therp BV'],
514+ 'website': 'https://launchpad.net/~openupgrade-committers',
515+ 'depends': [],
516+ 'init_xml': [],
517+ 'update_xml': [
518+ 'view/openupgrade_record.xml',
519+ 'view/comparison_config.xml',
520+ 'view/analysis_wizard.xml',
521+ 'view/generate_records_wizard.xml',
522+ 'view/install_all_wizard.xml',
523+ 'security/ir.model.access.csv',
524+ ],
525+ 'demo_xml': [
526+ ],
527+ 'test': [
528+ ],
529+ 'installable': True,
530+ 'auto_install': False,
531+ 'external_dependencies': {
532+ 'python' : ['openerplib'],
533+ },
534+}
535+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
536
537=== added file 'openerp/addons/openupgrade_records/__terp__.py'
538--- openerp/addons/openupgrade_records/__terp__.py 1970-01-01 00:00:00 +0000
539+++ openerp/addons/openupgrade_records/__terp__.py 2012-05-09 12:37:19 +0000
540@@ -0,0 +1,63 @@
541+# -*- coding: utf-8 -*-
542+##############################################################################
543+#
544+# OpenERP, Open Source Management Solution
545+# This module Copyright (C) 2012 OpenUpgrade community
546+# https://launchpad.net/~openupgrade-committers
547+#
548+# Contributors:
549+# Therp BV <http://therp.nl>
550+#
551+# This program is free software: you can redistribute it and/or modify
552+# it under the terms of the GNU Affero General Public License as
553+# published by the Free Software Foundation, either version 3 of the
554+# License, or (at your option) any later version.
555+#
556+# This program is distributed in the hope that it will be useful,
557+# but WITHOUT ANY WARRANTY; without even the implied warranty of
558+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
559+# GNU Affero General Public License for more details.
560+#
561+# You should have received a copy of the GNU Affero General Public License
562+# along with this program. If not, see <http://www.gnu.org/licenses/>.
563+#
564+##############################################################################
565+
566+
567+{
568+ 'name': 'OpenUpgrade Records',
569+ 'version': '0.2',
570+ 'category': 'Normal',
571+ 'description': """Allow OpenUpgrade records to be
572+stored in the database and compare with other servers.
573+
574+This module depends on OpenERP client lib:
575+
576+ easy_install openerp-client-lib
577+
578+""",
579+ 'author': 'OpenUpgrade Community',
580+ 'maintainer': 'OpenUpgrade Community',
581+ 'contributors': ['Therp BV'],
582+ 'website': 'https://launchpad.net/~openupgrade-committers',
583+ 'depends': [],
584+ 'init_xml': [],
585+ 'update_xml': [
586+ 'view/openupgrade_record.xml',
587+ 'view/comparison_config.xml',
588+ 'view/analysis_wizard.xml',
589+ 'view/generate_records_wizard.xml',
590+ 'view/install_all_wizard.xml',
591+ 'security/ir.model.access.csv',
592+ ],
593+ 'demo_xml': [
594+ ],
595+ 'test': [
596+ ],
597+ 'installable': True,
598+ 'auto_install': False,
599+ 'external_dependencies': {
600+ 'python' : ['openerplib'],
601+ },
602+}
603+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
604
605=== added directory 'openerp/addons/openupgrade_records/lib'
606=== added file 'openerp/addons/openupgrade_records/lib/__init__.py'
607--- openerp/addons/openupgrade_records/lib/__init__.py 1970-01-01 00:00:00 +0000
608+++ openerp/addons/openupgrade_records/lib/__init__.py 2012-05-09 12:37:19 +0000
609@@ -0,0 +1,2 @@
610+import apriori
611+import compare
612
613=== renamed file 'openerp/openupgrade/changes.py' => 'openerp/addons/openupgrade_records/lib/apriori.py'
614=== renamed file 'openerp/openupgrade/process-csv.py' => 'openerp/addons/openupgrade_records/lib/compare.py'
615--- openerp/openupgrade/process-csv.py 2012-02-15 22:19:54 +0000
616+++ openerp/addons/openupgrade_records/lib/compare.py 2012-05-09 12:37:19 +0000
617@@ -1,4 +1,3 @@
618-#!/usr/bin/env python
619 # -*- coding: utf-8 -*-
620 ##############################################################################
621 #
622@@ -20,21 +19,21 @@
623 #
624 ##############################################################################
625
626-USAGE = """
627-
628- Standalone runnable to analyse two progressive datase layouts from the
629- OpenUpgrade server.
630-
631- Usage: %(name)s <old.csv> <new.csv>
632-
633-"""
634-
635-import sys, copy, csv, re
636-import changes
637+#####################################################################
638+# library providing a function to analyse two progressive database
639+# layouts from the OpenUpgrade server.
640+#####################################################################
641+
642+import copy
643+
644+try:
645+ from openerp.addons.openupgrade_records.lib import apriori
646+except ImportError:
647+ from openupgrade_records.lib import apriori
648
649 keys = [
650 'module',
651- 'operation',
652+ 'mode',
653 'model',
654 'field',
655 'type',
656@@ -46,168 +45,196 @@
657 'inherits',
658 ]
659
660-def readfile(file):
661- fields = []
662- readfile = csv.reader(open(file, 'rb'), delimiter=',', quotechar='"')
663- for row in readfile:
664- if len(row) != len(keys):
665- print "Skip line %s (%s)" % (row, len(row))
666- continue
667- col = 0
668- field = {}
669- for key in keys:
670- field[key] = row[col]
671- col += 1
672- field['matched'] = False
673- fields.append(field)
674- return fields
675-
676-def equal(dicta, dictb, ignore):
677- ka = dicta.keys()
678- kb = dictb.keys()
679- kbstatic = dictb.keys()
680- for keyset in [ ka, kb, kbstatic ]:
681- for k in ignore:
682- keyset.remove(k)
683- for k in ka:
684- if k not in kbstatic:
685- return False
686- if dicta[k] != dictb[k]:
687- return False
688- kb.remove(k)
689- if kb:
690- return False
691- return True
692-
693-def compare(dict_old, dict_new, fields):
694+def module_map(module):
695+ return apriori.renamed_modules.get(
696+ module, module)
697+
698+def compare_records(dict_old, dict_new, fields):
699+ """
700+ Check equivalence of two OpenUpgrade field representations
701+ with respect to the keys in the 'fields' arguments.
702+ Take apriori knowledge into account for mapped modules or
703+ model names.
704+ Return True of False.
705+ """
706 for field in fields:
707 if field == 'module':
708- if (changes.renamed_modules.get(dict_old[field], dict_old[field]) != dict_new[field]):
709+ if (module_map(dict_old[field]) != dict_new[field]):
710 return False
711 elif field == 'model':
712- if (changes.renamed_models.get(dict_old[field], dict_old[field]) != dict_new[field]):
713+ if (apriori.renamed_models.get(
714+ dict_old[field], dict_old[field]) != dict_new[field]):
715 return False
716 else:
717 if dict_old[field] != dict_new[field]:
718 return False
719 return True
720
721-def search(item, dict, fields):
722- for i in dict:
723- if not compare(item, i, fields):
724+def search(item, item_list, fields):
725+ """
726+ Find a match of a dictionary in a list of similar dictionaries
727+ with respect to the keys in the 'fields' arguments.
728+ Return the item if found or None.
729+ """
730+ for i in item_list:
731+ if not compare_records(item, i, fields):
732 continue
733 return i
734 return None
735
736-def fieldprint(old, new, field='NOT SPECIFIED', text=None):
737-# repr = 'module %s, model %s, field %s (%s)' % (old['module'], old['model'], old['field'], old['type'])
738+def fieldprint(old, new, field, text, reprs):
739 fieldrepr = "%s (%s)" % (old['field'], old['type'])
740- repr = '%s / %s / %s' % (old['module'].ljust(12), old['model'].ljust(24), fieldrepr.ljust(30))
741+ repr = '%s / %s / %s' % (
742+ old['module'].ljust(12), old['model'].ljust(24), fieldrepr.ljust(30))
743 if text:
744- print "%s: %s" % (repr, text)
745+ reprs.setdefault(module_map(old['module']), []).append(
746+ "%s: %s" % (repr, text))
747 else:
748- print "%s: %s is now \'%s\' ('%s')" % (repr, field, new[field], old[field])
749+ reprs.setdefault(module_map(old['module']), []).append(
750+ "%s: %s is now \'%s\' ('%s')" % (
751+ repr, field, new[field], old[field]))
752
753-def report_generic(new, old, attrs):
754+def report_generic(new, old, attrs, reprs):
755 for attr in attrs:
756 if attr == 'required':
757 if old[attr] != new['required'] and new['required']:
758 text = "now required"
759- if column['req_default']:
760- text += ', default = %s' % column['req_default']
761- fieldprint(old, new, text=text)
762+ if new['req_default']:
763+ text += ', default = %s' % new['req_default']
764+ fieldprint(old, new, None, text, reprs)
765 elif attr == 'isfunction':
766 if old['isfunction'] != new['isfunction']:
767 if new['isfunction']:
768 text = "now a function"
769 else:
770 text = "not a function anymore"
771- fieldprint(old, new, text=text)
772+ fieldprint(old, new, None, text, reprs)
773 else:
774 if old[attr] != new[attr]:
775- fieldprint(old, new, attr)
776-
777-if len(sys.argv) != 3:
778- print USAGE % {'name': sys.argv[0]}
779- exit(1)
780-
781-k5 = readfile(sys.argv[1])
782-k6 = readfile(sys.argv[2])
783-
784-origlen = len(k5)
785-
786-models6 = set([ column['model'] for column in k6 ])
787-models5 = set([ column['model'] for column in k5 ])
788-
789-matched_direct = 0
790-matched_other_module = 0
791-matched_other_type = 0
792-matched_other_name = 0
793-in_obsolete_models = 0
794-
795-obsolete_models = []
796-for model in models5:
797- if model not in models6:
798- obsolete_models.append(model)
799- print '# obsolete model %s' % model
800-
801-for column in copy.copy(k5):
802- if column['model'] in obsolete_models:
803- k5.remove(column)
804- in_obsolete_models += 1
805-
806-for model in models6:
807- if model not in models5:
808- print '# new model %s' % model
809-
810-def match(match_fields, report_fields, warn=False):
811- count = 0
812- for column in copy.copy(k5):
813- found = search(column, k6, match_fields)
814+ fieldprint(old, new, attr, None, reprs)
815+
816+def compare_sets(old_records, new_records):
817+ """
818+ Compare a set of OpenUpgrade field representations.
819+ Try to match the equivalent fields in both sets.
820+ Return a textual representation of changes in a dictionary with
821+ module names as keys. Special case is the 'general' key
822+ which contains overall remarks and matching statistics.
823+ """
824+ reprs = {'general': []}
825+
826+ for record in old_records + new_records:
827+ record['matched'] = False
828+ origlen = len(old_records)
829+ new_models = set([ column['model'] for column in new_records ])
830+ old_models = set([ column['model'] for column in old_records ])
831+
832+ matched_direct = 0
833+ matched_other_module = 0
834+ matched_other_type = 0
835+ matched_other_name = 0
836+ in_obsolete_models = 0
837+
838+ obsolete_models = []
839+ for model in old_models:
840+ if model not in new_models:
841+ obsolete_models.append(model)
842+ reprs['general'].append('obsolete model %s' % model)
843+
844+ for column in copy.copy(old_records):
845+ if column['model'] in obsolete_models:
846+ old_records.remove(column)
847+ in_obsolete_models += 1
848+
849+ for model in new_models:
850+ if model not in old_models:
851+ reprs['general'].append('new model %s' % model)
852+
853+ def match(match_fields, report_fields, warn=False):
854+ count = 0
855+ for column in copy.copy(old_records):
856+ found = search(column, new_records, match_fields)
857+ if found:
858+ if warn:
859+ pass
860+ #print "Tentatively"
861+ report_generic(found, column, report_fields, reprs)
862+ old_records.remove(column)
863+ new_records.remove(found)
864+ count += 1
865+ return count
866+
867+ matched_direct = match(
868+ ['module', 'mode', 'model', 'field'],
869+ ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
870+
871+ # other module, same type and operation
872+ matched_other_module = match(
873+ ['mode', 'model', 'field', 'type'],
874+ ['module', 'relation', 'selection_keys', 'inherits', 'isfunction', 'required'])
875+
876+ # other module, same operation, other type
877+ matched_other_type = match(
878+ ['mode', 'model', 'field'],
879+ ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
880+
881+ # fields with other names
882+ #matched_other_name = match(
883+ # ['module', 'type', 'relation'],
884+ # ['field', 'relation', 'type', 'selection_keys',
885+ # 'inherits', 'isfunction', 'required'], warn=True)
886+
887+ printkeys = [
888+ 'relation', 'required', 'selection_keys',
889+ 'req_default', 'inherits', 'mode'
890+ ]
891+ for column in old_records:
892+ # we do not care about removed function fields
893+ if not column['isfunction']:
894+ if column['mode'] == 'create':
895+ column['mode'] = ''
896+ fieldprint(
897+ column, None, None, "DEL " + ", ".join(
898+ [k + ': ' + str(column[k]) for k in printkeys if column[k]]
899+ ), reprs)
900+
901+ for column in new_records:
902+ # we do not care about newly added function fields
903+ if not column['isfunction']:
904+ if column['mode'] == 'create':
905+ column['mode'] = ''
906+ fieldprint(
907+ column, None, None, "NEW " + ", ".join(
908+ [k + ': ' + str(column[k]) for k in printkeys if column[k]]
909+ ), reprs)
910+
911+ for line in [
912+ "# %d fields matched," % (origlen - len(old_records)),
913+ "# Direct match: %d" % matched_direct,
914+ "# Found in other module: %d" % matched_other_module,
915+ "# Found with different type: %d" % matched_other_type,
916+ "# Found with different name: %d" % matched_other_name,
917+ "# In obsolete models: %d" % in_obsolete_models,
918+ "# Not matched: %d" % len(old_records),
919+ "# New columns: %d" % len(new_records),
920+ ]:
921+ reprs['general'].append(line)
922+ return reprs
923+
924+def compare_xml_sets(old_records, new_records):
925+ reprs = {}
926+ match_fields = ['module', 'model', 'name']
927+ for column in copy.copy(old_records):
928+ found = search(column, new_records, match_fields)
929 if found:
930- if warn:
931- print "Tentatively"
932- report_generic(found, column, report_fields)
933- k5.remove(column)
934- k6.remove(found)
935- count += 1
936- return count
937-
938-matched_direct = match(['module', 'operation', 'model', 'field'],
939- ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
940-
941-# other module, same type and operation
942-matched_other_module = match(['operation', 'model', 'field', 'type'],
943- ['module', 'relation', 'selection_keys', 'inherits', 'isfunction', 'required'])
944-
945-# other module, same operation, other type
946-matched_other_type = match(['operation', 'model', 'field'],
947- ['relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'])
948-
949-# fields with other names
950-#matched_other_name = match(['module', 'type', 'relation'],
951-# ['field', 'relation', 'type', 'selection_keys', 'inherits', 'isfunction', 'required'], warn=True)
952-
953-printkeys = ['relation', 'required', 'selection_keys', 'req_default', 'inherits', 'operation']
954-for column in k5:
955- # we do not care about removed function fields
956- if not column['isfunction']:
957- if column['operation'] == 'create':
958- column['operation'] = ''
959- fieldprint(column, None, text="DEL " + ", ".join([k + ': ' + str(column[k]) for k in printkeys if column[k]]))
960-
961-for column in k6:
962- # we do not care about newly added function fields
963- if not column['isfunction']:
964- if column['operation'] == 'create':
965- column['operation'] = ''
966- fieldprint(column, None, text="NEW " + ", ".join([k + ': ' + str(column[k]) for k in printkeys if column[k]]))
967-
968-print "# %d fields matched," % (origlen - len(k5))
969-print "# Direct match: %d" % matched_direct
970-print "# Found in other module: %d" % matched_other_module
971-print "# Found with different type: %d" % matched_other_type
972-print "# Found with different name: %d" % matched_other_name
973-print "# In obsolete models: %d" % in_obsolete_models
974-print "# Not matched: %d" % len(k5)
975-print "# New columns: %d" % len(k6)
976+ old_records.remove(column)
977+ new_records.remove(found)
978+ for entry in sorted(
979+ old_records, key=lambda k: '%s%s' % (k['model'].ljust(128), k['name'])):
980+ reprs.setdefault(module_map(entry['module']), []).append(
981+ 'deleted xml-id of model %s: %s' % (entry['model'], entry['name']))
982+ for entry in sorted(
983+ new_records, key=lambda k: '%s%s' % (k['model'].ljust(128), k['name'])):
984+ reprs.setdefault(module_map(entry['module']), []).append(
985+ 'new xml-id of model %s: %s' % (entry['model'], entry['name']))
986+ return reprs
987
988=== added directory 'openerp/addons/openupgrade_records/model'
989=== added file 'openerp/addons/openupgrade_records/model/__init__.py'
990--- openerp/addons/openupgrade_records/model/__init__.py 1970-01-01 00:00:00 +0000
991+++ openerp/addons/openupgrade_records/model/__init__.py 2012-05-09 12:37:19 +0000
992@@ -0,0 +1,6 @@
993+import openupgrade_record
994+import comparison_config
995+import analysis_wizard
996+import generate_records_wizard
997+import install_all_wizard
998+
999
1000=== added file 'openerp/addons/openupgrade_records/model/analysis_wizard.py'
1001--- openerp/addons/openupgrade_records/model/analysis_wizard.py 1970-01-01 00:00:00 +0000
1002+++ openerp/addons/openupgrade_records/model/analysis_wizard.py 2012-05-09 12:37:19 +0000
1003@@ -0,0 +1,178 @@
1004+# -*- coding: utf-8 -*-
1005+##############################################################################
1006+#
1007+# OpenERP, Open Source Management Solution
1008+# This module Copyright (C) 2012 OpenUpgrade community
1009+# https://launchpad.net/~openupgrade-committers
1010+#
1011+# Contributors:
1012+# Therp BV <http://therp.nl>
1013+#
1014+# This program is free software: you can redistribute it and/or modify
1015+# it under the terms of the GNU Affero General Public License as
1016+# published by the Free Software Foundation, either version 3 of the
1017+# License, or (at your option) any later version.
1018+#
1019+# This program is distributed in the hope that it will be useful,
1020+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1021+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1022+# GNU Affero General Public License for more details.
1023+#
1024+# You should have received a copy of the GNU Affero General Public License
1025+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1026+#
1027+##############################################################################
1028+
1029+import os
1030+from osv import osv, fields
1031+
1032+try:
1033+ from openerp.addons.openupgrade_records.lib import compare
1034+ from openerp.openupgrade_records.lib import apriori
1035+ from openerp.addons import get_module_path
1036+except ImportError:
1037+ from openupgrade_records.lib import compare
1038+ from openupgrade_records.lib import apriori
1039+ from addons import get_module_path
1040+
1041+class openupgrade_analysis_wizard(osv.osv_memory):
1042+ _name = 'openupgrade.analysis.wizard'
1043+ _description = 'OpenUpgrade Analysis Wizard'
1044+ _columns = {
1045+ 'server_config': fields.many2one(
1046+ 'openupgrade.comparison.config',
1047+ 'Configuration', required=True),
1048+ 'state': fields.selection(
1049+ [('init', 'Init'), ('ready', 'Ready')], 'State',
1050+ readonly=True),
1051+ 'log': fields.text('Log'),
1052+ 'write': fields.boolean(
1053+ 'Write files',
1054+ help='Write analysis files to the module directories'
1055+ ),
1056+ }
1057+ _defaults = {
1058+ 'state': lambda *a: 'init',
1059+ 'write': lambda *a: True,
1060+ }
1061+
1062+ def get_communication(self, cr, uid, ids, context=None):
1063+ """
1064+ Retrieve both sets of database representations,
1065+ perform the comparison and register the resulting
1066+ change set
1067+ """
1068+ def write_file(
1069+ module, version, contents, filename='openupgrade_analysis.txt'):
1070+ module_path = get_module_path(module)
1071+ if not module_path:
1072+ return "ERROR: could not find module path:\n"
1073+ full_path = os.path.join(
1074+ module_path, 'migrations', version)
1075+ if not os.path.exists(full_path):
1076+ try:
1077+ os.makedirs(full_path)
1078+ except os.error:
1079+ return "ERROR: could not create migrations directory:\n"
1080+ logfile = os.path.join(full_path, filename)
1081+ try:
1082+ f = open(logfile, 'w')
1083+ except Exception:
1084+ return "ERROR: could not open file %s for writing:\n" % logfile
1085+ f.write(contents)
1086+ f.close()
1087+ return None
1088+
1089+ wizard = self.browse(cr, uid, ids[0], context=context)
1090+ # Retrieve connection and access methods
1091+ conf_obj = self.pool.get('openupgrade.comparison.config')
1092+ connection = conf_obj.get_connection(
1093+ cr, uid, [wizard.server_config.id], context=context)
1094+ remote_record_obj = connection.get_model('openupgrade.record')
1095+ local_record_obj = self.pool.get('openupgrade.record')
1096+
1097+ # Retrieve field representations and compare
1098+ remote_records = remote_record_obj.field_dump(context)
1099+ local_records = local_record_obj.field_dump(cr, uid, context)
1100+ res = compare.compare_sets(remote_records, local_records)
1101+
1102+ # Retrieve xml id representations and compare
1103+ fields = ['module', 'model', 'name']
1104+ local_xml_record_ids = local_record_obj.search(
1105+ cr, uid, [('type', '=', 'xmlid')])
1106+ remote_xml_record_ids = remote_record_obj.search(
1107+ [('type', '=', 'xmlid')])
1108+ local_xml_records = [
1109+ dict([(field, x[field]) for field in fields])
1110+ for x in local_record_obj.read(
1111+ cr, uid, local_xml_record_ids, fields)
1112+ ]
1113+ remote_xml_records = [
1114+ dict([(field, x[field]) for field in fields])
1115+ for x in remote_record_obj.read(
1116+ remote_xml_record_ids, fields)
1117+ ]
1118+ res_xml = compare.compare_xml_sets(
1119+ remote_xml_records, local_xml_records)
1120+
1121+ # reorder and output the result
1122+ keys = list(set(res.keys() + res_xml.keys()))
1123+ keys.remove('general')
1124+ keys = ['general'] + keys
1125+ module_obj = self.pool.get('ir.module.module')
1126+ module_ids = module_obj.search(
1127+ cr, uid, [('state', '=', 'installed')])
1128+ modules = dict([(x['name'], x) for x in module_obj.read(cr, uid, module_ids)])
1129+ general = ''
1130+ for key in keys:
1131+ contents = "---%s---\n" % key
1132+ if key in res:
1133+ contents += '\n'.join([unicode(line) for line in sorted(res[key])])
1134+ if res[key]:
1135+ contents += '\n'
1136+ if key in res_xml:
1137+ contents += '\n'.join([unicode(line) for line in sorted(res_xml[key])])
1138+ if res_xml[key]:
1139+ contents += '\n'
1140+ if key == 'general':
1141+ general += contents
1142+ continue
1143+ if key not in modules:
1144+ general += (
1145+ "ERROR: module not in list of installed modules:\n"
1146+ + contents)
1147+ continue
1148+ if wizard.write:
1149+ error = write_file(
1150+ key, modules[key]['installed_version'], contents)
1151+ if error:
1152+ general += error
1153+ general += contents
1154+ else:
1155+ general += contents
1156+
1157+ # Store the general log in as many places as possible ;-)
1158+ if wizard.write and 'base' in modules:
1159+ write_file(
1160+ 'base', modules['base']['installed_version'], general,
1161+ 'openupgrade_general_log.txt')
1162+ self.pool.get('openupgrade.comparison.config').write(
1163+ cr, uid, wizard.server_config.id,
1164+ {'last_log': general})
1165+ self.write(cr, uid, ids, {'state': 'ready', 'log': general})
1166+
1167+ result = {
1168+ 'name': self._description,
1169+ 'view_type': 'form',
1170+ 'view_mode': 'form',
1171+ 'res_model': 'openupgrade.analysis.wizard',
1172+ 'domain': [],
1173+ 'context': context,
1174+ 'type': 'ir.actions.act_window',
1175+ #'target': 'new',
1176+ 'res_id': ids[0],
1177+ }
1178+ return result
1179+
1180+openupgrade_analysis_wizard()
1181+
1182
1183=== added file 'openerp/addons/openupgrade_records/model/comparison_config.py'
1184--- openerp/addons/openupgrade_records/model/comparison_config.py 1970-01-01 00:00:00 +0000
1185+++ openerp/addons/openupgrade_records/model/comparison_config.py 2012-05-09 12:37:19 +0000
1186@@ -0,0 +1,98 @@
1187+# -*- coding: utf-8 -*-
1188+##############################################################################
1189+#
1190+# OpenERP, Open Source Management Solution
1191+# This module Copyright (C) 2012 OpenUpgrade community
1192+# https://launchpad.net/~openupgrade-committers
1193+#
1194+# Contributors:
1195+# Therp BV <http://therp.nl>
1196+#
1197+# This program is free software: you can redistribute it and/or modify
1198+# it under the terms of the GNU Affero General Public License as
1199+# published by the Free Software Foundation, either version 3 of the
1200+# License, or (at your option) any later version.
1201+#
1202+# This program is distributed in the hope that it will be useful,
1203+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1204+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1205+# GNU Affero General Public License for more details.
1206+#
1207+# You should have received a copy of the GNU Affero General Public License
1208+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1209+#
1210+##############################################################################
1211+
1212+from osv import osv, fields
1213+import openerplib
1214+from tools.translate import _
1215+
1216+class openupgrade_comparison_config(osv.osv):
1217+ _name = 'openupgrade.comparison.config'
1218+ _columns = {
1219+ 'name': fields.char('Name', size=64),
1220+ 'server': fields.char('Server', size=64, required=True),
1221+ 'port': fields.integer('Port', required=True),
1222+ 'protocol': fields.selection(
1223+ [('http://', 'XML-RPC')],
1224+ # ('https://', 'XML-RPC Secure')], not supported by libopenerp
1225+ 'Protocol', required=True),
1226+ 'database': fields.char('Database', size=64, required=True),
1227+ 'username': fields.char('Username', size=24, required=True),
1228+ 'password': fields.char('Password', size=24, required=True, password=True),
1229+ 'last_log': fields.text('Last log'),
1230+ }
1231+ _defaults = {
1232+ 'port': lambda *a: 8069,
1233+ 'protocol': lambda *a: 'http://',
1234+ }
1235+
1236+ def get_connection(self, cr, uid, ids, context=None):
1237+ if not ids:
1238+ raise osv.except_osv(
1239+ _("Cannot connect"), _("Invalid id passed."))
1240+ conf = self.read(cr, uid, ids[0], context=None)
1241+ return openerplib.get_connection(
1242+ hostname=conf['server'],
1243+ database=conf['database'],
1244+ login=conf['username'],
1245+ password=conf['password'],
1246+ port=conf['port'],
1247+ )
1248+
1249+ def test_connection(self, cr, uid, ids, context=None):
1250+ try:
1251+ connection = self.get_connection(cr, uid, [ids[0]], context)
1252+ user_model = connection.get_model("res.users")
1253+ ids = user_model.search([("login", "=", "admin")])
1254+ user_info = user_model.read(ids[0], ["name"])
1255+ except Exception, e:
1256+ raise osv.except_osv(
1257+ _("Connection failed."), unicode(e))
1258+ raise osv.except_osv(
1259+ _("Connection succesful."),
1260+ _("%s is connected.") % user_info["name"]
1261+ )
1262+
1263+ def analyze(self, cr, uid, ids, context=None):
1264+ """
1265+ Run the analysis wizard
1266+ """
1267+ wizard_obj = self.pool.get('openupgrade.analysis.wizard')
1268+ wizard_id = wizard_obj.create(
1269+ cr, uid, {'server_config': ids[0]}, context)
1270+ result = {
1271+ 'name': wizard_obj._description,
1272+ 'view_type': 'form',
1273+ 'view_mode': 'form',
1274+ 'res_model': 'openupgrade.analysis.wizard',
1275+ 'domain': [],
1276+ 'context': context,
1277+ 'type': 'ir.actions.act_window',
1278+ 'target': 'new',
1279+ 'res_id': wizard_id,
1280+ 'nodestroy': True,
1281+ }
1282+ return result
1283+
1284+openupgrade_comparison_config()
1285
1286=== added file 'openerp/addons/openupgrade_records/model/generate_records_wizard.py'
1287--- openerp/addons/openupgrade_records/model/generate_records_wizard.py 1970-01-01 00:00:00 +0000
1288+++ openerp/addons/openupgrade_records/model/generate_records_wizard.py 2012-05-09 12:37:19 +0000
1289@@ -0,0 +1,90 @@
1290+# -*- coding: utf-8 -*-
1291+##############################################################################
1292+#
1293+# OpenERP, Open Source Management Solution
1294+# This module Copyright (C) 2012 OpenUpgrade community
1295+# https://launchpad.net/~openupgrade-committers
1296+#
1297+# Contributors:
1298+# Therp BV <http://therp.nl>
1299+#
1300+# This program is free software: you can redistribute it and/or modify
1301+# it under the terms of the GNU Affero General Public License as
1302+# published by the Free Software Foundation, either version 3 of the
1303+# License, or (at your option) any later version.
1304+#
1305+# This program is distributed in the hope that it will be useful,
1306+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1307+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1308+# GNU Affero General Public License for more details.
1309+#
1310+# You should have received a copy of the GNU Affero General Public License
1311+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1312+#
1313+##############################################################################
1314+
1315+import os
1316+from osv import osv, fields
1317+import pooler
1318+try:
1319+ from openerp.openupgrade import openupgrade_tools
1320+except ImportError:
1321+ from openupgrade import openupgrade_tools
1322+
1323+class generate_records_wizard(osv.osv_memory):
1324+ _name = 'openupgrade.generate.records.wizard'
1325+ _description = 'OpenUpgrade Generate Records Wizard'
1326+ _columns = {
1327+ 'state': fields.selection([('init', 'init'), ('ready', 'ready')], 'State'),
1328+ }
1329+ _defaults = {
1330+ 'state': lambda *a: 'init',
1331+ }
1332+
1333+ def generate(self, cr, uid, ids, context=None):
1334+ """
1335+ Main wizard step. Make sure that all modules are up-to-date,
1336+ then reinitialize all installed modules.
1337+ Equivalent of running the server with '-d <database> --init all'
1338+
1339+ The goal of this is to fill the records table.
1340+
1341+ TODO: update module list and versions, then update all modules?
1342+ """
1343+ # Truncate the records table
1344+ if (openupgrade_tools.table_exists(cr, 'openupgrade_attribute') and
1345+ openupgrade_tools.table_exists(cr, 'openupgrade_record')):
1346+ cr.execute(
1347+ 'TRUNCATE openupgrade_attribute, openupgrade_record;'
1348+ )
1349+
1350+ # Need to get all modules in state 'installed'
1351+ module_obj = self.pool.get('ir.module.module')
1352+ module_ids = module_obj.search(
1353+ cr, uid, [('state', 'in', ['to install', 'to upgrade'])])
1354+ if module_ids:
1355+ cr.commit()
1356+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
1357+ # Did we succeed above?
1358+ module_ids = module_obj.search(
1359+ cr, uid, [('state', 'in', ['to install', 'to upgrade'])])
1360+ if module_ids:
1361+ modules = module_obj.read(
1362+ cr, uid, module_ids, ['name'], context=context)
1363+ raise except_osv(
1364+ "Cannot reliably generate records",
1365+ ("Cannot seem to install or upgrade modules " +
1366+ ', '.join([x['name'] for x in modules])))
1367+ # Now reinitialize all installed modules
1368+ module_ids = module_obj.search(
1369+ cr, uid, [('state', '=', 'installed')])
1370+ module_obj.write(
1371+ cr, uid, module_ids, {'state': 'to install'})
1372+ cr.commit()
1373+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
1374+ self.write(cr, uid, ids, {'state': 'ready'})
1375+ # and we are done
1376+ return True
1377+
1378+generate_records_wizard()
1379+
1380
1381=== added file 'openerp/addons/openupgrade_records/model/install_all_wizard.py'
1382--- openerp/addons/openupgrade_records/model/install_all_wizard.py 1970-01-01 00:00:00 +0000
1383+++ openerp/addons/openupgrade_records/model/install_all_wizard.py 2012-05-09 12:37:19 +0000
1384@@ -0,0 +1,113 @@
1385+# -*- coding: utf-8 -*-
1386+##############################################################################
1387+#
1388+# OpenERP, Open Source Management Solution
1389+# This module Copyright (C) 2012 OpenUpgrade community
1390+# https://launchpad.net/~openupgrade-committers
1391+#
1392+# Contributors:
1393+# Therp BV <http://therp.nl>
1394+#
1395+# This program is free software: you can redistribute it and/or modify
1396+# it under the terms of the GNU Affero General Public License as
1397+# published by the Free Software Foundation, either version 3 of the
1398+# License, or (at your option) any later version.
1399+#
1400+# This program is distributed in the hope that it will be useful,
1401+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1402+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1403+# GNU Affero General Public License for more details.
1404+#
1405+# You should have received a copy of the GNU Affero General Public License
1406+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1407+#
1408+##############################################################################
1409+
1410+import time
1411+import os
1412+from osv import osv, fields
1413+import pooler
1414+
1415+class install_all_wizard(osv.osv_memory):
1416+ _name = 'openupgrade.install.all.wizard'
1417+ _description = 'OpenUpgrade Install All Wizard'
1418+ _columns = {
1419+ 'state': fields.selection([('init', 'init'), ('ready', 'ready')], 'State', readonly=True),
1420+ 'to_install': fields.integer('Number of modules to install', readonly=True),
1421+ }
1422+ _defaults = {
1423+ 'state': lambda *a: 'init',
1424+ }
1425+
1426+
1427+ def default_get(self, cr, uid, fields, context=None):
1428+ """
1429+ Update module list and retrieve the number
1430+ of installable modules
1431+ """
1432+ res = super(install_all_wizard, self).default_get(
1433+ cr, uid, fields, context=None)
1434+ module_obj = self.pool.get('ir.module.module')
1435+ update, add = module_obj.update_list(cr, uid,)
1436+ print "%s modules added" % add
1437+ module_ids = module_obj.search(
1438+ cr, uid, [('state', 'not in', ['installed', 'uninstallable', 'unknown'])])
1439+ res.update(
1440+ {'to_install': module_ids and len(module_ids) or False}
1441+ )
1442+ return res
1443+
1444+ def quirk_fiscalyear(self, cr, uid, ids, context=None):
1445+ """
1446+ Install account module first and create a fiscal year,
1447+ in order to prevent "No fiscal year defined" exception
1448+ during an upgrade or reinstallation of the account module.
1449+
1450+ Refer to account_fiscalyear.find(), which is called as
1451+ a default function by the orm upon module upgrade.
1452+ """
1453+ module_obj = self.pool.get('ir.module.module')
1454+ pool = self.pool
1455+ # Retrieve status of the account module
1456+ account_module_id = module_obj.search(
1457+ cr, uid, [('name', '=', 'account')], context=context)[0]
1458+ state = module_obj.read(
1459+ cr, uid, account_module_id, ['state'], context=context)['state']
1460+ if state != 'installed':
1461+ # Cancel installation of other modules
1462+ module_ids = module_obj.search(
1463+ cr, uid, [('state', '=', 'to install')])
1464+ module_obj.write(cr, uid, module_ids, {'state': 'uninstalled'})
1465+ # Mark the module and its dependencies
1466+ module_obj.button_install(cr, uid, [account_module_id])
1467+ # Install account module
1468+ cr.commit()
1469+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
1470+ # get or create today's fiscal year
1471+ fy_obj = pool.get('account.fiscalyear')
1472+ if not fy_obj.find(cr, uid, False, exception=False, context=context):
1473+ fy_obj.create(cr, uid, {
1474+ 'name': time.strftime('%Y'),
1475+ 'code': time.strftime('%Y'),
1476+ 'date_start': "%s-01-01" % time.strftime('%Y'),
1477+ 'date_stop': "%s-12-31" % time.strftime('%Y'),
1478+ })
1479+
1480+ def install_all(self, cr, uid, ids, context=None):
1481+ """
1482+ Main wizard step. Set all installable modules to install
1483+ and actually install them.
1484+ """
1485+ module_obj = self.pool.get('ir.module.module')
1486+ module_ids = module_obj.search(
1487+ cr, uid, [('state', 'not in', ['installed', 'uninstallable', 'unknown'])])
1488+ if module_ids:
1489+ module_obj.write(
1490+ cr, uid, module_ids, {'state': 'to install'})
1491+ cr.commit()
1492+ _db, pool = pooler.restart_pool(cr.dbname, update_module=True)
1493+ self.write(cr, uid, ids, {'state': 'ready'})
1494+ return True
1495+
1496+install_all_wizard()
1497+
1498
1499=== added file 'openerp/addons/openupgrade_records/model/openupgrade_record.py'
1500--- openerp/addons/openupgrade_records/model/openupgrade_record.py 1970-01-01 00:00:00 +0000
1501+++ openerp/addons/openupgrade_records/model/openupgrade_record.py 2012-05-09 12:37:19 +0000
1502@@ -0,0 +1,111 @@
1503+# -*- coding: utf-8 -*-
1504+##############################################################################
1505+#
1506+# OpenERP, Open Source Management Solution
1507+# This module Copyright (C) 2012 OpenUpgrade community
1508+# https://launchpad.net/~openupgrade-committers
1509+#
1510+# Contributors:
1511+# Therp BV <http://therp.nl>
1512+#
1513+# This program is free software: you can redistribute it and/or modify
1514+# it under the terms of the GNU Affero General Public License as
1515+# published by the Free Software Foundation, either version 3 of the
1516+# License, or (at your option) any later version.
1517+#
1518+# This program is distributed in the hope that it will be useful,
1519+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1520+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1521+# GNU Affero General Public License for more details.
1522+#
1523+# You should have received a copy of the GNU Affero General Public License
1524+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1525+#
1526+##############################################################################
1527+
1528+from osv import osv, fields
1529+
1530+# Cannot use forward references in 6.0
1531+class openupgrade_record(osv.osv):
1532+ _name = 'openupgrade.record'
1533+openupgrade_record()
1534+
1535+class openupgrade_attribute(osv.osv):
1536+ _name = 'openupgrade.attribute'
1537+ _rec_name = 'attribute_id'
1538+ _columns = {
1539+ 'name': fields.char(
1540+ 'Name', size=24,
1541+ readonly=True,
1542+ ),
1543+ 'value': fields.char(
1544+ 'Value',
1545+ size=4096,
1546+ readonly=True,
1547+ ),
1548+ 'record_id': fields.many2one(
1549+ 'openupgrade.record', ondelete='CASCADE',
1550+ readonly=True,
1551+ ),
1552+ }
1553+openupgrade_attribute()
1554+
1555+class openupgrade_record(osv.osv):
1556+ _inherit = 'openupgrade.record'
1557+
1558+ _columns = {
1559+ 'name': fields.char('Name', size=256, readonly=True),
1560+ 'module': fields.char('Module', size=128, readonly=True),
1561+ 'model': fields.char('Model', size=128, readonly=True),
1562+ 'field': fields.char('Field', size=128, readonly=True),
1563+ 'mode': fields.selection(
1564+ [('create', 'Create'), ('modify', 'Modify')],
1565+ 'Mode',
1566+ help='Set to Create if a field is newly created '
1567+ 'in this module. If this module modifies an attribute of an '
1568+ 'exting field, set to Modify.',
1569+ readonly=True,
1570+ ),
1571+ 'type': fields.selection(
1572+ [('field', 'Field'), ('xmlid', 'XML ID')],
1573+ 'Type',
1574+ readonly=True,
1575+ ),
1576+ 'attribute_ids': fields.one2many(
1577+ 'openupgrade.attribute', 'record_id', 'Attributes',
1578+ readonly=True,
1579+ ),
1580+ }
1581+ def field_dump(self, cr, uid, context=None):
1582+ keys = [
1583+ 'module',
1584+ 'mode',
1585+ 'model',
1586+ 'field',
1587+ 'type',
1588+ 'isfunction',
1589+ 'relation',
1590+ 'required',
1591+ 'selection_keys',
1592+ 'req_default',
1593+ 'inherits',
1594+ ]
1595+
1596+ template = dict([(x, False) for x in keys])
1597+ ids = self.search(cr, uid, [('type', '=', 'field')], context=context)
1598+ records = self.browse(cr, uid, ids, context=context)
1599+ data = []
1600+ for record in records:
1601+ repr = template.copy()
1602+ repr.update({
1603+ 'module': record.module,
1604+ 'model': record.model,
1605+ 'field': record.field,
1606+ 'mode': record.mode,
1607+ })
1608+ repr.update(
1609+ dict([(x.name, x.value) for x in record.attribute_ids]))
1610+ data.append(repr)
1611+ return data
1612+
1613+openupgrade_record()
1614
1615=== added directory 'openerp/addons/openupgrade_records/security'
1616=== added file 'openerp/addons/openupgrade_records/security/ir.model.access.csv'
1617--- openerp/addons/openupgrade_records/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
1618+++ openerp/addons/openupgrade_records/security/ir.model.access.csv 2012-05-09 12:37:19 +0000
1619@@ -0,0 +1,3 @@
1620+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
1621+"access_openupgrade_record","openupgrade.record all","model_openupgrade_record",,1,0,0,0
1622+"access_openupgrade_attribute","openupgrade.attribute all","model_openupgrade_attribute",,1,0,0,0
1623
1624=== added directory 'openerp/addons/openupgrade_records/view'
1625=== added file 'openerp/addons/openupgrade_records/view/analysis_wizard.xml'
1626--- openerp/addons/openupgrade_records/view/analysis_wizard.xml 1970-01-01 00:00:00 +0000
1627+++ openerp/addons/openupgrade_records/view/analysis_wizard.xml 2012-05-09 12:37:19 +0000
1628@@ -0,0 +1,30 @@
1629+<?xml version="1.0" encoding="utf-8"?>
1630+<openerp>
1631+ <data>
1632+ <record id="view_openupgrade_analysis_wizard_form" model="ir.ui.view">
1633+ <field name="name">view.openupgrade.analysis_wizard.form</field>
1634+ <field name="model">openupgrade.analysis.wizard</field>
1635+ <field name="type">form</field>
1636+ <field name="arch" type="xml">
1637+ <form string="OpenUpgrade Analysis Wizard">
1638+ <field name="server_config" readonly="1"/>
1639+ <field name="state"/>
1640+ <field name="log" colspan="4"
1641+ attrs="{'invisible': [('state', '!=', 'ready')]}"/>
1642+ <field name="write"
1643+ attrs="{'readonly': [('state', '!=', 'init')]}"/>
1644+ <button icon="gtk-close"
1645+ special="cancel"
1646+ string="Close"
1647+ />
1648+ <button icon="gtk-ok"
1649+ string="Create"
1650+ name="get_communication"
1651+ type="object"
1652+ states="init"
1653+ />
1654+ </form>
1655+ </field>
1656+ </record>
1657+ </data>
1658+</openerp>
1659
1660=== added file 'openerp/addons/openupgrade_records/view/comparison_config.xml'
1661--- openerp/addons/openupgrade_records/view/comparison_config.xml 1970-01-01 00:00:00 +0000
1662+++ openerp/addons/openupgrade_records/view/comparison_config.xml 2012-05-09 12:37:19 +0000
1663@@ -0,0 +1,62 @@
1664+<?xml version="1.0" encoding="utf-8"?>
1665+<openerp>
1666+ <data>
1667+ <record id="view_openupgrade_comparison_config_tree" model="ir.ui.view">
1668+ <field name="name">view.openupgrade.comparison_config.tree</field>
1669+ <field name="model">openupgrade.comparison.config</field>
1670+ <field name="type">tree</field>
1671+ <field name="arch" type="xml">
1672+ <tree string="OpenUpgrade Comparison Config">
1673+ <field name="name" select="1"/>
1674+ <field name="protocol"/>
1675+ <field name="server" select="1"/>
1676+ <field name="port" select="1"/>
1677+ <field name="database" select="1"/>
1678+ </tree>
1679+ </field>
1680+ </record>
1681+ <record id="view_openupgrade_comparison_config_form" model="ir.ui.view">
1682+ <field name="name">view.openupgrade.comparison_config.form</field>
1683+ <field name="model">openupgrade.comparison.config</field>
1684+ <field name="type">form</field>
1685+ <field name="arch" type="xml">
1686+ <form string="OpenUpgrade Comparison Config">
1687+ <field name="name"/>
1688+ <field name="protocol"/>
1689+ <field name="server"/>
1690+ <field name="port"/>
1691+ <field name="database"/>
1692+ <field name="username"/>
1693+ <field name="password" password="1"/>
1694+ <button
1695+ name="test_connection"
1696+ string="Test Connection"
1697+ type="object" icon="gtk-network"
1698+ colspan="2"
1699+ />
1700+ <newline/>
1701+ <button
1702+ name="analyze"
1703+ string="Perform Analysis"
1704+ type="object" icon="gtk-execute"
1705+ colspan="2"
1706+ />
1707+ <separator string="Last log" colspan="4"/>
1708+ <field name="last_log" nolabel="1" colspan="4"/>
1709+ </form>
1710+ </field>
1711+ </record>
1712+ <record id="action_openupgrade_comparison_config_tree" model="ir.actions.act_window">
1713+ <field name="name">OpenUpgrade Comparison Configs</field>
1714+ <field name="type">ir.actions.act_window</field>
1715+ <field name="res_model">openupgrade.comparison.config</field>
1716+ <field name="view_type">form</field>
1717+ </record>
1718+ <menuitem
1719+ action="action_openupgrade_comparison_config_tree"
1720+ id="menu_openupgrade_comparison_config"
1721+ name="Comparison Configurations"
1722+ parent="menu_openupgrade"
1723+ />
1724+ </data>
1725+</openerp>
1726
1727=== added file 'openerp/addons/openupgrade_records/view/generate_records_wizard.xml'
1728--- openerp/addons/openupgrade_records/view/generate_records_wizard.xml 1970-01-01 00:00:00 +0000
1729+++ openerp/addons/openupgrade_records/view/generate_records_wizard.xml 2012-05-09 12:37:19 +0000
1730@@ -0,0 +1,52 @@
1731+<?xml version="1.0" encoding="utf-8"?>
1732+<openerp>
1733+ <data>
1734+ <record id="view_openupgrade_generate_records_wizard_form" model="ir.ui.view">
1735+ <field name="name">view.openupgrade.generate_records_wizard.form</field>
1736+ <field name="model">openupgrade.generate.records.wizard</field>
1737+ <field name="type">form</field>
1738+ <field name="arch" type="xml">
1739+ <form string="OpenUpgrade Generate Records Wizard">
1740+ <group states="init" colspan="4">
1741+ <label string="This will reinitialize all the modules installed on this database. Do not continue if you use this database in production."
1742+ />
1743+ <button icon="gtk-close"
1744+ special="cancel"
1745+ string="Cancel"
1746+ />
1747+ <button icon="gtk-ok"
1748+ string="Continue"
1749+ name="generate"
1750+ type="object"
1751+ />
1752+ </group>
1753+ <group states="ready" colspan="4">
1754+ <label string="Modules initialized and records created"
1755+ />
1756+ <field name="state" invisible="1"/>
1757+ <button icon="gtk-close"
1758+ special="cancel"
1759+ string="Close"
1760+ />
1761+ </group>
1762+ </form>
1763+ </field>
1764+ </record>
1765+
1766+ <record id="action_generate_records" model="ir.actions.act_window">
1767+ <field name="name">Generate Records</field>
1768+ <field name="type">ir.actions.act_window</field>
1769+ <field name="res_model">openupgrade.generate.records.wizard</field>
1770+ <field name="view_type">form</field>
1771+ <field name="view_mode">form,tree</field>
1772+ <field name="target">new</field>
1773+ </record>
1774+
1775+ <menuitem name="Generate Records"
1776+ id="menu_openupgrade_generate_records"
1777+ parent="menu_openupgrade"
1778+ action="action_generate_records"
1779+ sequence="15"/>
1780+
1781+ </data>
1782+</openerp>
1783
1784=== added file 'openerp/addons/openupgrade_records/view/install_all_wizard.xml'
1785--- openerp/addons/openupgrade_records/view/install_all_wizard.xml 1970-01-01 00:00:00 +0000
1786+++ openerp/addons/openupgrade_records/view/install_all_wizard.xml 2012-05-09 12:37:19 +0000
1787@@ -0,0 +1,54 @@
1788+<?xml version="1.0" encoding="utf-8"?>
1789+<openerp>
1790+ <data>
1791+ <record id="view_openupgrade_install_all_wizard_form" model="ir.ui.view">
1792+ <field name="name">view.openupgrade.install_all_wizard.form</field>
1793+ <field name="model">openupgrade.install.all.wizard</field>
1794+ <field name="type">form</field>
1795+ <field name="arch" type="xml">
1796+ <form string="OpenUpgrade Install All Modules Wizard">
1797+ <group states="init" colspan="4">
1798+ <label string="This will install all modules on the database. Do not continue if you use this database in production." colspan="4"
1799+ />
1800+ <field name="to_install"/>
1801+ <newline/>
1802+ <button icon="gtk-close"
1803+ special="cancel"
1804+ string="Cancel"
1805+ />
1806+ <button icon="gtk-ok"
1807+ string="Continue"
1808+ name="install_all"
1809+ type="object"
1810+ />
1811+ </group>
1812+ <group states="ready" colspan="4">
1813+ <label string="Modules installed"
1814+ />
1815+ <field name="state" invisible="1"/>
1816+ <button icon="gtk-close"
1817+ special="cancel"
1818+ string="Close"
1819+ />
1820+ </group>
1821+ </form>
1822+ </field>
1823+ </record>
1824+
1825+ <record id="action_install_all" model="ir.actions.act_window">
1826+ <field name="name">Install All Modules</field>
1827+ <field name="type">ir.actions.act_window</field>
1828+ <field name="res_model">openupgrade.install.all.wizard</field>
1829+ <field name="view_type">form</field>
1830+ <field name="view_mode">form,tree</field>
1831+ <field name="target">new</field>
1832+ </record>
1833+
1834+ <menuitem name="Install All Modules"
1835+ id="menu_openupgrade_install_all"
1836+ parent="menu_openupgrade"
1837+ action="action_install_all"
1838+ sequence="14"/>
1839+
1840+ </data>
1841+</openerp>
1842
1843=== added file 'openerp/addons/openupgrade_records/view/openupgrade_record.xml'
1844--- openerp/addons/openupgrade_records/view/openupgrade_record.xml 1970-01-01 00:00:00 +0000
1845+++ openerp/addons/openupgrade_records/view/openupgrade_record.xml 2012-05-09 12:37:19 +0000
1846@@ -0,0 +1,65 @@
1847+<?xml version="1.0" encoding="utf-8"?>
1848+<openerp>
1849+ <data>
1850+ <!-- Top level menu under 'Database structure' -->
1851+ <menuitem
1852+ id="menu_openupgrade"
1853+ name="OpenUpgrade Development"
1854+ parent="base.menu_administration"
1855+ sequence="99"
1856+ />
1857+ <record id="view_openupgrade_record_tree" model="ir.ui.view">
1858+ <field name="name">view.openupgrade.record.tree</field>
1859+ <field name="model">openupgrade.record</field>
1860+ <field name="type">tree</field>
1861+ <field name="arch" type="xml">
1862+ <tree string="OpenUpgrade Records">
1863+ <field name="module" select="1"/>
1864+ <field name="model" select="1"/>
1865+ <field name="field" select="1"/>
1866+ <field name="name" select="1"/>
1867+ <field name="type" select="1"/>
1868+ <field name="mode" select="1"/>
1869+ </tree>
1870+ </field>
1871+ </record>
1872+ <record id="view_openupgrade_record_form" model="ir.ui.view">
1873+ <field name="name">view.openupgrade.record.form</field>
1874+ <field name="model">openupgrade.record</field>
1875+ <field name="type">form</field>
1876+ <field name="arch" type="xml">
1877+ <form string="OpenUpgrade Record">
1878+ <field name="module" select="1"/>
1879+ <field name="model" select="1"/>
1880+ <field name="field" select="1"/>
1881+ <field name="name" select="1"/>
1882+ <field name="type" select="1"/>
1883+ <field name="mode" select="1"/>
1884+ <separator string="Attributes" colspan="4"/>
1885+ <field name="attribute_ids" mode="tree,form" nolabel="1" colspan="4">
1886+ <tree string="Attributes">
1887+ <field name="name"/>
1888+ <field name="value"/>
1889+ </tree>
1890+ <form string="Attribute">
1891+ <field name="name"/>
1892+ <field name="value"/>
1893+ </form>
1894+ </field>
1895+ </form>
1896+ </field>
1897+ </record>
1898+ <record id="action_openupgrade_record_tree" model="ir.actions.act_window">
1899+ <field name="name">OpenUpgrade Records</field>
1900+ <field name="type">ir.actions.act_window</field>
1901+ <field name="res_model">openupgrade.record</field>
1902+ <field name="view_type">form</field>
1903+ </record>
1904+ <menuitem
1905+ action="action_openupgrade_record_tree"
1906+ id="menu_openupgrade_records"
1907+ name="Records"
1908+ parent="menu_openupgrade"
1909+ />
1910+ </data>
1911+</openerp>
1912
1913=== modified file 'openerp/modules/loading.py'
1914--- openerp/modules/loading.py 2012-03-09 14:44:43 +0000
1915+++ openerp/modules/loading.py 2012-05-09 12:37:19 +0000
1916@@ -66,6 +66,15 @@
1917
1918 _logger = logging.getLogger(__name__)
1919
1920+### OpenUpgrade
1921+def table_exists(cr, table):
1922+ """ Check whether a certain table or view exists """
1923+ cr.execute(
1924+ 'SELECT count(relname) FROM pg_class WHERE relname = %s',
1925+ (table,))
1926+ return cr.fetchone()[0] == 1
1927+### End of OpenUpgrade
1928+
1929 def open_openerp_namespace():
1930 # See comment for open_openerp_namespace.
1931 if openerp.conf.deprecation.open_openerp_namespace:
1932@@ -144,8 +153,6 @@
1933 finally:
1934 fp.close()
1935
1936- fields_logger = logging.getLogger('OpenUpgrade_FIELD')
1937- xmlid_logger = logging.getLogger('OpenUpgrade_XMLID')
1938 local_registry = {}
1939 def get_repr(properties, type='val'):
1940 """
1941@@ -180,24 +187,12 @@
1942 if isinstance(model, osv.orm.TransientModel):
1943 return
1944
1945+ model_registry = local_registry.setdefault(
1946+ model._name, {})
1947 if model._inherits:
1948- properties = {
1949- 'model': model._name,
1950- 'field': '_inherits',
1951- 'type': '',
1952- 'isfunction': '',
1953- 'relation': '',
1954- 'required': '',
1955- 'selection_keys': '',
1956- 'req_default': '',
1957- 'inherits': unicode(model._inherits),
1958- }
1959- local_registry[get_repr(properties, 'key')] = get_repr(
1960- properties)
1961- for k,v in model._columns.items():
1962- properties = {
1963- 'model': model._name,
1964- 'field': k,
1965+ model_registry['_inherits'] = {'_inherits': unicode(model._inherits)}
1966+ for k, v in model._columns.items():
1967+ properties = {
1968 'type': v._type,
1969 'isfunction': (
1970 isinstance(v, osv.fields.function) and 'function' or ''),
1971@@ -224,45 +219,70 @@
1972 else:
1973 properties['req_default'] = unicode(
1974 model._defaults[k])
1975- local_registry[get_repr(properties, 'key')] = get_repr(
1976- properties)
1977+ for key, value in properties.items():
1978+ if value:
1979+ model_registry.setdefault(k, {})[key] = value
1980
1981- def compare_registries():
1982+ def get_record_id(cr, module, model, field, mode):
1983+ """
1984+ OpenUpgrade: get or create the id from the record table matching
1985+ the key parameter values
1986+ """
1987+ cr.execute(
1988+ "SELECT id FROM openupgrade_record "
1989+ "WHERE module = %s AND model = %s AND "
1990+ "field = %s AND mode = %s AND type = %s",
1991+ (module, model, field, mode, 'field')
1992+ )
1993+ record = cr.fetchone()
1994+ if record:
1995+ return record[0]
1996+ cr.execute(
1997+ "INSERT INTO openupgrade_record "
1998+ "(module, model, field, mode, type) "
1999+ "VALUES (%s, %s, %s, %s, %s)",
2000+ (module, model, field, mode, 'field')
2001+ )
2002+ cr.execute(
2003+ "SELECT id FROM openupgrade_record "
2004+ "WHERE module = %s AND model = %s AND "
2005+ "field = %s AND mode = %s AND type = %s",
2006+ (module, model, field, mode, 'field')
2007+ )
2008+ return cr.fetchone()[0]
2009+
2010+ def compare_registries(cr, module):
2011 """
2012 OpenUpgrade: Compare the local registry with the global registry,
2013 log any differences and merge the local registry with
2014 the global one.
2015 """
2016- for key in sorted(local_registry.keys()):
2017- if key in registry:
2018- if registry[key] != local_registry[key]:
2019- fields_logger.info(
2020- '"%s","modify",%s,%s',
2021- package.name, key, local_registry[key])
2022- else:
2023- fields_logger.info(
2024- '"%s","create",%s,%s',
2025- package.name, key, local_registry[key])
2026- registry[key] = local_registry[key]
2027-
2028- def log_xmlids(cr, package_name):
2029- """
2030- OpenUpgrade: Log all XMLID's owned by this package.
2031- TODO: other modules can really easily add items that 'belong' to
2032- another module. Needs deeper digging in the load_data methods.
2033-
2034- Need to pass the cursor, as the one passed to the upper method is
2035- closed by now.
2036- """
2037- cr.execute(
2038- 'select model, name from ir_model_data where module=%s '
2039- 'order by model, name', (package_name,))
2040- for res in cr.fetchall():
2041- xmlid_logger.info(
2042- ','.join([
2043- "\"" + string.replace(property, '\"', '\'') + "\""
2044- for property in (res[0], res[1], package_name)
2045- ]))
2046+ if not table_exists(cr, 'openupgrade_record'):
2047+ return
2048+ for model, fields in local_registry.items():
2049+ registry.setdefault(model, {})
2050+ for field, attributes in fields.items():
2051+ old_field = registry[model].setdefault(field, {})
2052+ mode = old_field and 'modify' or 'create'
2053+ record_id = False
2054+ for key, value in attributes.items():
2055+ if key not in old_field or old_field[key] != value:
2056+ if not record_id:
2057+ record_id = get_record_id(
2058+ cr, module, model, field, mode)
2059+ cr.execute(
2060+ "SELECT id FROM openupgrade_attribute "
2061+ "WHERE name = %s AND value = %s AND "
2062+ "record_id = %s",
2063+ (key, value, record_id)
2064+ )
2065+ if not cr.fetchone():
2066+ cr.execute(
2067+ "INSERT INTO openupgrade_attribute "
2068+ "(name, value, record_id) VALUES (%s, %s, %s)",
2069+ (key, value, record_id)
2070+ )
2071+ old_field[key] = value
2072
2073 if status is None:
2074 status = {}
2075@@ -294,11 +314,10 @@
2076 loaded_modules.append(package.name)
2077 if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
2078 # OpenUpgrade: add this module's models to the registry
2079- fields_logger.info('module %s', package.name)
2080 local_registry = {}
2081 for model in models:
2082 log_model(model)
2083- compare_registries()
2084+ compare_registries(cr, package.name)
2085
2086 init_module_models(cr, package.name, models)
2087
2088@@ -364,7 +383,6 @@
2089 if hasattr(package, kind):
2090 delattr(package, kind)
2091
2092- log_xmlids(cr, package.name) # OpenUpgrade
2093 cr.commit()
2094
2095 # mark new res_log records as read
2096
2097=== modified file 'openerp/openupgrade/__init__.py'
2098--- openerp/openupgrade/__init__.py 2012-01-15 11:39:02 +0000
2099+++ openerp/openupgrade/__init__.py 2012-05-09 12:37:19 +0000
2100@@ -1,1 +0,0 @@
2101-import openupgrade
2102
2103=== added file 'openerp/openupgrade/doc/source/analyse.rst'
2104--- openerp/openupgrade/doc/source/analyse.rst 1970-01-01 00:00:00 +0000
2105+++ openerp/openupgrade/doc/source/analyse.rst 2012-05-09 12:37:19 +0000
2106@@ -0,0 +1,29 @@
2107+How to run your own analysis
2108+============================
2109+If you do need to run your own analysis, you need to perform the following
2110+steps (the awkward processing of the server log file is now obsolete).
2111+
2112+* Set up two OpenUpgrade servers of subsequent OpenERP releases
2113+
2114+* On both instances, install a database without demo data and
2115+ install the *openupgrade_records* module, which is included in the
2116+ OpenUpgrade server distribution. This will add a menu
2117+ *OpenUpgrade Development* to the Administration menu.
2118+
2119+* On both instances, install the modules that you need to write migration
2120+ scripts for, or alternatively select *Install All Modules* from the
2121+ Development menu.
2122+
2123+* On both instances: from the development menu, select the *Generate Records*
2124+ option.
2125+
2126+* On the target instance (this is the more recent version): from the
2127+ Development menu, select the *Comparison Config* option and
2128+ create a new config to connect to the other instance. In the config's
2129+ form, click on *Perform Analysis*.
2130+
2131+Note that in many of the operations above you may get a client timeout or a
2132+concurrent access error even if the operation completes successfully. You
2133+should be able to assertain a succesful operation by verifying that all
2134+modules involved are in an installed state and the analysis files in the
2135+module directories have an appropriate modification time.
2136
2137=== modified file 'openerp/openupgrade/doc/source/analysis.rst'
2138--- openerp/openupgrade/doc/source/analysis.rst 2012-02-15 22:19:54 +0000
2139+++ openerp/openupgrade/doc/source/analysis.rst 2012-05-09 12:37:19 +0000
2140@@ -1,20 +1,22 @@
2141 Database analysis
2142 +++++++++++++++++
2143
2144-In this chapter you will find more information on how you can review the
2145-differences between databases that
2146-different versions of OpenERP generate, using a module based perspective.
2147+Database analysis files are now included in the openupgrade-addons
2148+distribution, so if you need to develop migration scripts for the
2149+standard modules you do not need to run the analysis process yourself.
2150+You can find the analysis file in the module's migrations directory
2151+under the current version, in a file called openupgrade_analysis.txt
2152
2153-The process of migrating a module from OpenERP 5 to OpenERP 6.0 is the same as
2154-migrating a module from OpenERP 6.0 to OpenERP 6.1, but the OpenERP log file is
2155-formatted slightly different in 6.1, so it needs to be processed accordingly.
2156+The analysis of the base module is included in the openupgrade-server
2157+distribution. This module includes an additional file,
2158+openupgrade_general_log.txt. This file contains some statistics as well
2159+as the analysis records of modules that could not be found in the target
2160+release of OpenERP.
2161
2162 .. toctree::
2163 :maxdepth: 2
2164
2165- install5
2166- install6
2167- install61
2168+ analyse
2169 xmlids
2170 format
2171 strategies
2172
2173=== removed file 'openerp/openupgrade/doc/source/install5.rst'
2174--- openerp/openupgrade/doc/source/install5.rst 2012-02-14 09:55:11 +0000
2175+++ openerp/openupgrade/doc/source/install5.rst 1970-01-01 00:00:00 +0000
2176@@ -1,20 +0,0 @@
2177-Step 1: Setup OpenERP 5 database
2178-================================
2179-
2180-Install the openupgrade server version 5. Configure logging to file.
2181-Create a new database. Install the module that you want to write an upgrade
2182-script for.
2183-Stop the openupgrade server version 5
2184-Delete the server log file.
2185-Start the openupgrade server with -u all -d <database> --stop-after-init
2186-
2187-Extract a csv file with the database layout per module, using the following
2188-command::
2189-
2190- grep OpenUpgrade_FIELD <server-5.log> |cut -d \: -f 5- | sort > server-5.csv
2191-
2192-Extract a text file with the XML IDs created per module, using the following
2193-command::
2194-
2195- grep OpenUpgrade_XMLID <server-5.log> |cut -d \: -f 5- | sort > xmlids-5.txt
2196-
2197
2198=== removed file 'openerp/openupgrade/doc/source/install6.rst'
2199--- openerp/openupgrade/doc/source/install6.rst 2012-02-14 09:55:11 +0000
2200+++ openerp/openupgrade/doc/source/install6.rst 1970-01-01 00:00:00 +0000
2201@@ -1,28 +0,0 @@
2202-Step 2: Setup OpenERP 6 database
2203-================================
2204-
2205-Next, we repeat the process for version 6.
2206-
2207-Install the openupgrade server version 6. Configure logging to file.
2208-Create a new database. Install the module that you want to write an upgrade
2209-script for.
2210-Stop the openupgrade server version 6
2211-Delete the server log file.
2212-Start the openupgrade server with -u all -d <database> --stop-after-init
2213-
2214-Extract a csv file with the database layout per module, using the following
2215-command::
2216-
2217- grep OpenUpgrade_FIELD <server-6.log> |cut -d \: -f 5- | sort > server-6.csv
2218-
2219-Extract a text file with the XML IDs created per module, using the following
2220-command::
2221-
2222- grep OpenUpgrade_XMLID <server-6.log> |cut -d \: -f 5- | sort > xmlids-6.txt
2223-
2224-Perform a rough matching mechanism on the csv files:
2225-
2226- /path/to/openupgrade-server/bin/openupgrade/process-csv.py server-5.csv server-6.csv
2227-
2228-Save the results as a starting point for your work. See below for a description
2229-of the output.
2230
2231=== removed file 'openerp/openupgrade/doc/source/install61.rst'
2232--- openerp/openupgrade/doc/source/install61.rst 2012-02-17 15:05:04 +0000
2233+++ openerp/openupgrade/doc/source/install61.rst 1970-01-01 00:00:00 +0000
2234@@ -1,27 +0,0 @@
2235-Step 2: Setup OpenERP 6.1 database
2236-==================================
2237-
2238-To extract the necessary information for OpenERP 6.1, install the openupgrade
2239-server version 6.1. Configure logging to file.
2240-Create a new database. Install the module that you want to write an upgrade
2241-script for.
2242-Stop the openupgrade server version 6.1
2243-Delete the server log file.
2244-Start the openupgrade server with -u all -d <database> --stop-after-init
2245-
2246-Extract a csv file with the database layout per module, using the following
2247-command::
2248-
2249- grep OpenUpgrade_FIELD <server-6.1.log> |cut -d \ -f 7- | sort > server-6.1.csv
2250-
2251-Extract a text file with the XML IDs created per module, using the following
2252-command (note that this is slightly different from previous server versions)::
2253-
2254- grep OpenUpgrade_XMLID <server-6.1.log> |cut -d \ -f 7- | sort > xmlids-6.1.txt
2255-
2256-Perform a rough matching mechanism on the csv files:
2257-
2258- /path/to/openupgrade-server/bin/openupgrade/process-csv.py old-server.csv new-server.csv
2259-
2260-Save the results as a starting point for your work. See below for a description
2261-of the output.
2262
2263=== modified file 'openerp/openupgrade/doc/source/modules60-61.rst'
2264--- openerp/openupgrade/doc/source/modules60-61.rst 2012-03-01 09:13:40 +0000
2265+++ openerp/openupgrade/doc/source/modules60-61.rst 2012-05-09 12:37:19 +0000
2266@@ -56,7 +56,7 @@
2267 +------------------------------+------------------------------+
2268 |base_calendar | Done |
2269 +------------------------------+------------------------------+
2270-|base_contact | |
2271+|base_contact | Done |
2272 +------------------------------+------------------------------+
2273 |base_crypt | Nothing to do |
2274 +------------------------------+------------------------------+
2275
2276=== modified file 'openerp/openupgrade/doc/source/status.rst'
2277--- openerp/openupgrade/doc/source/status.rst 2012-03-01 09:13:40 +0000
2278+++ openerp/openupgrade/doc/source/status.rst 2012-05-09 12:37:19 +0000
2279@@ -16,3 +16,9 @@
2280
2281 * 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!
2282
2283+.. toctree::
2284+ :maxdepth: 2
2285+
2286+ modules60-61
2287+
2288+
2289
2290=== modified file 'openerp/openupgrade/doc/source/xmlids.rst'
2291--- openerp/openupgrade/doc/source/xmlids.rst 2012-02-15 22:19:54 +0000
2292+++ openerp/openupgrade/doc/source/xmlids.rst 2012-05-09 12:37:19 +0000
2293@@ -1,15 +1,14 @@
2294 XML IDs
2295 ========
2296-Create a diff file of the XML IDs between the two database versions:
2297-
2298- diff xmlids-5.txt xmlids-6.txt > xmlids.diff
2299-
2300-This will give you a clear overview of the resources that are created by the
2301-modules. If you accidentally created the analysis from databases containing
2302+The OpenUpgrade analysis files give a representation of the XML IDs that a
2303+module defines, in comparison with the previous release of the module.
2304+
2305+Note, that if you run your own analysis on databases containing
2306 demo data, you will get a lot of noise here.
2307
2308 XML IDs which do not occur in the updated version of all installed modules
2309-will be removed automatically by the OpenERP server.
2310+will be removed automatically by the OpenERP server, if they do not have
2311+the noupdate attribute.
2312
2313 You can ignore most entries here, most notably
2314
2315@@ -63,4 +62,3 @@
2316
2317 [1] You might want to use this information to semi-automatically audit any manual
2318 customizations. This subject falls out of scope of this project for now)
2319-
2320
2321=== modified file 'openerp/openupgrade/openupgrade.py'
2322--- openerp/openupgrade/openupgrade.py 2012-03-06 22:36:49 +0000
2323+++ openerp/openupgrade/openupgrade.py 2012-05-09 12:37:19 +0000
2324@@ -4,11 +4,12 @@
2325 import pooler
2326 import logging
2327 import tools
2328+import openupgrade_tools
2329
2330 logger = logging.getLogger('OpenUpgrade')
2331
2332 __all__ = [
2333- 'load_xml',
2334+ 'load_data',
2335 'rename_columns',
2336 'rename_tables',
2337 'drop_columns',
2338@@ -61,7 +62,9 @@
2339 finally:
2340 fp.close()
2341
2342+# for backwards compatibility
2343 load_xml = load_data
2344+table_exists = openupgrade_tools.table_exists
2345
2346 def rename_columns(cr, column_spec):
2347 """
2348@@ -212,13 +215,6 @@
2349 logger.warn('No rows affected for query "%s"', query)
2350 return res
2351
2352-def table_exists(cr, table):
2353- """ Check whether a certain table or view exists """
2354- cr.execute(
2355- 'SELECT count(relname) FROM pg_class WHERE relname = %s',
2356- (table,))
2357- return cr.fetchone()[0] == 1
2358-
2359 def column_exists(cr, table, column):
2360 """ Check whether a certain column exists """
2361 cr.execute(
2362
2363=== added file 'openerp/openupgrade/openupgrade_log.py'
2364--- openerp/openupgrade/openupgrade_log.py 1970-01-01 00:00:00 +0000
2365+++ openerp/openupgrade/openupgrade_log.py 2012-05-09 12:37:19 +0000
2366@@ -0,0 +1,56 @@
2367+# -*- coding: utf-8 -*-
2368+from openupgrade_tools import table_exists
2369+
2370+def log_xml_id(cr, module, xml_id):
2371+ """
2372+ Log xml_ids at load time in the records table.
2373+ Called from openerp/tools/convert.py:xml_import._test_xml_id()
2374+
2375+ # Catcha's
2376+ - The module needs to be loaded with 'init', or the calling method
2377+ won't be called. This can be brought about by installing the
2378+ module or updating the 'state' field of the module to 'to install'
2379+ or call the server with '--init <module>' and the database argument.
2380+
2381+ - Do you get the right results immediately when installing the module?
2382+ No, sorry. This method retrieves the model from the ir_model_table, but when
2383+ the xml id is encountered for the first time, this method is called
2384+ before the item is present in this table. Therefore, you will not
2385+ get any meaningful results until the *second* time that you 'init'
2386+ the module.
2387+
2388+ - The good news is that the openupgrade_records module that comes
2389+ with this distribution allows you to deal with all of this with
2390+ one click on the menu item Settings -> Customizations ->
2391+ Database Structure -> OpenUpgrade -> Generate Records
2392+
2393+ - You cannot reinitialize the modules in your production database
2394+ and expect to keep working on it happily ever after. Do not perform
2395+ this routine on your production database.
2396+
2397+ :param module: The module that contains the xml_id
2398+ :param xml_id: the xml_id, with or without 'module.' prefix
2399+ """
2400+ if not table_exists(cr, 'openupgrade_record'):
2401+ return
2402+ if not '.' in xml_id:
2403+ xml_id = '%s.%s' % (module, xml_id)
2404+ cr.execute(
2405+ "SELECT model FROM ir_model_data "
2406+ "WHERE module = %s AND name = %s",
2407+ xml_id.split('.'))
2408+ record = cr.fetchone()
2409+ if not record:
2410+ print "Cannot find xml_id %s" % xml_id
2411+ return
2412+ else:
2413+ cr.execute(
2414+ "SELECT id FROM openupgrade_record "
2415+ "WHERE module=%s AND model=%s AND name=%s AND type=%s",
2416+ (module, record[0], xml_id, 'xmlid'))
2417+ if not cr.fetchone():
2418+ cr.execute(
2419+ "INSERT INTO openupgrade_record "
2420+ "(module, model, name, type) values(%s, %s, %s, %s)",
2421+ (module, record[0], xml_id, 'xmlid'))
2422+
2423
2424=== added file 'openerp/openupgrade/openupgrade_tools.py'
2425--- openerp/openupgrade/openupgrade_tools.py 1970-01-01 00:00:00 +0000
2426+++ openerp/openupgrade/openupgrade_tools.py 2012-05-09 12:37:19 +0000
2427@@ -0,0 +1,8 @@
2428+# -*- coding: utf-8 -*-
2429+def table_exists(cr, table):
2430+ """ Check whether a certain table or view exists """
2431+ cr.execute(
2432+ 'SELECT count(relname) FROM pg_class WHERE relname = %s',
2433+ (table,))
2434+ return cr.fetchone()[0] == 1
2435+
2436
2437=== modified file 'openerp/tools/convert.py'
2438--- openerp/tools/convert.py 2012-03-02 11:28:34 +0000
2439+++ openerp/tools/convert.py 2012-05-09 12:37:19 +0000
2440@@ -62,6 +62,8 @@
2441 unsafe_eval = eval
2442 from safe_eval import safe_eval as eval
2443
2444+from openerp.openupgrade import openupgrade_log
2445+
2446 class ConvertError(Exception):
2447 def __init__(self, doc, orig_excpt):
2448 self.d = doc
2449@@ -256,6 +258,7 @@
2450
2451 if len(id) > 64:
2452 _logger.error('id: %s is to long (max: 64)', id)
2453+ openupgrade_log.log_xml_id(self.cr, self.module, xml_id)
2454
2455 def _tag_delete(self, cr, rec, data_node=None):
2456 d_model = rec.get("model",'')
2457
2458=== modified file 'openerp/tools/sql.py'
2459--- openerp/tools/sql.py 2009-10-20 10:52:23 +0000
2460+++ openerp/tools/sql.py 2012-05-09 12:37:19 +0000
2461@@ -22,7 +22,8 @@
2462 def drop_view_if_exists(cr, viewname):
2463 cr.execute("select count(1) from pg_class where relkind=%s and relname=%s", ('v', viewname,))
2464 if cr.fetchone()[0]:
2465- cr.execute("DROP view %s" % (viewname,))
2466+ # OpenUpgrade: add CASCADE
2467+ cr.execute("DROP view %s CASCADE" % (viewname,))
2468 cr.commit()
2469
2470 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

Subscribers

People subscribed via source and target branches

to status/vote changes: