diff --git a/bin/osv/fields.py b/bin/osv/fields.py index 959e9f109f4..ca30b8bcc74 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -102,10 +102,10 @@ class _column(object): def set_memory(self, cr, obj, id, name, value, user=None, context=None): raise Exception(_('Not implemented set_memory method !')) - def get_memory(self, cr, obj, ids, name, context=None, values=None): + def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None): raise Exception(_('Not implemented get_memory method !')) - def get(self, cr, obj, ids, name, context=None, values=None): + def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): raise Exception(_('undefined get method !')) def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None): @@ -203,6 +203,33 @@ class binary(_column): _symbol_f = lambda symb: symb and psycopg.Binary(symb) or None _symbol_set = (_symbol_c, _symbol_f) + _classic_read = False + + def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None): + if not context: + context = {} + if not values: + values = [] + + def convert(b): + if not b: + return b + return '%d bytes' % b + + res = {} + for i in ids: + val = None + for v in values: + if v['id'] == i: + val = v[name] + break + res.setdefault(i, val) + if context.get('get_binary_size', True): + res[i] = convert(val) + + return res + + get = get_memory class selection(_column): _type = 'selection' diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 4295ed76971..168ffb9d252 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1112,22 +1112,26 @@ class orm_memory(orm_template): self.unlink(ids) return True - def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): - if not fields: - fields = self._columns.keys() + def read(self, cr, user, ids, fields_to_read=None, context=None, load='_classic_read'): + if not context: + context = {} + if not fields_to_read: + fields_to_read = self._columns.keys() result = [] if self.datas: for id in ids: r = {'id': id} - for f in fields: + for f in fields_to_read: if id in self.datas: r[f] = self.datas[id].get(f, False) + if r[f] and isinstance(self._columns[f], fields.binary) and context.get('get_binary_size', True): + r[f] = len(r[f]) result.append(r) if id in self.datas: self.datas[id]['internal.date_access'] = time.time() - fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields) + fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields_to_read) for f in fields_post: - res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=False) + res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=result) for record in result: record[f] = res2[record['id']] return result @@ -1685,24 +1689,31 @@ class orm(orm_template): return result[0] return result - def _read_flat(self, cr, user, ids, fields, context=None, load='_classic_read'): + def _read_flat(self, cr, user, ids, fields_to_read, context=None, load='_classic_read'): if not context: context = {} if not ids: return [] - if fields == None: - fields = self._columns.keys() + if fields_to_read == None: + fields_to_read = self._columns.keys() # construct a clause for the rules : 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) + self._inherits.values() + fields_pre = filter(lambda x: x in self._columns and getattr(self._columns[x], '_classic_write'), fields_to_read) + self._inherits.values() res = [] if len(fields_pre): - fields_pre2 = map(lambda x: (x in ('create_date', 'write_date')) and ('date_trunc(\'second\', '+x+') as '+x) or '"'+x+'"', fields_pre) + def convert_field(f): + if f in ('create_date', 'write_date'): + return "date_trunc('second', %s) as %s" % (f, f) + if isinstance(self._columns[f], fields.binary) and context.get('get_binary_size', True): + return "length(%s) as %s" % (f,f) + return '"%s"' % (f,) + #fields_pre2 = map(lambda x: (x in ('create_date', 'write_date')) and ('date_trunc(\'second\', '+x+') as '+x) or '"'+x+'"', fields_pre) + fields_pre2 = map(convert_field, fields_pre) for i in range(0, len(ids), cr.IN_MAX): sub_ids = ids[i:i+cr.IN_MAX] if d1: @@ -1747,7 +1758,7 @@ class orm(orm_template): del record[col] # all fields which need to be post-processed by a simple function (symbol_get) - fields_post = filter(lambda x: x in self._columns and self._columns[x]._symbol_get, fields) + fields_post = filter(lambda x: x in self._columns and self._columns[x]._symbol_get, fields_to_read) if fields_post: # maybe it would be faster to iterate on the fields then on res, so that we wouldn't need # to get the _symbol_get in each occurence @@ -1757,7 +1768,7 @@ class orm(orm_template): ids = map(lambda x: x['id'], res) # all non inherited fields for which the attribute whose name is in load is False - fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields) + fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields_to_read) # Compute POST fields todo = {}