server/edition.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 04 Sep 2012 06:09:17 +0200
branchstable
changeset 8529 1daea1f433c9
parent 7471 bf9443f8725f
child 8493 25da1e5c7c50
permissions -rw-r--r--
[datafeed] make cnxset handling of datafeed source more robust currently we may run in some cases where the session has no more cnxset depending on errors and parser's handling of the cnxset. Also, free the cnxset and reacquire it later, letting a chance to other threads to run.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7132
e9c92bb79787 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7123
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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)
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),
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   144
                                  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
   145
                                  relations=relations)
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   146
        except ValidationError, ex:
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   147
            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
   148
            raise
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   149
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   150
    def clone(self):
bb303290a6cb try to reconstruct the file forgotten by syt in changeset e094b3d4eb95
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
diff changeset
   151
        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
   152
        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
   153
        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
   154
        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
   155
        return thecopy