author | Julien Cristau <julien.cristau@logilab.fr> |
Thu, 08 Jan 2015 12:22:43 +0100 | |
changeset 10146 | 78f541f50369 |
parent 10041 | 504c4eacbfd8 |
child 10354 | 635cfac73d28 |
permissions | -rw-r--r-- |
9820
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
1 |
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
3 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
4 |
# This file is part of CubicWeb. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
5 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
6 |
# CubicWeb is free software: you can redistribute it and/or modify it under the |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
9 |
# any later version. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
10 |
# |
5424
8ecbcbff9777
replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5421
diff
changeset
|
11 |
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
13 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
14 |
# details. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
15 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5320
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
5733 | 18 |
"""Base class for entity objects manipulated in clients""" |
0 | 19 |
|
20 |
__docformat__ = "restructuredtext en" |
|
21 |
||
1154 | 22 |
from warnings import warn |
8661
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
23 |
from functools import partial |
1154 | 24 |
|
0 | 25 |
from logilab.common.decorators import cached |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
26 |
from logilab.common.deprecation import deprecated |
8190
2a3c1b787688
[vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7995
diff
changeset
|
27 |
from logilab.common.registry import yes |
8930
6a02be304486
remove unused import
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8907
diff
changeset
|
28 |
from logilab.mtconverter import TransformData, xml_escape |
631
99f5852f8604
major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents:
479
diff
changeset
|
29 |
|
0 | 30 |
from rql.utils import rqlvar_maker |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
31 |
from rql.stmts import Select |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
32 |
from rql.nodes import (Not, VariableRef, Constant, make_relation, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
33 |
Relation as RqlRelation) |
0 | 34 |
|
8748
f5027f8d2478
drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8735
diff
changeset
|
35 |
from cubicweb import Unauthorized, neg_role |
7827
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
36 |
from cubicweb.utils import support_args |
0 | 37 |
from cubicweb.rset import ResultSet |
2656
a93ae0f6c0ad
R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2650
diff
changeset
|
38 |
from cubicweb.appobject import AppObject |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
39 |
from cubicweb.schema import (RQLVocabularyConstraint, RQLConstraint, |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
40 |
GeneratedConstraint) |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
41 |
from cubicweb.rqlrewrite import RQLRewriter |
709 | 42 |
|
7914
fb757a7d887e
[request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7907
diff
changeset
|
43 |
from cubicweb.uilib import soup2xhtml |
4023
eae23c40627a
drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3998
diff
changeset
|
44 |
from cubicweb.mttransforms import ENGINE |
0 | 45 |
|
46 |
_marker = object() |
|
47 |
||
48 |
def greater_card(rschema, subjtypes, objtypes, index): |
|
49 |
for subjtype in subjtypes: |
|
50 |
for objtype in objtypes: |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
51 |
card = rschema.rdef(subjtype, objtype).cardinality[index] |
0 | 52 |
if card in '+*': |
53 |
return card |
|
54 |
return '1' |
|
55 |
||
6099
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
56 |
def can_use_rest_path(value): |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
57 |
"""return True if value can be used at the end of a Rest URL path""" |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
58 |
if value is None: |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
59 |
return False |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
60 |
value = unicode(value) |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
61 |
# the check for ?, /, & are to prevent problems when running |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
62 |
# behind Apache mod_proxy |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
63 |
if value == u'' or u'?' in value or u'/' in value or u'&' in value: |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
64 |
return False |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
65 |
return True |
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
66 |
|
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
67 |
def rel_vars(rel): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
68 |
return ((isinstance(rel.children[0], VariableRef) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
69 |
and rel.children[0].variable or None), |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
70 |
(isinstance(rel.children[1].children[0], VariableRef) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
71 |
and rel.children[1].children[0].variable or None) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
72 |
) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
73 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
74 |
def rel_matches(rel, rtype, role, varname, operator='='): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
75 |
if rel.r_type == rtype and rel.children[1].operator == operator: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
76 |
same_role_var_idx = 0 if role == 'subject' else 1 |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
77 |
variables = rel_vars(rel) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
78 |
if variables[same_role_var_idx].name == varname: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
79 |
return variables[1 - same_role_var_idx] |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
80 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
81 |
def build_cstr_with_linkto_infos(cstr, args, searchedvar, evar, |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
82 |
lt_infos, eidvars): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
83 |
"""restrict vocabulary as much as possible in entity creation, |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
84 |
based on infos provided by __linkto form param. |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
85 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
86 |
Example based on following schema: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
87 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
88 |
class works_in(RelationDefinition): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
89 |
subject = 'CWUser' |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
90 |
object = 'Lab' |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
91 |
cardinality = '1*' |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
92 |
constraints = [RQLConstraint('S in_group G, O welcomes G')] |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
93 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
94 |
class welcomes(RelationDefinition): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
95 |
subject = 'Lab' |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
96 |
object = 'CWGroup' |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
97 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
98 |
If you create a CWUser in the "scientists" CWGroup you can show |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
99 |
only the labs that welcome them using : |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
100 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
101 |
lt_infos = {('in_group', 'subject'): 321} |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
102 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
103 |
You get following restriction : 'O welcomes G, G eid 321' |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
104 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
105 |
""" |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
106 |
st = cstr.snippet_rqlst.copy() |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
107 |
# replace relations in ST by eid infos from linkto where possible |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
108 |
for (info_rtype, info_role), eids in lt_infos.iteritems(): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
109 |
eid = eids[0] # NOTE: we currently assume a pruned lt_info with only 1 eid |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
110 |
for rel in st.iget_nodes(RqlRelation): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
111 |
targetvar = rel_matches(rel, info_rtype, info_role, evar.name) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
112 |
if targetvar is not None: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
113 |
if targetvar.name in eidvars: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
114 |
rel.parent.remove(rel) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
115 |
else: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
116 |
eidrel = make_relation( |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
117 |
targetvar, 'eid', (targetvar.name, 'Substitute'), |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
118 |
Constant) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
119 |
rel.parent.replace(rel, eidrel) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
120 |
args[targetvar.name] = eid |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
121 |
eidvars.add(targetvar.name) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
122 |
# if modified ST still contains evar references we must discard the |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
123 |
# constraint, otherwise evar is unknown in the final rql query which can |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
124 |
# lead to a SQL table cartesian product and multiple occurences of solutions |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
125 |
evarname = evar.name |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
126 |
for rel in st.iget_nodes(RqlRelation): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
127 |
for variable in rel_vars(rel): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
128 |
if variable and evarname == variable.name: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
129 |
return |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
130 |
# else insert snippets into the global tree |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
131 |
return GeneratedConstraint(st, cstr.mainvars - set(evarname)) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
132 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
133 |
def pruned_lt_info(eschema, lt_infos): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
134 |
pruned = {} |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
135 |
for (lt_rtype, lt_role), eids in lt_infos.iteritems(): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
136 |
# we can only use lt_infos describing relation with a cardinality |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
137 |
# of value 1 towards the linked entity |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
138 |
if not len(eids) == 1: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
139 |
continue |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
140 |
lt_card = eschema.rdef(lt_rtype, lt_role).cardinality[ |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
141 |
0 if lt_role == 'subject' else 1] |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
142 |
if lt_card not in '?1': |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
143 |
continue |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
144 |
pruned[(lt_rtype, lt_role)] = eids |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
145 |
return pruned |
6099
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
146 |
|
5726
c3b99606644d
[json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5573
diff
changeset
|
147 |
class Entity(AppObject): |
0 | 148 |
"""an entity instance has e_schema automagically set on |
149 |
the class and instances has access to their issuing cursor. |
|
1474 | 150 |
|
0 | 151 |
A property is set for each attribute and relation on each entity's type |
152 |
class. Becare that among attributes, 'eid' is *NEITHER* stored in the |
|
153 |
dict containment (which acts as a cache for other attributes dynamically |
|
154 |
fetched) |
|
155 |
||
156 |
:type e_schema: `cubicweb.schema.EntitySchema` |
|
157 |
:ivar e_schema: the entity's schema |
|
158 |
||
7816
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
159 |
:type rest_attr: str |
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
160 |
:cvar rest_attr: indicates which attribute should be used to build REST urls |
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
161 |
If `None` is specified (the default), the first unique attribute will |
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
162 |
be used ('eid' if none found) |
1474 | 163 |
|
7702
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
164 |
:type cw_skip_copy_for: list |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
165 |
:cvar cw_skip_copy_for: a list of couples (rtype, role) for each relation |
7816
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
166 |
that should be skipped when copying this kind of entity. Note that some |
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
167 |
relations such as composite relations or relations that have '?1' as |
a8a424a78c26
[entity doc] fix typo (rest_var instead of rest_attr) and cleanup doc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7803
diff
changeset
|
168 |
object cardinality are always skipped. |
0 | 169 |
""" |
170 |
__registry__ = 'etypes' |
|
717 | 171 |
__select__ = yes() |
1264
fe2934a7df7f
cleanup, avoid spurious warning
sylvain.thenault@logilab.fr
parents:
1177
diff
changeset
|
172 |
|
1474 | 173 |
# class attributes that must be set in class definition |
0 | 174 |
rest_attr = None |
1138
22f634977c95
make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents:
1132
diff
changeset
|
175 |
fetch_attrs = None |
7702
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
176 |
skip_copy_for = () # bw compat (< 3.14), use cw_skip_copy_for instead |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
177 |
cw_skip_copy_for = [('in_state', 'subject')] |
1264
fe2934a7df7f
cleanup, avoid spurious warning
sylvain.thenault@logilab.fr
parents:
1177
diff
changeset
|
178 |
# class attributes set automatically at registration time |
fe2934a7df7f
cleanup, avoid spurious warning
sylvain.thenault@logilab.fr
parents:
1177
diff
changeset
|
179 |
e_schema = None |
1474 | 180 |
|
0 | 181 |
@classmethod |
2807
696ff03f9a58
__initialize__ needs the schema as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
182 |
def __initialize__(cls, schema): |
0 | 183 |
"""initialize a specific entity class by adding descriptors to access |
184 |
entity type's attributes and relations |
|
185 |
""" |
|
3376
f5c69485381f
[appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
186 |
etype = cls.__regid__ |
0 | 187 |
assert etype != 'Any', etype |
2807
696ff03f9a58
__initialize__ needs the schema as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
188 |
cls.e_schema = eschema = schema.eschema(etype) |
0 | 189 |
for rschema, _ in eschema.attribute_definitions(): |
190 |
if rschema.type == 'eid': |
|
191 |
continue |
|
192 |
setattr(cls, rschema.type, Attribute(rschema.type)) |
|
193 |
mixins = [] |
|
2941
196493bd099c
[entity] use role instead of x
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2931
diff
changeset
|
194 |
for rschema, _, role in eschema.relation_definitions(): |
196493bd099c
[entity] use role instead of x
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2931
diff
changeset
|
195 |
if role == 'subject': |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
196 |
attr = rschema.type |
0 | 197 |
else: |
198 |
attr = 'reverse_%s' % rschema.type |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
199 |
setattr(cls, attr, Relation(rschema, role)) |
1474 | 200 |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
201 |
fetch_attrs = ('modification_date',) |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
202 |
|
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
203 |
@classmethod |
7827
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
204 |
def cw_fetch_order(cls, select, attr, var): |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
205 |
"""This class method may be used to control sort order when multiple |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
206 |
entities of this type are fetched through ORM methods. Its arguments |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
207 |
are: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
208 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
209 |
* `select`, the RQL syntax tree |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
210 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
211 |
* `attr`, the attribute being watched |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
212 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
213 |
* `var`, the variable through which this attribute's value may be |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
214 |
accessed in the query |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
215 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
216 |
When you want to do some sorting on the given attribute, you should |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
217 |
modify the syntax tree accordingly. For instance: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
218 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
219 |
.. sourcecode:: python |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
220 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
221 |
from rql import nodes |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
222 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
223 |
class Version(AnyEntity): |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
224 |
__regid__ = 'Version' |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
225 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
226 |
fetch_attrs = ('num', 'description', 'in_state') |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
227 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
228 |
@classmethod |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
229 |
def cw_fetch_order(cls, select, attr, var): |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
230 |
if attr == 'num': |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
231 |
func = nodes.Function('version_sort_value') |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
232 |
func.append(nodes.variable_ref(var)) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
233 |
sterm = nodes.SortTerm(func, asc=False) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
234 |
select.add_sort_term(sterm) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
235 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
236 |
The default implementation call |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
237 |
:meth:`~cubicweb.entity.Entity.cw_fetch_unrelated_order` |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
238 |
""" |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
239 |
cls.cw_fetch_unrelated_order(select, attr, var) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
240 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
241 |
@classmethod |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
242 |
def cw_fetch_unrelated_order(cls, select, attr, var): |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
243 |
"""This class method may be used to control sort order when multiple entities of |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
244 |
this type are fetched to use in edition (e.g. propose them to create a |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
245 |
new relation on an edited entity). |
7827
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
246 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
247 |
See :meth:`~cubicweb.entity.Entity.cw_fetch_unrelated_order` for a |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
248 |
description of its arguments and usage. |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
249 |
|
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
250 |
By default entities will be listed on their modification date descending, |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
251 |
i.e. you'll get entities recently modified first. |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
252 |
""" |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
253 |
if attr == 'modification_date': |
7827
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
254 |
select.add_sort_var(var, asc=False) |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
255 |
|
0 | 256 |
@classmethod |
257 |
def fetch_rql(cls, user, restriction=None, fetchattrs=None, mainvar='X', |
|
258 |
settype=True, ordermethod='fetch_order'): |
|
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
259 |
st = cls.fetch_rqlst(user, mainvar=mainvar, fetchattrs=fetchattrs, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
260 |
settype=settype, ordermethod=ordermethod) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
261 |
rql = st.as_string() |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
262 |
if restriction: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
263 |
# cannot use RQLRewriter API to insert 'X rtype %(x)s' restriction |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
264 |
warn('[3.14] fetch_rql: use of `restriction` parameter is ' |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
265 |
'deprecated, please use fetch_rqlst and supply a syntax' |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
266 |
'tree with your restriction instead', DeprecationWarning) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
267 |
insert = ' WHERE ' + ','.join(restriction) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
268 |
if ' WHERE ' in rql: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
269 |
select, where = rql.split(' WHERE ', 1) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
270 |
rql = select + insert + ',' + where |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
271 |
else: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
272 |
rql += insert |
0 | 273 |
return rql |
1474 | 274 |
|
0 | 275 |
@classmethod |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
276 |
def fetch_rqlst(cls, user, select=None, mainvar='X', fetchattrs=None, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
277 |
settype=True, ordermethod='fetch_order'): |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
278 |
if select is None: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
279 |
select = Select() |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
280 |
mainvar = select.get_variable(mainvar) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
281 |
select.add_selected(mainvar) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
282 |
elif isinstance(mainvar, basestring): |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
283 |
assert mainvar in select.defined_vars |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
284 |
mainvar = select.get_variable(mainvar) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
285 |
# eases string -> syntax tree test transition: please remove once stable |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
286 |
select._varmaker = rqlvar_maker(defined=select.defined_vars, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
287 |
aliases=select.aliases, index=26) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
288 |
if settype: |
9359
31a1813d53f3
[entity/url publishing] fetch_rqlst should use 'is_instance_of' instead of 'is'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9340
diff
changeset
|
289 |
rel = select.add_type_restriction(mainvar, cls.__regid__) |
31a1813d53f3
[entity/url publishing] fetch_rqlst should use 'is_instance_of' instead of 'is'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9340
diff
changeset
|
290 |
# should use 'is_instance_of' instead of 'is' so we retrieve |
31a1813d53f3
[entity/url publishing] fetch_rqlst should use 'is_instance_of' instead of 'is'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9340
diff
changeset
|
291 |
# subclasses instances as well |
31a1813d53f3
[entity/url publishing] fetch_rqlst should use 'is_instance_of' instead of 'is'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9340
diff
changeset
|
292 |
rel.r_type = 'is_instance_of' |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
293 |
if fetchattrs is None: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
294 |
fetchattrs = cls.fetch_attrs |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
295 |
cls._fetch_restrictions(mainvar, select, fetchattrs, user, ordermethod) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
296 |
return select |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
297 |
|
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
298 |
@classmethod |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
299 |
def _fetch_ambiguous_rtypes(cls, select, var, fetchattrs, subjtypes, schema): |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
300 |
"""find rtypes in `fetchattrs` that relate different subject etypes |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
301 |
taken from (`subjtypes`) to different target etypes; these so called |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
302 |
"ambiguous" relations, are added directly to the `select` syntax tree |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
303 |
selection but removed from `fetchattrs` to avoid the fetch recursion |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
304 |
because we have to choose only one targettype for the recursion and |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
305 |
adding its own fetch attrs to the selection -when we recurse- would |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
306 |
filter out the other possible target types from the result set |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
307 |
""" |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
308 |
for attr in fetchattrs.copy(): |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
309 |
rschema = schema.rschema(attr) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
310 |
if rschema.final: |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
311 |
continue |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
312 |
ttypes = None |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
313 |
for subjtype in subjtypes: |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
314 |
cur_ttypes = set(rschema.objects(subjtype)) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
315 |
if ttypes is None: |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
316 |
ttypes = cur_ttypes |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
317 |
elif cur_ttypes != ttypes: |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
318 |
# we found an ambiguous relation: remove it from fetchattrs |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
319 |
fetchattrs.remove(attr) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
320 |
# ... and add it to the selection |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
321 |
targetvar = select.make_variable() |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
322 |
select.add_selected(targetvar) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
323 |
rel = make_relation(var, attr, (targetvar,), VariableRef) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
324 |
select.add_restriction(rel) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
325 |
break |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
326 |
|
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
327 |
@classmethod |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
328 |
def _fetch_restrictions(cls, mainvar, select, fetchattrs, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
329 |
user, ordermethod='fetch_order', visited=None): |
0 | 330 |
eschema = cls.e_schema |
331 |
if visited is None: |
|
332 |
visited = set((eschema.type,)) |
|
333 |
elif eschema.type in visited: |
|
334 |
# avoid infinite recursion |
|
335 |
return |
|
336 |
else: |
|
337 |
visited.add(eschema.type) |
|
338 |
_fetchattrs = [] |
|
339 |
for attr in fetchattrs: |
|
340 |
try: |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3683
diff
changeset
|
341 |
rschema = eschema.subjrels[attr] |
0 | 342 |
except KeyError: |
343 |
cls.warning('skipping fetch_attr %s defined in %s (not found in schema)', |
|
3376
f5c69485381f
[appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
344 |
attr, cls.__regid__) |
0 | 345 |
continue |
9820
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
346 |
# XXX takefirst=True to remove warning triggered by ambiguous inlined relations |
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
347 |
rdef = eschema.rdef(attr, takefirst=True) |
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
348 |
if not user.matching_groups(rdef.get_groups('read')): |
0 | 349 |
continue |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
350 |
if rschema.final or rdef.cardinality[0] in '?1': |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
351 |
var = select.make_variable() |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
352 |
select.add_selected(var) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
353 |
rel = make_relation(mainvar, attr, (var,), VariableRef) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
354 |
select.add_restriction(rel) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
355 |
else: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
356 |
cls.warning('bad relation %s specified in fetch attrs for %s', |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
357 |
attr, cls) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
358 |
continue |
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3683
diff
changeset
|
359 |
if not rschema.final: |
2871
83c5499e1436
[entity] fix fetch_rql w/ case where it's called while entity is not 'complete' (eg time where it's being added but have not yet all mandatory relations set)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2658
diff
changeset
|
360 |
# XXX we need outer join in case the relation is not mandatory |
83c5499e1436
[entity] fix fetch_rql w/ case where it's called while entity is not 'complete' (eg time where it's being added but have not yet all mandatory relations set)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2658
diff
changeset
|
361 |
# (card == '?') *or if the entity is being added*, since in |
83c5499e1436
[entity] fix fetch_rql w/ case where it's called while entity is not 'complete' (eg time where it's being added but have not yet all mandatory relations set)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2658
diff
changeset
|
362 |
# that case the relation may still be missing. As we miss this |
83c5499e1436
[entity] fix fetch_rql w/ case where it's called while entity is not 'complete' (eg time where it's being added but have not yet all mandatory relations set)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2658
diff
changeset
|
363 |
# later information here, systematically add it. |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
364 |
rel.change_optional('right') |
7302
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
365 |
targettypes = rschema.objects(eschema.type) |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
366 |
vreg = user._cw.vreg # XXX user._cw.vreg iiiirk |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
367 |
etypecls = vreg['etypes'].etype_class(targettypes[0]) |
7302
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
368 |
if len(targettypes) > 1: |
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
369 |
# find fetch_attrs common to all destination types |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
370 |
fetchattrs = vreg['etypes'].fetch_attrs(targettypes) |
7803
02e141e41da2
some minor cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7798
diff
changeset
|
371 |
# ... and handle ambiguous relations |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
372 |
cls._fetch_ambiguous_rtypes(select, var, fetchattrs, |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
373 |
targettypes, vreg.schema) |
7302
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
374 |
else: |
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
375 |
fetchattrs = etypecls.fetch_attrs |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
376 |
etypecls._fetch_restrictions(var, select, fetchattrs, |
7302
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
377 |
user, ordermethod, visited=visited) |
6258
9b5c008267b0
[entity] give ordermethod=None to fetch_rql to tell you don't want a specific order
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
378 |
if ordermethod is not None: |
7827
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
379 |
try: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
380 |
cmeth = getattr(cls, ordermethod) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
381 |
warn('[3.14] %s %s class method should be renamed to cw_%s' |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
382 |
% (cls.__regid__, ordermethod, ordermethod), |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
383 |
DeprecationWarning) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
384 |
except AttributeError: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
385 |
cmeth = getattr(cls, 'cw_' + ordermethod) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
386 |
if support_args(cmeth, 'select'): |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
387 |
cmeth(select, attr, var) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
388 |
else: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
389 |
warn('[3.14] %s should now take (select, attr, var) and ' |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
390 |
'modify the syntax tree when desired instead of ' |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
391 |
'returning something' % cmeth, DeprecationWarning) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
392 |
orderterm = cmeth(attr, var.name) |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
393 |
if orderterm is not None: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
394 |
try: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
395 |
var, order = orderterm.split() |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
396 |
except ValueError: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
397 |
if '(' in orderterm: |
7963
059914a691a9
[entity] fix dumb name error introduced by 3.14 entity refactoring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7920
diff
changeset
|
398 |
cls.error('ignore %s until %s is upgraded', |
059914a691a9
[entity] fix dumb name error introduced by 3.14 entity refactoring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7920
diff
changeset
|
399 |
orderterm, cmeth) |
7827
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
400 |
orderterm = None |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
401 |
elif not ' ' in orderterm.strip(): |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
402 |
var = orderterm |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
403 |
order = 'ASC' |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
404 |
if orderterm is not None: |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
405 |
select.add_sort_var(select.get_variable(var), |
9bbf83f68bcc
[entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7816
diff
changeset
|
406 |
order=='ASC') |
0 | 407 |
|
1471
c889c3bcf5ec
new parent_classes method (cached)
sylvain.thenault@logilab.fr
parents:
1435
diff
changeset
|
408 |
@classmethod |
c889c3bcf5ec
new parent_classes method (cached)
sylvain.thenault@logilab.fr
parents:
1435
diff
changeset
|
409 |
@cached |
7828
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
410 |
def cw_rest_attr_info(cls): |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
411 |
"""this class method return an attribute name to be used in URL for |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
412 |
entities of this type and a boolean flag telling if its value should be |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
413 |
checked for uniqness. |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
414 |
|
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
415 |
The attribute returned is, in order of priority: |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
416 |
|
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
417 |
* class's `rest_attr` class attribute |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
418 |
* an attribute defined as unique in the class'schema |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
419 |
* 'eid' |
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
420 |
""" |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
421 |
mainattr, needcheck = 'eid', True |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
422 |
if cls.rest_attr: |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
423 |
mainattr = cls.rest_attr |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
424 |
needcheck = not cls.e_schema.has_unique_values(mainattr) |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
425 |
else: |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
426 |
for rschema in cls.e_schema.subject_relations(): |
9978
8f4b15e5b300
[entities] cw_rest_attr_info() should only consider required attributes (closes #3766717)
Rémi Cardona <remi.cardona@logilab.fr>
parents:
9820
diff
changeset
|
427 |
if (rschema.final |
8f4b15e5b300
[entities] cw_rest_attr_info() should only consider required attributes (closes #3766717)
Rémi Cardona <remi.cardona@logilab.fr>
parents:
9820
diff
changeset
|
428 |
and rschema != 'eid' |
8f4b15e5b300
[entities] cw_rest_attr_info() should only consider required attributes (closes #3766717)
Rémi Cardona <remi.cardona@logilab.fr>
parents:
9820
diff
changeset
|
429 |
and cls.e_schema.has_unique_values(rschema) |
8f4b15e5b300
[entities] cw_rest_attr_info() should only consider required attributes (closes #3766717)
Rémi Cardona <remi.cardona@logilab.fr>
parents:
9820
diff
changeset
|
430 |
and cls.e_schema.rdef(rschema.type).cardinality[0] == '1'): |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
431 |
mainattr = str(rschema) |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
432 |
needcheck = False |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
433 |
break |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
434 |
if mainattr == 'eid': |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
435 |
needcheck = False |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
436 |
return mainattr, needcheck |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
437 |
|
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
438 |
@classmethod |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
439 |
def _cw_build_entity_query(cls, kwargs): |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
440 |
relations = [] |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
441 |
restrictions = set() |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
442 |
pendingrels = [] |
7200
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
443 |
eschema = cls.e_schema |
7376
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
444 |
qargs = {} |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
445 |
attrcache = {} |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
446 |
for attr, value in kwargs.items(): |
7200
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
447 |
if attr.startswith('reverse_'): |
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
448 |
attr = attr[len('reverse_'):] |
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
449 |
role = 'object' |
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
450 |
else: |
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
451 |
role = 'subject' |
7287
601ad29268ab
[entity] improve error message
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
7213
diff
changeset
|
452 |
assert eschema.has_relation(attr, role), '%s %s not found on %s' % (attr, role, eschema) |
7200
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
453 |
rschema = eschema.subjrels[attr] if role == 'subject' else eschema.objrels[attr] |
81fd6e40a6a8
[entity creation] ensure this is a relation and not an attribute before moving things into pending_relations because value is a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7139
diff
changeset
|
454 |
if not rschema.final and isinstance(value, (tuple, list, set, frozenset)): |
8199
fb5c0e60a615
[entity] fix crash when using cw_instantiate with empty related entity list; closes #2094462
Florent Cayré <florent.cayre@gmail.com>
parents:
7995
diff
changeset
|
455 |
if len(value) == 0: |
fb5c0e60a615
[entity] fix crash when using cw_instantiate with empty related entity list; closes #2094462
Florent Cayré <florent.cayre@gmail.com>
parents:
7995
diff
changeset
|
456 |
continue # avoid crash with empty IN clause |
fb5c0e60a615
[entity] fix crash when using cw_instantiate with empty related entity list; closes #2094462
Florent Cayré <florent.cayre@gmail.com>
parents:
7995
diff
changeset
|
457 |
elif len(value) == 1: |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
458 |
value = iter(value).next() |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
459 |
else: |
7213
7644e68c4e9f
[entities] fix cw_instantiate typo
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
7210
diff
changeset
|
460 |
# prepare IN clause |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
461 |
pendingrels.append( (attr, role, value) ) |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
462 |
continue |
7376
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
463 |
if rschema.final: # attribute |
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
464 |
relations.append('X %s %%(%s)s' % (attr, attr)) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
465 |
attrcache[attr] = value |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
466 |
elif value is None: |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
467 |
pendingrels.append( (attr, role, value) ) |
7376
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
468 |
else: |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
469 |
rvar = attr.upper() |
7213
7644e68c4e9f
[entities] fix cw_instantiate typo
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
7210
diff
changeset
|
470 |
if role == 'object': |
7644e68c4e9f
[entities] fix cw_instantiate typo
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
7210
diff
changeset
|
471 |
relations.append('%s %s X' % (rvar, attr)) |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
472 |
else: |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
473 |
relations.append('X %s %s' % (attr, rvar)) |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
474 |
restriction = '%s eid %%(%s)s' % (rvar, attr) |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
475 |
if not restriction in restrictions: |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
476 |
restrictions.add(restriction) |
7376
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
477 |
if hasattr(value, 'eid'): |
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
478 |
value = value.eid |
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
479 |
qargs[attr] = value |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
480 |
rql = u'' |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
481 |
if relations: |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
482 |
rql += ', '.join(relations) |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
483 |
if restrictions: |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
484 |
rql += ' WHERE %s' % ', '.join(restrictions) |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
485 |
return rql, qargs, pendingrels, attrcache |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
486 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
487 |
@classmethod |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
488 |
def _cw_handle_pending_relations(cls, eid, pendingrels, execute): |
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
489 |
for attr, role, values in pendingrels: |
7376
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
490 |
if role == 'object': |
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
491 |
restr = 'Y %s X' % attr |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
492 |
else: |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
493 |
restr = 'X %s Y' % attr |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
494 |
if values is None: |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
495 |
execute('DELETE %s WHERE X eid %%(x)s' % restr, {'x': eid}) |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
496 |
continue |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
497 |
execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % ( |
7376
38524ca653e5
[entity] fix cw_instantiate w/ reverse_ relation crash when either multiple entities are given or an eid instead of an entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7308
diff
changeset
|
498 |
restr, ','.join(str(getattr(r, 'eid', r)) for r in values)), |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
499 |
{'x': eid}, build_descr=False) |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
500 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
501 |
@classmethod |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
502 |
def cw_instantiate(cls, execute, **kwargs): |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
503 |
"""add a new entity of this given type |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
504 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
505 |
Example (in a shell session): |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
506 |
|
8705
5b3e17a63fad
Correct typo in example
Jérôme Roy <jerome.roy@logilab.fr>
parents:
8697
diff
changeset
|
507 |
>>> companycls = vreg['etypes'].etype_class('Company') |
5b3e17a63fad
Correct typo in example
Jérôme Roy <jerome.roy@logilab.fr>
parents:
8697
diff
changeset
|
508 |
>>> personcls = vreg['etypes'].etype_class('Person') |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
509 |
>>> c = companycls.cw_instantiate(session.execute, name=u'Logilab') |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
510 |
>>> p = personcls.cw_instantiate(session.execute, firstname=u'John', lastname=u'Doe', |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
511 |
... works_for=c) |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
512 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
513 |
You can also set relations where the entity has 'object' role by |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
514 |
prefixing the relation name by 'reverse_'. Also, relation values may be |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
515 |
an entity or eid, a list of entities or eids. |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
516 |
""" |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
517 |
rql, qargs, pendingrels, attrcache = cls._cw_build_entity_query(kwargs) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
518 |
if rql: |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
519 |
rql = 'INSERT %s X: %s' % (cls.__regid__, rql) |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
520 |
else: |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
521 |
rql = 'INSERT %s X' % (cls.__regid__) |
10041
504c4eacbfd8
[entity] rather than crashing with an IndexError on entity creation, raise a meaningful exception
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
10019
diff
changeset
|
522 |
try: |
504c4eacbfd8
[entity] rather than crashing with an IndexError on entity creation, raise a meaningful exception
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
10019
diff
changeset
|
523 |
created = execute(rql, qargs).get_entity(0, 0) |
504c4eacbfd8
[entity] rather than crashing with an IndexError on entity creation, raise a meaningful exception
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
10019
diff
changeset
|
524 |
except IndexError: |
504c4eacbfd8
[entity] rather than crashing with an IndexError on entity creation, raise a meaningful exception
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
10019
diff
changeset
|
525 |
raise Exception('could not create a %r with %r (%r)' % |
504c4eacbfd8
[entity] rather than crashing with an IndexError on entity creation, raise a meaningful exception
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
10019
diff
changeset
|
526 |
(cls.__regid__, rql, qargs)) |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
527 |
created._cw_update_attr_cache(attrcache) |
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
528 |
cls._cw_handle_pending_relations(created.eid, pendingrels, execute) |
5199
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
529 |
return created |
ebb50479d2ab
[entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
530 |
|
1435
6cd6172718bb
allow to instantiate an entity without rset
sylvain.thenault@logilab.fr
parents:
1363
diff
changeset
|
531 |
def __init__(self, req, rset=None, row=None, col=0): |
2822
f26578339214
deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2818
diff
changeset
|
532 |
AppObject.__init__(self, req, rset=rset, row=row, col=col) |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
533 |
self._cw_related_cache = {} |
0 | 534 |
if rset is not None: |
535 |
self.eid = rset[row][col] |
|
536 |
else: |
|
537 |
self.eid = None |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
538 |
self._cw_is_saved = True |
5726
c3b99606644d
[json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5573
diff
changeset
|
539 |
self.cw_attr_cache = {} |
1474 | 540 |
|
0 | 541 |
def __repr__(self): |
542 |
return '<Entity %s %s %s at %s>' % ( |
|
8696
0bb18407c053
[toward py3k] rewrite dict.keys() and dict.values() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8661
diff
changeset
|
543 |
self.e_schema, self.eid, list(self.cw_attr_cache), id(self)) |
0 | 544 |
|
8892
80783605d270
[toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8793
diff
changeset
|
545 |
def __lt__(self, other): |
80783605d270
[toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8793
diff
changeset
|
546 |
raise NotImplementedError('comparison not implemented for %s' % self.__class__) |
80783605d270
[toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8793
diff
changeset
|
547 |
|
80783605d270
[toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8793
diff
changeset
|
548 |
def __eq__(self, other): |
9261
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
549 |
if isinstance(self.eid, (int, long)): |
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
550 |
return self.eid == other.eid |
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
551 |
return self is other |
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
552 |
|
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
553 |
def __hash__(self): |
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
554 |
if isinstance(self.eid, (int, long)): |
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
555 |
return self.eid |
1dfe62a9da50
[entity] give a default reasonnable __eq__ and __hash__ to Entity
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9256
diff
changeset
|
556 |
return super(Entity, self).__hash__() |
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
557 |
|
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
558 |
def _cw_update_attr_cache(self, attrcache): |
8525
c09feae04094
[entity edition] don't remove values from attribute cache on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8509
diff
changeset
|
559 |
# if context is a repository session, don't consider dont-cache-attrs as |
9774
b7b71be569cf
deprecate get/set_shared_data API
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9712
diff
changeset
|
560 |
# the instance already holds modified values and loosing them could |
8525
c09feae04094
[entity edition] don't remove values from attribute cache on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8509
diff
changeset
|
561 |
# introduce severe problems |
9774
b7b71be569cf
deprecate get/set_shared_data API
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9712
diff
changeset
|
562 |
trdata = self._cw.transaction_data |
b7b71be569cf
deprecate get/set_shared_data API
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9712
diff
changeset
|
563 |
uncached_attrs = trdata.get('%s.storage-special-process-attrs' % self.eid, set()) |
8525
c09feae04094
[entity edition] don't remove values from attribute cache on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8509
diff
changeset
|
564 |
if self._cw.is_request: |
9774
b7b71be569cf
deprecate get/set_shared_data API
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9712
diff
changeset
|
565 |
uncached_attrs.update(trdata.get('%s.dont-cache-attrs' % self.eid, set())) |
8661
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
566 |
for attr in uncached_attrs: |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
567 |
attrcache.pop(attr, None) |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
568 |
self.cw_attr_cache.pop(attr, None) |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
569 |
self.cw_attr_cache.update(attrcache) |
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
570 |
|
8661
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
571 |
def _cw_dont_cache_attribute(self, attr, repo_side=False): |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
572 |
"""Repository side method called when some attribute has been |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
573 |
transformed by a hook, hence original value should not be cached by |
8661
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
574 |
the client. |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
575 |
|
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
576 |
If repo_side is True, this means that the attribute has been |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
577 |
transformed by a *storage*, hence the original value should |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
578 |
not be cached **by anyone**. |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
579 |
|
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
580 |
This only applies to a storage special case where the value |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
581 |
specified in creation or update is **not** the value that will |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
582 |
be transparently exposed later. |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
583 |
|
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
584 |
For example we have a special "fs_importing" mode in BFSS |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
585 |
where a file path is given as attribute value and stored as is |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
586 |
in the data base. Later access to the attribute will provide |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
587 |
the content of the file at the specified path. We do not want |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
588 |
the "filepath" value to be cached. |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
589 |
""" |
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
590 |
self._cw.transaction_data.setdefault('%s.dont-cache-attrs' % self.eid, set()).add(attr) |
8661
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
591 |
if repo_side: |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
592 |
trdata = self._cw.transaction_data |
4d24ac49f90d
[entity] add a "repo_side" parameter to `_cw_dont_cache_attribute`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8660
diff
changeset
|
593 |
trdata.setdefault('%s.storage-special-process-attrs' % self.eid, set()).add(attr) |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
594 |
|
5320
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
595 |
def __json_encode__(self): |
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
596 |
"""custom json dumps hook to dump the entity's eid |
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
597 |
which is not part of dict structure itself |
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
598 |
""" |
7876
df15d194a134
[views] implement json / jsonp export views (closes #1942658)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7828
diff
changeset
|
599 |
dumpable = self.cw_attr_cache.copy() |
5320
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
600 |
dumpable['eid'] = self.eid |
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
601 |
return dumpable |
848e92bb81cc
[json] provide a custom json encoder for entities that includes eid in the json object
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5199
diff
changeset
|
602 |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
603 |
def cw_adapt_to(self, interface): |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
604 |
"""return an adapter the entity to the given interface name. |
4965
04543ed0bbdc
[source] only consider edited_attributes in source.preprocess_entity()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4913
diff
changeset
|
605 |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
606 |
return None if it can not be adapted. |
0 | 607 |
""" |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
608 |
try: |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
609 |
cache = self._cw_adapters_cache |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
610 |
except AttributeError: |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
611 |
self._cw_adapters_cache = cache = {} |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
612 |
try: |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
613 |
return cache[interface] |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
614 |
except KeyError: |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
615 |
adapter = self._cw.vreg['adapters'].select_or_none( |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
616 |
interface, self._cw, entity=self) |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
617 |
cache[interface] = adapter |
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
618 |
return adapter |
1474 | 619 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
620 |
def has_eid(self): # XXX cw_has_eid |
0 | 621 |
"""return True if the entity has an attributed eid (False |
622 |
meaning that the entity has to be created |
|
623 |
""" |
|
624 |
try: |
|
8748
f5027f8d2478
drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8735
diff
changeset
|
625 |
int(self.eid) |
0 | 626 |
return True |
627 |
except (ValueError, TypeError): |
|
628 |
return False |
|
629 |
||
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
630 |
def cw_is_saved(self): |
0 | 631 |
"""during entity creation, there is some time during which the entity |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
632 |
has an eid attributed though it's not saved (eg during |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
633 |
'before_add_entity' hooks). You can use this method to ensure the entity |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
634 |
has an eid *and* is saved in its source. |
0 | 635 |
""" |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
636 |
return self.has_eid() and self._cw_is_saved |
1474 | 637 |
|
0 | 638 |
@cached |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
639 |
def cw_metainformation(self): |
9469
032825bbacab
[multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9359
diff
changeset
|
640 |
metas = self._cw.entity_metas(self.eid) |
032825bbacab
[multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9359
diff
changeset
|
641 |
metas['source'] = self._cw.source_defs()[metas['source']] |
032825bbacab
[multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9359
diff
changeset
|
642 |
return metas |
0 | 643 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
644 |
def cw_check_perm(self, action): |
3890
d7a270f50f54
backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
diff
changeset
|
645 |
self.e_schema.check_perm(self._cw, action, eid=self.eid) |
0 | 646 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
647 |
def cw_has_perm(self, action): |
3890
d7a270f50f54
backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
diff
changeset
|
648 |
return self.e_schema.has_perm(self._cw, action, eid=self.eid) |
1474 | 649 |
|
6085
8a059eefac75
[entity] entity.view now support initargs as req.view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5980
diff
changeset
|
650 |
def view(self, __vid, __registry='views', w=None, initargs=None, **kwargs): # XXX cw_view |
0 | 651 |
"""shortcut to apply a view on this entity""" |
6085
8a059eefac75
[entity] entity.view now support initargs as req.view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5980
diff
changeset
|
652 |
if initargs is None: |
8a059eefac75
[entity] entity.view now support initargs as req.view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5980
diff
changeset
|
653 |
initargs = kwargs |
8a059eefac75
[entity] entity.view now support initargs as req.view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5980
diff
changeset
|
654 |
else: |
8a059eefac75
[entity] entity.view now support initargs as req.view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5980
diff
changeset
|
655 |
initargs.update(kwargs) |
4451
65f4665233e6
misc typos found on my way: NameError / SyntaxError / double __select__, <sigh ...>
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4436
diff
changeset
|
656 |
view = self._cw.vreg[__registry].select(__vid, self._cw, rset=self.cw_rset, |
3459
e134d2dd9992
[entity] pass cw_row and cw_col to select(vid, ...) in self.view
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3452
diff
changeset
|
657 |
row=self.cw_row, col=self.cw_col, |
6085
8a059eefac75
[entity] entity.view now support initargs as req.view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5980
diff
changeset
|
658 |
**initargs) |
5522
6be95896d49e
[entity] avoid getting w in cw_extra_kwargs when calling .view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
659 |
return view.render(row=self.cw_row, col=self.cw_col, w=w, **kwargs) |
0 | 660 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
661 |
def absolute_url(self, *args, **kwargs): # XXX cw_url |
0 | 662 |
"""return an absolute url to view this entity""" |
2059
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
663 |
# use *args since we don't want first argument to be "anonymous" to |
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
664 |
# avoid potential clash with kwargs |
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
665 |
if args: |
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
666 |
assert len(args) == 1, 'only 0 or 1 non-named-argument expected' |
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
667 |
method = args[0] |
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
668 |
else: |
af33833d7571
absolute_url / build_url refactoring to avoid potential name clash
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2058
diff
changeset
|
669 |
method = None |
0 | 670 |
# in linksearch mode, we don't want external urls else selecting |
671 |
# the object for use in the relation is tricky |
|
672 |
# XXX search_state is web specific |
|
6317
0d4dd5f6f05c
[entity, url] we should not set base_url in kwargs when actually unset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6307
diff
changeset
|
673 |
use_ext_id = False |
6307
c07763c59fcb
[entity] fix typo in absolute_url method, breaking some code w/ control of absolute url of external entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6258
diff
changeset
|
674 |
if 'base_url' not in kwargs and \ |
6100
3cd1e6a74830
fix bug introduced by 6098:a0fde9334dd0
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6099
diff
changeset
|
675 |
getattr(self._cw, 'search_state', ('normal',))[0] == 'normal': |
7552
82dde8276a5b
[datafeed, entities] url for entities from a datafeed source should be on their origin site. Closes #1769391
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7543
diff
changeset
|
676 |
sourcemeta = self.cw_metainformation()['source'] |
82dde8276a5b
[datafeed, entities] url for entities from a datafeed source should be on their origin site. Closes #1769391
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7543
diff
changeset
|
677 |
if sourcemeta.get('use-cwuri-as-url'): |
82dde8276a5b
[datafeed, entities] url for entities from a datafeed source should be on their origin site. Closes #1769391
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7543
diff
changeset
|
678 |
return self.cwuri # XXX consider kwargs? |
82dde8276a5b
[datafeed, entities] url for entities from a datafeed source should be on their origin site. Closes #1769391
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7543
diff
changeset
|
679 |
if sourcemeta.get('base-url'): |
82dde8276a5b
[datafeed, entities] url for entities from a datafeed source should be on their origin site. Closes #1769391
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7543
diff
changeset
|
680 |
kwargs['base_url'] = sourcemeta['base-url'] |
6317
0d4dd5f6f05c
[entity, url] we should not set base_url in kwargs when actually unset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6307
diff
changeset
|
681 |
use_ext_id = True |
1904
e23536d29231
minor refactoring of absolute_url()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1842
diff
changeset
|
682 |
if method in (None, 'view'): |
7990
a673d1d9a738
[diet]Â drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7973
diff
changeset
|
683 |
kwargs['_restpath'] = self.rest_path(use_ext_id) |
0 | 684 |
else: |
685 |
kwargs['rql'] = 'Any X WHERE X eid %s' % self.eid |
|
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
686 |
return self._cw.build_url(method, **kwargs) |
0 | 687 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
688 |
def rest_path(self, use_ext_eid=False): # XXX cw_rest_path |
0 | 689 |
"""returns a REST-like (relative) path for this entity""" |
7828
749e1a67987f
[entity] rename Entity._rest_attr_info into cw_rest_attr_info (closes #1942759)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7827
diff
changeset
|
690 |
mainattr, needcheck = self.cw_rest_attr_info() |
0 | 691 |
etype = str(self.e_schema) |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
692 |
path = etype.lower() |
8286
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
693 |
fallback = False |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
694 |
if mainattr != 'eid': |
0 | 695 |
value = getattr(self, mainattr) |
6099
b22a4a3895df
work around Apache's mod_proxy limitation with special chars in URLs by not using Rest urls when such a case is detected
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6098
diff
changeset
|
696 |
if not can_use_rest_path(value): |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
697 |
mainattr = 'eid' |
8286
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
698 |
path = None |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
699 |
elif needcheck: |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
700 |
# make sure url is not ambiguous |
4363
5c18d82042fb
cache result of the COUNT query used to see if a non unique attribute may be used as rest path on the entity instance to avoid recomputing it later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
701 |
try: |
5c18d82042fb
cache result of the COUNT query used to see if a non unique attribute may be used as rest path on the entity instance to avoid recomputing it later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
702 |
nbresults = self.__unique |
5c18d82042fb
cache result of the COUNT query used to see if a non unique attribute may be used as rest path on the entity instance to avoid recomputing it later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
703 |
except AttributeError: |
5c18d82042fb
cache result of the COUNT query used to see if a non unique attribute may be used as rest path on the entity instance to avoid recomputing it later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
704 |
rql = 'Any COUNT(X) WHERE X is %s, X %s %%(value)s' % ( |
5c18d82042fb
cache result of the COUNT query used to see if a non unique attribute may be used as rest path on the entity instance to avoid recomputing it later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
705 |
etype, mainattr) |
5c18d82042fb
cache result of the COUNT query used to see if a non unique attribute may be used as rest path on the entity instance to avoid recomputing it later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
706 |
nbresults = self.__unique = self._cw.execute(rql, {'value' : value})[0][0] |
1904
e23536d29231
minor refactoring of absolute_url()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1842
diff
changeset
|
707 |
if nbresults != 1: # ambiguity? |
e23536d29231
minor refactoring of absolute_url()
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1842
diff
changeset
|
708 |
mainattr = 'eid' |
8286
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
709 |
path = None |
0 | 710 |
if mainattr == 'eid': |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
711 |
if use_ext_eid: |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
712 |
value = self.cw_metainformation()['extid'] |
1840
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
713 |
else: |
f4b5c15d1147
test and fix #342997: local eid used for absolute_url of external entities
sylvain.thenault@logilab.fr
parents:
1804
diff
changeset
|
714 |
value = self.eid |
8286
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
715 |
if path is None: |
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
716 |
# fallback url: <base-url>/<eid> url is used as cw entities uri, |
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
717 |
# prefer it to <base-url>/<etype>/eid/<eid> |
8b0146e31baa
[entity url] rest path fallback should be the url used as cwuri. Closes #2186039
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8199
diff
changeset
|
718 |
return unicode(value) |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
719 |
return '%s/%s' % (path, self._cw.url_quote(value)) |
0 | 720 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
721 |
def cw_attr_metadata(self, attr, metadata): |
1101
0c067de38e46
unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents:
1098
diff
changeset
|
722 |
"""return a metadata for an attribute (None if unspecified)""" |
0c067de38e46
unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents:
1098
diff
changeset
|
723 |
value = getattr(self, '%s_%s' % (attr, metadata), None) |
0c067de38e46
unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents:
1098
diff
changeset
|
724 |
if value is None and metadata == 'encoding': |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
725 |
value = self._cw.vreg.property_value('ui.encoding') |
1101
0c067de38e46
unification of meta-attributes handling:
sylvain.thenault@logilab.fr
parents:
1098
diff
changeset
|
726 |
return value |
0 | 727 |
|
728 |
def printable_value(self, attr, value=_marker, attrtype=None, |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
729 |
format='text/html', displaytime=True): # XXX cw_printable_value |
0 | 730 |
"""return a displayable value (i.e. unicode string) which may contains |
731 |
html tags |
|
732 |
""" |
|
733 |
attr = str(attr) |
|
734 |
if value is _marker: |
|
735 |
value = getattr(self, attr) |
|
736 |
if isinstance(value, basestring): |
|
737 |
value = value.strip() |
|
738 |
if value is None or value == '': # don't use "not", 0 is an acceptable value |
|
739 |
return u'' |
|
740 |
if attrtype is None: |
|
741 |
attrtype = self.e_schema.destination(attr) |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
742 |
props = self.e_schema.rdef(attr) |
0 | 743 |
if attrtype == 'String': |
744 |
# internalinalized *and* formatted string such as schema |
|
745 |
# description... |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
746 |
if props.internationalizable: |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
747 |
value = self._cw._(value) |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
748 |
attrformat = self.cw_attr_metadata(attr, 'format') |
0 | 749 |
if attrformat: |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
750 |
return self._cw_mtc_transform(value, attrformat, format, |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
751 |
self._cw.encoding) |
0 | 752 |
elif attrtype == 'Bytes': |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
753 |
attrformat = self.cw_attr_metadata(attr, 'format') |
0 | 754 |
if attrformat: |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
755 |
encoding = self.cw_attr_metadata(attr, 'encoding') |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
756 |
return self._cw_mtc_transform(value.getvalue(), attrformat, format, |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
757 |
encoding) |
0 | 758 |
return u'' |
7914
fb757a7d887e
[request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7907
diff
changeset
|
759 |
value = self._cw.printable_value(attrtype, value, props, |
fb757a7d887e
[request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7907
diff
changeset
|
760 |
displaytime=displaytime) |
0 | 761 |
if format == 'text/html': |
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2125
diff
changeset
|
762 |
value = xml_escape(value) |
0 | 763 |
return value |
764 |
||
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
765 |
def _cw_mtc_transform(self, data, format, target_format, encoding, |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
766 |
_engine=ENGINE): |
0 | 767 |
trdata = TransformData(data, format, encoding, appobject=self) |
768 |
data = _engine.convert(trdata, target_format).decode() |
|
9432
030745ac9873
[entities] unconditionnally sanitize the html output of printable_value
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9310
diff
changeset
|
769 |
if target_format == 'text/html': |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
770 |
data = soup2xhtml(data, self._cw.encoding) |
0 | 771 |
return data |
1474 | 772 |
|
0 | 773 |
# entity cloning ########################################################## |
774 |
||
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
775 |
def copy_relations(self, ceid): # XXX cw_copy_relations |
3626
017869a514c3
[doc] updated docstrings
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
3552
diff
changeset
|
776 |
"""copy relations of the object with the given eid on this |
017869a514c3
[doc] updated docstrings
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
3552
diff
changeset
|
777 |
object (this method is called on the newly created copy, and |
017869a514c3
[doc] updated docstrings
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
3552
diff
changeset
|
778 |
ceid designates the original entity). |
0 | 779 |
|
780 |
By default meta and composite relations are skipped. |
|
781 |
Overrides this if you want another behaviour |
|
782 |
""" |
|
783 |
assert self.has_eid() |
|
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
784 |
execute = self._cw.execute |
7702
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
785 |
skip_copy_for = {'subject': set(), 'object': set()} |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
786 |
for rtype in self.skip_copy_for: |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
787 |
skip_copy_for['subject'].add(rtype) |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
788 |
warn('[3.14] skip_copy_for on entity classes (%s) is deprecated, ' |
8900
010a59e12d89
use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8793
diff
changeset
|
789 |
'use cw_skip_for instead with list of couples (rtype, role)' % self.cw_etype, |
7702
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
790 |
DeprecationWarning) |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
791 |
for rtype, role in self.cw_skip_copy_for: |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
792 |
assert role in ('subject', 'object'), role |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
793 |
skip_copy_for[role].add(rtype) |
0 | 794 |
for rschema in self.e_schema.subject_relations(): |
9591
5b8bc486d0dc
[entity] User-defined relation to skip for copy has precedence
Jérôme Roy <jerome.roy@logilab.fr>
parents:
9440
diff
changeset
|
795 |
if rschema.type in skip_copy_for['subject']: |
5b8bc486d0dc
[entity] User-defined relation to skip for copy has precedence
Jérôme Roy <jerome.roy@logilab.fr>
parents:
9440
diff
changeset
|
796 |
continue |
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3683
diff
changeset
|
797 |
if rschema.final or rschema.meta: |
0 | 798 |
continue |
799 |
# skip already defined relations |
|
800 |
if getattr(self, rschema.type): |
|
801 |
continue |
|
9820
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
802 |
# XXX takefirst=True to remove warning triggered by ambiguous relations |
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
803 |
rdef = self.e_schema.rdef(rschema, takefirst=True) |
0 | 804 |
# skip composite relation |
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
805 |
if rdef.composite: |
0 | 806 |
continue |
807 |
# skip relation with card in ?1 else we either change the copied |
|
808 |
# object (inlined relation) or inserting some inconsistency |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
809 |
if rdef.cardinality[1] in '?1': |
0 | 810 |
continue |
811 |
rql = 'SET X %s V WHERE X eid %%(x)s, Y eid %%(y)s, Y %s V' % ( |
|
812 |
rschema.type, rschema.type) |
|
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
813 |
execute(rql, {'x': self.eid, 'y': ceid}) |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
814 |
self.cw_clear_relation_cache(rschema.type, 'subject') |
0 | 815 |
for rschema in self.e_schema.object_relations(): |
816 |
if rschema.meta: |
|
817 |
continue |
|
818 |
# skip already defined relations |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
819 |
if self.related(rschema.type, 'object'): |
0 | 820 |
continue |
7702
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
821 |
if rschema.type in skip_copy_for['object']: |
73cadb5d0097
[entities] skip_copy_for should be considered for object relations too (closes #1857474)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7552
diff
changeset
|
822 |
continue |
9820
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
823 |
# XXX takefirst=True to remove warning triggered by ambiguous relations |
3ad221fe04aa
[entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
9774
diff
changeset
|
824 |
rdef = self.e_schema.rdef(rschema, 'object', takefirst=True) |
0 | 825 |
# skip composite relation |
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
826 |
if rdef.composite: |
0 | 827 |
continue |
828 |
# skip relation with card in ?1 else we either change the copied |
|
829 |
# object (inlined relation) or inserting some inconsistency |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
830 |
if rdef.cardinality[0] in '?1': |
0 | 831 |
continue |
832 |
rql = 'SET V %s X WHERE X eid %%(x)s, Y eid %%(y)s, V %s Y' % ( |
|
833 |
rschema.type, rschema.type) |
|
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
834 |
execute(rql, {'x': self.eid, 'y': ceid}) |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
835 |
self.cw_clear_relation_cache(rschema.type, 'object') |
0 | 836 |
|
837 |
# data fetching methods ################################################### |
|
838 |
||
839 |
@cached |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
840 |
def as_rset(self): # XXX .cw_as_rset |
0 | 841 |
"""returns a resultset containing `self` information""" |
842 |
rset = ResultSet([(self.eid,)], 'Any X WHERE X eid %(x)s', |
|
8900
010a59e12d89
use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8793
diff
changeset
|
843 |
{'x': self.eid}, [(self.cw_etype,)]) |
4850
bd640b137f50
[refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4848
diff
changeset
|
844 |
rset.req = self._cw |
bd640b137f50
[refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4848
diff
changeset
|
845 |
return rset |
1474 | 846 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
847 |
def _cw_to_complete_relations(self): |
0 | 848 |
"""by default complete final relations to when calling .complete()""" |
849 |
for rschema in self.e_schema.subject_relations(): |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3683
diff
changeset
|
850 |
if rschema.final: |
0 | 851 |
continue |
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
852 |
targets = rschema.objects(self.e_schema) |
0 | 853 |
if rschema.inlined: |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
854 |
matching_groups = self._cw.user.matching_groups |
5797
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
855 |
if all(matching_groups(e.get_groups('read')) and |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
856 |
rschema.rdef(self.e_schema, e).get_groups('read') |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
857 |
for e in targets): |
0 | 858 |
yield rschema, 'subject' |
1474 | 859 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
860 |
def _cw_to_complete_attributes(self, skip_bytes=True, skip_pwd=True): |
0 | 861 |
for rschema, attrschema in self.e_schema.attribute_definitions(): |
862 |
# skip binary data by default |
|
863 |
if skip_bytes and attrschema.type == 'Bytes': |
|
864 |
continue |
|
865 |
attr = rschema.type |
|
866 |
if attr == 'eid': |
|
867 |
continue |
|
868 |
# password retreival is blocked at the repository server level |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
869 |
rdef = rschema.rdef(self.e_schema, attrschema) |
3890
d7a270f50f54
backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
diff
changeset
|
870 |
if not self._cw.user.matching_groups(rdef.get_groups('read')) \ |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4850
diff
changeset
|
871 |
or (attrschema.type == 'Password' and skip_pwd): |
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
872 |
self.cw_attr_cache[attr] = None |
0 | 873 |
continue |
874 |
yield attr |
|
1474 | 875 |
|
4408
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
876 |
_cw_completed = False |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
877 |
def complete(self, attributes=None, skip_bytes=True, skip_pwd=True): # XXX cw_complete |
0 | 878 |
"""complete this entity by adding missing attributes (i.e. query the |
879 |
repository to fill the entity) |
|
880 |
||
881 |
:type skip_bytes: bool |
|
882 |
:param skip_bytes: |
|
883 |
if true, attribute of type Bytes won't be considered |
|
884 |
""" |
|
885 |
assert self.has_eid() |
|
4408
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
886 |
if self._cw_completed: |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
887 |
return |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
888 |
if attributes is None: |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
889 |
self._cw_completed = True |
0 | 890 |
varmaker = rqlvar_maker() |
891 |
V = varmaker.next() |
|
892 |
rql = ['WHERE %s eid %%(x)s' % V] |
|
893 |
selected = [] |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
894 |
for attr in (attributes or self._cw_to_complete_attributes(skip_bytes, skip_pwd)): |
0 | 895 |
# if attribute already in entity, nothing to do |
8697
574bb05e40a4
[toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8696
diff
changeset
|
896 |
if attr in self.cw_attr_cache: |
0 | 897 |
continue |
898 |
# case where attribute must be completed, but is not yet in entity |
|
899 |
var = varmaker.next() |
|
900 |
rql.append('%s %s %s' % (V, attr, var)) |
|
901 |
selected.append((attr, var)) |
|
7995
9a9f35ef418c
Record a log of datafeed source imports (closes #2026097)
Julien Cristau <julien.cristau@logilab.fr>
parents:
7990
diff
changeset
|
902 |
# +1 since this doesn't include the main variable |
0 | 903 |
lastattr = len(selected) + 1 |
6124
c5900230809b
[ms] when entity is coming from an external source, don't add non final relations on complete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6100
diff
changeset
|
904 |
# don't fetch extra relation if attributes specified or of the entity is |
c5900230809b
[ms] when entity is coming from an external source, don't add non final relations on complete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6100
diff
changeset
|
905 |
# coming from an external source (may lead to error) |
c5900230809b
[ms] when entity is coming from an external source, don't add non final relations on complete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6100
diff
changeset
|
906 |
if attributes is None and self.cw_metainformation()['source']['uri'] == 'system': |
0 | 907 |
# fetch additional relations (restricted to 0..1 relations) |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
908 |
for rschema, role in self._cw_to_complete_relations(): |
0 | 909 |
rtype = rschema.type |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
910 |
if self.cw_relation_cached(rtype, role): |
0 | 911 |
continue |
5797
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
912 |
# at this point we suppose that: |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
913 |
# * this is a inlined relation |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
914 |
# * entity (self) is the subject |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
915 |
# * user has read perm on the relation and on the target entity |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
916 |
assert rschema.inlined |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
917 |
assert role == 'subject' |
0 | 918 |
var = varmaker.next() |
5797
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
919 |
# keep outer join anyway, we don't want .complete to crash on |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
920 |
# missing mandatory relation (see #1058267) |
7183f32fad13
[entity] fix .complete so we don't crash on missing mandatory relation. Also simplify code. Closes #1058267
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5762
diff
changeset
|
921 |
rql.append('%s %s %s?' % (V, rtype, var)) |
0 | 922 |
selected.append(((rtype, role), var)) |
923 |
if selected: |
|
924 |
# select V, we need it as the left most selected variable |
|
925 |
# if some outer join are included to fetch inlined relations |
|
926 |
rql = 'Any %s,%s %s' % (V, ','.join(var for attr, var in selected), |
|
927 |
','.join(rql)) |
|
6656
bea4ab297e67
[ms entity] proper error on external entity fetch error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6499
diff
changeset
|
928 |
try: |
bea4ab297e67
[ms entity] proper error on external entity fetch error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6499
diff
changeset
|
929 |
rset = self._cw.execute(rql, {'x': self.eid}, build_descr=False)[0] |
bea4ab297e67
[ms entity] proper error on external entity fetch error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6499
diff
changeset
|
930 |
except IndexError: |
bea4ab297e67
[ms entity] proper error on external entity fetch error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6499
diff
changeset
|
931 |
raise Exception('unable to fetch attributes for entity with eid %s' |
bea4ab297e67
[ms entity] proper error on external entity fetch error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6499
diff
changeset
|
932 |
% self.eid) |
0 | 933 |
# handle attributes |
934 |
for i in xrange(1, lastattr): |
|
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
935 |
self.cw_attr_cache[str(selected[i-1][0])] = rset[i] |
0 | 936 |
# handle relations |
937 |
for i in xrange(lastattr, len(rset)): |
|
2941
196493bd099c
[entity] use role instead of x
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2931
diff
changeset
|
938 |
rtype, role = selected[i-1][0] |
0 | 939 |
value = rset[i] |
940 |
if value is None: |
|
941 |
rrset = ResultSet([], rql, {'x': self.eid}) |
|
4850
bd640b137f50
[refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4848
diff
changeset
|
942 |
rrset.req = self._cw |
0 | 943 |
else: |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
944 |
rrset = self._cw.eid_rset(value) |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
945 |
self.cw_set_relation_cache(rtype, role, rrset) |
1474 | 946 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
947 |
def cw_attr_value(self, name): |
0 | 948 |
"""get value for the attribute relation <name>, query the repository |
949 |
to get the value if necessary. |
|
950 |
||
951 |
:type name: str |
|
952 |
:param name: name of the attribute to get |
|
953 |
""" |
|
954 |
try: |
|
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
955 |
return self.cw_attr_cache[name] |
0 | 956 |
except KeyError: |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
957 |
if not self.cw_is_saved(): |
0 | 958 |
return None |
959 |
rql = "Any A WHERE X eid %%(x)s, X %s A" % name |
|
960 |
try: |
|
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
961 |
rset = self._cw.execute(rql, {'x': self.eid}) |
0 | 962 |
except Unauthorized: |
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
963 |
self.cw_attr_cache[name] = value = None |
0 | 964 |
else: |
965 |
assert rset.rowcount <= 1, (self, rql, rset.rowcount) |
|
966 |
try: |
|
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
967 |
self.cw_attr_cache[name] = value = rset.rows[0][0] |
0 | 968 |
except IndexError: |
969 |
# probably a multisource error |
|
970 |
self.critical("can't get value for attribute %s of entity with eid %s", |
|
971 |
name, self.eid) |
|
972 |
if self.e_schema.destination(name) == 'String': |
|
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
973 |
self.cw_attr_cache[name] = value = self._cw._('unaccessible') |
0 | 974 |
else: |
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
975 |
self.cw_attr_cache[name] = value = None |
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
976 |
return value |
0 | 977 |
|
7911
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
978 |
def related(self, rtype, role='subject', limit=None, entities=False, # XXX .cw_related |
9293
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
979 |
safe=False, targettypes=None): |
0 | 980 |
"""returns a resultset of related entities |
1474 | 981 |
|
7911
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
982 |
:param rtype: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
983 |
the name of the relation, aka relation type |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
984 |
:param role: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
985 |
the role played by 'self' in the relation ('subject' or 'object') |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
986 |
:param limit: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
987 |
resultset's maximum size |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
988 |
:param entities: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
989 |
if True, the entites are returned; if False, a result set is returned |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
990 |
:param safe: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
991 |
if True, an empty rset/list of entities will be returned in case of |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
992 |
:exc:`Unauthorized`, else (the default), the exception is propagated |
9293
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
993 |
:param targettypes: |
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
994 |
a tuple of target entity types to restrict the query |
0 | 995 |
""" |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
996 |
rtype = str(rtype) |
9293
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
997 |
# Caching restricted/limited results is best avoided. |
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
998 |
cacheable = limit is None and targettypes is None |
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
999 |
if cacheable: |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1000 |
cache_key = '%s_%s' % (rtype, role) |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1001 |
if cache_key in self._cw_related_cache: |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1002 |
return self._cw_related_cache[cache_key][entities] |
5757
e501806ab489
[entity] when .related() is called on a not-yet-saved entity, return an empty rset/list instead of raising an assertion error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5733
diff
changeset
|
1003 |
if not self.has_eid(): |
e501806ab489
[entity] when .related() is called on a not-yet-saved entity, return an empty rset/list instead of raising an assertion error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5733
diff
changeset
|
1004 |
if entities: |
e501806ab489
[entity] when .related() is called on a not-yet-saved entity, return an empty rset/list instead of raising an assertion error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5733
diff
changeset
|
1005 |
return [] |
6807
7330d1fa02dd
[cleanup] pylint detected error (among a ton of false positives due to the dynamic nature of cubicweb's code...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6792
diff
changeset
|
1006 |
return self._cw.empty_rset() |
9293
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
1007 |
rql = self.cw_related_rql(rtype, role, limit=limit, targettypes=targettypes) |
7911
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
1008 |
try: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
1009 |
rset = self._cw.execute(rql, {'x': self.eid}) |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
1010 |
except Unauthorized: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
1011 |
if not safe: |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
1012 |
raise |
5ab88d05083f
[xml/rdf views] handle case where the user hasn't read access to a relation (closes #1984598)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7899
diff
changeset
|
1013 |
rset = self._cw.empty_rset() |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1014 |
if entities: |
9293
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
1015 |
if cacheable: |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1016 |
self.cw_set_relation_cache(rtype, role, rset) |
9293
723e2c586ea3
[entity] Entity.related(): add a targettypes argument (closes #2957313)
Aurelien Campeas
parents:
9283
diff
changeset
|
1017 |
return self.related(rtype, role, entities=entities) |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1018 |
return list(rset.entities()) |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1019 |
else: |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1020 |
return rset |
0 | 1021 |
|
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1022 |
def cw_related_rql(self, rtype, role='subject', targettypes=None, limit=None): |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
1023 |
vreg = self._cw.vreg |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
1024 |
rschema = vreg.schema[rtype] |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1025 |
select = Select() |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1026 |
mainvar, evar = select.get_variable('X'), select.get_variable('E') |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1027 |
select.add_selected(mainvar) |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1028 |
if limit is not None: |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1029 |
select.set_limit(limit) |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1030 |
select.add_eid_restriction(evar, 'x', 'Substitute') |
0 | 1031 |
if role == 'subject': |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1032 |
rel = make_relation(evar, rtype, (mainvar,), VariableRef) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1033 |
select.add_restriction(rel) |
3130
2486163c4630
allow to specify targettypes in related_rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3047
diff
changeset
|
1034 |
if targettypes is None: |
2486163c4630
allow to specify targettypes in related_rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3047
diff
changeset
|
1035 |
targettypes = rschema.objects(self.e_schema) |
3672
554a588ffaea
[entity] make related_rql honors its targettypes argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3671
diff
changeset
|
1036 |
else: |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1037 |
select.add_constant_restriction(mainvar, 'is', |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1038 |
targettypes, 'etype') |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1039 |
gcard = greater_card(rschema, (self.e_schema,), targettypes, 0) |
0 | 1040 |
else: |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1041 |
rel = make_relation(mainvar, rtype, (evar,), VariableRef) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1042 |
select.add_restriction(rel) |
3130
2486163c4630
allow to specify targettypes in related_rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3047
diff
changeset
|
1043 |
if targettypes is None: |
2486163c4630
allow to specify targettypes in related_rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3047
diff
changeset
|
1044 |
targettypes = rschema.subjects(self.e_schema) |
3672
554a588ffaea
[entity] make related_rql honors its targettypes argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3671
diff
changeset
|
1045 |
else: |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1046 |
select.add_constant_restriction(mainvar, 'is', targettypes, |
7964
4ea2abc83dce
[entity related rql] 'is' relation target constant should have 'etype' type, not String
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7963
diff
changeset
|
1047 |
'etype') |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1048 |
gcard = greater_card(rschema, targettypes, (self.e_schema,), 1) |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
1049 |
etypecls = vreg['etypes'].etype_class(targettypes[0]) |
0 | 1050 |
if len(targettypes) > 1: |
7798
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
1051 |
fetchattrs = vreg['etypes'].fetch_attrs(targettypes) |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
1052 |
self._fetch_ambiguous_rtypes(select, mainvar, fetchattrs, |
8930f7a284dd
[entity fetchattrs] also fetch ambiguous rtypes even if we do not recurse on them (closes #1720823)
Florent Cayré <florent.cayre@gmail.com>
parents:
7794
diff
changeset
|
1053 |
targettypes, vreg.schema) |
0 | 1054 |
else: |
7302
c281afe35b8b
[entity] fix entity fetch_rql when fetch_attrs contains a rtype with multiple destination etypes which do not have the same fetched attributes themselves (closes #1631282)
Florent Cayré <florent.cayre@gmail.com>
parents:
7288
diff
changeset
|
1055 |
fetchattrs = etypecls.fetch_attrs |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1056 |
etypecls.fetch_rqlst(self._cw.user, select, mainvar, fetchattrs, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1057 |
settype=False) |
0 | 1058 |
# optimisation: remove ORDERBY if cardinality is 1 or ? (though |
1059 |
# greater_card return 1 for those both cases) |
|
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1060 |
if gcard == '1': |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1061 |
select.remove_sort_terms() |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1062 |
elif not select.orderby: |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1063 |
# if modification_date is already retrieved, we use it instead |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1064 |
# of adding another variable for sorting. This should not be |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1065 |
# problematic, but it is with sqlserver, see ticket #694445 |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1066 |
for rel in select.where.get_nodes(RqlRelation): |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1067 |
if (rel.r_type == 'modification_date' |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1068 |
and rel.children[0].variable == mainvar |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1069 |
and rel.children[1].operator == '='): |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1070 |
var = rel.children[1].children[0].variable |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1071 |
select.add_sort_var(var, asc=False) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1072 |
break |
4630
528dee042927
fix #694445: related entity generates weird RQL which in turn generates weird SQL which fails on SQL Server
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4460
diff
changeset
|
1073 |
else: |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1074 |
mdvar = select.make_variable() |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1075 |
rel = make_relation(mainvar, 'modification_date', |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1076 |
(mdvar,), VariableRef) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1077 |
select.add_restriction(rel) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1078 |
select.add_sort_var(mdvar, asc=False) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1079 |
return select.as_string() |
1474 | 1080 |
|
0 | 1081 |
# generic vocabulary methods ############################################## |
1082 |
||
9712
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1083 |
def cw_linkable_rql(self, rtype, targettype, role, ordermethod=None, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1084 |
vocabconstraints=True, lt_infos={}, limit=None): |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1085 |
"""build a rql to fetch targettype entities either related or unrelated |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1086 |
to this entity using (rtype, role) relation. |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1087 |
|
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1088 |
Consider relation permissions so that returned entities may be actually |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1089 |
linked by `rtype`. |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1090 |
|
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1091 |
`lt_infos` are supplementary informations, usually coming from __linkto |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1092 |
parameter, that can help further restricting the results in case current |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1093 |
entity is not yet created. It is a dict describing entities the current |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1094 |
entity will be linked to, which keys are (rtype, role) tuples and values |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1095 |
are a list of eids. |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1096 |
""" |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1097 |
return self._cw_compute_linkable_rql(rtype, targettype, role, ordermethod=None, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1098 |
vocabconstraints=vocabconstraints, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1099 |
lt_infos=lt_infos, limit=limit, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1100 |
unrelated_only=False) |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1101 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1102 |
def cw_unrelated_rql(self, rtype, targettype, role, ordermethod=None, |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1103 |
vocabconstraints=True, lt_infos={}, limit=None): |
0 | 1104 |
"""build a rql to fetch `targettype` entities unrelated to this entity |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1105 |
using (rtype, role) relation. |
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1106 |
|
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1107 |
Consider relation permissions so that returned entities may be actually |
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1108 |
linked by `rtype`. |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1109 |
|
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1110 |
`lt_infos` are supplementary informations, usually coming from __linkto |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1111 |
parameter, that can help further restricting the results in case current |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1112 |
entity is not yet created. It is a dict describing entities the current |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1113 |
entity will be linked to, which keys are (rtype, role) tuples and values |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1114 |
are a list of eids. |
0 | 1115 |
""" |
9712
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1116 |
return self._cw_compute_linkable_rql(rtype, targettype, role, ordermethod=None, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1117 |
vocabconstraints=vocabconstraints, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1118 |
lt_infos=lt_infos, limit=limit, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1119 |
unrelated_only=True) |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1120 |
|
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1121 |
def _cw_compute_linkable_rql(self, rtype, targettype, role, ordermethod=None, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1122 |
vocabconstraints=True, lt_infos={}, limit=None, |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1123 |
unrelated_only=False): |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1124 |
"""build a rql to fetch `targettype` entities that may be related to |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1125 |
this entity using the (rtype, role) relation. |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1126 |
|
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1127 |
By default (unrelated_only=False), this includes the already linked |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1128 |
entities as well as the unrelated ones. If `unrelated_only` is True, the |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1129 |
rql filters out the already related entities. |
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1130 |
""" |
0 | 1131 |
ordermethod = ordermethod or 'fetch_unrelated_order' |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1132 |
rschema = self._cw.vreg.schema.rschema(rtype) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1133 |
rdef = rschema.role_rdef(self.e_schema, targettype, role) |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1134 |
rewriter = RQLRewriter(self._cw) |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1135 |
select = Select() |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1136 |
# initialize some variables according to the `role` of `self` in the |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1137 |
# relation (variable names must respect constraints conventions): |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1138 |
# * variable for myself (`evar`) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1139 |
# * variable for searched entities (`searchvedvar`) |
0 | 1140 |
if role == 'subject': |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1141 |
evar = subjvar = select.get_variable('S') |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1142 |
searchedvar = objvar = select.get_variable('O') |
0 | 1143 |
else: |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1144 |
searchedvar = subjvar = select.get_variable('S') |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1145 |
evar = objvar = select.get_variable('O') |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1146 |
select.add_selected(searchedvar) |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1147 |
if limit is not None: |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1148 |
select.set_limit(limit) |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1149 |
# initialize some variables according to `self` existence |
7177
0f2905cbe443
[entity vocab] fix bug introduced in 3.12 vs/ entity vocabulary, leading to some unexpected empty vocabulary. Fix test accordingly.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7154
diff
changeset
|
1150 |
if rdef.role_cardinality(neg_role(role)) in '?1': |
0f2905cbe443
[entity vocab] fix bug introduced in 3.12 vs/ entity vocabulary, leading to some unexpected empty vocabulary. Fix test accordingly.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7154
diff
changeset
|
1151 |
# if cardinality in '1?', we want a target entity which isn't |
0f2905cbe443
[entity vocab] fix bug introduced in 3.12 vs/ entity vocabulary, leading to some unexpected empty vocabulary. Fix test accordingly.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7154
diff
changeset
|
1152 |
# already linked using this relation |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1153 |
variable = select.make_variable() |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1154 |
if role == 'subject': |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1155 |
rel = make_relation(variable, rtype, (searchedvar,), VariableRef) |
7177
0f2905cbe443
[entity vocab] fix bug introduced in 3.12 vs/ entity vocabulary, leading to some unexpected empty vocabulary. Fix test accordingly.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7154
diff
changeset
|
1156 |
else: |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1157 |
rel = make_relation(searchedvar, rtype, (variable,), VariableRef) |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1158 |
select.add_restriction(Not(rel)) |
9712
6c6cd8c4b256
[entity] add a new `cw_linkable_rql` method
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
9635
diff
changeset
|
1159 |
elif self.has_eid() and unrelated_only: |
7177
0f2905cbe443
[entity vocab] fix bug introduced in 3.12 vs/ entity vocabulary, leading to some unexpected empty vocabulary. Fix test accordingly.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7154
diff
changeset
|
1160 |
# elif we have an eid, we don't want a target entity which is |
0f2905cbe443
[entity vocab] fix bug introduced in 3.12 vs/ entity vocabulary, leading to some unexpected empty vocabulary. Fix test accordingly.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7154
diff
changeset
|
1161 |
# already linked to ourself through this relation |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1162 |
rel = make_relation(subjvar, rtype, (objvar,), VariableRef) |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1163 |
select.add_restriction(Not(rel)) |
0 | 1164 |
if self.has_eid(): |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1165 |
rel = make_relation(evar, 'eid', ('x', 'Substitute'), Constant) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1166 |
select.add_restriction(rel) |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1167 |
args = {'x': self.eid} |
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1168 |
if role == 'subject': |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1169 |
sec_check_args = {'fromeid': self.eid} |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1170 |
else: |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1171 |
sec_check_args = {'toeid': self.eid} |
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1172 |
existant = None # instead of 'SO', improve perfs |
0 | 1173 |
else: |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1174 |
args = {} |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1175 |
sec_check_args = {} |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1176 |
existant = searchedvar.name |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1177 |
# undefine unused evar, or the type resolver will consider it |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1178 |
select.undefine_variable(evar) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1179 |
# retrieve entity class for targettype to compute base rql |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1180 |
etypecls = self._cw.vreg['etypes'].etype_class(targettype) |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1181 |
etypecls.fetch_rqlst(self._cw.user, select, searchedvar, |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1182 |
ordermethod=ordermethod) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1183 |
# from now on, we need variable type resolving |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1184 |
self._cw.vreg.solutions(self._cw, select, args) |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1185 |
# insert RQL expressions for schema constraints into the rql syntax tree |
0 | 1186 |
if vocabconstraints: |
1187 |
# RQLConstraint is a subclass for RQLVocabularyConstraint, so they |
|
1188 |
# will be included as well |
|
7153
7df83a6d17c0
[entity vocabulary] fix unrelated rql generation to skip rql constraints that don't make sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7152
diff
changeset
|
1189 |
cstrcls = RQLVocabularyConstraint |
0 | 1190 |
else: |
7153
7df83a6d17c0
[entity vocabulary] fix unrelated rql generation to skip rql constraints that don't make sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7152
diff
changeset
|
1191 |
cstrcls = RQLConstraint |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1192 |
lt_infos = pruned_lt_info(self.e_schema, lt_infos or {}) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1193 |
# if there are still lt_infos, use set to keep track of added eid |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1194 |
# relations (adding twice the same eid relation is incorrect RQL) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1195 |
eidvars = set() |
7153
7df83a6d17c0
[entity vocabulary] fix unrelated rql generation to skip rql constraints that don't make sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7152
diff
changeset
|
1196 |
for cstr in rdef.constraints: |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1197 |
# consider constraint.mainvars to check if constraint apply |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1198 |
if isinstance(cstr, cstrcls) and searchedvar.name in cstr.mainvars: |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1199 |
if not self.has_eid(): |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1200 |
if lt_infos: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1201 |
# we can perhaps further restrict with linkto infos using |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1202 |
# a custom constraint built from cstr and lt_infos |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1203 |
cstr = build_cstr_with_linkto_infos( |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1204 |
cstr, args, searchedvar, evar, lt_infos, eidvars) |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1205 |
if cstr is None: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1206 |
continue # could not build constraint -> discard |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1207 |
elif evar.name in cstr.mainvars: |
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1208 |
continue |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1209 |
# compute a varmap suitable to RQLRewriter.rewrite argument |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1210 |
varmap = dict((v, v) for v in (searchedvar.name, evar.name) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1211 |
if v in select.defined_vars and v in cstr.mainvars) |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1212 |
# rewrite constraint by constraint since we want a AND between |
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1213 |
# expressions. |
9188
0677e03077fb
[rqlrewrite] rewrite doesn't need a solutions argument, always use the Select'ones
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8992
diff
changeset
|
1214 |
rewriter.rewrite(select, [(varmap, (cstr,))], args, existant) |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1215 |
# insert security RQL expressions granting the permission to 'add' the |
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1216 |
# relation into the rql syntax tree, if necessary |
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1217 |
rqlexprs = rdef.get_rqlexprs('add') |
8472
444a8e25c940
[entity] fix unrelated_rql for creation form vocabulary for relation with specific permissions (closes #2423854)
Florent Cayré <florent.cayre@logilab.fr>
parents:
8307
diff
changeset
|
1218 |
if not self.has_eid(): |
444a8e25c940
[entity] fix unrelated_rql for creation form vocabulary for relation with specific permissions (closes #2423854)
Florent Cayré <florent.cayre@logilab.fr>
parents:
8307
diff
changeset
|
1219 |
rqlexprs = [rqlexpr for rqlexpr in rqlexprs |
444a8e25c940
[entity] fix unrelated_rql for creation form vocabulary for relation with specific permissions (closes #2423854)
Florent Cayré <florent.cayre@logilab.fr>
parents:
8307
diff
changeset
|
1220 |
if searchedvar.name in rqlexpr.mainvars] |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1221 |
if rqlexprs and not rdef.has_perm(self._cw, 'add', **sec_check_args): |
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1222 |
# compute a varmap suitable to RQLRewriter.rewrite argument |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1223 |
varmap = dict((v, v) for v in (searchedvar.name, evar.name) |
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1224 |
if v in select.defined_vars) |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1225 |
# rewrite all expressions at once since we want a OR between them. |
9188
0677e03077fb
[rqlrewrite] rewrite doesn't need a solutions argument, always use the Select'ones
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8992
diff
changeset
|
1226 |
rewriter.rewrite(select, [(varmap, rqlexprs)], args, existant) |
0 | 1227 |
# ensure we have an order defined |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1228 |
if not select.orderby: |
7794
aed065b97f12
refactor entity fetch_rql method to use a RQL syntax tree instead of RQL strings ; closes #1585650
Florent Cayré <florent.cayre@gmail.com>
parents:
7702
diff
changeset
|
1229 |
select.add_sort_var(select.defined_vars[searchedvar.name]) |
7154
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1230 |
# we're done, turn the rql syntax tree as a string |
5e2f93b88d86
[entity vocabulary] refactor unrelated rql to allow usage of RQLRewriter to insert schema constraints. Closes #1561806
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7153
diff
changeset
|
1231 |
rql = select.as_string() |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1232 |
return rql, args |
1474 | 1233 |
|
0 | 1234 |
def unrelated(self, rtype, targettype, role='subject', limit=None, |
7973
64639bc94e25
[entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents:
7964
diff
changeset
|
1235 |
ordermethod=None, lt_infos={}): # XXX .cw_unrelated |
0 | 1236 |
"""return a result set of target type objects that may be related |
1237 |
by a given relation, with self as subject or object |
|
1238 |
""" |
|
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1239 |
try: |
8735
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1240 |
rql, args = self.cw_unrelated_rql(rtype, targettype, role, limit=limit, |
5567a5117aeb
[entity] ensure the .related(entities=False) parameter is honored all the way down (closes #2755994)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8705
diff
changeset
|
1241 |
ordermethod=ordermethod, lt_infos=lt_infos) |
3241
1a6f7a0e7dbd
unrelated_rql now considers relation's add perm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3212
diff
changeset
|
1242 |
except Unauthorized: |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
1243 |
return self._cw.empty_rset() |
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5144
diff
changeset
|
1244 |
return self._cw.execute(rql, args) |
1474 | 1245 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1246 |
# relations cache handling ################################################# |
1474 | 1247 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1248 |
def cw_relation_cached(self, rtype, role): |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1249 |
"""return None if the given relation isn't already cached on the |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1250 |
instance, else the content of the cache (a 2-uple (rset, entities)). |
0 | 1251 |
""" |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1252 |
return self._cw_related_cache.get('%s_%s' % (rtype, role)) |
1474 | 1253 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1254 |
def cw_set_relation_cache(self, rtype, role, rset): |
0 | 1255 |
"""set cached values for the given relation""" |
1256 |
if rset: |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1257 |
related = list(rset.entities(0)) |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
1258 |
rschema = self._cw.vreg.schema.rschema(rtype) |
0 | 1259 |
if role == 'subject': |
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
1260 |
rcard = rschema.rdef(self.e_schema, related[0].e_schema).cardinality[1] |
0 | 1261 |
target = 'object' |
1262 |
else: |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3826
diff
changeset
|
1263 |
rcard = rschema.rdef(related[0].e_schema, self.e_schema).cardinality[0] |
0 | 1264 |
target = 'subject' |
1265 |
if rcard in '?1': |
|
1266 |
for rentity in related: |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1267 |
rentity._cw_related_cache['%s_%s' % (rtype, target)] = ( |
3552
8facb3324170
[entity] put cached related entities as tuple to be sure no one is modifying
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3546
diff
changeset
|
1268 |
self.as_rset(), (self,)) |
0 | 1269 |
else: |
3552
8facb3324170
[entity] put cached related entities as tuple to be sure no one is modifying
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3546
diff
changeset
|
1270 |
related = () |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1271 |
self._cw_related_cache['%s_%s' % (rtype, role)] = (rset, related) |
1474 | 1272 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1273 |
def cw_clear_relation_cache(self, rtype=None, role=None): |
0 | 1274 |
"""clear cached values for the given relation or the entire cache if |
1275 |
no relation is given |
|
1276 |
""" |
|
1277 |
if rtype is None: |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1278 |
self._cw_related_cache = {} |
5573
8dfb1726526b
[entity]Â clearing adapters cache in clear_relations_cache avoid weird caching issue, notably on repository session's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5559
diff
changeset
|
1279 |
self._cw_adapters_cache = {} |
0 | 1280 |
else: |
1281 |
assert role |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1282 |
self._cw_related_cache.pop('%s_%s' % (rtype, role), None) |
1474 | 1283 |
|
7293
97505b798975
[entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7246
diff
changeset
|
1284 |
def cw_clear_all_caches(self): |
4408
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1285 |
"""flush all caches on this entity. Further attributes/relations access |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1286 |
will triggers new database queries to get back values. |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1287 |
|
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1288 |
If you use custom caches on your entity class (take care to @cached!), |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1289 |
you should override this method to clear them as well. |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1290 |
""" |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1291 |
# clear attributes cache |
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1292 |
self._cw_completed = False |
5726
c3b99606644d
[json] fix json serialization for recent simplejson implementation, and test encoding of entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5573
diff
changeset
|
1293 |
self.cw_attr_cache.clear() |
4408
899b426087ab
[entity] small optimization: once an entity has been completed, don't redo it (for nothing)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4406
diff
changeset
|
1294 |
# clear relations cache |
5573
8dfb1726526b
[entity]Â clearing adapters cache in clear_relations_cache avoid weird caching issue, notably on repository session's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5559
diff
changeset
|
1295 |
self.cw_clear_relation_cache() |
4460
5c22869079b9
clear rest_path __unique cache in clear_all_caches, fix related test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4451
diff
changeset
|
1296 |
# rest path unique cache |
5c22869079b9
clear rest_path __unique cache in clear_all_caches, fix related test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4451
diff
changeset
|
1297 |
try: |
5c22869079b9
clear rest_path __unique cache in clear_all_caches, fix related test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4451
diff
changeset
|
1298 |
del self.__unique |
5c22869079b9
clear rest_path __unique cache in clear_all_caches, fix related test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4451
diff
changeset
|
1299 |
except AttributeError: |
5c22869079b9
clear rest_path __unique cache in clear_all_caches, fix related test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4451
diff
changeset
|
1300 |
pass |
4759 | 1301 |
|
0 | 1302 |
# raw edition utilities ################################################### |
1474 | 1303 |
|
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1304 |
def cw_set(self, **kwargs): |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1305 |
"""update this entity using given attributes / relation, working in the |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1306 |
same fashion as :meth:`cw_instantiate`. |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1307 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1308 |
Example (in a shell session): |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1309 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1310 |
>>> c = rql('Any X WHERE X is Company').get_entity(0, 0) |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1311 |
>>> p = rql('Any X WHERE X is Person').get_entity(0, 0) |
9310
80c58c35145f
Fix example in cw_set method
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
9277
diff
changeset
|
1312 |
>>> c.cw_set(name=u'Logilab') |
80c58c35145f
Fix example in cw_set method
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
9277
diff
changeset
|
1313 |
>>> p.cw_set(firstname=u'John', lastname=u'Doe', works_for=c) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1314 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1315 |
You can also set relations where the entity has 'object' role by |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1316 |
prefixing the relation name by 'reverse_'. Also, relation values may be |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1317 |
an entity or eid, a list of entities or eids, or None (meaning that all |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1318 |
relations of the given type from or to this object should be deleted). |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1319 |
""" |
0 | 1320 |
assert kwargs |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1321 |
assert self.cw_is_saved(), "should not call set_attributes while entity "\ |
5127
3c2dda44e2f6
[entity] explain why the assert failed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5115
diff
changeset
|
1322 |
"hasn't been saved yet" |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
1323 |
rql, qargs, pendingrels, attrcache = self._cw_build_entity_query(kwargs) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1324 |
if rql: |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1325 |
rql = 'SET ' + rql |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1326 |
qargs['x'] = self.eid |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1327 |
if ' WHERE ' in rql: |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1328 |
rql += ', X eid %(x)s' |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1329 |
else: |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1330 |
rql += ' WHERE X eid %(x)s' |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1331 |
self._cw.execute(rql, qargs) |
5115
2e43ef618d14
[repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5009
diff
changeset
|
1332 |
# update current local object _after_ the rql query to avoid |
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
1333 |
# interferences between the query execution itself and the cw_edited / |
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
1334 |
# skip_security machinery |
8493
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
1335 |
self._cw_update_attr_cache(attrcache) |
25da1e5c7c50
[entity/hooks] fix regression introduced by 4ba11607d84a
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8483
diff
changeset
|
1336 |
self._cw_handle_pending_relations(self.eid, pendingrels, self._cw.execute) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1337 |
# XXX update relation cache |
3671
c765adac7f5c
new set_relations method on entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3665
diff
changeset
|
1338 |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1339 |
def cw_delete(self, **kwargs): |
0 | 1340 |
assert self.has_eid(), self.eid |
3378
2f25f701301d
use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3376
diff
changeset
|
1341 |
self._cw.execute('DELETE %s X WHERE X eid %%(x)s' % self.e_schema, |
4835
13b0b96d7982
[repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4831
diff
changeset
|
1342 |
{'x': self.eid}, **kwargs) |
1474 | 1343 |
|
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
1344 |
# server side utilities #################################################### |
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1345 |
|
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1346 |
def _cw_clear_local_perm_cache(self, action): |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1347 |
for rqlexpr in self.e_schema.get_rqlexprs(action): |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1348 |
self._cw.local_perm_cache.pop((rqlexpr.eid, (('x', self.eid),)), None) |
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1349 |
|
6142
8bc6eac1fac1
[session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6124
diff
changeset
|
1350 |
# deprecated stuff ######################################################### |
0 | 1351 |
|
8980
c0b82dbcf6a3
[entity] improve deprecation messages
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8735
diff
changeset
|
1352 |
@deprecated('[3.16] use cw_set() instead of set_attributes()') |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1353 |
def set_attributes(self, **kwargs): # XXX cw_set_attributes |
9277
c964d8cf6efc
[entity] do not raise an AssertionError if the kwargs given to set_relations/attributes is empty
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9188
diff
changeset
|
1354 |
if kwargs: |
c964d8cf6efc
[entity] do not raise an AssertionError if the kwargs given to set_relations/attributes is empty
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9188
diff
changeset
|
1355 |
self.cw_set(**kwargs) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1356 |
|
8980
c0b82dbcf6a3
[entity] improve deprecation messages
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
8735
diff
changeset
|
1357 |
@deprecated('[3.16] use cw_set() instead of set_relations()') |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1358 |
def set_relations(self, **kwargs): # XXX cw_set_relations |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1359 |
"""add relations to the given object. To set a relation where this entity |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1360 |
is the object of the relation, use 'reverse_'<relation> as argument name. |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1361 |
|
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1362 |
Values may be an entity or eid, a list of entities or eids, or None |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1363 |
(meaning that all relations of the given type from or to this object |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1364 |
should be deleted). |
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1365 |
""" |
9277
c964d8cf6efc
[entity] do not raise an AssertionError if the kwargs given to set_relations/attributes is empty
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9188
diff
changeset
|
1366 |
if kwargs: |
c964d8cf6efc
[entity] do not raise an AssertionError if the kwargs given to set_relations/attributes is empty
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
9188
diff
changeset
|
1367 |
self.cw_set(**kwargs) |
8483
4ba11607d84a
[entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8307
diff
changeset
|
1368 |
|
7293
97505b798975
[entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7246
diff
changeset
|
1369 |
@deprecated('[3.13] use entity.cw_clear_all_caches()') |
97505b798975
[entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7246
diff
changeset
|
1370 |
def clear_all_caches(self): |
97505b798975
[entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7246
diff
changeset
|
1371 |
return self.cw_clear_all_caches() |
97505b798975
[entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7246
diff
changeset
|
1372 |
|
5870
d3ec7c4bb373
restore bw compat on Entity.related_rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5797
diff
changeset
|
1373 |
|
0 | 1374 |
# attribute and relation descriptors ########################################## |
1375 |
||
1376 |
class Attribute(object): |
|
1377 |
"""descriptor that controls schema attribute access""" |
|
1378 |
||
1379 |
def __init__(self, attrname): |
|
1380 |
assert attrname != 'eid' |
|
1381 |
self._attrname = attrname |
|
1382 |
||
1383 |
def __get__(self, eobj, eclass): |
|
1384 |
if eobj is None: |
|
1385 |
return self |
|
5557
1a534c596bff
[entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5556
diff
changeset
|
1386 |
return eobj.cw_attr_value(self._attrname) |
0 | 1387 |
|
6499
c4123c741c66
[deprecation] enhanced messages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6498
diff
changeset
|
1388 |
@deprecated('[3.10] assign to entity.cw_attr_cache[attr] or entity.cw_edited[attr]') |
0 | 1389 |
def __set__(self, eobj, value): |
6498
0ad62d6b6f8e
[bw compat] fix compat for entity.attr assigment
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6467
diff
changeset
|
1390 |
if hasattr(eobj, 'cw_edited') and not eobj.cw_edited.saved: |
0ad62d6b6f8e
[bw compat] fix compat for entity.attr assigment
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6467
diff
changeset
|
1391 |
eobj.cw_edited[self._attrname] = value |
0ad62d6b6f8e
[bw compat] fix compat for entity.attr assigment
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6467
diff
changeset
|
1392 |
else: |
0ad62d6b6f8e
[bw compat] fix compat for entity.attr assigment
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6467
diff
changeset
|
1393 |
eobj.cw_attr_cache[self._attrname] = value |
0 | 1394 |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
1395 |
|
0 | 1396 |
class Relation(object): |
1397 |
"""descriptor that controls schema relation access""" |
|
1398 |
||
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
1399 |
def __init__(self, rschema, role): |
0 | 1400 |
self._rtype = rschema.type |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5522
diff
changeset
|
1401 |
self._role = role |
0 | 1402 |
|
1403 |
def __get__(self, eobj, eclass): |
|
1404 |
if eobj is None: |
|
6419 | 1405 |
raise AttributeError('%s can only be accessed from instances' |
0 | 1406 |
% self._rtype) |
1407 |
return eobj.related(self._rtype, self._role, entities=True) |
|
1474 | 1408 |
|
0 | 1409 |
def __set__(self, eobj, value): |
1410 |
raise NotImplementedError |
|
1411 |
||
1412 |
||
1413 |
from logging import getLogger |
|
1414 |
from cubicweb import set_log_methods |
|
1415 |
set_log_methods(Entity, getLogger('cubicweb.entity')) |