[IMP] shortcut call to eval_domain_and_context to be evaluated on the JS side, also add some offline-evaluation of contexts and domains in rpc call methods
bzr revid: xmo@openerp.com-20121011100532-5ihje0maslp37zpf
This commit is contained in:
parent
b94e9c30a7
commit
e6b77eb820
|
@ -997,75 +997,6 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
|
|||
this.server = this.origin; // keep chs happy
|
||||
this.rpc_function = (this.origin == window_origin) ? this.rpc_json : this.rpc_jsonp;
|
||||
},
|
||||
/**
|
||||
* FIXME: Huge testing hack, especially the evaluation context, rewrite + test for real before switching
|
||||
*/
|
||||
test_eval: function (source, expected) {
|
||||
var match_template = '<ul>' +
|
||||
'<li>Source: %(source)s</li>' +
|
||||
'<li>Local: %(local)s</li>' +
|
||||
'<li>Remote: %(remote)s</li>' +
|
||||
'</ul>',
|
||||
fail_template = '<ul>' +
|
||||
'<li>Error: %(error)s</li>' +
|
||||
'<li>Source: %(source)s</li>' +
|
||||
'</ul>';
|
||||
try {
|
||||
// see Session.eval_context in Python
|
||||
var ctx = instance.web.pyeval.eval('contexts',
|
||||
([this.context] || []).concat(source.contexts));
|
||||
if (!_.isEqual(ctx, expected.context)) {
|
||||
instance.webclient.notification.warn('Context mismatch, report to xmo',
|
||||
_.str.sprintf(match_template, {
|
||||
source: JSON.stringify(source.contexts),
|
||||
local: JSON.stringify(ctx),
|
||||
remote: JSON.stringify(expected.context)
|
||||
}), true);
|
||||
}
|
||||
} catch (e) {
|
||||
instance.webclient.notification.warn('Context fail, report to xmo',
|
||||
_.str.sprintf(fail_template, {
|
||||
error: e.message,
|
||||
source: JSON.stringify(source.contexts)
|
||||
}), true);
|
||||
}
|
||||
|
||||
try {
|
||||
var dom = instance.web.pyeval.eval('domains', source.domains);
|
||||
if (!_.isEqual(dom, expected.domain)) {
|
||||
instance.webclient.notification.warn('Domains mismatch, report to xmo',
|
||||
_.str.sprintf(match_template, {
|
||||
source: JSON.stringify(source.domains),
|
||||
local: JSON.stringify(dom),
|
||||
remote: JSON.stringify(expected.domain)
|
||||
}), true);
|
||||
}
|
||||
} catch (e) {
|
||||
instance.webclient.notification.warn('Domain fail, report to xmo',
|
||||
_.str.sprintf(fail_template, {
|
||||
error: e.message,
|
||||
source: JSON.stringify(source.domains)
|
||||
}), true);
|
||||
}
|
||||
|
||||
try {
|
||||
var groups = instance.web.pyeval.eval('groupbys', source.group_by_seq);
|
||||
if (!_.isEqual(groups, expected.group_by)) {
|
||||
instance.webclient.notification.warn('GroupBy mismatch, report to xmo',
|
||||
_.str.sprintf(match_template, {
|
||||
source: JSON.stringify(source.group_by_seq),
|
||||
local: JSON.stringify(groups),
|
||||
remote: JSON.stringify(expected.group_by)
|
||||
}), true);
|
||||
}
|
||||
} catch (e) {
|
||||
instance.webclient.notification.warn('GroupBy fail, report to xmo',
|
||||
_.str.sprintf(fail_template, {
|
||||
error: e.message,
|
||||
source: JSON.stringify(source.group_by_seq)
|
||||
}), true);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Executes an RPC call, registering the provided callbacks.
|
||||
*
|
||||
|
@ -1098,13 +1029,17 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
|
|||
this.trigger('request', url, payload);
|
||||
var aborter = params.aborter;
|
||||
delete params.aborter;
|
||||
var request = this.rpc_function(url, payload).then(
|
||||
function (response, textStatus, jqXHR) {
|
||||
var request;
|
||||
if (url.url === '/web/session/eval_domain_and_context') {
|
||||
// intercept eval_domain_and_context
|
||||
request = instance.web.pyeval.eval_domains_and_contexts(
|
||||
params)
|
||||
} else {
|
||||
request = this.rpc_function(url, payload);
|
||||
}
|
||||
request.then(function (response, textStatus, jqXHR) {
|
||||
self.trigger('response', response);
|
||||
if (!response.error) {
|
||||
if (url.url === '/web/session/eval_domain_and_context') {
|
||||
self.test_eval(params, response.result);
|
||||
}
|
||||
deferred.resolve(response["result"], textStatus, jqXHR);
|
||||
} else if (response.error.data.type === "session_invalid") {
|
||||
self.uid = false;
|
||||
|
|
|
@ -61,8 +61,10 @@ instance.web.Query = instance.web.Class.extend({
|
|||
return instance.session.rpc('/web/dataset/search_read', {
|
||||
model: this._model.name,
|
||||
fields: this._fields || false,
|
||||
domain: this._model.domain(this._filter),
|
||||
context: this._model.context(this._context),
|
||||
domain: instance.web.pyeval.eval('domains',
|
||||
[this._model.domain(this._filter)]),
|
||||
context: instance.web.pyeval.eval('contexts',
|
||||
[this._model.context(this._context)]),
|
||||
offset: this._offset,
|
||||
limit: this._limit,
|
||||
sort: instance.web.serialize_sort(this._order_by)
|
||||
|
@ -280,6 +282,7 @@ instance.web.Model = instance.web.Class.extend({
|
|||
kwargs = args;
|
||||
args = [];
|
||||
}
|
||||
instance.web.pyeval.ensure_evaluated(args, kwargs);
|
||||
return instance.session.rpc('/web/dataset/call_kw', {
|
||||
model: this.name,
|
||||
method: method,
|
||||
|
@ -291,7 +294,7 @@ instance.web.Model = instance.web.Class.extend({
|
|||
* Fetches a Query instance bound to this model, for searching
|
||||
*
|
||||
* @param {Array<String>} [fields] fields to ultimately fetch during the search
|
||||
* @returns {openerp.web.Query}
|
||||
* @returns {instance.web.Query}
|
||||
*/
|
||||
query: function (fields) {
|
||||
return new instance.web.Query(this, fields);
|
||||
|
@ -339,9 +342,11 @@ instance.web.Model = instance.web.Class.extend({
|
|||
* FIXME: remove when evaluator integrated
|
||||
*/
|
||||
call_button: function (method, args) {
|
||||
instance.web.pyeval.ensure_evaluated(args, {});
|
||||
return instance.session.rpc('/web/dataset/call_button', {
|
||||
model: this.name,
|
||||
method: method,
|
||||
// Should not be necessary anymore. Integrate remote in this?
|
||||
domain_id: null,
|
||||
context_id: args.length - 1,
|
||||
args: args || []
|
||||
|
@ -599,9 +604,12 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
|
|||
* @returns {$.Deferred}
|
||||
*/
|
||||
call_and_eval: function (method, args, domain_index, context_index) {
|
||||
instance.web.pyeval.ensure_evaluated(args, {});
|
||||
return instance.session.rpc('/web/dataset/call', {
|
||||
model: this.model,
|
||||
method: method,
|
||||
// Should not be necessary anymore as ensure_evaluated traverses
|
||||
// all of the args array
|
||||
domain_id: domain_index == undefined ? null : domain_index,
|
||||
context_id: context_index == undefined ? null : context_index,
|
||||
args: args || []
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* py.js helpers and setup
|
||||
*/
|
||||
openerp.web.pyeval = function (instance) {
|
||||
var _t = instance.web._t;
|
||||
instance.web.pyeval = {};
|
||||
|
||||
var obj = function () {};
|
||||
|
@ -317,4 +318,60 @@ openerp.web.pyeval = function (instance) {
|
|||
}
|
||||
throw new Error("Unknow evaluation type " + type)
|
||||
};
|
||||
|
||||
var eval_arg = function (arg) {
|
||||
if (typeof arg !== 'object' || !arg.__ref) { return arg; }
|
||||
switch(arg.__ref) {
|
||||
case 'domain': case 'compound_domain':
|
||||
return instance.web.pyeval.eval('domains', [arg]);
|
||||
case 'context': case 'compound_context':
|
||||
return instance.web.pyeval.eval('contexts', [arg]);
|
||||
default:
|
||||
throw new Error(_t("Unknown nonliteral type " + arg.__ref));
|
||||
}
|
||||
};
|
||||
/**
|
||||
* If args or kwargs are unevaluated contexts or domains (compound or not),
|
||||
* evaluated them in-place.
|
||||
*
|
||||
* Potentially mutates both parameters.
|
||||
*
|
||||
* @param args
|
||||
* @param kwargs
|
||||
*/
|
||||
instance.web.pyeval.ensure_evaluated = function (args, kwargs) {
|
||||
for (var i=0; i<args.length; ++i) {
|
||||
args[i] = eval_arg(args[i]);
|
||||
}
|
||||
for (var k in kwargs) {
|
||||
if (!kwargs.hasOwnProperty(k)) { continue; }
|
||||
kwargs[k] = eval_arg(kwargs[k]);
|
||||
}
|
||||
};
|
||||
instance.web.pyeval.eval_domains_and_contexts = function (source) {
|
||||
var d = new $.Deferred();
|
||||
setTimeout(function () {
|
||||
try {
|
||||
var contexts = ([instance.session.context] || []).concat(source.contexts);
|
||||
// see Session.eval_context in Python
|
||||
d.resolve({result: {
|
||||
context: instance.web.pyeval.eval('contexts', contexts),
|
||||
domain: instance.web.pyeval.eval('domains', source.domains),
|
||||
group_by: instance.web.pyeval.eval('groupbys', source.group_by_seq)
|
||||
}}, 'success', {});
|
||||
} catch (e) {
|
||||
d.resolve({ error: {
|
||||
code: 400,
|
||||
message: _t("Evaluation Error"),
|
||||
data: {
|
||||
type: 'local_exception',
|
||||
debug: _.str.sprintf(
|
||||
_t("Local evaluation failure\n%s\n\n%s"),
|
||||
e.message, JSON.stringify(source))
|
||||
}
|
||||
}});
|
||||
}
|
||||
}, 0);
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue