From 7da8126ad934e2b4b44a7c0c01b4a49634e0190f Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 13 Oct 2011 13:44:49 +0200 Subject: [FIX] BufferedDataSet to not break the m2o read contract of returning a name_get format BufferedDataSet simply shoves stuff read() or create()d in its cache, but m2o is asymmetric: client writes a single id, but reads a pair of [id, name]. Since create() and write() are async (by definition) it's the best place to check if the data being written contains any m2o field, and to fix those m2o values. This, however, completely breaks o2m fields get_value(), and doesn't even work correctly for create() calls. Should probably not cache the same thing we put for creation or update eh bzr revid: xmo@openerp.com-20111013114449-rkhe95g1oi3gudab --- addons/web/static/src/js/data.js | 130 ++++++++++++++++++++++++++++++--------- 1 file changed, 100 insertions(+), 30 deletions(-) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index ea0824fb1df..79485497fdd 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -610,44 +610,114 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ on_default_get: function(res) { this.last_default_get = res; }, + /** + * Makes sure this dataset has the fields_get for its model stored locally, + * so create/write methods are able to determine if written fields are m2os + * and can name_get those fields if that's the case (in order to cache a + * correct m2o value for them) + * + * @returns {$.Deferred} whether the fields_get is done executing, provides the fields_get value to its callbacks + */ + ensure_has_fields: function () { + var self = this; + + if (this.fields_get) { + var d = $.Deferred(); + setTimeout(function () { d.resolve(self.fields_get, true); }, 0); + return d.promise(); + } else { + return self.call('fields_get', [], function (fields_get) { + self.fields_get = fields_get; + }); + } + }, + /** + * Relational fields may not be written in the same format they are read. + * + * Since the BufferedDataSet is a bit dumb, it returns what it's got stored + * in its cache, which for modified value is what it was given. This breaks + * some basic contracts of openerp such as m2o read being in the + * ``name_get`` format. + * + * Because create & write are supposed to be asynchronous, though, it + * should be easy to just name_get all incorrect values. + * + * @param {Object} data form-data to write to the cache + * @returns {$.Deferred} resolved with a fixed data dictionary + */ + fix_relational: function (data) { + var self = this; + var results = $.Deferred(); + this.ensure_has_fields().then(function (fields) { + var fields_to_fix = _(fields).chain() + .map(function (d, k) { return {key: k, descriptor: d}; }) + .filter(function (field) { + // keep m2o fields which are in the data dict + return field.descriptor.type === 'many2one' && + field.key in data; + }).pluck('key') + .value(); + var name_gets = _(fields_to_fix).map(function (field) { + return new openerp.web.DataSet(self, self.fields_get[field].relation) + .name_get([data[field]], null); + }); + $.when.apply(null, name_gets).then(function () { + var record = _.extend({}, data); + for(var i=0; i Date: Thu, 13 Oct 2011 14:42:27 +0200 Subject: [FIX] inconsistency between multiple m2o fields to name_get and single when sent to $.when bzr revid: xmo@openerp.com-20111013124227-at1nvix8yqtae8a9 --- addons/web/static/src/js/data.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 79485497fdd..a9c4319baa8 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -661,10 +661,16 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ return new openerp.web.DataSet(self, self.fields_get[field].relation) .name_get([data[field]], null); }); - $.when.apply(null, name_gets).then(function () { + // null-concat forces stupid bastard `when` to always return an + // array containing the Array-ified results of all the name_gets. + // otherwise, if there's a single field to fix it returns the + // results of the unique name_get directly. + $.when.apply(null, name_gets.concat([null])).then(function () { var record = _.extend({}, data); for(var i=0; i Date: Thu, 13 Oct 2011 14:44:35 +0200 Subject: [FIX] excessive coherence between BufferedDataSet cache and to_write and to_create queues ~/projects/tiny/web/current cache should hold readable values (so pairs for m2o fields), whereas to_create and to_write hold the data which will be processed into o2m commands and sent over the wire to create, write and context-value calls. As a result, to_create and to_write should only have atomic ids for m2o fields. Therefore, only use fixed m2o values to store in read cache. bzr revid: xmo@openerp.com-20111013124435-vbjolacjnc9f6qz4 --- addons/web/static/src/js/data.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index a9c4319baa8..dd121ed9db7 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -680,14 +680,14 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ create: function(data, callback, error_callback) { var self = this; var prom = $.Deferred().then(callback); - this.fix_relational(data).then(function (fixed_data) { + this.fix_relational(data).then(function (fixed_m2o_data) { var cached = { id:_.uniqueId(self.virtual_id_prefix), - values: fixed_data, + values: fixed_m2o_data, defaults: self.last_default_get }; self.to_create.push(_.extend(_.clone(cached), { - values: _.clone(cached.values)})); + values: _.clone(data)})); self.cache.push(cached); self.on_change(); prom.resolve({result: cached.id}); @@ -697,21 +697,21 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ write: function (id, data, options, callback) { var self = this; var to_return = $.Deferred().then(callback); - this.fix_relational(data).then(function (fixed_data) { + this.fix_relational(data).then(function (fixed_m2o_data) { var record = _.detect(self.to_create, function(x) {return x.id === id;}); record = record || _.detect(self.to_write, function(x) {return x.id === id;}); var dirty = false; if (record) { - for (var k in fixed_data) { - if (record.values[k] === undefined || record.values[k] !== fixed_data[k]) { + for (var k in data) { + if (record.values[k] === undefined || record.values[k] !== data[k]) { dirty = true; break; } } - $.extend(record.values, fixed_data); + _.extend(record.values, data); } else { dirty = true; - record = {id: id, values: fixed_data}; + record = {id: id, values: data}; self.to_write.push(record); } var cached = _.detect(self.cache, function(x) {return x.id === id;}); @@ -719,7 +719,7 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ cached = {id: id, values: {}}; this.cache.push(cached); } - $.extend(cached.values, record.values); + _.extend(cached.values, fixed_m2o_data); if (dirty) self.on_change(); to_return.resolve({result: true}); -- cgit v1.2.3 From 322d20d53c651ee86bf20f6ca936b13a2b817705 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 13 Oct 2011 14:58:58 +0200 Subject: [FIX] when performing name_get on m2o fields being written to BufferedDataSet, ignore m2o fields with 'false' value as well as those not being written at all bzr revid: xmo@openerp.com-20111013125858-pboz81w3s58lk2rl --- addons/web/static/src/js/data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index dd121ed9db7..1eaffcd0e30 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -654,7 +654,7 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ .filter(function (field) { // keep m2o fields which are in the data dict return field.descriptor.type === 'many2one' && - field.key in data; + data[field.key]; }).pluck('key') .value(); var name_gets = _(fields_to_fix).map(function (field) { -- cgit v1.2.3 From 2915308f6c6f678aead0c7a31ed337239c6eabc8 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Oct 2011 08:15:54 +0200 Subject: [REV] xmo@openerp.com-20111013124912-wton5lidyvaezsj6 see: niv bzr revid: xmo@openerp.com-20111017061554-ijg5uwg2val9hu2h --- addons/web/static/src/js/data.js | 136 +++++++++------------------------------ 1 file changed, 30 insertions(+), 106 deletions(-) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 1eaffcd0e30..ea0824fb1df 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -610,120 +610,44 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({ on_default_get: function(res) { this.last_default_get = res; }, - /** - * Makes sure this dataset has the fields_get for its model stored locally, - * so create/write methods are able to determine if written fields are m2os - * and can name_get those fields if that's the case (in order to cache a - * correct m2o value for them) - * - * @returns {$.Deferred} whether the fields_get is done executing, provides the fields_get value to its callbacks - */ - ensure_has_fields: function () { - var self = this; - - if (this.fields_get) { - var d = $.Deferred(); - setTimeout(function () { d.resolve(self.fields_get, true); }, 0); - return d.promise(); - } else { - return self.call('fields_get', [], function (fields_get) { - self.fields_get = fields_get; - }); - } - }, - /** - * Relational fields may not be written in the same format they are read. - * - * Since the BufferedDataSet is a bit dumb, it returns what it's got stored - * in its cache, which for modified value is what it was given. This breaks - * some basic contracts of openerp such as m2o read being in the - * ``name_get`` format. - * - * Because create & write are supposed to be asynchronous, though, it - * should be easy to just name_get all incorrect values. - * - * @param {Object} data form-data to write to the cache - * @returns {$.Deferred} resolved with a fixed data dictionary - */ - fix_relational: function (data) { - var self = this; - var results = $.Deferred(); - this.ensure_has_fields().then(function (fields) { - var fields_to_fix = _(fields).chain() - .map(function (d, k) { return {key: k, descriptor: d}; }) - .filter(function (field) { - // keep m2o fields which are in the data dict - return field.descriptor.type === 'many2one' && - data[field.key]; - }).pluck('key') - .value(); - var name_gets = _(fields_to_fix).map(function (field) { - return new openerp.web.DataSet(self, self.fields_get[field].relation) - .name_get([data[field]], null); - }); - // null-concat forces stupid bastard `when` to always return an - // array containing the Array-ified results of all the name_gets. - // otherwise, if there's a single field to fix it returns the - // results of the unique name_get directly. - $.when.apply(null, name_gets.concat([null])).then(function () { - var record = _.extend({}, data); - for(var i=0; i Date: Thu, 20 Oct 2011 18:20:22 +0200 Subject: [ADD] Added DataSet#select_id() bzr revid: fme@openerp.com-20111020162022-l9wifgvi6qvjb5a2 --- addons/web/static/src/js/data.js | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index ea0824fb1df..475dbe5421c 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -263,6 +263,15 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet } return this; }, + select_id: function(id) { + var idx = _.indexOf(this.ids, id); + if (idx === -1) { + return false; + } else { + this.index = idx; + return true; + } + }, /** * Read records. * -- cgit v1.2.3 From 0259bb76299927f7a15566ac79a389effeeb3e20 Mon Sep 17 00:00:00 2001 From: vishmita Date: Fri, 21 Oct 2011 17:36:45 +0530 Subject: [FIX] FF issues in dataset limit. lp bug: https://launchpad.net/bugs/876603 fixed bzr revid: vja@vja-desktop-20111021120645-qx0en9plxihle0dj --- addons/web/static/src/js/data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js/data.js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 475dbe5421c..069506586ad 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -493,7 +493,7 @@ openerp.web.DataSetStatic = openerp.web.DataSet.extend({ offset = options.offset || 0, limit = options.limit || false, fields = fields || false; - var end_pos = limit && limit !== -1 ? offset + limit : undefined; + var end_pos = limit && limit !== -1 ? offset + limit : this.ids.length; return this.read_ids(this.ids.slice(offset, end_pos), fields, callback); }, set_ids: function (ids) { -- cgit v1.2.3