Commit ce83adb2 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[server] move EditedEntity class to its own module, to avoid cyclic dependency...

[server] move EditedEntity class to its own module, to avoid cyclic dependency when needed from e.g. session.py

--HG--
branch : stable
parent 44775b275d45
# -*- coding: utf-8 -*-
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -81,7 +81,7 @@ from logilab.common.decorators import cached
from logilab.common.deprecation import deprecated
from cubicweb.server.utils import eschema_eid
from cubicweb.server.ssplanner import EditedEntity
from cubicweb.server.edition import EditedEntity
def count_lines(stream_or_filename):
if isinstance(stream_or_filename, basestring):
......
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -38,7 +38,8 @@ from cubicweb.rset import ResultSet
from cubicweb.server.utils import cleanup_solutions
from cubicweb.server.rqlannotation import SQLGenAnnotator, set_qdata
from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction, EditedEntity
from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction
from cubicweb.server.edition import EditedEntity
from cubicweb.server.session import security_enabled
def empty_rset(rql, args, rqlst=None):
......
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......
......@@ -31,7 +31,7 @@ from yams.schema import role_name
from cubicweb import ValidationError, set_log_methods, server
from cubicweb.schema import VIRTUAL_RTYPES
from cubicweb.server.sqlutils import SQL_PREFIX
from cubicweb.server.ssplanner import EditedEntity
from cubicweb.server.edition import EditedEntity
def dbg_st_search(uri, union, varmap, args, cachekey=None, prefix='rql for'):
......
......@@ -58,7 +58,7 @@ from cubicweb.server.sqlutils import SQL_PREFIX, SQLAdapterMixIn
from cubicweb.server.rqlannotation import set_qdata
from cubicweb.server.hook import CleanupDeletedEidsCacheOp
from cubicweb.server.session import hooks_control, security_enabled
from cubicweb.server.ssplanner import EditedEntity
from cubicweb.server.edition import EditedEntity
from cubicweb.server.sources import AbstractSource, dbg_st_search, dbg_results
from cubicweb.server.sources.rql2sql import SQLGenerator
......
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -24,7 +24,7 @@ from yams.schema import role_name
from cubicweb import Binary, ValidationError
from cubicweb.server import hook
from cubicweb.server.ssplanner import EditedEntity
from cubicweb.server.edition import EditedEntity
def set_attribute_storage(repo, etype, attr, storage):
......
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -21,8 +21,6 @@ from __future__ import with_statement
__docformat__ = "restructuredtext en"
from copy import copy
from rql.stmts import Union, Select
from rql.nodes import Constant, Relation
......@@ -31,6 +29,7 @@ from cubicweb.schema import VIRTUAL_RTYPES
from cubicweb.rqlrewrite import add_types_restriction
from cubicweb.server.session import security_enabled
from cubicweb.server.hook import CleanupDeletedEidsCacheOp
from cubicweb.server.edition import EditedEntity
READ_ONLY_RTYPES = set(('eid', 'has_text', 'is', 'is_instance_of', 'identity'))
......@@ -128,132 +127,6 @@ def _build_substep_query(select, origrqlst):
return select
_MARKER = object()
class dict_protocol_catcher(object):
def __init__(self, entity):
self.__entity = entity
def __getitem__(self, attr):
return self.__entity.cw_edited[attr]
def __setitem__(self, attr, value):
self.__entity.cw_edited[attr] = value
def __getattr__(self, attr):
return getattr(self.__entity, attr)
class EditedEntity(dict):
"""encapsulate entities attributes being written by an RQL query"""
def __init__(self, entity, **kwargs):
dict.__init__(self, **kwargs)
self.entity = entity
self.skip_security = set()
self.querier_pending_relations = {}
self.saved = False
def __hash__(self):
# dict|set keyable
return hash(id(self))
def __cmp__(self, other):
# we don't want comparison by value inherited from dict
return cmp(id(self), id(other))
def __setitem__(self, attr, value):
assert attr != 'eid'
# don't add attribute into skip_security if already in edited
# attributes, else we may accidentaly skip a desired security check
if attr not in self:
self.skip_security.add(attr)
self.edited_attribute(attr, value)
def __delitem__(self, attr):
assert not self.saved, 'too late to modify edited attributes'
super(EditedEntity, self).__delitem__(attr)
self.entity.cw_attr_cache.pop(attr, None)
def pop(self, attr, *args):
# don't update skip_security by design (think to storage api)
assert not self.saved, 'too late to modify edited attributes'
value = super(EditedEntity, self).pop(attr, *args)
self.entity.cw_attr_cache.pop(attr, *args)
return value
def setdefault(self, attr, default):
assert attr != 'eid'
# don't add attribute into skip_security if already in edited
# attributes, else we may accidentaly skip a desired security check
if attr not in self:
self[attr] = default
return self[attr]
def update(self, values, skipsec=True):
if skipsec:
setitem = self.__setitem__
else:
setitem = self.edited_attribute
for attr, value in values.iteritems():
setitem(attr, value)
def edited_attribute(self, attr, value):
"""attribute being edited by a rql query: should'nt be added to
skip_security
"""
assert not self.saved, 'too late to modify edited attributes'
super(EditedEntity, self).__setitem__(attr, value)
self.entity.cw_attr_cache[attr] = value
def oldnewvalue(self, attr):
"""returns the couple (old attr value, new attr value)
NOTE: will only work in a before_update_entity hook
"""
assert not self.saved, 'too late to get the old value'
# get new value and remove from local dict to force a db query to
# fetch old value
newvalue = self.entity.cw_attr_cache.pop(attr, _MARKER)
oldvalue = getattr(self.entity, attr)
if newvalue is not _MARKER:
self.entity.cw_attr_cache[attr] = newvalue
else:
newvalue = oldvalue
return oldvalue, newvalue
def set_defaults(self):
"""set default values according to the schema"""
for attr, value in self.entity.e_schema.defaults():
if not attr in self:
self[str(attr)] = value
def check(self, creation=False):
"""check the entity edition against its schema. Only final relation
are checked here, constraint on actual relations are checked in hooks
"""
entity = self.entity
if creation:
# on creations, we want to check all relations, especially
# required attributes
relations = [rschema for rschema in entity.e_schema.subject_relations()
if rschema.final and rschema.type != 'eid']
else:
relations = [entity._cw.vreg.schema.rschema(rtype)
for rtype in self]
from yams import ValidationError
try:
entity.e_schema.check(dict_protocol_catcher(entity),
creation=creation, _=entity._cw._,
relations=relations)
except ValidationError, ex:
ex.entity = self.entity
raise
def clone(self):
thecopy = EditedEntity(copy(self.entity))
thecopy.entity.cw_attr_cache = copy(self.entity.cw_attr_cache)
thecopy.entity._cw_related_cache = {}
thecopy.update(self, skipsec=False)
return thecopy
class SSPlanner(object):
"""SingleSourcePlanner: build execution plan for rql queries
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment