server/edition.py
author Rémi Cardona <remi.cardona@logilab.fr>
Tue, 15 Dec 2015 11:41:25 +0100
changeset 10978 6f88cb7b7a84
parent 10354 635cfac73d28
child 10661 e6eb0c7c2e98
permissions -rw-r--r--
merge with 3.20.12
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8494
1527b012802f [entity] more tweaks for entity attribute cache handling on cw_set/cw_create to fix test regression
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8493
diff changeset
     1
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
7132
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     3
#
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     4
# This file is part of CubicWeb.
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     5
#
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     9
# any later version.
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    10
#
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    14
# details.
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    15
#
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    18
"""helper classes to handle server-side edition of entities"""
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    19
__docformat__ = "restructuredtext en"
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    20
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    21
from copy import copy
7132
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    22
from yams import ValidationError
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    23
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    24
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    25
_MARKER = object()
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    26
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    27
class dict_protocol_catcher(object):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    28
    def __init__(self, entity):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    29
        self.__entity = entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    30
    def __getitem__(self, attr):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    31
        return self.__entity.cw_edited[attr]
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    32
    def __setitem__(self, attr, value):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    33
        self.__entity.cw_edited[attr] = value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    34
    def __getattr__(self, attr):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    35
        return getattr(self.__entity, attr)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    36
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    37
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    38
class EditedEntity(dict):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    39
    """encapsulate entities attributes being written by an RQL query"""
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    40
    def __init__(self, entity, **kwargs):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    41
        dict.__init__(self, **kwargs)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    42
        self.entity = entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    43
        self.skip_security = set()
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    44
        self.querier_pending_relations = {}
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    45
        self.saved = False
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    46
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    47
    def __hash__(self):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    48
        # dict|set keyable
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    49
        return hash(id(self))
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    50
8892
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
    51
    def __lt__(self, other):
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    52
        # we don't want comparison by value inherited from dict
8892
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
    53
        return id(self) < id(other)
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
    54
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
    55
    def __eq__(self, other):
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
    56
        return id(self) == id(other)
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    57
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    58
    def __setitem__(self, attr, value):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    59
        assert attr != 'eid'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    60
        # don't add attribute into skip_security if already in edited
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    61
        # attributes, else we may accidentaly skip a desired security check
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    62
        if attr not in self:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    63
            self.skip_security.add(attr)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    64
        self.edited_attribute(attr, value)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    65
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    66
    def __delitem__(self, attr):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    67
        assert not self.saved, 'too late to modify edited attributes'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    68
        super(EditedEntity, self).__delitem__(attr)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    69
        self.entity.cw_attr_cache.pop(attr, None)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    70
7471
bf9443f8725f [dataimport] fix #1732685: cached entity and shared cw_edited data with NoHookRQLObjectStore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7132
diff changeset
    71
    def __copy__(self):
bf9443f8725f [dataimport] fix #1732685: cached entity and shared cw_edited data with NoHookRQLObjectStore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7132
diff changeset
    72
        # default copy protocol fails in EditedEntity.__setitem__ because
bf9443f8725f [dataimport] fix #1732685: cached entity and shared cw_edited data with NoHookRQLObjectStore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7132
diff changeset
    73
        # copied entity has no skip_security attribute at this point
bf9443f8725f [dataimport] fix #1732685: cached entity and shared cw_edited data with NoHookRQLObjectStore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7132
diff changeset
    74
        return EditedEntity(self.entity, **self)
bf9443f8725f [dataimport] fix #1732685: cached entity and shared cw_edited data with NoHookRQLObjectStore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7132
diff changeset
    75
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    76
    def pop(self, attr, *args):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    77
        # don't update skip_security by design (think to storage api)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    78
        assert not self.saved, 'too late to modify edited attributes'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    79
        value = super(EditedEntity, self).pop(attr, *args)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    80
        self.entity.cw_attr_cache.pop(attr, *args)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    81
        return value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    82
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    83
    def setdefault(self, attr, default):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    84
        assert attr != 'eid'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    85
        # don't add attribute into skip_security if already in edited
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    86
        # attributes, else we may accidentaly skip a desired security check
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    87
        if attr not in self:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    88
            self[attr] = default
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    89
        return self[attr]
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    90
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    91
    def update(self, values, skipsec=True):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    92
        if skipsec:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    93
            setitem = self.__setitem__
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    94
        else:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    95
            setitem = self.edited_attribute
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    96
        for attr, value in values.iteritems():
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    97
            setitem(attr, value)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    98
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    99
    def edited_attribute(self, attr, value):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   100
        """attribute being edited by a rql query: should'nt be added to
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   101
        skip_security
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   102
        """
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   103
        assert not self.saved, 'too late to modify edited attributes'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   104
        super(EditedEntity, self).__setitem__(attr, value)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   105
        self.entity.cw_attr_cache[attr] = value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   106
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   107
    def oldnewvalue(self, attr):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   108
        """returns the couple (old attr value, new attr value)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   109
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   110
        NOTE: will only work in a before_update_entity hook
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   111
        """
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   112
        assert not self.saved, 'too late to get the old value'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   113
        # get new value and remove from local dict to force a db query to
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   114
        # fetch old value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   115
        newvalue = self.entity.cw_attr_cache.pop(attr, _MARKER)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   116
        oldvalue = getattr(self.entity, attr)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   117
        if newvalue is not _MARKER:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   118
            self.entity.cw_attr_cache[attr] = newvalue
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   119
        else:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   120
            newvalue = oldvalue
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   121
        return oldvalue, newvalue
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   122
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   123
    def set_defaults(self):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   124
        """set default values according to the schema"""
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   125
        for attr, value in self.entity.e_schema.defaults():
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   126
            if not attr in self:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   127
                self[str(attr)] = value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   128
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   129
    def check(self, creation=False):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   130
        """check the entity edition against its schema. Only final relation
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   131
        are checked here, constraint on actual relations are checked in hooks
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   132
        """
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   133
        entity = self.entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   134
        if creation:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   135
            # on creations, we want to check all relations, especially
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   136
            # required attributes
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   137
            relations = [rschema for rschema in entity.e_schema.subject_relations()
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   138
                         if rschema.final and rschema.type != 'eid']
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   139
        else:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   140
            relations = [entity._cw.vreg.schema.rschema(rtype)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   141
                         for rtype in self]
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   142
        try:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   143
            entity.e_schema.check(dict_protocol_catcher(entity),
8556
bbe0d6985e59 [validation error] refactor validation error handling so translation is done on the web side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8513
diff changeset
   144
                                  creation=creation, relations=relations)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
   145
        except ValidationError as ex:
9184
b982e88e4836 [repo] normalize ValidationError on edited entity (closes #2509729)
David Douard <david.douard@logilab.fr>
parents: 8892
diff changeset
   146
            ex.entity = self.entity.eid
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   147
            raise
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   148
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   149
    def clone(self):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   150
        thecopy = EditedEntity(copy(self.entity))
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   151
        thecopy.entity.cw_attr_cache = copy(self.entity.cw_attr_cache)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   152
        thecopy.entity._cw_related_cache = {}
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   153
        thecopy.update(self, skipsec=False)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   154
        return thecopy