server/edition.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 02 Aug 2012 19:00:22 +0200
changeset 8513 552de9f0c46d
parent 8494 1527b012802f
child 8556 bbe0d6985e59
permissions -rw-r--r--
[entity edition] stop comparing values as it may trigger exceptions (e.g. timeseries cube tests) Rely on a changes in yams instead where we have guarantee to have only comparable objects. This follows changesets 1527b012802f, 25da1e5c7c50 and 4ba11607d84a, and should definitly closes #2423719
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
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    20
from __future__ import with_statement
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    21
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    22
__docformat__ = "restructuredtext en"
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
from copy import copy
7132
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    25
from yams import ValidationError
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
    26
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    27
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    28
_MARKER = object()
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    29
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    30
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
    31
    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
    32
        self.__entity = entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    33
    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
    34
        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
    35
    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
    36
        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
    37
    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
    38
        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
    39
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    40
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    41
class EditedEntity(dict):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    42
    """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
    43
    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
    44
        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
    45
        self.entity = entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    46
        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
    47
        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
    48
        self.saved = False
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    49
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    50
    def __hash__(self):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    51
        # dict|set keyable
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    52
        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
    53
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    54
    def __cmp__(self, other):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    55
        # we don't want comparison by value inherited from dict
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    56
        return cmp(id(self), id(other))
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)
8513
552de9f0c46d [entity edition] stop comparing values as it may trigger exceptions (e.g. timeseries cube tests)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8494
diff changeset
    64
        # mark attribute as needing purge by the client
552de9f0c46d [entity edition] stop comparing values as it may trigger exceptions (e.g. timeseries cube tests)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8494
diff changeset
    65
        self.entity._cw_dont_cache_attribute(attr)
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    66
        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
    67
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    68
    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
    69
        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
    70
        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
    71
        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
    72
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
    73
    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
    74
        # 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
    75
        # 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
    76
        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
    77
7123
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    78
    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
    79
        # 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
    80
        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
    81
        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
    82
        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
    83
        return value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    84
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    85
    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
    86
        assert attr != 'eid'
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    87
        # 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
    88
        # 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
    89
        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
    90
            self[attr] = default
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    91
        return self[attr]
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    92
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    93
    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
    94
        if skipsec:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    95
            setitem = self.__setitem__
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    96
        else:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
    97
            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
    98
        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
    99
            setitem(attr, value)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   100
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   101
    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
   102
        """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
   103
        skip_security
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   104
        """
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   105
        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
   106
        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
   107
        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
   108
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   109
    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
   110
        """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
   111
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   112
        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
   113
        """
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   114
        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
   115
        # 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
   116
        # fetch old value
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   117
        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
   118
        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
   119
        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
   120
            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
   121
        else:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   122
            newvalue = oldvalue
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   123
        return oldvalue, newvalue
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   124
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   125
    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
   126
        """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
   127
        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
   128
            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
   129
                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
   130
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   131
    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
   132
        """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
   133
        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
   134
        """
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   135
        entity = self.entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   136
        if creation:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   137
            # 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
   138
            # required attributes
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   139
            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
   140
                         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
   141
        else:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   142
            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
   143
                         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
   144
        try:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   145
            entity.e_schema.check(dict_protocol_catcher(entity),
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   146
                                  creation=creation, _=entity._cw._,
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   147
                                  relations=relations)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   148
        except ValidationError, ex:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   149
            ex.entity = self.entity
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   150
            raise
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   151
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   152
    def clone(self):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   153
        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
   154
        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
   155
        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
   156
        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
   157
        return thecopy