OSV: Fix callable _sql_constraint messages
authorP. Christeas <p_christ@hol.gr>
Thu, 18 Nov 2010 18:46:43 +0000 (20:46 +0200)
committerP. Christeas <p_christ@hol.gr>
Thu, 18 Nov 2010 18:46:43 +0000 (20:46 +0200)
This fixes the support for callable sql_constraint messages, which have
always been wrong. It respects the (cr, uid, ids, context) arguments and
will fallback to Postgres's error if it cannot call.

Note that sql constraints are not properly explained when base_module_record
or audittrail are installed.

bzr revid: p_christ@hol.gr-20101118184643-8tnmj83b09kuvf1j

bin/osv/orm.py
bin/osv/osv.py

index e168146..f0678d9 100644 (file)
@@ -980,6 +980,8 @@ class orm_template(object):
                     for key in self.pool._sql_error.keys():
                         if key in e[0]:
                             msg = self.pool._sql_error[key]
+                            if hasattr(msg, '__call__'):
+                                msg = msg(cr, uid, [res_id,], context=context)
                             break
                     return (-1, res, 'Line ' + str(counter) +' : ' + msg, '')
                 if isinstance(e, osv.orm.except_orm):
index 9b1bb3a..fc72069 100644 (file)
@@ -74,17 +74,44 @@ class osv_pool(netsvc.Service):
                     uid = args[0]
 
                 lang = ctx and ctx.get('lang', False)
-                if not lang:
+                if not (lang or hasattr(src, '__call__')):
                     return src
 
                 # We open a *new* cursor here, one reason is that failed SQL
                 # queries (as in IntegrityError) will invalidate the current one.
                 cr = False
+                
+                if hasattr(src, '__call__'):
+                    # callable. We need to find the right parameters to call
+                    # the  orm._sql_message(self, cr, uid, ids, context) function,
+                    # or we skip..
+                    # our signature is f(osv_pool, dbname [,uid, obj, method, args])
+                    try:
+                        if args and len(args) > 1:
+                            obj = self.get(args[1])
+                            if len(args) > 3 and isinstance(args[3], (long, int, list)):
+                                ids = args[3]
+                            else:
+                                ids = []
+                        cr = pooler.get_db_only(dbname).cursor()
+                        return src(obj, cr, uid, ids, context=(ctx or {}))
+                    except Exception, e:
+                        pass
+                    finally:
+                        if cr: cr.close()
+                   
+                    return False # so that the original SQL error will
+                                 # be returned, it is the best we have.
+
                 try:
                     cr = pooler.get_db_only(dbname).cursor()
                     #return trans_obj._get_source( name=?)
-                    return translate(cr, name=False, source_type=ttype,
+                    res = translate(cr, name=False, source_type=ttype,
                                     lang=lang, source=src)
+                    if res:
+                        return res
+                    else:
+                        return src
                 finally:
                     if cr: cr.close()
 
@@ -105,7 +132,7 @@ class osv_pool(netsvc.Service):
                 for key in self._sql_error.keys():
                     if key in inst[0]:
                         self.abortResponse(1, _('Constraint Error'), 'warning',
-                                        tr(self._sql_error[key], 'sql_constraint'))
+                                        tr(self._sql_error[key], 'sql_constraint') or inst[0])
                 if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION):
                     msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set')
                     self.logger.debug("IntegrityError", exc_info=True)