[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:
Vo Minh Thu 2011-08-12 14:41:28 +02:00
parent 2f5e8d48b3
commit ddd65ab5c1
3 changed files with 44 additions and 202 deletions

View File

@ -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):
"""

View File

@ -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.

View File

@ -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. """