[REF] osv: removed orm_memory, adapted the distinguished bits to osv_memory,
so yes, there are still two user-visible classes instead of a boolean flag. bzr revid: vmt@openerp.com-20110812124128-43rr422swy6h2vs8
This commit is contained in:
parent
2f5e8d48b3
commit
ddd65ab5c1
|
@ -91,6 +91,13 @@ def OR(domains):
|
|||
""" OR([D1,D2,...]) returns a domain representing D1 or D2 or ... """
|
||||
return combine(OR_OPERATOR, FALSE_DOMAIN, TRUE_DOMAIN, domains)
|
||||
|
||||
# Probably bad style: the domain should be already normalized (and non-empty).
|
||||
def expression_and(term, domain):
|
||||
if domain:
|
||||
return ['&', term] + normalize(domain)
|
||||
else:
|
||||
return term
|
||||
|
||||
|
||||
class expression(object):
|
||||
"""
|
||||
|
|
|
@ -2246,205 +2246,6 @@ class orm_template(object):
|
|||
values = defaults
|
||||
return values
|
||||
|
||||
class orm_memory(orm_template):
|
||||
|
||||
_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']
|
||||
_inherit_fields = {}
|
||||
_check_time = 20
|
||||
|
||||
@classmethod
|
||||
def createInstance(cls, pool, cr):
|
||||
return cls.makeInstance(pool, cr, ['_columns', '_defaults'])
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
super(orm_memory, self).__init__(pool, cr)
|
||||
self.datas = {}
|
||||
self.next_id = 0
|
||||
cr.execute('delete from wkf_instance where res_type=%s', (self._name,))
|
||||
|
||||
def _check_access(self, uid, object_id, mode):
|
||||
if uid != 1 and self.datas[object_id]['internal.create_uid'] != uid:
|
||||
raise except_orm(_('AccessError'), '%s access is only allowed on your own records for osv_memory objects except for the super-user' % mode.capitalize())
|
||||
|
||||
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:
|
||||
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.vacuum(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, id, context=None):
|
||||
return id in self.datas
|
||||
|
||||
class orm(orm_template):
|
||||
_sql_constraints = []
|
||||
_table = None
|
||||
|
@ -3541,6 +3342,7 @@ class orm(orm_template):
|
|||
vals[field] = False
|
||||
return res
|
||||
|
||||
# TODO check READ access
|
||||
def perm_read(self, cr, user, ids, context=None, details=True):
|
||||
"""
|
||||
Returns some metadata about the given records.
|
||||
|
|
|
@ -215,6 +215,7 @@ class osv_memory(orm.orm):
|
|||
self.check_id = 0
|
||||
self._max_count = config.get('osv_memory_count_limit')
|
||||
self._max_hours = config.get('osv_memory_age_limit')
|
||||
cr.execute('delete from wkf_instance where res_type=%s', (self._name,))
|
||||
|
||||
def _clean_transient_rows_older_than(self, cr, seconds):
|
||||
if not self._log_access:
|
||||
|
@ -222,9 +223,9 @@ class osv_memory(orm.orm):
|
|||
"Transient model without write_date: %s" % (self._name,))
|
||||
return
|
||||
|
||||
cr.execute("SELECT id FROM " + self._table + " WHERE "
|
||||
"COALESCE(write_date, create_date, now())::timestamp < "
|
||||
"(now() - interval %s)", ("%s seconds" % seconds,))
|
||||
cr.execute("SELECT id FROM " + self._table + " WHERE"
|
||||
" COALESCE(write_date, create_date, now())::timestamp <"
|
||||
" (now() - interval %s)", ("%s seconds" % seconds,))
|
||||
ids = [x[0] for x in cr.fetchall()]
|
||||
self.unlink(cr, openerp.SUPERUSER, ids)
|
||||
|
||||
|
@ -263,6 +264,38 @@ class osv_memory(orm.orm):
|
|||
|
||||
return True
|
||||
|
||||
def check_access_rule(self, cr, uid, ids, operation, context=None):
|
||||
# No access rules for osv_memory
|
||||
if self._log_access and uid != openerp.SUPERUSER:
|
||||
cr.execute("SELECT distinct create_uid FROM " + self._table + " WHERE"
|
||||
" id in ", (tuple(ids),))
|
||||
uids = [x[0] for x in cr.fetchall()]
|
||||
if len(uids) != 1 or uids[0] != uid:
|
||||
raise orm.except_orm(_('AccessError'), '%s access is '
|
||||
'restricted to your own records for osv_memory objects '
|
||||
'(except for the super-user).' % mode.capitalize())
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
self.vacuum(cr, uid)
|
||||
super(osv_memory, self).create(cr, uid, vals, context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
super(osv_memory, self).unlink(cr, uid, ids, context)
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
if ids:
|
||||
cr.execute('delete from wkf_instance where res_type=%s and res_id IN %s', (self._name, tuple(ids)))
|
||||
return True
|
||||
|
||||
def _search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
|
||||
|
||||
# Restrict acces to the current user, except for the super-user.
|
||||
if self._log_access and uid != openerp.SUPERUSER:
|
||||
domain = expression.expression_and(('create_uid', '=', uid), domain)
|
||||
|
||||
# TODO unclear: shoudl access_rights_uid be set to None (effectively ignoring it) or used instead of uid?
|
||||
return self._search(cr, uid, domain, offset, limit, order, context, count, access_rights_uid)
|
||||
|
||||
|
||||
class osv(orm.orm):
|
||||
""" Deprecated class. """
|
||||
|
|
Loading…
Reference in New Issue