summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Laurent <olt@tinyerp.com>2009-01-15 17:33:25 +0100
committerOlivier Laurent <olt@tinyerp.com>2009-01-15 17:33:25 +0100
commitf4eedf53bbf75e25bf0bbcf4bb3f773b2aaca99d (patch)
treed79b9617a1bcc62a6e188d7e1db4744b48a53298
parent29f3a32c9bdc74af94a9e817b1c13bd9f91cf3b7 (diff)
parent863785242d6d01fbccdd943666b10596792a5513 (diff)
merge
bzr revid: olt@tinyerp.com-20090115163325-9rxxi81k98qhm0ry
-rw-r--r--bin/addons/base/ir/ir_ui_menu.py4
-rw-r--r--bin/addons/base/ir/ir_values.py4
-rw-r--r--bin/addons/base/module/module.py7
-rw-r--r--bin/netsvc.py5
-rw-r--r--bin/osv/orm.py67
-rw-r--r--bin/service/web_services.py13
6 files changed, 57 insertions, 43 deletions
diff --git a/bin/addons/base/ir/ir_ui_menu.py b/bin/addons/base/ir/ir_ui_menu.py
index 74da6bdfd5d..46c81d5a041 100644
--- a/bin/addons/base/ir/ir_ui_menu.py
+++ b/bin/addons/base/ir/ir_ui_menu.py
@@ -191,8 +191,8 @@ class ir_ui_menu(osv.osv):
if context is None:
context = {}
ctx = context.copy()
- if 'read_delta' in ctx:
- del ctx['read_delta']
+ if self.CONCURRENCY_CHECK_FIELD in ctx:
+ del ctx[self.CONCURRENCY_CHECK_FIELD]
values_obj = self.pool.get('ir.values')
values_ids = values_obj.search(cursor, user, [
('model', '=', self._name), ('key', '=', 'action'),
diff --git a/bin/addons/base/ir/ir_values.py b/bin/addons/base/ir/ir_values.py
index 116a581c3b0..087b14dc99d 100644
--- a/bin/addons/base/ir/ir_values.py
+++ b/bin/addons/base/ir/ir_values.py
@@ -43,8 +43,8 @@ class ir_values(osv.osv):
if context is None:
context = {}
ctx = context.copy()
- if 'read_delta' in ctx:
- del ctx['read_delta']
+ if self.CONCURRENCY_CHECK_FIELD in ctx:
+ del ctx[self.CONCURRENCY_CHECK_FIELD]
if not self.browse(cursor, user, id, context=context).object:
value = pickle.dumps(eval(value))
self.write(cursor, user, id, {name[:-9]: value}, context=ctx)
diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py
index 35c1e9f48ca..a4f822a5e16 100644
--- a/bin/addons/base/module/module.py
+++ b/bin/addons/base/module/module.py
@@ -462,9 +462,12 @@ class module(osv.osv):
for mod in self.browse(cr, uid, ids):
if mod.state != 'installed':
continue
-
+ modpath = addons.get_module_path(mod.name)
+ if not modpath:
+ # unable to find the module. we skip
+ continue
for lang in filter_lang:
- f = os.path.join(addons.get_module_path(mod.name), 'i18n', lang + '.po')
+ f = os.path.join(modpath, 'i18n', lang + '.po')
if os.path.exists(f):
logger.notifyChannel("init", netsvc.LOG_INFO, 'module %s: loading translation file for language %s' % (mod.name, lang))
tools.trans_load(cr.dbname, f, lang, verbose=False)
diff --git a/bin/netsvc.py b/bin/netsvc.py
index b0e5035e29f..745921023e3 100644
--- a/bin/netsvc.py
+++ b/bin/netsvc.py
@@ -228,7 +228,10 @@ class OpenERPDispatcher:
return result
except Exception, e:
self.log('exception', tools.exception_to_unicode(e))
- tb = sys.exc_info()
+ if hasattr(e, 'traceback'):
+ tb = e.traceback
+ else:
+ tb = sys.exc_info()
tb_s = "".join(traceback.format_exception(*tb))
if tools.config['debug_mode']:
import pdb
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 3dcc510db27..f6a54423894 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -303,6 +303,8 @@ class orm_template(object):
_inherits = {}
_table = None
_invalids = set()
+
+ CONCURRENCY_CHECK_FIELD = '__last_update'
def _field_create(self, cr, context={}):
cr.execute("SELECT id FROM ir_model WHERE model=%s", (self._name,))
@@ -1861,13 +1863,20 @@ class orm(orm_template):
d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name)
# all inherited fields + all non inherited fields for which the attribute whose name is in load is True
- fields_pre = filter(lambda x: x in self._columns and getattr(self._columns[x], '_classic_write'), fields_to_read) + self._inherits.values()
+ fields_pre = [f for f in fields_to_read if
+ f == self.CONCURRENCY_CHECK_FIELD
+ or (f in self._columns and getattr(self._columns[f], '_classic_write'))
+ ] + self._inherits.values()
res = []
if len(fields_pre):
def convert_field(f):
if f in ('create_date', 'write_date'):
return "date_trunc('second', %s) as %s" % (f, f)
+ if f == self.CONCURRENCY_CHECK_FIELD:
+ if self._log_access:
+ return "COALESCE(write_date, create_date, now())::timestamp AS %s" % (f,)
+ return "now()::timestamp AS %s" % (f,)
if isinstance(self._columns[f], fields.binary) and context.get('bin_size', False):
return "length(%s) as %s" % (f,f)
return '"%s"' % (f,)
@@ -1892,6 +1901,8 @@ class orm(orm_template):
res = map(lambda x: {'id': x}, ids)
for f in fields_pre:
+ if f == self.CONCURRENCY_CHECK_FIELD:
+ continue
if self._columns[f].translate:
ids = map(lambda x: x['id'], res)
res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids)
@@ -2012,26 +2023,33 @@ class orm(orm_template):
return res[ids]
return res
- def unlink(self, cr, uid, ids, context=None):
+ def _check_concurrency(self, cr, ids, context):
if not context:
- context = {}
+ return
+ if context.get(self.CONCURRENCY_CHECK_FIELD) and self._log_access:
+ santa = "(id = %s AND %s < COALESCE(write_date, create_date, now())::timestamp)"
+ for i in range(0, len(ids), cr.IN_MAX):
+ sub_ids = tools.flatten(((i, context[self.CONCURRENCY_CHECK_FIELD][str(i)])
+ for i in ids[i:i+cr.IN_MAX]
+ if str(i) in context[self.CONCURRENCY_CHECK_FIELD]))
+ if sub_ids:
+ cr.execute("SELECT count(1) FROM %s WHERE %s" % (self._table, " OR ".join([santa]*(len(sub_ids)/2))), sub_ids)
+ res = cr.fetchone()
+ if res and res[0]:
+ raise except_orm('ConcurrencyException', _('Records were modified in the meanwhile'))
+
+ del context[self.CONCURRENCY_CHECK_FIELD]
+
+
+ def unlink(self, cr, uid, ids, context=None):
if not ids:
return True
if isinstance(ids, (int, long)):
ids = [ids]
result_store = self._store_get_values(cr, uid, ids, None, context)
- delta = context.get('read_delta', False)
- if delta and self._log_access:
- for i in range(0, len(ids), cr.IN_MAX):
- sub_ids = ids[i:i+cr.IN_MAX]
- cr.execute("select (now() - min(write_date)) <= '%s'::interval " \
- "from \"%s\" where id in (%s)" %
- (delta, self._table, ",".join(map(str, sub_ids))))
- res = cr.fetchone()
- if res and res[0]:
- raise except_orm(_('ConcurrencyException'),
- _('This record was modified in the meanwhile'))
+
+ self._check_concurrency(cr, ids, context)
self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink')
@@ -2112,24 +2130,11 @@ class orm(orm_template):
return True
if isinstance(ids, (int, long)):
ids = [ids]
- delta = context.get('read_delta', False)
- if delta and self._log_access:
- for i in range(0, len(ids), cr.IN_MAX):
- sub_ids = ids[i:i+cr.IN_MAX]
- cr.execute("select (now() - min(write_date)) <= '%s'::interval " \
- "from %s where id in (%s)" %
- (delta, self._table, ",".join(map(str, sub_ids))))
- res = cr.fetchone()
- if res and res[0]:
- for field in vals:
- if field in self._columns and self._columns[field]._classic_write:
- raise except_orm(_('ConcurrencyException'),
- _('This record was modified in the meanwhile'))
+
+ self._check_concurrency(cr, ids, context)
self.pool.get('ir.model.access').check(cr, user, self._name, 'write')
- #for v in self._inherits.values():
- # assert v not in vals, (v, vals)
upd0 = []
upd1 = []
upd_todo = []
@@ -2277,10 +2282,6 @@ class orm(orm_template):
''', (leftbound,rightbound,cwidth,cleft,cright,treeshift,leftbound,rightbound,
cwidth,cleft,cright,treeshift,leftrange,rightrange))
- if 'read_delta' in context:
- del context['read_delta']
-
-
result = self._store_get_values(cr, user, ids, vals.keys(), context)
for order, object, ids, fields in result:
self.pool.get(object)._store_set_values(cr, user, ids, fields, context)
diff --git a/bin/service/web_services.py b/bin/service/web_services.py
index 7b4b5c35156..ab13bae4451 100644
--- a/bin/service/web_services.py
+++ b/bin/service/web_services.py
@@ -518,6 +518,13 @@ wizard()
# Report state:
# False -> True
#
+
+class ExceptionWithTraceback(Exception):
+ def __init__(self, msg, tb):
+ self.message = msg
+ self.traceback = tb
+ self.args = (msg, tb)
+
class report_spool(netsvc.Service):
def __init__(self, name='report'):
netsvc.Service.__init__(self, name)
@@ -553,12 +560,12 @@ class report_spool(netsvc.Service):
except Exception, exception:
import traceback
import sys
- tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
- sys.exc_type, sys.exc_value, sys.exc_traceback))
+ tb = sys.exc_info()
+ tb_s = "".join(traceback.format_exception(*tb))
logger = netsvc.Logger()
logger.notifyChannel('web-services', netsvc.LOG_ERROR,
'Exception: %s\n%s' % (str(exception), tb_s))
- self._reports[id]['exception'] = exception
+ self._reports[id]['exception'] = ExceptionWithTraceback(tools.exception_to_unicode(exception), tb)
self._reports[id]['state'] = True
cr.close()
return True