diff --git a/bin/addons/base/i18n/fr.po b/bin/addons/base/i18n/fr.po index 3c360967a9b..d047c631b97 100644 --- a/bin/addons/base/i18n/fr.po +++ b/bin/addons/base/i18n/fr.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 07:50+0000\n" +"PO-Revision-Date: 2010-09-03 07:19+0000\n" "Last-Translator: Quentin THEURET \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n" +"X-Launchpad-Export-Date: 2010-09-04 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/hr.po b/bin/addons/base/i18n/hr.po index 4dbb8a39452..f2446ea8fc0 100644 --- a/bin/addons/base/i18n/hr.po +++ b/bin/addons/base/i18n/hr.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 06:44+0000\n" +"PO-Revision-Date: 2010-09-04 08:13+0000\n" "Last-Translator: nafterburner \n" "Language-Team: openerp-translators\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Language: hr\n" diff --git a/bin/addons/base/i18n/it.po b/bin/addons/base/i18n/it.po index a194927953f..eed23b6ee92 100644 --- a/bin/addons/base/i18n/it.po +++ b/bin/addons/base/i18n/it.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 06:41+0000\n" +"PO-Revision-Date: 2010-09-04 08:20+0000\n" "Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/ja.po b/bin/addons/base/i18n/ja.po index 71e5a32dbc5..aa567d7849c 100644 --- a/bin/addons/base/i18n/ja.po +++ b/bin/addons/base/i18n/ja.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 06:33+0000\n" +"PO-Revision-Date: 2010-09-04 08:10+0000\n" "Last-Translator: Harry (Open ERP) \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:43+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/mn.po b/bin/addons/base/i18n/mn.po index 6748220b4a6..57900b436c8 100644 --- a/bin/addons/base/i18n/mn.po +++ b/bin/addons/base/i18n/mn.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 10:24+0000\n" +"PO-Revision-Date: 2010-09-04 08:22+0000\n" "Last-Translator: ub121 \n" "Language-Team: Mongolian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/pt_BR.po b/bin/addons/base/i18n/pt_BR.po index eabd96a5066..e016d315dab 100644 --- a/bin/addons/base/i18n/pt_BR.po +++ b/bin/addons/base/i18n/pt_BR.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: pt_BR\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 06:28+0000\n" +"PO-Revision-Date: 2010-09-04 08:17+0000\n" "Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:45+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/sv.po b/bin/addons/base/i18n/sv.po index d9877949a9c..fcfcb8b9dc6 100644 --- a/bin/addons/base/i18n/sv.po +++ b/bin/addons/base/i18n/sv.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 06:31+0000\n" +"PO-Revision-Date: 2010-09-04 08:02+0000\n" "Last-Translator: Anders Wallenquist \n" "Language-Team: <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:45+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/uk.po b/bin/addons/base/i18n/uk.po index 43859e4c63f..863baa1730b 100644 --- a/bin/addons/base/i18n/uk.po +++ b/bin/addons/base/i18n/uk.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-09-02 06:38+0000\n" +"PO-Revision-Date: 2010-09-04 08:16+0000\n" "Last-Translator: Fabien (Open ERP) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-09-03 03:45+0000\n" +"X-Launchpad-Export-Date: 2010-09-05 04:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/res/res_currency_view.xml b/bin/addons/base/res/res_currency_view.xml index a26d22346ce..e469e520353 100644 --- a/bin/addons/base/res/res_currency_view.xml +++ b/bin/addons/base/res/res_currency_view.xml @@ -29,10 +29,10 @@ - + - + @@ -44,7 +44,7 @@ - +
diff --git a/bin/netsvc.py b/bin/netsvc.py index 3c3a727cb71..11f7ca5b695 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -165,21 +165,24 @@ LEVEL_COLOR_MAPPING = { logging.CRITICAL: (WHITE, RED), } -class ColoredFormatter(logging.Formatter): +class DBFormatter(logging.Formatter): + def format(self, record): + record.dbname = getattr(threading.current_thread(), 'dbname', '?') + return logging.Formatter.format(self, record) + +class ColoredFormatter(DBFormatter): def format(self, record): fg_color, bg_color = LEVEL_COLOR_MAPPING[record.levelno] record.levelname = COLOR_PATTERN % (30 + fg_color, 40 + bg_color, record.levelname) - return logging.Formatter.format(self, record) - + return DBFormatter.format(self, record) def init_logger(): import os from tools.translate import resetlocale resetlocale() - logger = logging.getLogger() # create a format for log messages and dates - format = '[%(asctime)s] %(levelname)s:%(name)s:%(message)s' + format = '[%(asctime)s][%(dbname)s] %(levelname)s:%(name)s:%(message)s' if tools.config['syslog']: # SysLog Handler @@ -188,7 +191,7 @@ def init_logger(): else: handler = logging.handlers.SysLogHandler('/dev/log') format = '%s %s' % (release.description, release.version) \ - + ':%(levelname)s:%(name)s:%(message)s' + + ':%(dbname)s:%(levelname)s:%(name)s:%(message)s' elif tools.config['logfile']: # LogFile Handler @@ -213,10 +216,11 @@ def init_logger(): if isinstance(handler, logging.StreamHandler) and os.isatty(handler.stream.fileno()): formatter = ColoredFormatter(format) else: - formatter = logging.Formatter(format) + formatter = DBFormatter(format) handler.setFormatter(formatter) # add the handler to the root logger + logger = logging.getLogger() logger.addHandler(handler) logger.setLevel(int(tools.config['log_level'] or '0')) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 8df4f9e1fc9..6f73f821f8e 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -44,7 +44,6 @@ import logging import operator import pickle import re -import string import time import traceback import types @@ -200,10 +199,10 @@ class browse_record(object): field_values = self._table.read(self._cr, self._uid, ids, field_names, context=self._context, load="_classic_write") if self._fields_process: lang = self._context.get('lang', 'en_US') or 'en_US' - lang_obj_ids = self.pool.get('res.lang').search(self._cr, self._uid,[('code','=',lang)]) + lang_obj_ids = self.pool.get('res.lang').search(self._cr, self._uid, [('code', '=', lang)]) if not lang_obj_ids: raise Exception(_('Language with code "%s" is not defined in your system !\nDefine it through the Administration menu.') % (lang,)) - lang_obj = self.pool.get('res.lang').browse(self._cr, self._uid,lang_obj_ids[0]) + lang_obj = self.pool.get('res.lang').browse(self._cr, self._uid, lang_obj_ids[0]) for field_name, field_column in fields_to_fetch: if field_column._type in self._fields_process: @@ -215,7 +214,7 @@ class browse_record(object): if not field_values: # Where did those ids come from? Perhaps old entries in ir_model_dat? self.__logger.warn("No field_values found for ids %s in %s", ids, self) - raise KeyError('Field %s not found in %s'%(name,self)) + raise KeyError('Field %s not found in %s'%(name, self)) # create browse records for 'remote' objects for result_line in field_values: new_data = {} @@ -223,7 +222,7 @@ class browse_record(object): if field_column._type in ('many2one', 'one2one'): if result_line[field_name]: obj = self._table.pool.get(field_column._obj) - if isinstance(result_line[field_name], (list,tuple)): + if isinstance(result_line[field_name], (list, tuple)): value = result_line[field_name][0] else: value = result_line[field_name] @@ -347,7 +346,7 @@ def get_pg_type(f): f_type = ('int4', 'INTEGER') else: f_type = ('varchar', 'VARCHAR(%d)' % f_size) - elif isinstance(f, fields.function) and eval('fields.'+(f._type),globals()) in type_dict: + elif isinstance(f, fields.function) and eval('fields.'+(f._type), globals()) in type_dict: t = eval('fields.'+(f._type), globals()) f_type = (type_dict[t], type_dict[t]) elif isinstance(f, fields.function) and f._type == 'float': @@ -394,7 +393,7 @@ class orm_template(object): context=context ) - def view_init(self, cr , uid , fields_list, context=None): + def view_init(self, cr, uid, fields_list, context=None): """Override this method to do specific things when a view on the object is opened.""" pass @@ -410,8 +409,8 @@ class orm_template(object): else: model_id = cr.fetchone()[0] if 'module' in context: - name_id = 'model_'+self._name.replace('.','_') - cr.execute('select * from ir_model_data where name=%s and res_id=%s and module=%s', (name_id,model_id,context['module'])) + name_id = 'model_'+self._name.replace('.', '_') + cr.execute('select * from ir_model_data where name=%s and res_id=%s and module=%s', (name_id, model_id, context['module'])) if not cr.rowcount: cr.execute("INSERT INTO ir_model_data (name,date_init,date_update,module,model,res_id) VALUES (%s, now(), now(), %s, %s, %s)", \ (name_id, context['module'], 'ir.model', model_id) @@ -434,15 +433,15 @@ class orm_template(object): 'relation': f._obj or '', 'view_load': (f.view_load and 1) or 0, 'select_level': tools.ustr(f.select or 0), - 'readonly':(f.readonly and 1) or 0, - 'required':(f.required and 1) or 0, - 'selectable' : (f.selectable and 1) or 0, - 'relation_field': (f._type=='one2many' and isinstance(f,fields.one2many)) and f._fields_id or '', + 'readonly': (f.readonly and 1) or 0, + 'required': (f.required and 1) or 0, + 'selectable': (f.selectable and 1) or 0, + 'relation_field': (f._type=='one2many' and isinstance(f, fields.one2many)) and f._fields_id or '', } # When its a custom field,it does not contain f.select - if context.get('field_state','base') == 'manual': - if context.get('field_name','') == k: - vals['select_level'] = context.get('select','0') + if context.get('field_state', 'base') == 'manual': + if context.get('field_name', '') == k: + vals['select_level'] = context.get('select', '0') #setting value to let the problem NOT occur next time else: vals['select_level'] = cols[k]['select_level'] @@ -459,7 +458,7 @@ class orm_template(object): )""", ( id, vals['model_id'], vals['model'], vals['name'], vals['field_description'], vals['ttype'], vals['relation'], bool(vals['view_load']), 'base', - vals['select_level'],vals['relation_field'] + vals['select_level'], vals['relation_field'] )) if 'module' in context: name1 = 'field_' + self._table + '_' + k @@ -481,7 +480,7 @@ class orm_template(object): model=%s AND name=%s""", ( vals['model_id'], vals['field_description'], vals['ttype'], vals['relation'], bool(vals['view_load']), - vals['select_level'], bool(vals['readonly']),bool(vals['required']),bool(vals['selectable']),vals['relation_field'],vals['model'], vals['name'] + vals['select_level'], bool(vals['readonly']), bool(vals['required']), bool(vals['selectable']), vals['relation_field'], vals['model'], vals['name'] )) continue cr.commit() @@ -495,8 +494,8 @@ class orm_template(object): msg = "The class %s has to have a _name attribute" % name logger = netsvc.Logger() - logger.notifyChannel('orm', netsvc.LOG_ERROR, msg ) - raise except_orm('ValueError', msg ) + logger.notifyChannel('orm', netsvc.LOG_ERROR, msg) + raise except_orm('ValueError', msg) if not self._description: self._description = self._name @@ -563,11 +562,11 @@ class orm_template(object): r = r['id'] elif f[i] == 'id': model_data = self.pool.get('ir.model.data') - data_ids = model_data.search(cr, uid, [('model','=',r._table_name),('res_id','=',r['id'])]) + data_ids = model_data.search(cr, uid, [('model', '=', r._table_name), ('res_id', '=', r['id'])]) if len(data_ids): - d = model_data.read(cr, uid, data_ids, ['name','module'])[0] + d = model_data.read(cr, uid, data_ids, ['name', 'module'])[0] if d['module']: - r = '%s.%s'%(d['module'],d['name']) + r = '%s.%s' % (d['module'], d['name']) else: r = d['name'] else: @@ -575,7 +574,7 @@ class orm_template(object): else: r = r[f[i]] # To display external name of selection field when its exported - if not context.get('import_comp',False):# Allow external name only if its not import compatible + if not context.get('import_comp', False):# Allow external name only if its not import compatible cols = False if f[i] in self._columns.keys(): cols = self._columns[f[i]] @@ -609,7 +608,7 @@ class orm_template(object): data[fpos2] = lines2[0][fpos2] if not data[fpos]: dt = '' - for rr in r : + for rr in r: if isinstance(rr.name, browse_record): rr = rr.name rr_name = self.pool.get(rr._table_name).name_get(cr, uid, [rr.id], context=context) @@ -646,31 +645,31 @@ class orm_template(object): """ if context is None: context = {} - imp_comp = context.get('import_comp',False) + imp_comp = context.get('import_comp', False) cols = self._columns.copy() for f in self._inherit_fields: cols.update({f: self._inherit_fields[f][2]}) fields_to_export = map(lambda x: x.split('/'), fields_to_export) - fields_export = fields_to_export+[] + fields_export = fields_to_export + [] warning = '' warning_fields = [] for field in fields_export: - if imp_comp and len(field)>1: - warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field))) - elif len (field) <=1: - if imp_comp and cols.get(field and field[0],False): + if imp_comp and len(field) > 1: + warning_fields.append('/'.join(map(lambda x: x in cols and cols[x].string or x,field))) + elif len (field) <= 1: + if imp_comp and cols.get(field and field[0], False): if ((isinstance(cols[field[0]], fields.function) and not cols[field[0]].store) \ or isinstance(cols[field[0]], fields.related)\ or isinstance(cols[field[0]], fields.one2many)): - warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field))) + warning_fields.append('/'.join(map(lambda x: x in cols and cols[x].string or x,field))) datas = [] if imp_comp and len(warning_fields): - warning = 'Following columns cannot be exported since you select to be import compatible.\n%s' %('\n'.join(warning_fields)) + warning = 'Following columns cannot be exported since you select to be import compatible.\n%s' % ('\n'.join(warning_fields)) cr.rollback() - return {'warning' : warning} + return {'warning': warning} for row in self.browse(cr, uid, ids, context): datas += self.__export_row(cr, uid, row, fields_to_export, context) - return {'datas':datas} + return {'datas': datas} def import_data(self, cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None): """ @@ -699,7 +698,7 @@ class orm_template(object): def _check_db_id(self, model_name, db_id): obj_model = self.pool.get(model_name) - ids = obj_model.search(cr, uid, [('id','=',int(db_id))]) + ids = obj_model.search(cr, uid, [('id', '=', int(db_id))]) if not len(ids): raise Exception(_("Database ID doesn't exist: %s : %s") %(model_name, db_id)) return True @@ -730,28 +729,28 @@ class orm_template(object): if (len(field)==len(prefix)+1) and field[len(prefix)].endswith(':db_id'): # Database ID - res = False - if line[i]: - field_name = field[0].split(':')[0] - model_rel = fields_def[field_name]['relation'] + res = False + if line[i]: + field_name = field[0].split(':')[0] + model_rel = fields_def[field_name]['relation'] - if fields_def[field[len(prefix)][:-6]]['type']=='many2many': - res_id = [] - for db_id in line[i].split(config.get('csv_internal_sep')): - try: - _check_db_id(self, model_rel, db_id) - res_id.append(db_id) - except Exception,e: - warning += [tools.exception_to_unicode(e)] - logger.notifyChannel("import", netsvc.LOG_ERROR, - tools.exception_to_unicode(e)) - if len(res_id): - res = [(6, 0, res_id)] + if fields_def[field[len(prefix)][:-6]]['type'] == 'many2many': + res_id = [] + for db_id in line[i].split(config.get('csv_internal_sep')): + try: + _check_db_id(self, model_rel, db_id) + res_id.append(db_id) + except Exception, e: + warning += [tools.exception_to_unicode(e)] + logger.notifyChannel("import", netsvc.LOG_ERROR, + tools.exception_to_unicode(e)) + if len(res_id): + res = [(6, 0, res_id)] else: try: _check_db_id(self, model_rel, line[i]) res = line[i] - except Exception,e: + except Exception, e: warning += [tools.exception_to_unicode(e)] logger.notifyChannel("import", netsvc.LOG_ERROR, tools.exception_to_unicode(e)) @@ -761,7 +760,7 @@ class orm_template(object): if (len(field)==len(prefix)+1) and field[len(prefix)].endswith(':id'): res_id = False if line[i]: - if fields_def[field[len(prefix)][:-3]]['type']=='many2many': + if fields_def[field[len(prefix)][:-3]]['type'] == 'many2many': res_id = [] for word in line[i].split(config.get('csv_internal_sep')): if '.' in word: @@ -792,7 +791,7 @@ class orm_template(object): if (len(field) == len(prefix)+1) and \ len(field[len(prefix)].split(':lang=')) == 2: f, lang = field[len(prefix)].split(':lang=') - translate.setdefault(lang, {})[f]=line[i] or False + translate.setdefault(lang, {})[f] = line[i] or False continue if (len(field) == len(prefix)+1) and \ (prefix == field[0:len(prefix)]): @@ -800,22 +799,22 @@ class orm_template(object): # XML ID db_id = False is_xml_id = data_id = line[i] - d = data_id.split('.') - module = len(d)>1 and d[0] or '' - name = len(d)>1 and d[1] or d[0] - data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('name','=',name)]) + d = data_id.split('.') + module = len(d) > 1 and d[0] or '' + name = len(d) > 1 and d[1] or d[0] + data_ids = ir_model_data_obj.search(cr, uid, [('module', '=', module), ('model', '=', model_name), ('name', '=', name)]) if len(data_ids): d = ir_model_data_obj.read(cr, uid, data_ids, ['res_id'])[0] db_id = d['res_id'] if is_db_id and not db_id: - data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('res_id','=',is_db_id)]) - if not len(data_ids): - ir_model_data_obj.create(cr, uid, {'module':module, 'model':model_name, 'name':name, 'res_id':is_db_id}) - db_id = is_db_id + data_ids = ir_model_data_obj.search(cr, uid, [('module', '=', module), ('model', '=', model_name), ('res_id', '=', is_db_id)]) + if not len(data_ids): + ir_model_data_obj.create(cr, uid, {'module': module, 'model': model_name, 'name': name, 'res_id': is_db_id}) + db_id = is_db_id if is_db_id and int(db_id) != int(is_db_id): - warning += [_("Id is not the same than existing one: %s")%(is_db_id)] + warning += [_("Id is not the same than existing one: %s") % (is_db_id)] logger.notifyChannel("import", netsvc.LOG_ERROR, - _("Id is not the same than existing one: %s")%(is_db_id)) + _("Id is not the same than existing one: %s") % (is_db_id)) continue if field[len(prefix)] == "db_id": @@ -823,25 +822,25 @@ class orm_template(object): try: _check_db_id(self, model_name, line[i]) data_res_id = is_db_id = int(line[i]) - except Exception,e: + except Exception, e: warning += [tools.exception_to_unicode(e)] logger.notifyChannel("import", netsvc.LOG_ERROR, tools.exception_to_unicode(e)) continue - data_ids = ir_model_data_obj.search(cr, uid, [('model','=',model_name),('res_id','=',line[i])]) + data_ids = ir_model_data_obj.search(cr, uid, [('model', '=', model_name), ('res_id', '=', line[i])]) if len(data_ids): - d = ir_model_data_obj.read(cr, uid, data_ids, ['name','module'])[0] + d = ir_model_data_obj.read(cr, uid, data_ids, ['name', 'module'])[0] data_id = d['name'] if d['module']: - data_id = '%s.%s'%(d['module'],d['name']) + data_id = '%s.%s' % (d['module'], d['name']) else: data_id = d['name'] if is_xml_id and not data_id: data_id = is_xml_id - if is_xml_id and is_xml_id!=data_id: - warning += [_("Id is not the same than existing one: %s")%(line[i])] + if is_xml_id and is_xml_id != data_id: + warning += [_("Id is not the same than existing one: %s") % (line[i])] logger.notifyChannel("import", netsvc.LOG_ERROR, - _("Id is not the same than existing one: %s")%(line[i])) + _("Id is not the same than existing one: %s") % (line[i])) continue if fields_def[field[len(prefix)]]['type'] == 'integer': @@ -859,7 +858,7 @@ class orm_template(object): sel = fields_def[field[len(prefix)]]['selection'](self, cr, uid, context) for key, val in sel: - if line[i] in [tools.ustr(key),tools.ustr(val)]: #Acepting key or value for selection field + if line[i] in [tools.ustr(key), tools.ustr(val)]: #Acepting key or value for selection field res = key break if line[i] and not res: @@ -867,9 +866,9 @@ class orm_template(object): _("key '%s' not found in selection field '%s'") % \ (line[i], field[len(prefix)])) - warning += [_("Key/value '%s' not found in selection field '%s'")%(line[i],field[len(prefix)])] + warning += [_("Key/value '%s' not found in selection field '%s'") % (line[i], field[len(prefix)])] - elif fields_def[field[len(prefix)]]['type']=='many2one': + elif fields_def[field[len(prefix)]]['type'] == 'many2one': res = False if line[i]: relation = fields_def[field[len(prefix)]]['relation'] @@ -877,10 +876,10 @@ class orm_template(object): line[i], [], operator='=', context=context) res = (res2 and res2[0][0]) or False if not res: - warning += [_("Relation not found: %s on '%s'")%(line[i],relation)] + warning += [_("Relation not found: %s on '%s'") % (line[i], relation)] logger.notifyChannel("import", netsvc.LOG_WARNING, - _("Relation not found: %s on '%s'")%(line[i],relation)) - elif fields_def[field[len(prefix)]]['type']=='many2many': + _("Relation not found: %s on '%s'") % (line[i], relation)) + elif fields_def[field[len(prefix)]]['type'] == 'many2many': res = [] if line[i]: relation = fields_def[field[len(prefix)]]['relation'] @@ -889,10 +888,10 @@ class orm_template(object): uid, word, [], operator='=', context=context) res3 = (res2 and res2[0][0]) or False if not res3: - warning += [_("Relation not found: %s on '%s'")%(line[i],relation)] + warning += [_("Relation not found: %s on '%s'") % (line[i], relation)] logger.notifyChannel("import", netsvc.LOG_WARNING, - _("Relation not found: %s on '%s'")%(line[i],relation)) + _("Relation not found: %s on '%s'") % (line[i], relation)) else: res.append(res3) if len(res): @@ -919,7 +918,7 @@ class orm_template(object): row[field] = (reduce(lambda x, y: x or y, newrow.values()) and \ [(0, 0, newrow)]) or [] i = max2 - while (position+i)\n' ' \n' @@ -1556,7 +1555,7 @@ class orm_template(object): # End: _find(node, node2) doc_dest = etree.fromstring(encode(inherit)) - toparse = [ doc_dest ] + toparse = [doc_dest] while len(toparse): node2 = toparse.pop(0) @@ -1699,7 +1698,7 @@ class orm_template(object): else: xml = '' # what happens here, graph case? - raise except_orm(_('Invalid Architecture!'),_("There is no view of type '%s' defined for the structure!") % view_type) + raise except_orm(_('Invalid Architecture!'), _("There is no view of type '%s' defined for the structure!") % view_type) result['arch'] = etree.fromstring(encode(xml)) result['name'] = 'default' result['field_parent'] = False @@ -1710,13 +1709,13 @@ class orm_template(object): result['fields'] = xfields if submenu: - if context and context.get('active_id',False): + if context and context.get('active_id', False): data_menu = self.pool.get('ir.ui.menu').browse(cr, user, context['active_id'], context).action if data_menu: act_id = data_menu.id if act_id: data_action = self.pool.get('ir.actions.act_window').browse(cr, user, [act_id], context)[0] - result['submenu'] = getattr(data_action,'menus', False) + result['submenu'] = getattr(data_action, 'menus', False) if toolbar: def clean(x): x = x[2] @@ -1743,7 +1742,7 @@ class orm_template(object): resprint = filter(lambda x: not x.get('multi', False), resprint) resrelate = map(lambda x: x[2], resrelate) - for x in resprint+resaction+resrelate: + for x in resprint + resaction + resrelate: x['string'] = x['name'] result['toolbar'] = { @@ -1751,10 +1750,10 @@ class orm_template(object): 'action': resaction, 'relate': resrelate } - if result['type']=='form' and result['arch'].count("default_focus")>1: - msg = "Form View contain more than one default_focus attribute" - netsvc.Logger().notifyChannel('orm', netsvc.LOG_ERROR, msg) - raise except_orm('View Error !',msg) + if result['type'] == 'form' and result['arch'].count("default_focus") > 1: + msg = "Form View contain more than one default_focus attribute" + netsvc.Logger().notifyChannel('orm', netsvc.LOG_ERROR, msg) + raise except_orm('View Error !', msg) return result _view_look_dom_arch = __view_look_dom_arch @@ -1946,8 +1945,8 @@ class orm_template(object): for dv in defaults: # FIXME: also handle inherited m2m if dv in self._columns and self._columns[dv]._type == 'many2many' \ - and defaults[dv] and isinstance(defaults[dv][0], (int, long)): - defaults[dv] = [(6, 0, defaults[dv])] + and defaults[dv] and isinstance(defaults[dv][0], (int, long)): + defaults[dv] = [(6, 0, defaults[dv])] defaults.update(values) values = defaults return values @@ -1981,7 +1980,7 @@ class orm_memory(orm_template): if self.datas[id]['internal.date_access'] < max: tounlink.append(id) self.unlink(cr, 1, tounlink) - if len(self.datas)>self._max_count: + if len(self.datas) > self._max_count: sorted = map(lambda x: (x[1]['internal.date_access'], x[0]), self.datas.items()) sorted.sort() ids = map(lambda x: x[1], sorted[:len(self.datas)-self._max_count]) @@ -2075,7 +2074,7 @@ class orm_memory(orm_template): if not context: context = {} args = args[:] - res=[] + res = [] # if the object has a field named 'active', filter out all inactive # records unless they were explicitely asked for if 'active' in self._columns and (active_test and context.get('active_test', True)): @@ -2106,16 +2105,16 @@ class orm_memory(orm_template): args.insert(0, ('internal.create_uid', '=', user)) result = self._where_calc(cr, user, args, context=context) - if result==[]: + if result == []: return self.datas.keys() - res=[] - counter=0 + res = [] + counter = 0 #Find the value of dict - f=False + f = False if result: for id, data in self.datas.items(): - counter=counter+1 + counter = counter + 1 data['id'] = id if limit and (counter > int(limit)): break @@ -2123,7 +2122,7 @@ class orm_memory(orm_template): for arg in result: if arg[1] == '=': val = eval('data[arg[0]]'+'==' +' arg[2]', locals()) - elif arg[1] in ['<','>','in','not in','<=','>=','<>']: + elif arg[1] in ['<', '>', 'in', 'not in', '<=', '>=', '<>']: val = eval('data[arg[0]]'+arg[1] +' arg[2]', locals()) elif arg[1] in ['ilike']: val = (str(data[arg[0]]).find(str(arg[2]))!=-1) @@ -2169,7 +2168,7 @@ class orm_memory(orm_template): class orm(orm_template): _sql_constraints = [] _table = None - _protected = ['read','write','create','default_get','perm_read','unlink','fields_get','fields_view_get','search','name_get','distinct_field_get','name_search','copy','import_data','search_count', 'exists'] + _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists'] def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None): """ @@ -2220,25 +2219,25 @@ class orm(orm_template): if groupby: if groupby and isinstance(groupby, list): groupby = groupby[0] - tables, where_clause, qfield = self._inherits_join_calc(groupby,tables,where_clause) + tables, where_clause, qfield = self._inherits_join_calc(groupby, tables, where_clause) if len(where_clause): - where_clause = ' where '+string.join(where_clause, ' and ') + where_clause = ' where ' + ' and '.join(where_clause) else: where_clause = '' limit_str = limit and ' limit %d' % limit or '' offset_str = offset and ' offset %d' % offset or '' fget = self.fields_get(cr, uid, fields) - float_int_fields = filter(lambda x: fget[x]['type'] in ('float','integer'), fields) + float_int_fields = filter(lambda x: fget[x]['type'] in ('float', 'integer'), fields) sum = {} flist = '' group_by = groupby if groupby: - if fget.get(groupby,False) and fget[groupby]['type'] in ('date','datetime'): - flist = "to_char(%s,'yyyy-mm') as %s "%(groupby,groupby) - groupby = "to_char(%s,'yyyy-mm')"%(groupby) + if fget.get(groupby, False) and fget[groupby]['type'] in ('date', 'datetime'): + flist = "to_char(%s,'yyyy-mm') as %s " % (groupby, groupby) + groupby = "to_char(%s,'yyyy-mm')" % (groupby) else: flist = groupby @@ -2247,8 +2246,8 @@ class orm(orm_template): f == self.CONCURRENCY_CHECK_FIELD or (f in self._columns and getattr(self._columns[f], '_classic_write'))] for f in fields_pre: - if f not in ['id','sequence']: - operator = fget[f].get('group_operator','sum') + if f not in ['id', 'sequence']: + operator = fget[f].get('group_operator', 'sum') if flist: flist += ',' flist += operator+'('+f+') as '+f @@ -2261,25 +2260,25 @@ class orm(orm_template): alldata = {} groupby = group_by for r in cr.dictfetchall(): - for fld,val in r.items(): - if val == None:r[fld] = False + for fld, val in r.items(): + if val == None: r[fld] = False alldata[r['id']] = r del r['id'] data = self.read(cr, uid, alldata.keys(), groupby and [groupby] or ['id'], context=context) for d in data: if groupby: - d['__domain'] = [(groupby,'=',alldata[d['id']][groupby] or False)] + domain - if not isinstance(groupby_list,(str, unicode)): + d['__domain'] = [(groupby, '=', alldata[d['id']][groupby] or False)] + domain + if not isinstance(groupby_list, (str, unicode)): if groupby or not context.get('group_by_no_leaf', False): - d['__context'] = {'group_by':groupby_list[1:]} - if groupby and fget.has_key(groupby): - if d[groupby] and fget[groupby]['type'] in ('date','datetime'): - dt = datetime.datetime.strptime(alldata[d['id']][groupby][:7],'%Y-%m') + d['__context'] = {'group_by': groupby_list[1:]} + if groupby and groupby in fget: + if d[groupby] and fget[groupby]['type'] in ('date', 'datetime'): + dt = datetime.datetime.strptime(alldata[d['id']][groupby][:7], '%Y-%m') days = calendar.monthrange(dt.year, dt.month)[1] - d[groupby] = datetime.datetime.strptime(d[groupby][:10],'%Y-%m-%d').strftime('%B %Y') - d['__domain'] = [(groupby,'>=',alldata[d['id']][groupby] and datetime.datetime.strptime(alldata[d['id']][groupby][:7] + '-01','%Y-%m-%d').strftime('%Y-%m-%d') or False),\ - (groupby,'<=',alldata[d['id']][groupby] and datetime.datetime.strptime(alldata[d['id']][groupby][:7] + '-' + str(days),'%Y-%m-%d').strftime('%Y-%m-%d') or False)] + domain + d[groupby] = datetime.datetime.strptime(d[groupby][:10], '%Y-%m-%d').strftime('%B %Y') + d['__domain'] = [(groupby, '>=', alldata[d['id']][groupby] and datetime.datetime.strptime(alldata[d['id']][groupby][:7] + '-01', '%Y-%m-%d').strftime('%Y-%m-%d') or False),\ + (groupby, '<=', alldata[d['id']][groupby] and datetime.datetime.strptime(alldata[d['id']][groupby][:7] + '-' + str(days), '%Y-%m-%d').strftime('%Y-%m-%d') or False)] + domain del alldata[d['id']][groupby] d.update(alldata[d['id']]) del d['id'] @@ -2327,7 +2326,7 @@ class orm(orm_template): if not self._parent_store: return logger = netsvc.Logger() - logger.notifyChannel('orm', netsvc.LOG_INFO, 'Computing parent left and right for table %s...' % (self._table, )) + logger.notifyChannel('data', netsvc.LOG_INFO, 'Computing parent left and right for table %s...' % (self._table, )) def browse_rec(root, pos=0): # TODO: set order where = self._parent_name+'='+str(root) @@ -2340,11 +2339,11 @@ class orm(orm_template): childs = cr.fetchall() for id in childs: pos2 = browse_rec(id[0], pos2) - cr.execute('update '+self._table+' set parent_left=%s, parent_right=%s where id=%s', (pos,pos2,root)) - return pos2+1 + cr.execute('update '+self._table+' set parent_left=%s, parent_right=%s where id=%s', (pos, pos2, root)) + return pos2 + 1 query = 'SELECT id FROM '+self._table+' WHERE '+self._parent_name+' IS NULL' if self._parent_order: - query += ' order by '+self._parent_order + query += ' order by ' + self._parent_order pos = 0 cr.execute(query) for (root,) in cr.fetchall(): @@ -2353,7 +2352,7 @@ class orm(orm_template): def _update_store(self, cr, f, k): logger = netsvc.Logger() - logger.notifyChannel('orm', netsvc.LOG_INFO, "storing computed values of fields.function '%s'" % (k,)) + logger.notifyChannel('data', netsvc.LOG_INFO, "storing computed values of fields.function '%s'" % (k,)) ss = self._columns[k]._symbol_set update_query = 'UPDATE "%s" SET "%s"=%s WHERE id=%%s' % (self._table, k, ss[0]) cr.execute('select id from '+self._table) @@ -2362,11 +2361,11 @@ class orm(orm_template): iids = ids_lst[:40] ids_lst = ids_lst[40:] res = f.get(cr, self, iids, k, 1, {}) - for key,val in res.items(): + for key, val in res.items(): if f._multi: val = val[k] # if val is a many2one, just write the ID - if type(val)==tuple: + if type(val) == tuple: val = val[0] if (val<>False) or (type(val)<>bool): cr.execute(update_query, (ss[1](val), key)) @@ -2383,26 +2382,30 @@ class orm(orm_template): " AND c.oid=a.attrelid" " AND a.attisdropped=%s" " AND pg_catalog.format_type(a.atttypid, a.atttypmod) NOT IN ('cid', 'tid', 'oid', 'xid')" - " AND a.attname NOT IN %s" ,(self._table, False, tuple(columns))), + " AND a.attname NOT IN %s", (self._table, False, tuple(columns))), for column in cr.dictfetchall(): if log: logger.notifyChannel("orm", netsvc.LOG_DEBUG, "column %s is in the table %s but not in the corresponding object %s" % (column['attname'], self._table, self._name)) if column['attnotnull']: cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, column['attname'])) + logging.getLogger('schema').info("Table '%s': column '%s': dropped NOT NULL constraint" % (self._table, column['attname'])) def _auto_init(self, cr, context={}): - store_compute = False + store_compute = False logger = netsvc.Logger() create = False todo_end = [] self._field_create(cr, context=context) if getattr(self, '_auto', True): - cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s" ,( self._table,)) + cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (self._table,)) if not cr.rowcount: cr.execute('CREATE TABLE "%s" (id SERIAL NOT NULL, PRIMARY KEY(id)) WITHOUT OIDS' % (self._table,)) - cr.execute("COMMENT ON TABLE \"%s\" IS '%s'" % (self._table, self._description.replace("'","''"))) + cr.execute("COMMENT ON TABLE \"%s\" IS '%s'" % (self._table, self._description.replace("'", "''"))) create = True + + logging.getLogger('schema').info("Table '%s': created" % (self._table, )) + cr.commit() if self._parent_store: cr.execute("""SELECT c.relname @@ -2410,14 +2413,17 @@ class orm(orm_template): WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid """, (self._table, 'parent_left')) if not cr.rowcount: - if 'parent_left' not in self._columns: - logger.notifyChannel('orm', netsvc.LOG_ERROR, 'create a column parent_left on object %s: fields.integer(\'Left Parent\', select=1)' % (self._table, )) - if 'parent_right' not in self._columns: - logger.notifyChannel('orm', netsvc.LOG_ERROR, 'create a column parent_right on object %s: fields.integer(\'Right Parent\', select=1)' % (self._table, )) - if self._columns[self._parent_name].ondelete != 'cascade': - logger.notifyChannel('orm', netsvc.LOG_ERROR, "The column %s on object %s must be set as ondelete='cascade'" % (self._parent_name, self._name)) cr.execute('ALTER TABLE "%s" ADD COLUMN "parent_left" INTEGER' % (self._table,)) cr.execute('ALTER TABLE "%s" ADD COLUMN "parent_right" INTEGER' % (self._table,)) + if 'parent_left' not in self._columns: + logger.notifyChannel('orm', netsvc.LOG_ERROR, 'create a column parent_left on object %s: fields.integer(\'Left Parent\', select=1)' % (self._table, )) + logging.getLogger('schema').info("Table '%s': added column '%s' with definition=%s" % (self._table, 'parent_left', 'INTEGER')) + if 'parent_right' not in self._columns: + logger.notifyChannel('orm', netsvc.LOG_ERROR, 'create a column parent_right on object %s: fields.integer(\'Right Parent\', select=1)' % (self._table, )) + logging.getLogger('schema').info("Table '%s': added column '%s' with definition=%s" % (self._table, 'parent_right', 'INTEGER')) + if self._columns[self._parent_name].ondelete != 'cascade': + logger.notifyChannel('orm', netsvc.LOG_ERROR, "The column %s on object %s must be set as ondelete='cascade'" % (self._parent_name, self._name)) + cr.commit() store_compute = True @@ -2437,6 +2443,7 @@ class orm(orm_template): if not cr.rowcount: cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k])) cr.commit() + logging.getLogger('schema').info("Table '%s': added column '%s' with definition=%s" % (self._table, k, logs[k])) self._check_removed_columns(cr, log=False) @@ -2458,13 +2465,16 @@ class orm(orm_template): if self.pool.get(f._obj): if f._fields_id not in self.pool.get(f._obj)._columns.keys(): if not self.pool.get(f._obj)._inherits or (f._fields_id not in self.pool.get(f._obj)._inherit_fields.keys()): - raise except_orm('Programming Error', ("There is no reference field '%s' found for '%s'") % (f._fields_id,f._obj,)) + raise except_orm('Programming Error', ("There is no reference field '%s' found for '%s'") % (f._fields_id, f._obj,)) if cr.fetchone(): cr.execute("SELECT count(1) as c FROM pg_class c,pg_attribute a WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid", (f._obj, f._fields_id)) res = cr.fetchone()[0] if not res: cr.execute('ALTER TABLE "%s" ADD FOREIGN KEY (%s) REFERENCES "%s" ON DELETE SET NULL' % (self._obj, f._fields_id, f._table)) + logging.getLogger('schema').info("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE SET NULL" % ( + self._obj, f._fields_id, f._table) + ) elif isinstance(f, fields.many2many): cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (f._rel,)) if not cr.dictfetchall(): @@ -2477,6 +2487,7 @@ class orm(orm_template): cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id2, f._rel, f._id2)) cr.execute("COMMENT ON TABLE \"%s\" IS 'RELATION BETWEEN %s AND %s'" % (f._rel, self._table, ref)) cr.commit() + logging.getLogger('schema').info("Create table '%s': relation between '%s' and '%s'" % (f._rel, self._table, ref)) else: cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \ "FROM pg_class c,pg_attribute a,pg_type t " \ @@ -2485,7 +2496,7 @@ class orm(orm_template): "AND c.oid=a.attrelid " \ "AND a.atttypid=t.oid", (self._table, k)) res = cr.dictfetchall() - if not res and hasattr(f,'oldname'): + if not res and hasattr(f, 'oldname'): cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \ "FROM pg_class c,pg_attribute a,pg_type t " \ "WHERE c.relname=%s " \ @@ -2493,14 +2504,13 @@ class orm(orm_template): "AND c.oid=a.attrelid " \ "AND a.atttypid=t.oid", (self._table, f.oldname)) res_old = cr.dictfetchall() - logger.notifyChannel('orm', netsvc.LOG_DEBUG, 'trying to rename %s(%s) to %s'% (self._table, f.oldname, k)) - if res_old and len(res_old)==1: - cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % ( self._table,f.oldname, k)) + if res_old and len(res_old) == 1: + cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % (self._table, f.oldname, k)) res = res_old res[0]['attname'] = k + logging.getLogger('schema').info("Table '%s': renamed column '%s' to '%s'" % (self._table, f.oldname, k)) - - if len(res)==1: + if len(res) == 1: f_pg_def = res[0] f_pg_type = f_pg_def['typname'] f_pg_size = f_pg_def['size'] @@ -2508,8 +2518,9 @@ class orm(orm_template): if isinstance(f, fields.function) and not f.store and\ not getattr(f, 'nodrop', False): logger.notifyChannel('orm', netsvc.LOG_INFO, 'column %s (%s) in table %s removed: converted to a function !\n' % (k, f.string, self._table)) - cr.execute('ALTER TABLE "%s" DROP COLUMN "%s" CASCADE'% (self._table, k)) + cr.execute('ALTER TABLE "%s" DROP COLUMN "%s" CASCADE' % (self._table, k)) cr.commit() + logging.getLogger('schema').info("Table '%s': dropped column '%s' with cascade" % (self._table, k)) f_obj_type = None else: f_obj_type = get_pg_type(f) and get_pg_type(f)[0] @@ -2526,23 +2537,22 @@ class orm(orm_template): ('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]), ] if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size < f.size: - logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed size" % (k, self._table)) cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" VARCHAR(%d)' % (self._table, k, f.size)) cr.execute('UPDATE "%s" SET "%s"=temp_change_size::VARCHAR(%d)' % (self._table, k, f.size)) cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,)) cr.commit() + logging.getLogger('schema').info("Table '%s': column '%s' (type varchar) changed size from %s to %s" % (self._table, k, f_pg_size, f.size)) for c in casts: if (f_pg_type==c[0]) and (f._type==c[1]): if f_pg_type != f_obj_type: - if f_pg_type != f_obj_type: - logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed type to %s." % (k, self._table, c[1])) ok = True cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2])) cr.execute(('UPDATE "%s" SET "%s"=temp_change_size'+c[3]) % (self._table, k)) cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,)) cr.commit() + logging.getLogger('schema').info("Table '%s': column '%s' changed type from %s to %s" % (self._table, k, c[0], c[1])) break if f_pg_type != f_obj_type: @@ -2556,13 +2566,15 @@ class orm(orm_template): "AND c.oid=a.attrelid ", (self._table, newname)) if not cr.fetchone()[0]: break - i+=1 - logger.notifyChannel('orm', netsvc.LOG_WARNING, "column '%s' in table '%s' has changed type (DB=%s, def=%s), data moved to table %s !" % (k, self._table, f_pg_type, f._type, newname)) + i += 1 if f_pg_notnull: cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k)) cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (self._table, k, newname)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1])) - cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'","''"))) + cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''"))) + logging.getLogger('schema').info("Table '%s': column '%s' has changed type (DB=%s, def=%s), data moved to column %s !" % ( + self._table, k, f_pg_type, f._type, newname) + ) # if the field is required and hasn't got a NOT NULL constraint if f.required and f_pg_notnull == 0: @@ -2582,13 +2594,18 @@ class orm(orm_template): try: cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (self._table, k)) cr.commit() + logging.getLogger('schema').info("Table '%s': column '%s': added NOT NULL constraint" % (self._table, k)) except Exception: - logger.notifyChannel('orm', netsvc.LOG_WARNING, 'unable to set a NOT NULL constraint on column %s of the %s table !\nIf you want to have it, you should update the records and execute manually:\nALTER TABLE %s ALTER COLUMN %s SET NOT NULL' % (k, self._table, self._table, k)) + msg = "Table '%s': unable to set a NOT NULL constraint on column '%s' !\n"\ + "If you want to have it, you should update the records and execute manually:\n"\ + "ALTER TABLE %s ALTER COLUMN %s SET NOT NULL" % ( + self._table, k, self._table, k) + logger.notifyChannel('schema', netsvc.LOG_WARNING, msg) cr.commit() elif not f.required and f_pg_notnull == 1: cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k)) cr.commit() - + logging.getLogger('schema').info("Table '%s': column '%s': dropped NOT NULL constraint" % (self._table, k)) # Verify index indexname = '%s_%s_index' % (self._table, k) cr.execute("SELECT indexname FROM pg_indexes WHERE indexname = %s and tablename = %s", (indexname, self._table)) @@ -2598,13 +2615,16 @@ class orm(orm_template): cr.commit() if f._type == 'text': # FIXME: for fields.text columns we should try creating GIN indexes instead (seems most suitable for an ERP context) - logger.notifyChannel('orm', netsvc.LOG_WARNING, "Adding (b-tree) index for text column '%s' in table '%s'."\ - "This is probably useless (does not work for fulltext search) and prevents INSERTs of long texts because there is a length limit for indexable btree values!\n"\ - "Use a search view instead if you simply want to make the field searchable." % (k, f._type, self._table)) + msg = "Table '%s': Adding (b-tree) index for text column '%s'."\ + "This is probably useless (does not work for fulltext search) and prevents INSERTs of long texts"\ + " because there is a length limit for indexable btree values!\n"\ + "Use a search view instead if you simply want to make the field searchable." % (self._table, k, f._type) + logger.notifyChannel('schema', netsvc.LOG_WARNING, msg) if res2 and not f.select: cr.execute('DROP INDEX "%s_%s_index"' % (self._table, k)) cr.commit() - logger.notifyChannel('orm', netsvc.LOG_WARNING, "Dropping index for column '%s' of type '%s' in table '%s' as it is not required anymore" % (k, f._type, self._table)) + msg = "Table '%s': dropping index for column '%s' of type '%s' as it is not required anymore" % (self._table, k, f._type) + logger.notifyChannel('schema', netsvc.LOG_WARNING, msg) if isinstance(f, fields.many2one): ref = self.pool.get(f._obj)._table @@ -2630,14 +2650,15 @@ class orm(orm_template): cr.execute('ALTER TABLE "' + self._table + '" DROP CONSTRAINT "' + res2[0]['conname'] + '"') cr.execute('ALTER TABLE "' + self._table + '" ADD FOREIGN KEY ("' + k + '") REFERENCES "' + ref + '" ON DELETE ' + f.ondelete) cr.commit() - elif len(res)>1: - logger.notifyChannel('orm', netsvc.LOG_ERROR, "Programming error, column %s->%s has multiple instances !"%(self._table,k)) + logging.getLogger('schema').info("Table '%s': column '%s': XXX" % (self._table, k)) + elif len(res) > 1: + logger.notifyChannel('orm', netsvc.LOG_ERROR, "Programming error, column %s->%s has multiple instances !" % (self._table, k)) if not res: if not isinstance(f, fields.function) or f.store: - # add the missing field cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1])) - cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'","''"))) + cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''"))) + logging.getLogger('schema').info("Table '%s': added column '%s' with definition=%s" % (self._table, k, get_pg_type(f)[1])) # initialize it if not create and k in self._defaults: @@ -2650,15 +2671,13 @@ class orm(orm_template): query = 'UPDATE "%s" SET "%s"=%s' % (self._table, k, ss[0]) cr.execute(query, (ss[1](default),)) cr.commit() - logger.notifyChannel('orm', netsvc.LOG_DEBUG, 'setting default value of new column %s of table %s'% (k, self._table)) - elif not create: - logger.notifyChannel('orm', netsvc.LOG_DEBUG, 'creating new column %s of table %s'% (k, self._table)) + logger.notifyChannel('data', netsvc.LOG_DEBUG, "Table '%s': setting default value of new column %s" % (self._table, k)) if isinstance(f, fields.function): order = 10 if f.store is not True: order = f.store[f.store.keys()[0]][2] - todo_update_store.append((order, f,k)) + todo_update_store.append((order, f, k)) # and add constraints if needed if isinstance(f, fields.many2one): @@ -2669,16 +2688,23 @@ class orm(orm_template): # ir_actions is inherited so foreign key doesn't work on it if ref != 'ir_actions': cr.execute('ALTER TABLE "%s" ADD FOREIGN KEY ("%s") REFERENCES "%s" ON DELETE %s' % (self._table, k, ref, f.ondelete)) + logging.getLogger('schema').info("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s" % ( + self._table, k, ref, f.ondelete)) if f.select: cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (self._table, k, self._table, k)) if f.required: try: cr.commit() cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (self._table, k)) + logging.getLogger('schema').info("Table '%s': column '%s': added a NOT NULL constraint" % (self._table, k)) except Exception: - logger.notifyChannel('orm', netsvc.LOG_WARNING, 'WARNING: unable to set column %s of table %s not null !\nTry to re-run: openerp-server.py --update=module\nIf it doesn\'t work, update records and execute manually:\nALTER TABLE %s ALTER COLUMN %s SET NOT NULL' % (k, self._table, self._table, k)) + msg = "WARNING: unable to set column %s of table %s not null !\n"\ + "Try to re-run: openerp-server.py --update=module\n"\ + "If it doesn't work, update records and execute manually:\n"\ + "ALTER TABLE %s ALTER COLUMN %s SET NOT NULL" % (k, self._table, self._table, k) + logger.notifyChannel('orm', netsvc.LOG_WARNING, msg) cr.commit() - for order,f,k in todo_update_store: + for order, f, k in todo_update_store: todo_end.append((order, self._update_store, (f, k))) else: @@ -2689,14 +2715,50 @@ class orm(orm_template): for (key, con, _) in self._sql_constraints: conname = '%s_%s' % (self._table, key) - cr.execute("SELECT conname FROM pg_constraint where conname=%s", (conname,)) - if not cr.dictfetchall(): - query = 'ALTER TABLE "%s" ADD CONSTRAINT "%s" %s' % (self._table, conname, con,) + + cr.execute("SELECT conname, pg_catalog.pg_get_constraintdef(oid, true) as condef FROM pg_constraint where conname=%s", (conname,)) + existing_constraints = cr.dictfetchall() + + sql_actions = { + 'drop': { + 'execute': False, + 'query': 'ALTER TABLE "%s" DROP CONSTRAINT "%s"' % (self._table, conname, ), + 'msg_ok': "Table '%s': dropped constraint '%s'. Reason: its definition changed from '%%s' to '%s'" % ( + self._table, conname, con), + 'msg_err': "Table '%s': unable to drop \'%s\' constraint !" % (self._table, con), + 'order': 1, + }, + 'add': { + 'execute': False, + 'query': 'ALTER TABLE "%s" ADD CONSTRAINT "%s" %s' % (self._table, conname, con,), + 'msg_ok': "Table '%s': added constraint '%s' with definition=%s" % (self._table, conname, con), + 'msg_err': "Table '%s': unable to add \'%s\' constraint !\n If you want to have it, you should update the records and execute manually:\n%%s" % ( + self._table, con), + 'order': 2, + }, + } + + if not existing_constraints: + # constraint does not exists: + sql_actions['add']['execute'] = True + sql_actions['add']['msg_err'] = sql_actions['add']['msg_err'] % (sql_actions['add']['query'], ) + elif con.lower() not in [item['condef'].lower() for item in existing_constraints]: + # constraint exists but its definition has changed: + sql_actions['drop']['execute'] = True + sql_actions['drop']['msg_ok'] = sql_actions['drop']['msg_ok'] % (existing_constraints[0]['condef'].lower(), ) + sql_actions['add']['execute'] = True + sql_actions['add']['msg_err'] = sql_actions['add']['msg_err'] % (sql_actions['add']['query'], ) + + # we need to add the constraint: + sql_actions = [item for item in sql_actions.values()] + sql_actions.sort(key=lambda x: x['order']) + for sql_action in [action for action in sql_actions if action['execute']]: try: - cr.execute(query) + cr.execute(sql_action['query']) cr.commit() + logging.getLogger('schema').info(sql_action['msg_ok']) except: - logger.notifyChannel('orm', netsvc.LOG_WARNING, 'unable to add \'%s\' constraint on table %s !\n If you want to have it, you should update the records and execute manually:\n%s' % (con, self._table, query)) + logger.notifyChannel('schema', netsvc.LOG_WARNING, sql_action['msg_err']) cr.rollback() if create: @@ -2728,27 +2790,27 @@ class orm(orm_template): if not f.store: continue if self._columns[store_field].store is True: - sm = {self._name:(lambda self,cr, uid, ids, c={}: ids, None, 10, None)} + sm = {self._name: (lambda self, cr, uid, ids, c={}: ids, None, 10, None)} else: sm = self._columns[store_field].store for object, aa in sm.items(): - if len(aa)==4: - (fnct,fields2,order,length)=aa - elif len(aa)==3: - (fnct,fields2,order)=aa + if len(aa) == 4: + (fnct, fields2, order, length) = aa + elif len(aa) == 3: + (fnct, fields2, order) = aa length = None else: raise except_orm('Error', ('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority, time length)}.' % (store_field, self._name))) self.pool._store_function.setdefault(object, []) ok = True - for x,y,z,e,f,l in self.pool._store_function[object]: + for x, y, z, e, f, l in self.pool._store_function[object]: if (x==self._name) and (y==store_field) and (e==fields2): - if f==order: + if f == order: ok = False if ok: self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order, length)) - self.pool._store_function[object].sort(lambda x,y: cmp(x[4],y[4])) + self.pool._store_function[object].sort(lambda x, y: cmp(x[4], y[4])) for (key, _, msg) in self._sql_constraints: self.pool._sql_error[self._table+'_'+key] = msg @@ -2783,14 +2845,14 @@ class orm(orm_template): elif field['ttype'] == 'many2many': _rel1 = field['relation'].replace('.', '_') _rel2 = field['model'].replace('.', '_') - _rel_name = 'x_%s_%s_%s_rel' %(_rel1, _rel2, field['name']) + _rel_name = 'x_%s_%s_%s_rel' % (_rel1, _rel2, field['name']) self._columns[field['name']] = getattr(fields, field['ttype'])(field['relation'], _rel_name, 'id1', 'id2', **attrs) else: self._columns[field['name']] = getattr(fields, field['ttype'])(**attrs) self._inherits_check() self._inherits_reload() if not self._sequence: - self._sequence = self._table+'_id_seq' + self._sequence = self._table + '_id_seq' for k in self._defaults: assert (k in self._columns) or (k in self._inherit_fields), 'Default function defined in %s but field %s does not exist !' % (self._name, k,) for f in self._columns: @@ -2820,7 +2882,7 @@ class orm(orm_template): for table, field_name in self._inherits.items(): if field_name not in self._columns: logging.getLogger('init').info('Missing many2one field definition for _inherits reference "%s" in "%s", using default one.' % (field_name, self._name)) - self._columns[field_name] = fields.many2one(table, string="Automatically created field to link to parent %s" % table, + self._columns[field_name] = fields.many2one(table, string="Automatically created field to link to parent %s" % table, required=True, ondelete="cascade") elif not self._columns[field_name].required or self._columns[field_name].ondelete.lower() != "cascade": logging.getLogger('init').warning('Field definition for _inherits reference "%s" in "%s" must be marked as "required" with ondelete="cascade", forcing it.' % (field_name, self._name)) @@ -2895,7 +2957,7 @@ class orm(orm_template): select = [ids] else: select = ids - select = map(lambda x: isinstance(x,dict) and x['id'] or x, select) + select = map(lambda x: isinstance(x, dict) and x['id'] or x, select) result = self._read_flat(cr, user, select, fields, context, load) for r in result: @@ -2978,6 +3040,21 @@ class orm(orm_template): else: res = map(lambda x: {'id': x}, ids) + if not res: + res = map(lambda x: {'id': x}, ids) + for record in res: + for f in fields_to_read: + field_val = False + if f in self._columns.keys(): + ftype = self._columns[f]._type + elif key in self._inherit_fields.keys(): + ftype = self._inherit_fields[f][2]._type + else: + continue + if ftype in ('one2many', 'many2many'): + field_val = [] + record.update({f:field_val}) + for f in fields_pre: if f == self.CONCURRENCY_CHECK_FIELD: continue @@ -3001,7 +3078,7 @@ class orm(orm_template): del r['id'] for record in res: - if not record[col]:# if the record is deleted from _inherits table? + if not record[col]: # if the record is deleted from _inherits table? continue record.update(res3[record[col]]) if col not in fields_to_read: @@ -3023,12 +3100,12 @@ class orm(orm_template): for f in fields_post: todo.setdefault(self._columns[f]._multi, []) todo[self._columns[f]._multi].append(f) - for key,val in todo.items(): + for key, val in todo.items(): if key: res2 = self._columns[val[0]].get(cr, self, ids, val, user, context=context, values=res) for pos in val: for record in res: - if isinstance(res2[record['id']], str):res2[record['id']] = eval(res2[record['id']]) #TOCHECK : why got string instend of dict in python2.6 + if isinstance(res2[record['id']], str): res2[record['id']] = eval(res2[record['id']]) #TOCHECK : why got string instend of dict in python2.6 record[pos] = res2[record['id']][pos] else: for f in val: @@ -3198,8 +3275,8 @@ class orm(orm_template): 'where id IN %s', (sub_ids,)) for order, object, store_ids, fields in result_store: if object != self._name: - obj = self.pool.get(object) - cr.execute('select id from '+obj._table+' where id IN %s',(tuple(store_ids),)) + obj = self.pool.get(object) + cr.execute('select id from '+obj._table+' where id IN %s', (tuple(store_ids),)) rids = map(lambda x: x[0], cr.fetchall()) if rids: obj._store_set_values(cr, uid, rids, fields, context) @@ -3272,7 +3349,7 @@ class orm(orm_template): for group in groups: module = group.split(".")[0] grp = group.split(".")[1] - cr.execute("select count(*) from res_groups_users_rel where gid IN (select res_id from ir_model_data where name=%s and module=%s and model=%s) and uid=%s" \ + cr.execute("select count(*) from res_groups_users_rel where gid IN (select res_id from ir_model_data where name=%s and module=%s and model=%s) and uid=%s", \ (grp, module, 'res.groups', user)) readonly = cr.fetchall() if readonly[0][0] >= 1: @@ -3369,11 +3446,11 @@ class orm(orm_template): # TODO: optimize for f in direct: if self._columns[f].translate: - src_trans = self.pool.get(self._name).read(cr,user,ids,[f])[0][f] + src_trans = self.pool.get(self._name).read(cr, user, ids, [f])[0][f] if not src_trans: src_trans = vals[f] # Inserting value to DB - self.write(cr, user, ids, {f:vals[f]}) + self.write(cr, user, ids, {f: vals[f]}) self.pool.get('ir.translation')._set_ids(cr, user, self._name+','+f, 'model', context['lang'], ids, vals[f], src_trans) @@ -3412,7 +3489,7 @@ class orm(orm_template): # parent_left/right (via a child_of domain) if parents_changed: if self.pool._init: - self.pool._init_parent[self._name]=True + self.pool._init_parent[self._name] = True else: order = self._parent_order or self._order parent_val = vals[self._parent_name] @@ -3433,7 +3510,7 @@ class orm(orm_template): for (parent_pright, parent_id) in parents: if parent_id == id: break - position = parent_pright+1 + position = parent_pright + 1 # It's the first node of the parent if not position: @@ -3441,7 +3518,7 @@ class orm(orm_template): position = 1 else: cr.execute('select parent_left from '+self._table+' where id=%s', (parent_val,)) - position = cr.fetchone()[0]+1 + position = cr.fetchone()[0] + 1 if pleft < position <= pright: raise except_orm(_('UserError'), _('Recursivity Detected.')) @@ -3449,18 +3526,18 @@ class orm(orm_template): if pleft < position: cr.execute('update '+self._table+' set parent_left=parent_left+%s where parent_left>=%s', (distance, position)) cr.execute('update '+self._table+' set parent_right=parent_right+%s where parent_right>=%s', (distance, position)) - cr.execute('update '+self._table+' set parent_left=parent_left+%s, parent_right=parent_right+%s where parent_left>=%s and parent_left<%s', (position-pleft,position-pleft, pleft, pright)) + cr.execute('update '+self._table+' set parent_left=parent_left+%s, parent_right=parent_right+%s where parent_left>=%s and parent_left<%s', (position-pleft, position-pleft, pleft, pright)) else: cr.execute('update '+self._table+' set parent_left=parent_left+%s where parent_left>=%s', (distance, position)) cr.execute('update '+self._table+' set parent_right=parent_right+%s where parent_right>=%s', (distance, position)) - cr.execute('update '+self._table+' set parent_left=parent_left-%s, parent_right=parent_right-%s where parent_left>=%s and parent_left<%s', (pleft-position+distance,pleft-position+distance, pleft+distance, pright+distance)) + cr.execute('update '+self._table+' set parent_left=parent_left-%s, parent_right=parent_right-%s where parent_left>=%s and parent_left<%s', (pleft-position+distance, pleft-position+distance, pleft+distance, pright+distance)) result += self._store_get_values(cr, user, ids, vals.keys(), context) result.sort() done = {} for order, object, ids, fields in result: - key = (object,tuple(fields)) + key = (object, tuple(fields)) done.setdefault(key, {}) # avoid to do several times the same computation todo = [] @@ -3511,7 +3588,7 @@ class orm(orm_template): if self._inherits[v] not in vals: tocreate[v] = {} else: - tocreate[v] = {'id' : vals[self._inherits[v]]} + tocreate[v] = {'id': vals[self._inherits[v]]} (upd0, upd1, upd2) = ('', '', []) upd_todo = [] for v in vals.keys(): @@ -3543,7 +3620,7 @@ class orm(orm_template): else: self.pool.get(table).write(cr, user, [record_id], tocreate[table], context=context) - upd0 += ','+self._inherits[table] + upd0 += ',' + self._inherits[table] upd1 += ',%s' upd2.append(record_id) @@ -3617,7 +3694,7 @@ class orm(orm_template): if self._parent_store and not context.get('defer_parent_store_computation'): if self.pool._init: - self.pool._init_parent[self._name]=True + self.pool._init_parent[self._name] = True else: parent = vals.get(self._parent_name, False) if parent: @@ -3637,7 +3714,7 @@ class orm(orm_template): pleft = cr.fetchone()[0] or 0 cr.execute('update '+self._table+' set parent_left=parent_left+2 where parent_left>%s', (pleft,)) cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%s', (pleft,)) - cr.execute('update '+self._table+' set parent_left=%s,parent_right=%s where id=%s', (pleft+1,pleft+2,id_new)) + cr.execute('update '+self._table+' set parent_left=%s,parent_right=%s where id=%s', (pleft+1, pleft+2, id_new)) # default element in context must be remove when call a one2many or many2many rel_context = context.copy() @@ -3663,7 +3740,7 @@ class orm(orm_template): message = self._description + \ " '" + \ self.name_get(cr, user, [id_new], context=context)[0][1] + \ - "' "+ _("created.") + "' " + _("created.") self.log(cr, user, id_new, message, True, context=context) wf_service = netsvc.LocalService("workflow") wf_service.trg_create(user, self._name, id_new, cr) @@ -3687,24 +3764,24 @@ class orm(orm_template): result.setdefault(fncts[fnct][0], {}) # uid == 1 for accessing objects having rules defined on store fields - ids2 = fncts[fnct][2](self,cr, 1, ids, context) + ids2 = fncts[fnct][2](self, cr, 1, ids, context) for id in filter(None, ids2): result[fncts[fnct][0]].setdefault(id, []) result[fncts[fnct][0]][id].append(fnct) dict = {} for object in result: k2 = {} - for id,fnct in result[object].items(): + for id, fnct in result[object].items(): k2.setdefault(tuple(fnct), []) k2[tuple(fnct)].append(id) - for fnct,id in k2.items(): - dict.setdefault(fncts[fnct[0]][4],[]) - dict[fncts[fnct[0]][4]].append((fncts[fnct[0]][4],object,id,map(lambda x: fncts[x][1], fnct))) + for fnct, id in k2.items(): + dict.setdefault(fncts[fnct[0]][4], []) + dict[fncts[fnct[0]][4]].append((fncts[fnct[0]][4], object, id, map(lambda x: fncts[x][1], fnct))) result2 = [] tmp = dict.keys() tmp.sort() for k in tmp: - result2+=dict[k] + result2 += dict[k] return result2 def _store_set_values(self, cr, uid, ids, fields, context): @@ -3713,7 +3790,7 @@ class orm(orm_template): field_flag = False field_dict = {} if self._log_access: - cr.execute('select id,write_date from '+self._table+' where id IN %s',(tuple(ids),)) + cr.execute('select id,write_date from '+self._table+' where id IN %s', (tuple(ids),)) res = cr.fetchall() for r in res: if r[1]: @@ -3740,7 +3817,7 @@ class orm(orm_template): if key: # uid == 1 for accessing objects having rules defined on store fields result = self._columns[val[0]].get(cr, self, ids, val, 1, context=context) - for id,value in result.items(): + for id, value in result.items(): if field_flag: for f in value.keys(): if f in field_dict[id]: @@ -3760,7 +3837,7 @@ class orm(orm_template): upd1.append(id) if upd0 and upd1: cr.execute('update "' + self._table + '" set ' + \ - string.join(upd0, ',') + ' where id = %s', upd1) + ','.join(upd0) + ' where id = %s', upd1) else: for f in val: @@ -3771,14 +3848,14 @@ class orm(orm_template): if r in field_dict.keys(): if f in field_dict[r]: result.pop(r) - for id,value in result.items(): + for id, value in result.items(): if self._columns[f]._type in ('many2one', 'one2one'): try: value = value[0] except: pass cr.execute('update "' + self._table + '" set ' + \ - '"'+f+'"='+self._columns[f]._symbol_set[0] + ' where id = %s', (self._columns[f]._symbol_set[1](value),id)) + '"'+f+'"='+self._columns[f]._symbol_set[0] + ' where id = %s', (self._columns[f]._symbol_set[1](value), id)) return True # @@ -3847,7 +3924,7 @@ class orm(orm_template): the appropriate JOIN for linking the current model to the one referenced in model_name. :return: True if additional clauses where applied. """ - added_clause, added_params, added_tables = self.pool.get('ir.rule').domain_get(cr, uid, model_name or self._name, mode, context=context) + added_clause, added_params, added_tables = self.pool.get('ir.rule').domain_get(cr, uid, model_name or self._name, mode, context=context) if added_clause: where_clause += added_clause where_clause_params += added_params @@ -3904,7 +3981,7 @@ class orm(orm_template): limit_str = limit and ' limit %d' % limit or '' offset_str = offset and ' offset %d' % offset or '' - + if where: where_str = " WHERE %s" % " AND ".join(where) else: @@ -4014,7 +4091,7 @@ class orm(orm_template): # we must recursively copy the translations for o2o and o2m if field_def['type'] in ('one2one', 'one2many'): target_obj = self.pool.get(field_def['relation']) - old_record, new_record = self.read(cr, uid, [old_id, new_id], [field_name], context=context) + old_record, new_record = self.read(cr, uid, [old_id, new_id], [field_name], context=context) # here we rely on the order of the ids to match the translations # as foreseen in copy_data() old_childs = sorted(old_record[field_name]) @@ -4032,9 +4109,9 @@ class orm(orm_template): if trans_name: trans_ids = trans_obj.search(cr, uid, [ ('name', '=', trans_name), - ('res_id','=', old_id) + ('res_id', '=', old_id) ]) - translation_records.extend(trans_obj.read(cr,uid,trans_ids,context=context)) + translation_records.extend(trans_obj.read(cr, uid, trans_ids, context=context)) for record in translation_records: del record['id'] @@ -4062,7 +4139,7 @@ class orm(orm_template): return new_id def exists(self, cr, uid, ids, context=None): - if type(ids) in (int,long): + if type(ids) in (int, long): ids = [ids] query = 'SELECT count(1) FROM "%s"' % (self._table) cr.execute(query + "WHERE ID IN %s", (tuple(ids),)) @@ -4111,10 +4188,10 @@ class orm(orm_template): """ result = dict.fromkeys(ids, '') model_data_obj = self.pool.get('ir.model.data') - data_ids = model_data_obj.search(cr,uid, - [('model','=',self._name),('res_id','in',ids)]) - data_results = model_data_obj.read(cr,uid,data_ids, - ['name','module','res_id']) + data_ids = model_data_obj.search(cr, uid, + [('model', '=', self._name), ('res_id', 'in', ids)]) + data_results = model_data_obj.read(cr, uid, data_ids, + ['name', 'module', 'res_id']) for record in data_results: result[record['res_id']] = '%(module)s.%(name)s' % record return result diff --git a/bin/service/web_services.py b/bin/service/web_services.py index 8f1fc910739..8b33b41a0b3 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -20,7 +20,6 @@ ############################################################################## import base64 -import logging import os import security import thread @@ -39,8 +38,6 @@ import tools import locale from cStringIO import StringIO -logging.basicConfig() - class db(netsvc.ExportService): def __init__(self, name="db"): netsvc.ExportService.__init__(self, name) diff --git a/bin/sql_db.py b/bin/sql_db.py index 5ed7b14c0df..438d513b0e4 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -15,12 +15,13 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## __all__ = ['db_connect', 'close_db'] +from threading import current_thread import logging from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE from psycopg2.psycopg1 import cursor as psycopg1cursor @@ -107,7 +108,7 @@ class Cursor(object): self._close(True) @check - def execute(self, query, params=None): + def execute(self, query, params=None, log_exceptions=True): if '%d' in query or '%f' in query: self.__logger.warn(query) self.__logger.warn("SQL queries cannot contain %d or %f anymore. " @@ -122,10 +123,12 @@ class Cursor(object): params = params or None res = self._obj.execute(query, params) except psycopg2.ProgrammingError, pe: - self.__logger.error("Programming error: %s, in query %s", pe, query) + if log_exceptions or self.sql_log: + self.__logger.error("Programming error: %s, in query %s", pe, query) raise except Exception: - self.__logger.exception("bad query: %s", self._obj.query) + if log_exceptions or self.sql_log: + self.__logger.exception("bad query: %s", self._obj.query or query) raise if self.sql_log: @@ -267,7 +270,7 @@ class ConnectionPool(object): delattr(cnx, 'leaked') self._connections.pop(i) self._connections.append((cnx, False)) - self._debug('Free leaked connection to %r', cnx.dsn) + self.__logger.warn('%r: Free leaked connection to %r', self, cnx.dsn) for i, (cnx, used) in enumerate(self._connections): if not used and dsn_are_equals(cnx.dsn, dsn): @@ -310,7 +313,7 @@ class ConnectionPool(object): @locked def close_all(self, dsn): - self._debug('Close all connections to %r', dsn) + self.__logger.info('%r: Close all connections to %r', self, dsn) for i, (cnx, used) in tools.reverse_enumerate(self._connections): if dsn_are_equals(cnx.dsn, dsn): cnx.close() @@ -362,11 +365,15 @@ def dsn_are_equals(first, second): _Pool = ConnectionPool(int(tools.config['db_maxconn'])) def db_connect(db_name): + current_thread().dbname = db_name return Connection(_Pool, db_name) def close_db(db_name): _Pool.close_all(dsn(db_name)) tools.cache.clean_caches_for_db(db_name) + ct = current_thread() + if hasattr(ct, 'dbname'): + delattr(ct, 'dbname') # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: