[MERGE] no-op merge of trunk, discarding osv-memory fix, obsolete already

bzr revid: odo@openerp.com-20110924022846-p08bawfxh5lym37u
bzr revid: odo@openerp.com-20110924025346-1khpike23e2honll
This commit is contained in:
Olivier Dony 2011-09-24 04:53:46 +02:00
commit 1bf74fa77e
6 changed files with 230 additions and 124 deletions

View File

@ -88,8 +88,11 @@ def setup_pid_file():
def preload_registry(dbname): def preload_registry(dbname):
""" Preload a registry, and start the cron.""" """ Preload a registry, and start the cron."""
db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) try:
pool.get('ir.cron').restart(db.dbname) db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
pool.get('ir.cron').restart(db.dbname)
except Exception:
logging.exception('Failed to initialize database `%s`.', dbname)
def run_test_file(dbname, test_file): def run_test_file(dbname, test_file):
""" Preload a registry, possibly run a test file, and start the cron.""" """ Preload a registry, possibly run a test file, and start the cron."""

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-server\n" "Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-01-11 11:14+0000\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n"
"PO-Revision-Date: 2011-09-16 12:13+0000\n" "PO-Revision-Date: 2011-09-22 14:47+0000\n"
"Last-Translator: John Bradshaw <Unknown>\n" "Last-Translator: John Bradshaw <Unknown>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n" "Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-09-17 04:54+0000\n" "X-Launchpad-Export-Date: 2011-09-23 04:38+0000\n"
"X-Generator: Launchpad (build 13955)\n" "X-Generator: Launchpad (build 14012)\n"
#. module: base #. module: base
#: view:ir.filters:0 #: view:ir.filters:0
@ -4192,7 +4192,7 @@ msgstr "Menus"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Serbian (Latin) / srpski" msgid "Serbian (Latin) / srpski"
msgstr "" msgstr "Serbian (Latin) / srpski"
#. module: base #. module: base
#: model:res.country,name:base.il #: model:res.country,name:base.il
@ -4368,7 +4368,7 @@ msgstr ""
#. module: base #. module: base
#: view:base.language.import:0 #: view:base.language.import:0
msgid "- module,type,name,res_id,src,value" msgid "- module,type,name,res_id,src,value"
msgstr "" msgstr "- module,type,name,res_id,src,value"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
@ -4387,7 +4387,7 @@ msgstr ""
#. module: base #. module: base
#: help:ir.model.fields,relation:0 #: help:ir.model.fields,relation:0
msgid "For relationship fields, the technical name of the target model" msgid "For relationship fields, the technical name of the target model"
msgstr "" msgstr "For relationship fields, the technical name of the target model"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
@ -4402,7 +4402,7 @@ msgstr "Inherited View"
#. module: base #. module: base
#: view:ir.translation:0 #: view:ir.translation:0
msgid "Source Term" msgid "Source Term"
msgstr "" msgstr "Source Term"
#. module: base #. module: base
#: model:ir.ui.menu,name:base.menu_main_pm #: model:ir.ui.menu,name:base.menu_main_pm
@ -4412,7 +4412,7 @@ msgstr "Project"
#. module: base #. module: base
#: field:ir.ui.menu,web_icon_hover_data:0 #: field:ir.ui.menu,web_icon_hover_data:0
msgid "Web Icon Image (hover)" msgid "Web Icon Image (hover)"
msgstr "" msgstr "Web Icon Image (hover)"
#. module: base #. module: base
#: view:base.module.import:0 #: view:base.module.import:0
@ -4432,7 +4432,7 @@ msgstr "Create User"
#. module: base #. module: base
#: view:partner.clear.ids:0 #: view:partner.clear.ids:0
msgid "Want to Clear Ids ? " msgid "Want to Clear Ids ? "
msgstr "" msgstr "Want to Clear Ids ? "
#. module: base #. module: base
#: field:publisher_warranty.contract,name:0 #: field:publisher_warranty.contract,name:0
@ -4484,17 +4484,17 @@ msgstr "Fed. State"
#. module: base #. module: base
#: field:ir.actions.server,copy_object:0 #: field:ir.actions.server,copy_object:0
msgid "Copy Of" msgid "Copy Of"
msgstr "" msgstr "Copy Of"
#. module: base #. module: base
#: field:ir.model,osv_memory:0 #: field:ir.model,osv_memory:0
msgid "In-memory model" msgid "In-memory model"
msgstr "" msgstr "In-memory model"
#. module: base #. module: base
#: view:partner.clear.ids:0 #: view:partner.clear.ids:0
msgid "Clear Ids" msgid "Clear Ids"
msgstr "" msgstr "Clear Ids"
#. module: base #. module: base
#: model:res.country,name:base.io #: model:res.country,name:base.io
@ -4516,7 +4516,7 @@ msgstr "Field Mapping"
#. module: base #. module: base
#: view:publisher_warranty.contract:0 #: view:publisher_warranty.contract:0
msgid "Refresh Validation Dates" msgid "Refresh Validation Dates"
msgstr "" msgstr "Refresh Validation Dates"
#. module: base #. module: base
#: view:ir.model:0 #: view:ir.model:0
@ -4587,7 +4587,7 @@ msgstr "_Ok"
#. module: base #. module: base
#: help:ir.filters,user_id:0 #: help:ir.filters,user_id:0
msgid "False means for every user" msgid "False means for every user"
msgstr "" msgstr "False means for every user"
#. module: base #. module: base
#: code:addons/base/module/module.py:198 #: code:addons/base/module/module.py:198
@ -4636,6 +4636,7 @@ msgstr "Contacts"
msgid "" msgid ""
"Unable to delete this document because it is used as a default property" "Unable to delete this document because it is used as a default property"
msgstr "" msgstr ""
"Unable to delete this document because it is used as a default property"
#. module: base #. module: base
#: view:res.widget.wizard:0 #: view:res.widget.wizard:0
@ -4689,7 +4690,7 @@ msgstr ""
#: code:addons/orm.py:1350 #: code:addons/orm.py:1350
#, python-format #, python-format
msgid "Insufficient fields for Calendar View!" msgid "Insufficient fields for Calendar View!"
msgstr "" msgstr "Insufficient fields for Calendar View!"
#. module: base #. module: base
#: selection:ir.property,type:0 #: selection:ir.property,type:0
@ -4702,6 +4703,8 @@ msgid ""
"The path to the main report file (depending on Report Type) or NULL if the " "The path to the main report file (depending on Report Type) or NULL if the "
"content is in another data field" "content is in another data field"
msgstr "" msgstr ""
"The path to the main report file (depending on Report Type) or NULL if the "
"content is in another data field"
#. module: base #. module: base
#: help:res.config.users,company_id:0 #: help:res.config.users,company_id:0
@ -4763,7 +4766,7 @@ msgstr "Close"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Spanish (MX) / Español (MX)" msgid "Spanish (MX) / Español (MX)"
msgstr "" msgstr "Spanish (MX) / Español (MX)"
#. module: base #. module: base
#: view:res.log:0 #: view:res.log:0
@ -4798,7 +4801,7 @@ msgstr "Publisher Warranty Contracts"
#. module: base #. module: base
#: help:res.log,name:0 #: help:res.log,name:0
msgid "The logging message." msgid "The logging message."
msgstr "" msgstr "The logging message."
#. module: base #. module: base
#: field:base.language.export,format:0 #: field:base.language.export,format:0
@ -5033,7 +5036,7 @@ msgstr ""
#. module: base #. module: base
#: help:ir.cron,interval_number:0 #: help:ir.cron,interval_number:0
msgid "Repeat every x." msgid "Repeat every x."
msgstr "" msgstr "Repeat every x."
#. module: base #. module: base
#: wizard_view:server.action.create,step_1:0 #: wizard_view:server.action.create,step_1:0
@ -5093,6 +5096,8 @@ msgid ""
"If specified, this action will be opened at logon for this user, in addition " "If specified, this action will be opened at logon for this user, in addition "
"to the standard menu." "to the standard menu."
msgstr "" msgstr ""
"If specified, this action will be opened at logon for this user, in addition "
"to the standard menu."
#. module: base #. module: base
#: view:ir.values:0 #: view:ir.values:0
@ -5103,7 +5108,7 @@ msgstr "Client Actions"
#: code:addons/orm.py:1806 #: code:addons/orm.py:1806
#, python-format #, python-format
msgid "The exists method is not implemented on this object !" msgid "The exists method is not implemented on this object !"
msgstr "" msgstr "The exists method is not implemented on this object !"
#. module: base #. module: base
#: code:addons/base/module/module.py:336 #: code:addons/base/module/module.py:336
@ -5128,7 +5133,7 @@ msgstr "Connect Events to Actions"
#. module: base #. module: base
#: model:ir.model,name:base.model_base_update_translations #: model:ir.model,name:base.model_base_update_translations
msgid "base.update.translations" msgid "base.update.translations"
msgstr "" msgstr "base.update.translations"
#. module: base #. module: base
#: field:ir.module.category,parent_id:0 #: field:ir.module.category,parent_id:0
@ -5139,7 +5144,7 @@ msgstr "Parent Category"
#. module: base #. module: base
#: selection:ir.property,type:0 #: selection:ir.property,type:0
msgid "Integer Big" msgid "Integer Big"
msgstr "" msgstr "Integer Big"
#. module: base #. module: base
#: selection:res.partner.address,type:0 #: selection:res.partner.address,type:0
@ -5173,7 +5178,7 @@ msgstr "Communication"
#. module: base #. module: base
#: view:ir.actions.report.xml:0 #: view:ir.actions.report.xml:0
msgid "RML Report" msgid "RML Report"
msgstr "" msgstr "RML Report"
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_server_object_lines #: model:ir.model,name:base.model_ir_server_object_lines
@ -5221,7 +5226,7 @@ msgstr "Nigeria"
#: code:addons/base/ir/ir_model.py:250 #: code:addons/base/ir/ir_model.py:250
#, python-format #, python-format
msgid "For selection fields, the Selection Options must be given!" msgid "For selection fields, the Selection Options must be given!"
msgstr "" msgstr "For selection fields, the Selection Options must be given!"
#. module: base #. module: base
#: model:ir.actions.act_window,name:base.action_partner_sms_send #: model:ir.actions.act_window,name:base.action_partner_sms_send
@ -5269,6 +5274,13 @@ msgid ""
"installed the CRM, with the history tab, you can track all the interactions " "installed the CRM, with the history tab, you can track all the interactions "
"with a partner such as opportunities, emails, or sales orders issued." "with a partner such as opportunities, emails, or sales orders issued."
msgstr "" msgstr ""
"Customers (also called Partners in other areas of the system) helps you "
"manage your address book of companies whether they are prospects, customers "
"and/or suppliers. The partner form allows you to track and record all the "
"necessary information to interact with your partners from the company "
"address to their contacts as well as pricelists, and much more. If you "
"installed the CRM, with the history tab, you can track all interactions with "
"a partner such as opportunities, emails, or sales orders issued."
#. module: base #. module: base
#: model:res.country,name:base.ph #: model:res.country,name:base.ph
@ -5293,7 +5305,7 @@ msgstr "Content"
#. module: base #. module: base
#: help:ir.rule,global:0 #: help:ir.rule,global:0
msgid "If no group is specified the rule is global and applied to everyone" msgid "If no group is specified the rule is global and applied to everyone"
msgstr "" msgstr "If no group is specified the rule is global and applied to everyone"
#. module: base #. module: base
#: model:res.country,name:base.td #: model:res.country,name:base.td
@ -5370,6 +5382,9 @@ msgid ""
"groups. If this field is empty, OpenERP will compute visibility based on the " "groups. If this field is empty, OpenERP will compute visibility based on the "
"related object's read access." "related object's read access."
msgstr "" msgstr ""
"If you have groups, the visibility of this menu will be based on these "
"groups. If this field is empty, OpenERP will compute visibility based on the "
"related object's read access."
#. module: base #. module: base
#: model:ir.actions.act_window,name:base.action_ui_view_custom #: model:ir.actions.act_window,name:base.action_ui_view_custom
@ -5511,7 +5526,7 @@ msgstr "Spanish (EC) / Español (EC)"
#. module: base #. module: base
#: help:ir.ui.view,xml_id:0 #: help:ir.ui.view,xml_id:0
msgid "ID of the view defined in xml file" msgid "ID of the view defined in xml file"
msgstr "" msgstr "ID of the view defined in xml file"
#. module: base #. module: base
#: model:ir.model,name:base.model_base_module_import #: model:ir.model,name:base.model_base_module_import
@ -5527,7 +5542,7 @@ msgstr "American Samoa"
#. module: base #. module: base
#: help:ir.actions.act_window,res_model:0 #: help:ir.actions.act_window,res_model:0
msgid "Model name of the object to open in the view window" msgid "Model name of the object to open in the view window"
msgstr "" msgstr "Model name of the object to open in the view window"
#. module: base #. module: base
#: field:res.log,secondary:0 #: field:res.log,secondary:0
@ -5707,11 +5722,15 @@ msgid ""
"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't " "Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't "
"be possible to email new users." "be possible to email new users."
msgstr "" msgstr ""
"If an email is provided, the user will be sent a message welcoming them.\n"
"\n"
"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't "
"be possible to email new users."
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Flemish (BE) / Vlaams (BE)" msgid "Flemish (BE) / Vlaams (BE)"
msgstr "" msgstr "Flemish (BE) / Vlaams (BE)"
#. module: base #. module: base
#: field:ir.cron,interval_number:0 #: field:ir.cron,interval_number:0
@ -5761,7 +5780,7 @@ msgstr "ir.actions.todo"
#: code:addons/base/res/res_config.py:94 #: code:addons/base/res/res_config.py:94
#, python-format #, python-format
msgid "Couldn't find previous ir.actions.todo" msgid "Couldn't find previous ir.actions.todo"
msgstr "" msgstr "Couldn't find previous ir.actions.todo"
#. module: base #. module: base
#: view:ir.actions.act_window:0 #: view:ir.actions.act_window:0
@ -5776,7 +5795,7 @@ msgstr "Custom Shortcuts"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Vietnamese / Tiếng Việt" msgid "Vietnamese / Tiếng Việt"
msgstr "" msgstr "Vietnamese / Tiếng Việt"
#. module: base #. module: base
#: model:res.country,name:base.dz #: model:res.country,name:base.dz
@ -5791,7 +5810,7 @@ msgstr "Belgium"
#. module: base #. module: base
#: model:ir.model,name:base.model_osv_memory_autovacuum #: model:ir.model,name:base.model_osv_memory_autovacuum
msgid "osv_memory.autovacuum" msgid "osv_memory.autovacuum"
msgstr "" msgstr "osv_memory.autovacuum"
#. module: base #. module: base
#: field:base.language.export,lang:0 #: field:base.language.export,lang:0
@ -5824,30 +5843,30 @@ msgstr "Companies"
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
msgid "%H - Hour (24-hour clock) [00,23]." msgid "%H - Hour (24-hour clock) [00,23]."
msgstr "" msgstr "%H - Hour (24-hour clock) [00,23]."
#. module: base #. module: base
#: model:ir.model,name:base.model_res_widget #: model:ir.model,name:base.model_res_widget
msgid "res.widget" msgid "res.widget"
msgstr "" msgstr "res.widget"
#. module: base #. module: base
#: code:addons/base/ir/ir_model.py:258 #: code:addons/base/ir/ir_model.py:258
#, python-format #, python-format
msgid "Model %s does not exist!" msgid "Model %s does not exist!"
msgstr "" msgstr "Model %s does not exist!"
#. module: base #. module: base
#: code:addons/base/res/res_lang.py:159 #: code:addons/base/res/res_lang.py:159
#, python-format #, python-format
msgid "You cannot delete the language which is User's Preferred Language !" msgid "You cannot delete the language which is User's Preferred Language !"
msgstr "" msgstr "You cannot delete the language which is User's Preferred Language !"
#. module: base #. module: base
#: code:addons/fields.py:103 #: code:addons/fields.py:103
#, python-format #, python-format
msgid "Not implemented get_memory method !" msgid "Not implemented get_memory method !"
msgstr "" msgstr "Not implemented get_memory method !"
#. module: base #. module: base
#: view:ir.actions.server:0 #: view:ir.actions.server:0
@ -5894,7 +5913,7 @@ msgstr "Neutral Zone"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Hindi / हिंदी" msgid "Hindi / हिंदी"
msgstr "" msgstr "Hindi / हिंदी"
#. module: base #. module: base
#: view:ir.model:0 #: view:ir.model:0
@ -5941,7 +5960,7 @@ msgstr "Window Actions"
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
msgid "%I - Hour (12-hour clock) [01,12]." msgid "%I - Hour (12-hour clock) [01,12]."
msgstr "" msgstr "%I - Hour (12-hour clock) [01,12]."
#. module: base #. module: base
#: selection:publisher_warranty.contract.wizard,state:0 #: selection:publisher_warranty.contract.wizard,state:0
@ -5979,12 +5998,14 @@ msgid ""
"View type: set to 'tree' for a hierarchical tree view, or 'form' for other " "View type: set to 'tree' for a hierarchical tree view, or 'form' for other "
"views" "views"
msgstr "" msgstr ""
"View type: set to 'tree' for a hierarchical tree view, or 'form' for other "
"views"
#. module: base #. module: base
#: code:addons/base/res/res_config.py:421 #: code:addons/base/res/res_config.py:421
#, python-format #, python-format
msgid "Click 'Continue' to configure the next addon..." msgid "Click 'Continue' to configure the next addon..."
msgstr "" msgstr "Click 'Continue' to configure the next addon..."
#. module: base #. module: base
#: field:ir.actions.server,record_id:0 #: field:ir.actions.server,record_id:0
@ -6025,7 +6046,7 @@ msgstr ""
#: code:addons/base/ir/ir_actions.py:629 #: code:addons/base/ir/ir_actions.py:629
#, python-format #, python-format
msgid "Please specify server option --email-from !" msgid "Please specify server option --email-from !"
msgstr "" msgstr "Please specify server option --email-from !"
#. module: base #. module: base
#: field:base.language.import,name:0 #: field:base.language.import,name:0
@ -6085,6 +6106,7 @@ msgid ""
"It gives the status if the tip has to be displayed or not when a user " "It gives the status if the tip has to be displayed or not when a user "
"executes an action" "executes an action"
msgstr "" msgstr ""
"It shows if the tip is to be displayed or not when a user executes an action"
#. module: base #. module: base
#: view:ir.model:0 #: view:ir.model:0
@ -6141,7 +6163,7 @@ msgstr "Code"
#. module: base #. module: base
#: model:ir.model,name:base.model_res_config_installer #: model:ir.model,name:base.model_res_config_installer
msgid "res.config.installer" msgid "res.config.installer"
msgstr "" msgstr "res.config.installer"
#. module: base #. module: base
#: model:res.country,name:base.mc #: model:res.country,name:base.mc
@ -6185,7 +6207,7 @@ msgstr "Sequence Codes"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Spanish (CO) / Español (CO)" msgid "Spanish (CO) / Español (CO)"
msgstr "" msgstr "Spanish (CO) / Español (CO)"
#. module: base #. module: base
#: view:base.module.configuration:0 #: view:base.module.configuration:0
@ -6193,6 +6215,8 @@ msgid ""
"All pending configuration wizards have been executed. You may restart " "All pending configuration wizards have been executed. You may restart "
"individual wizards via the list of configuration wizards." "individual wizards via the list of configuration wizards."
msgstr "" msgstr ""
"All pending configuration wizards have been executed. You may restart "
"individual wizards via the list of configuration wizards."
#. module: base #. module: base
#: wizard_button:server.action.create,step_1,create:0 #: wizard_button:server.action.create,step_1,create:0
@ -6202,7 +6226,7 @@ msgstr "Create"
#. module: base #. module: base
#: view:ir.sequence:0 #: view:ir.sequence:0
msgid "Current Year with Century: %(year)s" msgid "Current Year with Century: %(year)s"
msgstr "" msgstr "Current Year with Century: %(year)s"
#. module: base #. module: base
#: field:ir.exports,export_fields:0 #: field:ir.exports,export_fields:0
@ -6217,13 +6241,13 @@ msgstr "France"
#. module: base #. module: base
#: model:ir.model,name:base.model_res_log #: model:ir.model,name:base.model_res_log
msgid "res.log" msgid "res.log"
msgstr "" msgstr "res.log"
#. module: base #. module: base
#: help:ir.translation,module:0 #: help:ir.translation,module:0
#: help:ir.translation,xml_id:0 #: help:ir.translation,xml_id:0
msgid "Maps to the ir_model_data for which this translation is provided." msgid "Maps to the ir_model_data for which this translation is provided."
msgstr "" msgstr "Maps to the ir_model_data for which this translation is provided."
#. module: base #. module: base
#: view:workflow.activity:0 #: view:workflow.activity:0
@ -6317,7 +6341,7 @@ msgstr "Todo"
#. module: base #. module: base
#: field:ir.attachment,datas:0 #: field:ir.attachment,datas:0
msgid "File Content" msgid "File Content"
msgstr "" msgstr "File Content"
#. module: base #. module: base
#: model:res.country,name:base.pa #: model:res.country,name:base.pa
@ -6334,12 +6358,13 @@ msgstr "Ltd"
msgid "" msgid ""
"The group that a user must have to be authorized to validate this transition." "The group that a user must have to be authorized to validate this transition."
msgstr "" msgstr ""
"The group that a user must have to be authorized to validate this transition."
#. module: base #. module: base
#: constraint:res.config.users:0 #: constraint:res.config.users:0
#: constraint:res.users:0 #: constraint:res.users:0
msgid "The chosen company is not in the allowed companies for this user" msgid "The chosen company is not in the allowed companies for this user"
msgstr "" msgstr "The chosen company is not in the allowed companies for this user"
#. module: base #. module: base
#: model:res.country,name:base.gi #: model:res.country,name:base.gi
@ -6361,6 +6386,7 @@ msgstr "Pitcairn Island"
msgid "" msgid ""
"We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." "We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)."
msgstr "" msgstr ""
"We suggest reloading the menu tab to see the new menus (Ctrl+T then Ctrl+R)."
#. module: base #. module: base
#: model:ir.actions.act_window,name:base.action_rule #: model:ir.actions.act_window,name:base.action_rule
@ -6413,7 +6439,7 @@ msgstr "Search View"
#. module: base #. module: base
#: sql_constraint:res.lang:0 #: sql_constraint:res.lang:0
msgid "The code of the language must be unique !" msgid "The code of the language must be unique !"
msgstr "" msgstr "The code of the language must be unique !"
#. module: base #. module: base
#: model:ir.actions.act_window,name:base.action_attachment #: model:ir.actions.act_window,name:base.action_attachment
@ -6456,7 +6482,7 @@ msgstr "Write Access"
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
msgid "%m - Month number [01,12]." msgid "%m - Month number [01,12]."
msgstr "" msgstr "%m - Month number [01,12]."
#. module: base #. module: base
#: field:res.bank,city:0 #: field:res.bank,city:0
@ -6514,7 +6540,7 @@ msgstr "English (US)"
#: view:ir.model.data:0 #: view:ir.model.data:0
#: model:ir.ui.menu,name:base.ir_model_data_menu #: model:ir.ui.menu,name:base.ir_model_data_menu
msgid "Object Identifiers" msgid "Object Identifiers"
msgstr "" msgstr "Object Identifiers"
#. module: base #. module: base
#: model:ir.actions.act_window,help:base.action_partner_title_partner #: model:ir.actions.act_window,help:base.action_partner_title_partner
@ -6522,11 +6548,13 @@ msgid ""
"Manage the partner titles you want to have available in your system. The " "Manage the partner titles you want to have available in your system. The "
"partner titles is the legal status of the company: Private Limited, SA, etc." "partner titles is the legal status of the company: Private Limited, SA, etc."
msgstr "" msgstr ""
"Manage the partner titles you want to have available in your system. The "
"partner title is the legal status of the company: Private Limited, SA, etc."
#. module: base #. module: base
#: view:base.language.export:0 #: view:base.language.export:0
msgid "To browse official translations, you can start with these links:" msgid "To browse official translations, you can start with these links:"
msgstr "" msgstr "To browse official translations, you can start with these links:"
#. module: base #. module: base
#: code:addons/base/ir/ir_model.py:484 #: code:addons/base/ir/ir_model.py:484
@ -6535,6 +6563,8 @@ msgid ""
"You can not read this document (%s) ! Be sure your user belongs to one of " "You can not read this document (%s) ! Be sure your user belongs to one of "
"these groups: %s." "these groups: %s."
msgstr "" msgstr ""
"You can not read this document (%s) ! Be sure your user belongs to one of "
"these groups: %s."
#. module: base #. module: base
#: view:res.bank:0 #: view:res.bank:0
@ -6553,7 +6583,7 @@ msgstr "Installed version"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Mongolian / монгол" msgid "Mongolian / монгол"
msgstr "" msgstr "Mongolian / монгол"
#. module: base #. module: base
#: model:res.country,name:base.mr #: model:res.country,name:base.mr
@ -6568,7 +6598,7 @@ msgstr "ir.translation"
#. module: base #. module: base
#: view:base.module.update:0 #: view:base.module.update:0
msgid "Module update result" msgid "Module update result"
msgstr "" msgstr "Module update result"
#. module: base #. module: base
#: view:workflow.activity:0 #: view:workflow.activity:0
@ -6590,7 +6620,7 @@ msgstr "Parent Company"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
msgid "Spanish (CR) / Español (CR)" msgid "Spanish (CR) / Español (CR)"
msgstr "" msgstr "Spanish (CR) / Español (CR)"
#. module: base #. module: base
#: field:res.currency.rate,rate:0 #: field:res.currency.rate,rate:0
@ -6630,6 +6660,9 @@ msgid ""
"for the currency: %s \n" "for the currency: %s \n"
"at the date: %s" "at the date: %s"
msgstr "" msgstr ""
"No rate found \n"
"for the currency: %s \n"
"at the date: %s"
#. module: base #. module: base
#: model:ir.actions.act_window,help:base.action_ui_view_custom #: model:ir.actions.act_window,help:base.action_ui_view_custom
@ -6637,6 +6670,8 @@ msgid ""
"Customized views are used when users reorganize the content of their " "Customized views are used when users reorganize the content of their "
"dashboard views (via web client)" "dashboard views (via web client)"
msgstr "" msgstr ""
"Customised views are used when users reorganise the content of their "
"dashboard views (via web client)"
#. module: base #. module: base
#: field:ir.model,name:0 #: field:ir.model,name:0
@ -6675,7 +6710,7 @@ msgstr "Icon"
#. module: base #. module: base
#: help:ir.model.fields,model_id:0 #: help:ir.model.fields,model_id:0
msgid "The model this field belongs to" msgid "The model this field belongs to"
msgstr "" msgstr "The model this field belongs to"
#. module: base #. module: base
#: model:res.country,name:base.mq #: model:res.country,name:base.mq
@ -6685,7 +6720,7 @@ msgstr "Martinique (French)"
#. module: base #. module: base
#: view:ir.sequence.type:0 #: view:ir.sequence.type:0
msgid "Sequences Type" msgid "Sequences Type"
msgstr "" msgstr "Sequences Type"
#. module: base #. module: base
#: model:ir.actions.act_window,name:base.res_request-act #: model:ir.actions.act_window,name:base.res_request-act
@ -6709,7 +6744,7 @@ msgstr "Or"
#: model:ir.actions.act_window,name:base.res_log_act_window #: model:ir.actions.act_window,name:base.res_log_act_window
#: model:ir.ui.menu,name:base.menu_res_log_act_window #: model:ir.ui.menu,name:base.menu_res_log_act_window
msgid "Client Logs" msgid "Client Logs"
msgstr "" msgstr "Client Logs"
#. module: base #. module: base
#: model:res.country,name:base.al #: model:res.country,name:base.al
@ -6728,6 +6763,8 @@ msgid ""
"You cannot delete the language which is Active !\n" "You cannot delete the language which is Active !\n"
"Please de-activate the language first." "Please de-activate the language first."
msgstr "" msgstr ""
"You cannot delete a language which is active !\n"
"Please de-activate the language first."
#. module: base #. module: base
#: view:base.language.install:0 #: view:base.language.install:0
@ -6736,6 +6773,8 @@ msgid ""
"Please be patient, this operation may take a few minutes (depending on the " "Please be patient, this operation may take a few minutes (depending on the "
"number of modules currently installed)..." "number of modules currently installed)..."
msgstr "" msgstr ""
"Please be patient, this operation may take a few minutes (depending on the "
"number of modules currently installed)..."
#. module: base #. module: base
#: field:ir.ui.menu,child_id:0 #: field:ir.ui.menu,child_id:0
@ -6754,18 +6793,18 @@ msgstr "Problem in configuration `Record Id` in Server Action!"
#: code:addons/orm.py:2316 #: code:addons/orm.py:2316
#, python-format #, python-format
msgid "ValidateError" msgid "ValidateError"
msgstr "" msgstr "ValidateError"
#. module: base #. module: base
#: view:base.module.import:0 #: view:base.module.import:0
#: view:base.module.update:0 #: view:base.module.update:0
msgid "Open Modules" msgid "Open Modules"
msgstr "" msgstr "Open Modules"
#. module: base #. module: base
#: model:ir.actions.act_window,help:base.action_res_bank_form #: model:ir.actions.act_window,help:base.action_res_bank_form
msgid "Manage bank records you want to be used in the system." msgid "Manage bank records you want to be used in the system."
msgstr "" msgstr "Manage bank records you want to be used in the system."
#. module: base #. module: base
#: view:base.module.import:0 #: view:base.module.import:0
@ -6783,6 +6822,8 @@ msgid ""
"The path to the main report file (depending on Report Type) or NULL if the " "The path to the main report file (depending on Report Type) or NULL if the "
"content is in another field" "content is in another field"
msgstr "" msgstr ""
"The path to the main report file (depending on Report Type) or NULL if the "
"content is in another field"
#. module: base #. module: base
#: model:res.country,name:base.la #: model:res.country,name:base.la
@ -6809,6 +6850,8 @@ msgid ""
"The sum of the data (2nd field) is null.\n" "The sum of the data (2nd field) is null.\n"
"We can't draw a pie chart !" "We can't draw a pie chart !"
msgstr "" msgstr ""
"The sum of the data (2nd field) is null.\n"
"We can't draw a pie chart !"
#. module: base #. module: base
#: model:ir.ui.menu,name:base.menu_lunch_reporting #: model:ir.ui.menu,name:base.menu_lunch_reporting
@ -6830,7 +6873,7 @@ msgstr "Togo"
#. module: base #. module: base
#: selection:ir.module.module,license:0 #: selection:ir.module.module,license:0
msgid "Other Proprietary" msgid "Other Proprietary"
msgstr "" msgstr "Other Proprietary"
#. module: base #. module: base
#: selection:workflow.activity,kind:0 #: selection:workflow.activity,kind:0
@ -6841,7 +6884,7 @@ msgstr "Stop All"
#: code:addons/orm.py:412 #: code:addons/orm.py:412
#, python-format #, python-format
msgid "The read_group method is not implemented on this object !" msgid "The read_group method is not implemented on this object !"
msgstr "" msgstr "The read_group method is not implemented on this object !"
#. module: base #. module: base
#: view:ir.model.data:0 #: view:ir.model.data:0
@ -6861,7 +6904,7 @@ msgstr "Cascade"
#. module: base #. module: base
#: field:workflow.transition,group_id:0 #: field:workflow.transition,group_id:0
msgid "Group Required" msgid "Group Required"
msgstr "" msgstr "Group Required"
#. module: base #. module: base
#: view:ir.actions.configuration.wizard:0 #: view:ir.actions.configuration.wizard:0
@ -6884,17 +6927,19 @@ msgid ""
"Enable this if you want to execute missed occurences as soon as the server " "Enable this if you want to execute missed occurences as soon as the server "
"restarts." "restarts."
msgstr "" msgstr ""
"Enable this if you want to execute missed occurences as soon as the server "
"restarts."
#. module: base #. module: base
#: view:base.module.upgrade:0 #: view:base.module.upgrade:0
msgid "Start update" msgid "Start update"
msgstr "" msgstr "Start update"
#. module: base #. module: base
#: code:addons/base/publisher_warranty/publisher_warranty.py:144 #: code:addons/base/publisher_warranty/publisher_warranty.py:144
#, python-format #, python-format
msgid "Contract validation error" msgid "Contract validation error"
msgstr "" msgstr "Contract validation error"
#. module: base #. module: base
#: field:res.country.state,name:0 #: field:res.country.state,name:0
@ -6921,7 +6966,7 @@ msgstr "ir.actions.report.xml"
#. module: base #. module: base
#: model:res.partner.title,shortcut:base.res_partner_title_miss #: model:res.partner.title,shortcut:base.res_partner_title_miss
msgid "Mss" msgid "Mss"
msgstr "" msgstr "Mss"
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_ui_view #: model:ir.model,name:base.model_ir_ui_view
@ -6931,7 +6976,7 @@ msgstr "ir.ui.view"
#. module: base #. module: base
#: constraint:res.partner:0 #: constraint:res.partner:0
msgid "Error ! You can not create recursive associated members." msgid "Error ! You can not create recursive associated members."
msgstr "" msgstr "Error ! You can not create recursive associated members."
#. module: base #. module: base
#: help:res.lang,code:0 #: help:res.lang,code:0
@ -6946,7 +6991,7 @@ msgstr "OpenERP Partners"
#. module: base #. module: base
#: model:ir.ui.menu,name:base.menu_hr_manager #: model:ir.ui.menu,name:base.menu_hr_manager
msgid "HR Manager Dashboard" msgid "HR Manager Dashboard"
msgstr "" msgstr "HR Manager Dashboard"
#. module: base #. module: base
#: code:addons/base/module/module.py:253 #: code:addons/base/module/module.py:253
@ -6954,11 +6999,12 @@ msgstr ""
msgid "" msgid ""
"Unable to install module \"%s\" because an external dependency is not met: %s" "Unable to install module \"%s\" because an external dependency is not met: %s"
msgstr "" msgstr ""
"Unable to install module \"%s\" because an external dependency is not met: %s"
#. module: base #. module: base
#: view:ir.module.module:0 #: view:ir.module.module:0
msgid "Search modules" msgid "Search modules"
msgstr "" msgstr "Search modules"
#. module: base #. module: base
#: model:res.country,name:base.by #: model:res.country,name:base.by
@ -6983,6 +7029,10 @@ msgid ""
"not connect to the system. You can assign them groups in order to give them " "not connect to the system. You can assign them groups in order to give them "
"specific access to the applications they need to use in the system." "specific access to the applications they need to use in the system."
msgstr "" msgstr ""
"Create and manage users that will connect to the system. Users can be "
"deactivated should there be a period of time during which they will/should "
"not connect to the system. You can assign them groups to give them specific "
"access to the applications they need to use."
#. module: base #. module: base
#: selection:res.request,priority:0 #: selection:res.request,priority:0
@ -6998,13 +7048,13 @@ msgstr "Street2"
#. module: base #. module: base
#: model:ir.actions.act_window,name:base.action_view_base_module_update #: model:ir.actions.act_window,name:base.action_view_base_module_update
msgid "Module Update" msgid "Module Update"
msgstr "" msgstr "Module Update"
#. module: base #. module: base
#: code:addons/base/module/wizard/base_module_upgrade.py:95 #: code:addons/base/module/wizard/base_module_upgrade.py:95
#, python-format #, python-format
msgid "Following modules are not installed or unknown: %s" msgid "Following modules are not installed or unknown: %s"
msgstr "" msgstr "Following modules are not installed or unknown: %s"
#. module: base #. module: base
#: view:ir.cron:0 #: view:ir.cron:0
@ -7033,7 +7083,7 @@ msgstr "Open Window"
#. module: base #. module: base
#: field:ir.actions.act_window,auto_search:0 #: field:ir.actions.act_window,auto_search:0
msgid "Auto Search" msgid "Auto Search"
msgstr "" msgstr "Auto Search"
#. module: base #. module: base
#: field:ir.actions.act_window,filter:0 #: field:ir.actions.act_window,filter:0
@ -7079,25 +7129,25 @@ msgstr "Load"
#: help:res.config.users,name:0 #: help:res.config.users,name:0
#: help:res.users,name:0 #: help:res.users,name:0
msgid "The new user's real name, used for searching and most listings" msgid "The new user's real name, used for searching and most listings"
msgstr "" msgstr "The new user's real name, used for searching and most listings"
#. module: base #. module: base
#: code:addons/osv.py:154 #: code:addons/osv.py:154
#: code:addons/osv.py:156 #: code:addons/osv.py:156
#, python-format #, python-format
msgid "Integrity Error" msgid "Integrity Error"
msgstr "" msgstr "Integrity Error"
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_wizard_screen #: model:ir.model,name:base.model_ir_wizard_screen
msgid "ir.wizard.screen" msgid "ir.wizard.screen"
msgstr "" msgstr "ir.wizard.screen"
#. module: base #. module: base
#: code:addons/base/ir/ir_model.py:223 #: code:addons/base/ir/ir_model.py:223
#, python-format #, python-format
msgid "Size of the field can never be less than 1 !" msgid "Size of the field can never be less than 1 !"
msgstr "" msgstr "Size of the field can never be less than 1 !"
#. module: base #. module: base
#: model:res.country,name:base.so #: model:res.country,name:base.so
@ -7107,7 +7157,7 @@ msgstr "Somalia"
#. module: base #. module: base
#: selection:publisher_warranty.contract,state:0 #: selection:publisher_warranty.contract,state:0
msgid "Terminated" msgid "Terminated"
msgstr "" msgstr "Terminated"
#. module: base #. module: base
#: model:res.partner.category,name:base.res_partner_category_13 #: model:res.partner.category,name:base.res_partner_category_13
@ -7117,7 +7167,7 @@ msgstr "Important customers"
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
msgid "Update Terms" msgid "Update Terms"
msgstr "" msgstr "Update Terms"
#. module: base #. module: base
#: field:partner.sms.send,mobile_to:0 #: field:partner.sms.send,mobile_to:0
@ -7136,7 +7186,7 @@ msgstr "Arguments"
#: code:addons/orm.py:716 #: code:addons/orm.py:716
#, python-format #, python-format
msgid "Database ID doesn't exist: %s : %s" msgid "Database ID doesn't exist: %s : %s"
msgstr "" msgstr "Database ID doesn't exist: %s : %s"
#. module: base #. module: base
#: selection:ir.module.module,license:0 #: selection:ir.module.module,license:0
@ -7152,7 +7202,7 @@ msgstr "GPL Version 3"
#: code:addons/orm.py:836 #: code:addons/orm.py:836
#, python-format #, python-format
msgid "key '%s' not found in selection field '%s'" msgid "key '%s' not found in selection field '%s'"
msgstr "" msgstr "key '%s' not found in selection field '%s'"
#. module: base #. module: base
#: view:partner.wizard.ean.check:0 #: view:partner.wizard.ean.check:0
@ -7163,7 +7213,7 @@ msgstr "Correct EAN13"
#: code:addons/orm.py:2317 #: code:addons/orm.py:2317
#, python-format #, python-format
msgid "The value \"%s\" for the field \"%s\" is not in the selection" msgid "The value \"%s\" for the field \"%s\" is not in the selection"
msgstr "" msgstr "The value \"%s\" for the field \"%s\" is not in the selection"
#. module: base #. module: base
#: field:res.partner,customer:0 #: field:res.partner,customer:0

View File

@ -466,3 +466,38 @@
assert len(all_ids) == 1, "Must match India only, got %r"%all_ids assert len(all_ids) == 1, "Must match India only, got %r"%all_ids
all_ids = self.search(cr, uid, [('name', '=ilike', 'z%')]) all_ids = self.search(cr, uid, [('name', '=ilike', 'z%')])
assert len(all_ids) == 3, "Must match only countries with names starting with Z (currently 3), got %r"%all_ids assert len(all_ids) == 3, "Must match only countries with names starting with Z (currently 3), got %r"%all_ids
-
Use the create_date column on res.country (which doesn't declare it in _columns).
-
!python {model: res.country }: |
ids = self.search(cr, uid, [('create_date', '<', '2001-01-01 12:00:00')])
-
Verify that invalid expressions are refused, even for magic fields
-
!python {model: res.country }: |
try:
self.search(cr, uid, [('does_not_exist', '=', 'foo')])
raise AssertionError('Invalid fields should not be accepted')
except ValueError:
pass
try:
self.search(cr, uid, [('create_date', '>>', 'foo')])
raise AssertionError('Invalid operators should not be accepted')
except ValueError:
pass
import psycopg2
try:
cr._default_log_exceptions = False
cr.execute('SAVEPOINT expression_failure_test')
self.search(cr, uid, [('create_date', '=', "1970-01-01'); --")])
# if the above search gives no error, the operand was not escaped!
cr.execute('RELEASE SAVEPOINT expression_failure_test')
raise AssertionError('Operands should always be SQL escaped')
except psycopg2.DataError:
# Should give: 'DataError: invalid input syntax for type timestamp' or similar
cr.execute('ROLLBACK TO SAVEPOINT expression_failure_test')

View File

@ -126,6 +126,7 @@ import logging
from openerp.tools import flatten, reverse_enumerate from openerp.tools import flatten, reverse_enumerate
import fields import fields
import openerp.modules import openerp.modules
from openerp.osv.orm import MAGIC_COLUMNS
#.apidoc title: Domain Expressions #.apidoc title: Domain Expressions
@ -413,7 +414,7 @@ class expression(object):
# check if the expression is valid # check if the expression is valid
if not is_leaf(e): if not is_leaf(e):
raise ValueError('Bad domain expression: %r, %r is not a valid term.' % (exp, e)) raise ValueError("Invalid term %r in domain expression %r" % (e, exp))
# normalize the leaf's operator # normalize the leaf's operator
e = normalize_leaf(*e) e = normalize_leaf(*e)
@ -421,41 +422,47 @@ class expression(object):
left, operator, right = e left, operator, right = e
working_table = table # The table containing the field (the name provided in the left operand) working_table = table # The table containing the field (the name provided in the left operand)
fargs = left.split('.', 1) field_path = left.split('.', 1)
# If the field is _inherits'd, search for the working_table, # If the field is _inherits'd, search for the working_table,
# and extract the field. # and extract the field.
if fargs[0] in table._inherit_fields: if field_path[0] in table._inherit_fields:
while True: while True:
field = working_table._columns.get(fargs[0]) field = working_table._columns.get(field_path[0])
if field: if field:
self.__field_tables[i] = working_table self.__field_tables[i] = working_table
break break
next_table = working_table.pool.get(working_table._inherit_fields[fargs[0]][0]) next_table = working_table.pool.get(working_table._inherit_fields[field_path[0]][0])
if next_table not in self.__all_tables: if next_table not in self.__all_tables:
self.__joins.append('%s."%s"=%s."%s"' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name])) self.__joins.append('%s."%s"=%s."%s"' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name]))
self.__all_tables.add(next_table) self.__all_tables.add(next_table)
working_table = next_table working_table = next_table
# Or (try to) directly extract the field. # Or (try to) directly extract the field.
else: else:
field = working_table._columns.get(fargs[0]) field = working_table._columns.get(field_path[0])
if not field: if not field:
if left == 'id' and operator == 'child_of': if left == 'id' and operator == 'child_of':
ids2 = to_ids(right, table) ids2 = to_ids(right, table)
dom = child_of_domain(left, ids2, working_table) dom = child_of_domain(left, ids2, working_table)
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:] self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
else:
# field could not be found in model columns, it's probably invalid, unless
# it's one of the _log_access special fields
# TODO: make these fields explicitly available in self.columns instead!
if field_path[0] not in MAGIC_COLUMNS:
raise ValueError("Invalid field %r in domain expression %r" % (left, exp))
continue continue
field_obj = table.pool.get(field._obj) field_obj = table.pool.get(field._obj)
if len(fargs) > 1: if len(field_path) > 1:
if field._type == 'many2one': if field._type == 'many2one':
right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context) right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context)
self.__exp[i] = (fargs[0], 'in', right) self.__exp[i] = (field_path[0], 'in', right)
# Making search easier when there is a left operand as field.o2m or field.m2m # Making search easier when there is a left operand as field.o2m or field.m2m
if field._type in ['many2many', 'one2many']: if field._type in ['many2many', 'one2many']:
right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context) right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context)
right1 = table.search(cr, uid, [(fargs[0], 'in', right)], context=context) right1 = table.search(cr, uid, [(field_path[0], 'in', right)], context=context)
self.__exp[i] = ('id', 'in', right1) self.__exp[i] = ('id', 'in', right1)
if not isinstance(field, fields.property): if not isinstance(field, fields.property):
@ -657,6 +664,12 @@ class expression(object):
def __leaf_to_sql(self, leaf, table): def __leaf_to_sql(self, leaf, table):
left, operator, right = leaf left, operator, right = leaf
# final sanity checks - should never fail
assert operator in (TERM_OPERATORS + ('inselect',)), \
"Invalid operator %r in domain term %r" % (operator, leaf)
assert leaf in (TRUE_LEAF, FALSE_LEAF) or left in table._all_columns \
or left in MAGIC_COLUMNS, "Invalid field %r in domain term %r" % (left, leaf)
if leaf == TRUE_LEAF: if leaf == TRUE_LEAF:
query = 'TRUE' query = 'TRUE'
params = [] params = []
@ -704,8 +717,8 @@ class expression(object):
query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left) query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
elif check_nulls and operator == 'not in': elif check_nulls and operator == 'not in':
query = '(%s AND %s."%s" IS NOT NULL)' % (query, table._table, left) # needed only for TRUE. query = '(%s AND %s."%s" IS NOT NULL)' % (query, table._table, left) # needed only for TRUE.
else: # Must not happen. else: # Must not happen
pass raise ValueError("Invalid domain term %r" % (leaf,))
elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '='): elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '='):
query = '(%s."%s" IS NULL or %s."%s" = false )' % (table._table, left, table._table, left) query = '(%s."%s" IS NULL or %s."%s" = false )' % (table._table, left, table._table, left)
@ -725,15 +738,12 @@ class expression(object):
elif (operator == '=?'): elif (operator == '=?'):
if (right is False or right is None): if (right is False or right is None):
# '=?' is a short-circuit that makes the term TRUE if right is None or False
query = 'TRUE' query = 'TRUE'
params = [] params = []
elif left in table._columns:
format = table._columns[left]._symbol_set[0]
query = '(%s."%s" = %s)' % (table._table, left, format)
params = table._columns[left]._symbol_set[1](right)
else: else:
query = "(%s.\"%s\" = '%%s')" % (table._table, left) # '=?' behaves like '=' in other cases
params = right query, params = self.__leaf_to_sql((left, '=', right), table)
elif left == 'id': elif left == 'id':
query = '%s.id %s %%s' % (table._table, operator) query = '%s.id %s %%s' % (table._table, operator)
@ -749,11 +759,11 @@ class expression(object):
query = '(unaccent(%s."%s") %s unaccent(%s))' % (table._table, left, sql_operator, format) query = '(unaccent(%s."%s") %s unaccent(%s))' % (table._table, left, sql_operator, format)
else: else:
query = '(%s."%s" %s %s)' % (table._table, left, sql_operator, format) query = '(%s."%s" %s %s)' % (table._table, left, sql_operator, format)
else: elif left in MAGIC_COLUMNS:
if self.has_unaccent and sql_operator in ('ilike', 'not ilike'): query = "(%s.\"%s\" %s %%s)" % (table._table, left, sql_operator)
query = "(unaccent(%s.\"%s\") %s unaccent('%s'))" % (table._table, left, sql_operator, right) params = right
else: else: # Must not happen
query = "(%s.\"%s\" %s '%s')" % (table._table, left, sql_operator, right) raise ValueError("Invalid field %r in domain term %r" % (left, leaf))
add_null = False add_null = False
if need_wildcard: if need_wildcard:

View File

@ -55,7 +55,6 @@ import types
import warnings import warnings
from lxml import etree from lxml import etree
import expression
import fields import fields
import openerp import openerp
import openerp.netsvc as netsvc import openerp.netsvc as netsvc
@ -586,6 +585,17 @@ class MetaModel(type):
self.module_to_models.setdefault(self._module, []).append(self) self.module_to_models.setdefault(self._module, []).append(self)
# Definition of log access columns, automatically added to models if
# self._log_access is True
LOG_ACCESS_COLUMNS = {
'create_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
'create_date': 'TIMESTAMP',
'write_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
'write_date': 'TIMESTAMP'
}
# special columns automatically created by the ORM
MAGIC_COLUMNS = ['id'] + LOG_ACCESS_COLUMNS.keys()
class BaseModel(object): class BaseModel(object):
""" Base class for OpenERP models. """ Base class for OpenERP models.
@ -2492,7 +2502,7 @@ class BaseModel(object):
# iterate on the database columns to drop the NOT NULL constraints # iterate on the database columns to drop the NOT NULL constraints
# of fields which were required but have been removed (or will be added by another module) # of fields which were required but have been removed (or will be added by another module)
columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)] columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)]
columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns columns += MAGIC_COLUMNS
cr.execute("SELECT a.attname, a.attnotnull" cr.execute("SELECT a.attname, a.attnotnull"
" FROM pg_class c, pg_attribute a" " FROM pg_class c, pg_attribute a"
" WHERE c.relname=%s" " WHERE c.relname=%s"
@ -2559,7 +2569,7 @@ class BaseModel(object):
column_data = self._select_column_data(cr) column_data = self._select_column_data(cr)
for k, f in self._columns.iteritems(): for k, f in self._columns.iteritems():
if k in ('id', 'write_uid', 'write_date', 'create_uid', 'create_date'): if k in MAGIC_COLUMNS:
continue continue
# Don't update custom (also called manual) fields # Don't update custom (also called manual) fields
if f.manual and not update_custom_fields: if f.manual and not update_custom_fields:
@ -2861,23 +2871,17 @@ class BaseModel(object):
def _add_log_columns(self, cr): def _add_log_columns(self, cr):
logs = { for field, field_def in LOG_ACCESS_COLUMNS.iteritems():
'create_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
'create_date': 'TIMESTAMP',
'write_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
'write_date': 'TIMESTAMP'
}
for k in logs:
cr.execute(""" cr.execute("""
SELECT c.relname SELECT c.relname
FROM pg_class c, pg_attribute a FROM pg_class c, pg_attribute a
WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid
""", (self._table, k)) """, (self._table, field))
if not cr.rowcount: if not cr.rowcount:
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k])) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, field, field_def))
cr.commit() cr.commit()
self.__schema.debug("Table '%s': added column '%s' with definition=%s", self.__schema.debug("Table '%s': added column '%s' with definition=%s",
self._table, k, logs[k]) self._table, field, field_def)
def _select_column_data(self, cr): def _select_column_data(self, cr):
@ -4142,7 +4146,6 @@ class BaseModel(object):
domain = [('active', '=', 1)] domain = [('active', '=', 1)]
if domain: if domain:
import expression
e = expression.expression(cr, user, domain, self, context) e = expression.expression(cr, user, domain, self, context)
tables = e.get_tables() tables = e.get_tables()
where_clause, where_params = e.to_sql() where_clause, where_params = e.to_sql()
@ -4368,7 +4371,7 @@ class BaseModel(object):
for f in fields: for f in fields:
ftype = fields[f]['type'] ftype = fields[f]['type']
if self._log_access and f in ('create_date', 'create_uid', 'write_date', 'write_uid'): if self._log_access and f in LOG_ACCESS_COLUMNS:
del data[f] del data[f]
if f in default: if f in default:
@ -4630,6 +4633,9 @@ class BaseModel(object):
return True return True
# keep this import here, at top it will cause dependency cycle errors
import expression
class Model(BaseModel): class Model(BaseModel):
"""Main super-class for regular database-persisted OpenERP models. """Main super-class for regular database-persisted OpenERP models.

View File

@ -183,6 +183,8 @@ class Cursor(object):
self.__caller = False self.__caller = False
self.__closer = False self.__closer = False
self._default_log_exceptions = True
def __del__(self): def __del__(self):
if not self.__closed: if not self.__closed:
# Oops. 'self' has not been closed explicitly. # Oops. 'self' has not been closed explicitly.
@ -199,7 +201,7 @@ class Cursor(object):
self._close(True) self._close(True)
@check @check
def execute(self, query, params=None, log_exceptions=True): def execute(self, query, params=None, log_exceptions=None):
if '%d' in query or '%f' in query: if '%d' in query or '%f' in query:
self.__logger.warn(query) self.__logger.warn(query)
self.__logger.warn("SQL queries cannot contain %d or %f anymore. " self.__logger.warn("SQL queries cannot contain %d or %f anymore. "
@ -212,11 +214,11 @@ class Cursor(object):
params = params or None params = params or None
res = self._obj.execute(query, params) res = self._obj.execute(query, params)
except psycopg2.ProgrammingError, pe: except psycopg2.ProgrammingError, pe:
if log_exceptions: if self._default_log_exceptions or log_exceptions:
self.__logger.error("Programming error: %s, in query %s", pe, query) self.__logger.error("Programming error: %s, in query %s", pe, query)
raise raise
except Exception: except Exception:
if log_exceptions: if self._default_log_exceptions or log_exceptions:
self.__logger.exception("bad query: %s", self._obj.query or query) self.__logger.exception("bad query: %s", self._obj.query or query)
raise raise