dataset split, crashmanager

bzr revid: al@openerp.com-20110406211037-uzn3n0uravuy900q
This commit is contained in:
Antony Lesuisse 2011-04-06 23:10:37 +02:00
parent ebcc06bb5a
commit a65ac8c709
6 changed files with 200 additions and 168 deletions

View File

@ -9,10 +9,7 @@ import openerpweb
import openerpweb.ast
import openerpweb.nonliterals
__all__ = ['Session', 'Menu', 'DataSet', 'View',
'FormView', 'ListView', 'SearchView',
'Action']
# Should move to openerpweb.Xml2Json
class Xml2Json:
# xml2json-direct
# Simple and straightforward XML-to-JSON converter in Python
@ -276,12 +273,9 @@ class DataSet(openerpweb.Controller):
return {'fields': req.session.model(model).fields_get()}
@openerpweb.jsonrequest
def find(self, request, model, fields=False, offset=0, limit=False,
domain=None, context=None, sort=None):
return self.do_find(request, model, fields, offset, limit,
domain, context, sort)
def do_find(self, request, model, fields=False, offset=0, limit=False,
domain=None, context=None, sort=None):
def search_read(self, request, model, fields=False, offset=0, limit=False, domain=None, context=None, sort=None):
return self.do_search_read(request, model, fields, offset, limit, domain, context, sort)
def do_search_read(self, request, model, fields=False, offset=0, limit=False, domain=None, context=None, sort=None):
""" Performs a search() followed by a read() (if needed) using the
provided search criteria
@ -464,7 +458,6 @@ class FormView(View):
fields_view = self.fields_view_get(req.session, model, view_id, 'form')
return {'fields_view': fields_view}
class ListView(View):
_cp_path = "/base/listview"
@ -473,7 +466,6 @@ class ListView(View):
fields_view = self.fields_view_get(req.session, model, view_id, 'tree')
return {'fields_view': fields_view}
class SearchView(View):
_cp_path = "/base/searchview"
@ -491,7 +483,6 @@ class SideBar(View):
[[model, object_id]], False, {})
return result
class Action(openerpweb.Controller):
_cp_path = "/base/action"

View File

@ -468,9 +468,24 @@ openerp.base.Controller = openerp.base.BasicController.extend( /** @lends opener
});
openerp.base.CrashManager = openerp.base.Controller.extend({
// Controller to display exception and stacktrace and eventually report error trought maitenance contract
// if should hook on Session.on_rpc_error: function(error) {
// and display OPW etc...
init: function(session, element_id) {
this._super(session, element_id);
this.session.on_rpc_error.add(this.on_rpc_error);
},
on_rpc_error: function(error) {
var msg = error.message + "\n" + error.data.debug;
this.display_error(msg);
},
display_error: function(message) {
$('<pre></pre>').text(message).dialog({
modal: true,
buttons: {
OK: function() {
$(this).dialog("close");
}
}
});
}
});
openerp.base.Database = openerp.base.Controller.extend({
@ -677,6 +692,7 @@ openerp.base.WebClient = openerp.base.Controller.extend({
this.session = new openerp.base.Session("oe_errors");
this.loading = new openerp.base.Loading(this.session, "oe_loading");
this.crashmanager = new openerp.base.CrashManager(this.session);
// Do you autorize this ?
openerp.base.Controller.prototype.notification = new openerp.base.Notification(this.session, "oe_notification");

View File

@ -29,55 +29,119 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
init: function(session, model) {
this._super(session);
this.model = model;
this.ids = [];
this.offset
this.context = {};
this.index = 0;
this.count = 0;
this.sort = [];
this.domain = [];
this.context = {};
},
start: function() {
},
previous: function () {
this.index -= 1;
if (this.index < 0) {
this.index = this.ids.length - 1;
this.index = this.count - 1;
}
return this;
},
next: function () {
this.index += 1;
if (this.index >= this.ids.length) {
if (this.index >= this.count) {
this.index = 0;
}
return this;
},
/**
* Read records.
*/
read_ids: function (ids, fields, callback) {
var self = this;
this.rpc('/base/dataset/get', {
model: this.model,
ids: ids,
fields: fields
}, callback);
},
/**
* Read a slice of the records represented by this DataSet, based on its
* domain and context.
*
* @param {Number} [offset=0] The index from which selected records should be returned
* @param {Number} [limit=null] The maximum number of records to return
*/
read_slice: function (fields, offset, limit, callback) {
},
/**
* Read the indexed record.
*/
read_index: function (fields, callback) {
if (_.isEmpty(this.ids)) {
callback([]);
} else {
fields = fields || false;
this.read_ids([this.ids[this.index]], fields, function(records) {
callback(records[0]);
});
}
},
default_get: function() {
},
create: function() {
},
/**
* Fetch all the records selected by this DataSet, based on its domain
* and context.
*
* Fires the on_ids event.
*
* TODO: return deferred
*
* @param {Number} [offset=0] The index from which selected records should be returned
* @param {Number} [limit=null] The maximum number of records to return
* @returns itself
*/
// Rename into read() ?
fetch: function (fields, offset, limit, callback) {
write: function (id, data, callback) {
this.rpc('/base/dataset/save', {
model: this.model,
id: id,
data: data,
context: this.context
}, callback);
},
unlink: function() {
},
call: function (method, ids, args, callback) {
ids = ids || [];
args = args || [];
this.rpc('/base/dataset/call', {
model: this.model,
method: method,
ids: ids,
args: args
}, callback);
},
});
openerp.base.DataSetStatic = openerp.base.DataSet.extend({
init: function(session, model, ids) {
this._super(session, model);
// all local records
this.ids = ids;
this.count = ids.length;
},
read_slice: function (fields, offset, limit, callback) {
this.read_ids(this.ids.slice(offset, offset + limit));
},
});
openerp.base.DataSetSearch = openerp.base.DataSet.extend({
init: function(session, model) {
this._super(session, model);
this.domain = [];
this.sort = [];
this.offset = 0;
// subset records[offset:offset+limit]
// is it necessary ?
this.ids = [];
},
read_slice: function (fields, offset, limit, callback) {
var self = this;
offset = offset || 0;
this.rpc('/base/dataset/find', {
// cached search, not sure it's a good idea
if(this.offset <= offset) {
var start = offset - this.offset;
if(this.ids.length - start >= limit) {
// TODO: check if this could work do only read if possible
// return read_ids(ids.slice(start,start+limit),fields,callback)
}
}
this.rpc('/base/dataset/search_read', {
model: this.model,
fields: fields,
domain: this.domain,
@ -94,50 +158,6 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
callback(records);
});
},
fetch_ids: function (ids, fields, callback) {
var self = this;
this.rpc('/base/dataset/get', {
model: this.model,
ids: ids,
fields: fields
}, callback);
},
fetch_index: function (fields, callback) {
if (_.isEmpty(this.ids)) {
callback([]);
} else {
fields = fields || false;
this.fetch_ids([this.ids[this.index]], fields, function(records) {
callback(records[0]);
});
}
},
write: function (id, data, callback) {
this.rpc('/base/dataset/save', {
model: this.model,
id: id,
data: data,
context: this.context
}, callback);
},
call: function (method, ids, args, callback) {
ids = ids || [];
args = args || [];
this.rpc('/base/dataset/call', {
model: this.model,
method: method,
ids: ids,
args: args
}, callback);
},
unlink: function() {
}
});
openerp.base.DataSetSearch = openerp.base.DataSet.extend( /** @lends openerp.base.DataSet# */{
});
openerp.base.DataSetRelational = openerp.base.DataSet.extend( /** @lends openerp.base.DataSet# */{
});
};

View File

@ -56,6 +56,13 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
this.view_manager.sidebar.load_multi_actions();
}
},
do_show: function () {
this.dataset.read_index(this.fields_view.fields, this.on_record_loaded);
this.$element.show();
},
do_hide: function () {
this.$element.hide();
},
on_record_loaded: function(record) {
if (record) {
this.datarecord = record;
@ -79,6 +86,30 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
this.do_onchange(widget);
}
},
on_pager_action: function(action) {
switch (action) {
case 'first':
this.dataset.index = 0;
break;
case 'previous':
this.dataset.previous();
break;
case 'next':
this.dataset.next();
break;
case 'last':
this.dataset.index = this.dataset.ids.length - 1;
break;
}
this.dataset.read_index(this.fields_view.fields, this.on_record_loaded);
},
do_update_pager: function() {
var $pager = this.$element.find('div.oe_form_pager');
$pager.find("button[data-pager-action='first'], button[data-pager-action='previous']").attr('disabled', this.dataset.index == 0);
$pager.find("button[data-pager-action='next'], button[data-pager-action='last']").attr('disabled', this.dataset.index == this.dataset.ids.length - 1);
this.$element.find('span.oe_pager_index').html(this.dataset.index + 1);
this.$element.find('span.oe_pager_count').html(this.dataset.count);
},
do_onchange: function(widget) {
var self = this;
this.ready = false;
@ -159,37 +190,6 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
this.switch_readonly();
}
},
do_show: function () {
this.dataset.fetch_index(this.fields_view.fields, this.on_record_loaded);
this.$element.show();
},
do_hide: function () {
this.$element.hide();
},
do_update_pager: function() {
var $pager = this.$element.find('div.oe_form_pager');
$pager.find("button[data-pager-action='first'], button[data-pager-action='previous']").attr('disabled', this.dataset.index == 0);
$pager.find("button[data-pager-action='next'], button[data-pager-action='last']").attr('disabled', this.dataset.index == this.dataset.ids.length - 1);
this.$element.find('span.oe_pager_index').html(this.dataset.index + 1);
this.$element.find('span.oe_pager_count').html(this.dataset.count);
},
on_pager_action: function(action) {
switch (action) {
case 'first':
this.dataset.index = 0;
break;
case 'previous':
this.dataset.previous();
break;
case 'next':
this.dataset.next();
break;
case 'last':
this.dataset.index = this.dataset.ids.length - 1;
break;
}
this.dataset.fetch_index(this.fields_view.fields, this.on_record_loaded);
},
switch_readonly: function() {
},
switch_editable: function() {
@ -676,32 +676,43 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
});
openerp.base.form.FieldOne2ManyDatasSet = openerp.base.DataSet.extend({
// Extends view manager
start: function() {
},
write: function (id, data, callback) {
this._super(id, data, callback);
},
write: function (id, data, callback) {
this._super(id, data, callback);
},
unlink: function() {
}
});
openerp.base.form.FieldOne2ManyViewManager = openerp.base.ViewManager.extend({
// Extends view manager
init: function(session, element_id, dataset, views) {
this._super(session, element_id, dataset, views);
},
});
openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldOne2Many";
this.viewmanager = null;
this.operations = [];
},
start: function() {
this._super.apply(this, arguments);
this.log("o2m.start");
var action = { res_model: this.field.relation, views: [ [false,"list"], ], };
this.viewmanager = new openerp.base.ViewManagerAction(this.view.session, this.element_id, action);
var views = [ [false,"list"], ];
this.dataset = new openerp.base.form.FieldOne2ManyDatasSet(this.session, this.field.relation);
this.viewmanager = new openerp.base.form.FieldOne2ManyViewManager(this.view.session, this.element_id, this.dataset, views);
this.viewmanager.start();
},
set_value: function(value) {
this.value = value;
this.log("o2m.set_value",value);
this.viewmanager.dataset.ids = value;
// this.viewmanager.views.list.controller.do_update();
this.viewmanager.views.list.controller.do_update();
},
get_value: function(value) {
return this.operations;

View File

@ -93,12 +93,12 @@ openerp.base.ListView = openerp.base.Controller.extend({
// TODO: handle non-empty results.group_by with read_group
self.dataset.context = results.context;
self.dataset.domain = results.domain;
self.dataset.fetch(self.dataset.fields, 0, self.limit, self.do_fill_table);
self.dataset.read_slice(self.dataset.fields, 0, self.limit, self.do_fill_table);
});
},
do_update: function () {
var self = this;
self.dataset.fetch(self.dataset.fields, 0, self.limit, self.do_fill_table);
self.dataset.read(self.dataset.ids, self.dataset.fields, self.do_fill_table);
}
});

View File

@ -32,15 +32,14 @@ openerp.base.ActionManager = openerp.base.Controller.extend({
openerp.base.views = new openerp.base.Registry();
openerp.base.ViewManager = openerp.base.Controller.extend({
init: function(session, element_id, model, views) {
init: function(session, element_id, dataset, views) {
this._super(session, element_id);
this.model = model;
this.dataset = new openerp.base.DataSet(this.session, model);
this.model = dataset.model;
this.dataset = dataset;
this.searchview = null;
this.active_view = null;
this.views_src = views;
this.views = {};
},
/**
* @returns {jQuery.Deferred} initial view loading promise
@ -102,6 +101,23 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
}
return view_promise;
},
/**
* Sets up the current viewmanager's search view.
*
* @param view_id the view to use or false for a default one
* @returns {jQuery.Deferred} search view startup deferred
*/
setup_search_view: function(view_id, search_defaults) {
var self = this;
if (this.searchview) {
this.searchview.stop();
}
this.searchview = new openerp.base.SearchView(this, this.session, this.element_id + "_search", this.dataset, view_id, search_defaults);
this.searchview.on_search.add(function() {
self.views[self.active_view].controller.do_search.apply(self, arguments);
});
return this.searchview.start();
},
/**
* Called when one of the view want to execute an action
*/
@ -117,7 +133,8 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
init: function(session, element_id, action, sidebar) {
this._super(session, element_id, action.res_model, action.views);
var dataset = new openerp.base.DataSetSearch(session, action.res_model);
this._super(session, element_id, dataset, action.views);
this.action = action;
this.sidebar = sidebar;
if (sidebar)
@ -126,12 +143,25 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
start: function() {
var self = this;
var inital_view_loaded = this._super();
// init sidebar
if (this.sidebar) {
this.$element.find('.view-manager-main-sidebar').html(this.sidebar.render());
this.sidebar.start();
}
var searchview_loaded = this.setup_search_view(this.action);
// init search view
var view_id = this.action.search_view_id ? this.action.search_view_id[0] || false : false;
var search_defaults = {};
_.each(this.action.context, function (value, key) {
var match = /^search_default_(.*)$/.exec(key);
if (match) {
search_defaults[match[1]] = value;
}
});
var searchview_loaded = this.setup_search_view(view_id,search_defaults);
// schedule auto_search
if (this.action['auto_search']) {
$.when(searchview_loaded, inital_view_loaded)
.then(this.searchview.do_search);
@ -144,42 +174,6 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
}
this._super();
},
/**
* Sets up the current viewmanager's search view.
*
* @param action the action being executed
* @returns {jQuery.Deferred} search view startup deferred
*/
setup_search_view:function (action) {
var self = this;
if (this.searchview) {
this.searchview.stop();
}
var view_id = action.search_view_id ? action.search_view_id[0] || false : false;
this.searchview = new openerp.base.SearchView(this, this.session, this.element_id + "_search", this.dataset, view_id, this.search_defaults());
this.searchview.on_search.add(function() {
self.views[self.active_view].controller.do_search.apply(self, arguments);
});
return this.searchview.start();
},
/**
* Extract search view defaults from the current action's context.
*
* These defaults are of the form {search_default_*: value}
*
* @returns {Object} a clean defaults mapping of {field_name: value}
*/
search_defaults: function () {
var defaults = {};
_.each(this.action.context, function (value, key) {
var match = /^search_default_(.*)$/.exec(key);
if (match) {
defaults[match[1]] = value;
}
});
return defaults;
},
});
openerp.base.BaseWidget = openerp.base.Controller.extend({