- if self.datas:
- ids_orig = ids
- if isinstance(ids, (int, long)):
- ids = [ids]
- for id in ids:
- r = {'id': id}
- for f in fields_to_read:
- record = self.datas.get(id)
- if record:
- self._check_access(user, id, 'read')
- r[f] = record.get(f, False)
- if r[f] and isinstance(self._columns[f], fields.binary) and context.get('bin_size', False):
- 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_to_read)
- for f in fields_post:
- res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=result)
- for record in result:
- record[f] = res2[record['id']]
- if isinstance(ids_orig, (int, long)):
- return result[0]
- return result
-
- def write(self, cr, user, ids, vals, context=None):
- if not ids:
- return True
- vals2 = {}
- upd_todo = []
- for field in vals:
- if self._columns[field]._classic_write:
- vals2[field] = vals[field]
- else:
- upd_todo.append(field)
- for object_id in ids:
- self._check_access(user, object_id, mode='write')
- self.datas[object_id].update(vals2)
- self.datas[object_id]['internal.date_access'] = time.time()
- for field in upd_todo:
- self._columns[field].set_memory(cr, self, object_id, field, vals[field], user, context)
- self._validate(cr, user, [object_id], context)
- wf_service = netsvc.LocalService("workflow")
- wf_service.trg_write(user, self._name, object_id, cr)
- return object_id
-
- def create(self, cr, user, vals, context=None):
- self.vaccum(cr, user)
- self.next_id += 1
- id_new = self.next_id
-
- vals = self._add_missing_default_values(cr, user, vals, context)
-
- vals2 = {}
- upd_todo = []
- for field in vals:
- if self._columns[field]._classic_write:
- vals2[field] = vals[field]
- else:
- upd_todo.append(field)
- self.datas[id_new] = vals2
- self.datas[id_new]['internal.date_access'] = time.time()
- self.datas[id_new]['internal.create_uid'] = user
-
- for field in upd_todo:
- self._columns[field].set_memory(cr, self, id_new, field, vals[field], user, context)
- self._validate(cr, user, [id_new], context)
- if self._log_create and not (context and context.get('no_store_function', False)):
- message = self._description + \
- " '" + \
- self.name_get(cr, user, [id_new], context=context)[0][1] + \
- "' "+ _("created.")
- self.log(cr, user, id_new, message, True, context=context)
- wf_service = netsvc.LocalService("workflow")
- wf_service.trg_create(user, self._name, id_new, cr)
- return id_new
-
- def _where_calc(self, cr, user, args, active_test=True, context=None):
- if not context:
- context = {}
- args = args[:]
- res = []
- # if the object has a field named 'active', filter out all inactive
- # records unless they were explicitely asked for
- if 'active' in self._columns and (active_test and context.get('active_test', True)):
- if args:
- active_in_args = False
- for a in args:
- if a[0] == 'active':
- active_in_args = True
- if not active_in_args:
- args.insert(0, ('active', '=', 1))
- else:
- args = [('active', '=', 1)]
- if args:
- import expression
- e = expression.expression(args)
- e.parse(cr, user, self, context)
- res = e.exp
- return res or []
-
- def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
- if not context:
- context = {}
-
- # implicit filter on current user except for superuser
- if user != 1:
- if not args:
- args = []
- args.insert(0, ('internal.create_uid', '=', user))
-
- result = self._where_calc(cr, user, args, context=context)
- if result == []:
- return self.datas.keys()
-
- res = []
- counter = 0
- #Find the value of dict
- f = False
- if result:
- for id, data in self.datas.items():
- counter = counter + 1
- data['id'] = id
- if limit and (counter > int(limit)):
- break
- f = True
- for arg in result:
- if arg[1] == '=':
- val = eval('data[arg[0]]'+'==' +' arg[2]', locals())
- elif arg[1] in ['<', '>', 'in', 'not in', '<=', '>=', '<>']:
- val = eval('data[arg[0]]'+arg[1] +' arg[2]', locals())
- elif arg[1] in ['ilike']:
- val = (str(data[arg[0]]).find(str(arg[2]))!=-1)
-
- f = f and val
-
- if f:
- res.append(id)
- if count:
- return len(res)
- return res or []
-
- def unlink(self, cr, uid, ids, context=None):
- for id in ids:
- self._check_access(uid, id, 'unlink')
- self.datas.pop(id, None)
- if len(ids):
- cr.execute('delete from wkf_instance where res_type=%s and res_id IN %s', (self._name, tuple(ids)))
- return True
-
- def perm_read(self, cr, user, ids, context=None, details=True):
- result = []
- credentials = self.pool.get('res.users').name_get(cr, user, [user])[0]
- create_date = time.strftime('%Y-%m-%d %H:%M:%S')
- for id in ids:
- self._check_access(user, id, 'read')
- result.append({
- 'create_uid': credentials,
- 'create_date': create_date,
- 'write_uid': False,
- 'write_date': False,
- 'id': id,
- 'xmlid' : False,
- })
- return result
-
- def _check_removed_columns(self, cr, log=False):
- # nothing to check in memory...
- pass
-
- def exists(self, cr, uid, ids, context=None):
- if isinstance(ids, (long,int)):
- ids = [ids]
- return [id for id in ids if id in self.datas]
-
- def check_access_rule(self, cr, uid, ids, operation, context=None):
- # ir.rules do not currently apply for orm.memory instances,
- # only the implicit visibility=owner one.
- for id in ids:
- self._check_access(uid, id, operation)
-
-class orm(orm_template):
- _sql_constraints = []
- _table = None
- _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists']
- __logger = logging.getLogger('orm')
- __schema = logging.getLogger('orm.schema')
+ known_values = {}
+ def append_left(left_side):
+ grouped_value = left_side[groupby] and left_side[groupby][0]
+ if not grouped_value in known_values:
+ result.append(left_side)
+ known_values[grouped_value] = left_side
+ else:
+ count_attr = groupby + '_count'
+ known_values[grouped_value].update({count_attr: left_side[count_attr]})
+ def append_right(right_side):
+ grouped_value = right_side[0]
+ if not grouped_value in known_values:
+ line = dict(result_template)
+ line.update({
+ groupby: right_side,
+ '__domain': [(groupby,'=',grouped_value)] + domain,
+ })
+ result.append(line)
+ known_values[grouped_value] = line
+ while read_group_result or all_groups:
+ left_side = read_group_result[0] if read_group_result else None
+ right_side = all_groups[0] if all_groups else None
+ assert left_side is None or left_side[groupby] is False \
+ or isinstance(left_side[groupby], (tuple,list)), \
+ 'M2O-like pair expected, got %r' % left_side[groupby]
+ assert right_side is None or isinstance(right_side, (tuple,list)), \
+ 'M2O-like pair expected, got %r' % right_side
+ if left_side is None:
+ append_right(all_groups.pop(0))
+ elif right_side is None:
+ append_left(read_group_result.pop(0))
+ elif left_side[groupby] == right_side:
+ append_left(read_group_result.pop(0))
+ all_groups.pop(0) # discard right_side
+ elif not left_side[groupby] or not left_side[groupby][0]:
+ # left side == "Undefined" entry, not present on right_side
+ append_left(read_group_result.pop(0))
+ else:
+ append_right(all_groups.pop(0))
+ return result
+