diff --git a/bin/addons/base/ir/ir_rule.py b/bin/addons/base/ir/ir_rule.py index 20ceb737601..f096d53a93d 100644 --- a/bin/addons/base/ir/ir_rule.py +++ b/bin/addons/base/ir/ir_rule.py @@ -137,10 +137,9 @@ class ir_rule(osv.osv): if not (field_id or operator or operand): return {} - def domain_get(self, cr, uid, model_name): - # root user above constraint + def domain_get2(self, cr, uid, model_name): if uid == 1: - return '', [] + return [] cr.execute("""SELECT r.id FROM ir_rule r @@ -152,64 +151,14 @@ class ir_rule(osv.osv): JOIN res_groups_users_rel u_rel ON (g_rel.group_id = u_rel.gid) WHERE u_rel.uid = %s) OR g.global)""", (model_name, uid)) ids = map(lambda x:x[0], cr.fetchall()) - if not ids: - return '', [] - obj = self.pool.get(model_name) - add = [] - add_str = [] - sub = [] - sub_str = [] - clause={} - clause_global={} + dom = [] for rule in self.browse(cr, uid, ids): - dom = rule.domain - if rule.rule_group['global']: - clause_global.setdefault(rule.rule_group.id, []) - clause_global[rule.rule_group.id].append(obj._where_calc(cr, uid, dom, active_test=False)) - else: - clause.setdefault(rule.rule_group.id, []) - clause[rule.rule_group.id].append(obj._where_calc(cr, uid, dom, active_test=False)) - - def _query(clause, test): - query = '' - val = [] - for g in clause.values(): - if not g: - continue - if len(query): - query += ' '+test+' ' - query += '(' - first = True - for c in g: - if not first: - query += ' AND ' - first = False - query += '(' - first2 = True - for clause in c[0]: - if not first2: - query += ' AND ' - first2 = False - query += clause - query += ')' - val += c[1] - query += ')' - return query, val - - query, val = _query(clause, 'OR') - query_global, val_global = _query(clause_global, 'OR') - if query_global: - if query: - query = '('+query+') OR '+query_global - val.extend(val_global) - else: - query = query_global - val = val_global - - - if query: - query = '('+query+')' - return query, val + dom += rule.domain + return dom + def domain_get(self, cr, uid, model_name): + dom = self.domain_get2(cr, uid, model_name) + d1,d2,tables = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False) + return ' and '.join(d1), d2, tables domain_get = tools.cache()(domain_get) def unlink(self, cr, uid, ids, context=None): diff --git a/bin/osv/expression.py b/bin/osv/expression.py index d1fdfedf464..6dbe600fe0c 100644 --- a/bin/osv/expression.py +++ b/bin/osv/expression.py @@ -115,14 +115,14 @@ class expression(object): main_table = table fargs = left.split('.', 1) index = i - if left in table._inherit_fields: + if fargs[0] in table._inherit_fields: while True: field = main_table._columns.get(fargs[0], False) if field: working_table = main_table self.__tables[i] = working_table break - working_table = main_table.pool.get(main_table._inherit_fields[left][0]) + working_table = main_table.pool.get(main_table._inherit_fields[fargs[0]][0]) if working_table not in self.__tables.values(): self.__joins.append(('%s.%s=%s.%s' % (working_table._table, 'id', main_table._table, main_table._inherits[working_table._name]), working_table._table)) self.__tables[index] = working_table diff --git a/bin/osv/fields.py b/bin/osv/fields.py index d86c48bdc1a..a8cf6e85b8d 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -506,12 +506,12 @@ class many2many(_column): limit_str = self._limit is not None and ' limit %d' % self._limit or '' obj = obj.pool.get(self._obj) - d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name) + d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name) if d1: d1 = ' and ' + d1 cr.execute('SELECT '+self._rel+'.'+self._id2+','+self._rel+'.'+self._id1+' \ - FROM '+self._rel+' , '+obj._table+' \ + FROM '+self._rel+' , '+(','.join(tables))+' \ WHERE '+self._rel+'.'+self._id1+' = ANY (%s) \ AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+d1 +limit_str+' order by '+obj._table+'.'+obj._order+' offset %s', @@ -544,10 +544,10 @@ class many2many(_column): cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%s', (id,)) elif act[0] == 6: - d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name) + d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name) if d1: d1 = ' and ' + d1 - cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+obj._table+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2) + cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2) for act_nbr in act[2]: cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s, %s)', (id, act_nbr)) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index f15b452d5b2..d445e966bc9 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -2343,7 +2343,6 @@ class orm(orm_template): select = map(lambda x: isinstance(x,dict) and x['id'] or x, select) result = self._read_flat(cr, user, select, fields, context, load) - for r in result: for key, v in r.items(): if v == None: @@ -2361,8 +2360,7 @@ class orm(orm_template): id_exist = cr.fetchone() if not id_exist: cr.execute('update "'+self._table+'" set "'+key+'"=NULL where "%s"=%s' %(key,''.join("'"+str(v)+"'"))) - r[key] = '' - + r[key] = '' if isinstance(ids, (int, long, dict)): return result and result[0] or False return result @@ -2377,7 +2375,7 @@ class orm(orm_template): 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) + d1, d2, tables = 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 = [f for f in fields_to_read if @@ -2392,7 +2390,7 @@ class orm(orm_template): return "date_trunc('second', %s) as %s" % (f, f) if f == self.CONCURRENCY_CHECK_FIELD: if self._log_access: - return "COALESCE(write_date, create_date, now())::timestamp AS %s" % (f,) + return "COALESCE(%s.write_date, %s.create_date, now())::timestamp AS %s" % (self._table, self._table, f,) return "now()::timestamp AS %s" % (f,) if isinstance(self._columns[f], fields.binary) and context.get('bin_size', False): return 'length("%s") as "%s"' % (f, f) @@ -2401,8 +2399,8 @@ class orm(orm_template): for i in range(0, len(ids), cr.IN_MAX): sub_ids = ids[i:i+cr.IN_MAX] if d1: - cr.execute('SELECT %s FROM \"%s\" WHERE id = ANY (%%s) AND %s ORDER BY %s' % \ - (','.join(fields_pre2 + ['id']), self._table, d1, + cr.execute('SELECT %s FROM %s WHERE %s.id = ANY (%%s) AND %s ORDER BY %s' % \ + (','.join(fields_pre2 + [self._table + '.id']), ','.join(tables), self._table, d1, self._order),[sub_ids,]+d2) if not cr.rowcount == len({}.fromkeys(sub_ids)): raise except_orm(_('AccessError'), @@ -2588,7 +2586,7 @@ class orm(orm_template): # ids2 = [x[self._inherits[key]] for x in res] # self.pool.get(key).unlink(cr, uid, ids2) - d1, d2 = self.pool.get('ir.rule').domain_get(cr, uid, self._name) + d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name) if d1: d1 = ' AND '+d1 @@ -2596,19 +2594,15 @@ class orm(orm_template): sub_ids = ids[i:i+cr.IN_MAX] str_d = string.join(('%s',)*len(sub_ids), ',') if d1: - cr.execute('SELECT id FROM "'+self._table+'" ' \ - 'WHERE id IN ('+str_d+')'+d1, sub_ids+d2) + cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \ + 'WHERE '+self._table+'.id IN ('+str_d+')'+d1, sub_ids+d2) if not cr.rowcount == len(sub_ids): raise except_orm(_('AccessError'), _('You try to bypass an access rule (Document type: %s).') % \ self._description) - if d1: - cr.execute('delete from "'+self._table+'" ' \ - 'where id in ('+str_d+')'+d1, sub_ids+d2) - else: - cr.execute('delete from "'+self._table+'" ' \ - 'where id in ('+str_d+')', sub_ids) + cr.execute('delete from '+self._table+' ' \ + 'where id in ('+str_d+')', sub_ids) for order, object, store_ids, fields in result_store: if object<>self._name: @@ -2708,7 +2702,7 @@ class orm(orm_template): if len(upd0): - d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name) + d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name) if d1: d1 = ' and '+d1 @@ -2716,8 +2710,8 @@ class orm(orm_template): sub_ids = ids[i:i+cr.IN_MAX] ids_str = string.join(map(str, sub_ids), ',') if d1: - cr.execute('SELECT id FROM "'+self._table+'" ' \ - 'WHERE id IN ('+ids_str+')'+d1, d2) + cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \ + 'WHERE '+self._table+'.id IN ('+ids_str+')'+d1, d2) if not cr.rowcount == len({}.fromkeys(sub_ids)): raise except_orm(_('AccessError'), _('You try to bypass an access rule (Document type: %s).') % \ @@ -2728,12 +2722,8 @@ class orm(orm_template): raise except_orm(_('AccessError'), _('You try to write on an record that doesn\'t exist ' \ '(Document type: %s).') % self._description) - if d1: - cr.execute('update "'+self._table+'" set '+string.join(upd0, ',')+' ' \ - 'where id in ('+ids_str+')'+d1, upd1+ d2) - else: - cr.execute('update "'+self._table+'" set '+string.join(upd0, ',')+' ' \ - 'where id in ('+ids_str+')', upd1) + cr.execute('update '+self._table+' set '+string.join(upd0, ',')+' ' \ + 'where id in ('+ids_str+')', upd1) if totranslate: # TODO: optimize @@ -3161,8 +3151,8 @@ class orm(orm_template): if not context: context = {} # compute the where, order by, limit and offset clauses - (qu1, qu2, tables) = self._where_calc(cr, user, args, context=context) - + dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name) + (qu1, qu2, tables) = self._where_calc(cr, user, args+dom, context=context) if len(qu1): qu1 = ' where '+string.join(qu1, ' and ') else: @@ -3176,12 +3166,6 @@ class orm(orm_template): offset_str = offset and ' offset %d' % offset or '' - # construct a clause for the rules : - d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name) - if d1: - qu1 = qu1 and qu1+' and '+d1 or ' where '+d1 - qu2 += d2 - if count: cr.execute('select count(%s.id) from ' % self._table + ','.join(tables) +qu1 + limit_str + offset_str, qu2)