author | Vincent Michel and Alain Leufroy |
Wed, 04 Apr 2012 17:47:58 +0200 | |
changeset 8354 | a9984ceebc26 |
child 8356 | e6688dd9fb52 |
permissions | -rw-r--r-- |
8354
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
1 |
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
3 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
4 |
# This file is part of CubicWeb. |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
5 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
6 |
# CubicWeb is free software: you can redistribute it and/or modify it under the |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
9 |
# any later version. |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
10 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
11 |
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
13 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
14 |
# details. |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
15 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
18 |
"""Source to query another RQL remote repository""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
19 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
20 |
__docformat__ = "restructuredtext en" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
21 |
_ = unicode |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
22 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
23 |
from os.path import join |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
24 |
from base64 import b64decode |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
25 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
26 |
from logilab.common.configuration import REQUIRED |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
27 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
28 |
from yams.schema import role_name |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
29 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
30 |
from rql.nodes import Constant |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
31 |
from rql.utils import rqlvar_maker |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
32 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
33 |
from cubicweb import dbapi, server |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
34 |
from cubicweb import ValidationError, BadConnectionId, UnknownEid |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
35 |
from cubicweb.schema import VIRTUAL_RTYPES |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
36 |
from cubicweb.server.sources import (AbstractSource, ConnectionWrapper, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
37 |
TimedCache, dbg_st_search, dbg_results) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
38 |
from cubicweb.server.msplanner import neged_relation |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
39 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
40 |
def uidtype(union, col, etype, args): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
41 |
select, col = union.locate_subquery(col, etype, args) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
42 |
return getattr(select.selection[col], 'uidtype', None) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
43 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
44 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
45 |
class ReplaceByInOperator(Exception): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
46 |
def __init__(self, eids): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
47 |
self.eids = eids |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
48 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
49 |
class RemoteSource(AbstractSource): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
50 |
"""Generic external repository source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
51 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
52 |
CNX_TYPE = None # Must be ovewritted ! |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
53 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
54 |
# boolean telling if modification hooks should be called when something is |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
55 |
# modified in this source |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
56 |
should_call_hooks = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
57 |
# boolean telling if the repository should connect to this source during |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
58 |
# migration |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
59 |
connect_for_migration = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
60 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
61 |
options = ( |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
62 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
63 |
('cubicweb-user', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
64 |
{'type' : 'string', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
65 |
'default': REQUIRED, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
66 |
'help': 'user to use for connection on the distant repository', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
67 |
'group': 'remote-source', 'level': 0, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
68 |
}), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
69 |
('cubicweb-password', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
70 |
{'type' : 'password', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
71 |
'default': '', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
72 |
'help': 'user to use for connection on the distant repository', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
73 |
'group': 'remote-source', 'level': 0, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
74 |
}), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
75 |
('base-url', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
76 |
{'type' : 'string', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
77 |
'default': '', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
78 |
'help': 'url of the web site for the distant repository, if you want ' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
79 |
'to generate external link to entities from this repository', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
80 |
'group': 'remote-source', 'level': 1, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
81 |
}), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
82 |
('skip-external-entities', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
83 |
{'type' : 'yn', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
84 |
'default': False, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
85 |
'help': 'should entities not local to the source be considered or not', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
86 |
'group': 'remote-source', 'level': 0, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
87 |
}), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
88 |
('synchronization-interval', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
89 |
{'type' : 'time', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
90 |
'default': '5min', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
91 |
'help': 'interval between synchronization with the external \ |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
92 |
repository (default to 5 minutes).', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
93 |
'group': 'remote-source', 'level': 2, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
94 |
})) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
95 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
96 |
PUBLIC_KEYS = AbstractSource.PUBLIC_KEYS + ('base-url',) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
97 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
98 |
_conn = None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
99 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
100 |
def __init__(self, repo, source_config, eid=None): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
101 |
super(AbstractSource, self).__init__(repo, source_config, eid) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
102 |
self.update_config(None, self.check_conf_dict(eid, source_config, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
103 |
fail_if_unknown=False)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
104 |
self._query_cache = TimedCache(1800) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
105 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
106 |
def update_config(self, source_entity, processed_config): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
107 |
"""update configuration from source entity""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
108 |
baseurl = processed_config.get('base-url') |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
109 |
if baseurl and not baseurl.endswith('/'): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
110 |
processed_config['base-url'] += '/' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
111 |
self.config = processed_config |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
112 |
self._skip_externals = processed_config['skip-external-entities'] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
113 |
if source_entity is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
114 |
self.latest_retrieval = source_entity.latest_retrieval |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
115 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
116 |
def _get_connection(self): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
117 |
"""open and return a connection to the source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
118 |
self.info('connecting to source %(base-url)s with user %(cubicweb-user)s', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
119 |
self.config) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
120 |
cnxprops = ConnectionProperties(cnxtype=self.CNX_TYPE) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
121 |
return dbapi.connect(login=self.config['cubicweb-user'], |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
122 |
password=self.config['cubicweb-password'], |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
123 |
cnxprops=cnxprops) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
124 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
125 |
def get_connection(self): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
126 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
127 |
return self._get_connection() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
128 |
except ConnectionError, ex: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
129 |
self.critical("can't get connection to source %s: %s", self.uri, ex) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
130 |
return ConnectionWrapper() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
131 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
132 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
133 |
def reset_caches(self): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
134 |
"""method called during test to reset potential source caches""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
135 |
self._query_cache = TimedCache(1800) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
136 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
137 |
def init(self, activated, source_entity): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
138 |
"""method called by the repository once ready to handle request""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
139 |
self.load_mapping(source_entity._cw) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
140 |
if activated: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
141 |
interval = self.config['synchronization-interval'] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
142 |
self.repo.looping_task(interval, self.synchronize) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
143 |
self.repo.looping_task(self._query_cache.ttl.seconds/10, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
144 |
self._query_cache.clear_expired) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
145 |
self.latest_retrieval = source_entity.latest_retrieval |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
146 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
147 |
def load_mapping(self, session=None): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
148 |
self.support_entities = {} |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
149 |
self.support_relations = {} |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
150 |
self.dont_cross_relations = set(('owned_by', 'created_by')) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
151 |
self.cross_relations = set() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
152 |
assert self.eid is not None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
153 |
self._schemacfg_idx = {} |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
154 |
self._load_mapping(session) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
155 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
156 |
etype_options = set(('write',)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
157 |
rtype_options = set(('maycross', 'dontcross', 'write',)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
158 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
159 |
def _check_options(self, schemacfg, allowedoptions): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
160 |
if schemacfg.options: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
161 |
options = set(w.strip() for w in schemacfg.options.split(':')) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
162 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
163 |
options = set() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
164 |
if options - allowedoptions: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
165 |
options = ', '.join(sorted(options - allowedoptions)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
166 |
msg = _('unknown option(s): %s' % options) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
167 |
raise ValidationError(schemacfg.eid, {role_name('options', 'subject'): msg}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
168 |
return options |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
169 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
170 |
def add_schema_config(self, schemacfg, checkonly=False): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
171 |
"""added CWSourceSchemaConfig, modify mapping accordingly""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
172 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
173 |
ertype = schemacfg.schema.name |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
174 |
except AttributeError: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
175 |
msg = schemacfg._cw._("attribute/relation can't be mapped, only " |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
176 |
"entity and relation types") |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
177 |
raise ValidationError(schemacfg.eid, {role_name('cw_for_schema', 'subject'): msg}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
178 |
if schemacfg.schema.__regid__ == 'CWEType': |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
179 |
options = self._check_options(schemacfg, self.etype_options) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
180 |
if not checkonly: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
181 |
self.support_entities[ertype] = 'write' in options |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
182 |
else: # CWRType |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
183 |
if ertype in ('is', 'is_instance_of', 'cw_source') or ertype in VIRTUAL_RTYPES: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
184 |
msg = schemacfg._cw._('%s relation should not be in mapped') % ertype |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
185 |
raise ValidationError(schemacfg.eid, {role_name('cw_for_schema', 'subject'): msg}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
186 |
options = self._check_options(schemacfg, self.rtype_options) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
187 |
if 'dontcross' in options: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
188 |
if 'maycross' in options: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
189 |
msg = schemacfg._("can't mix dontcross and maycross options") |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
190 |
raise ValidationError(schemacfg.eid, {role_name('options', 'subject'): msg}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
191 |
if 'write' in options: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
192 |
msg = schemacfg._("can't mix dontcross and write options") |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
193 |
raise ValidationError(schemacfg.eid, {role_name('options', 'subject'): msg}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
194 |
if not checkonly: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
195 |
self.dont_cross_relations.add(ertype) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
196 |
elif not checkonly: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
197 |
self.support_relations[ertype] = 'write' in options |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
198 |
if 'maycross' in options: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
199 |
self.cross_relations.add(ertype) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
200 |
if not checkonly: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
201 |
# add to an index to ease deletion handling |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
202 |
self._schemacfg_idx[schemacfg.eid] = ertype |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
203 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
204 |
def del_schema_config(self, schemacfg, checkonly=False): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
205 |
"""deleted CWSourceSchemaConfig, modify mapping accordingly""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
206 |
if checkonly: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
207 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
208 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
209 |
ertype = self._schemacfg_idx[schemacfg.eid] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
210 |
if ertype[0].isupper(): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
211 |
del self.support_entities[ertype] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
212 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
213 |
if ertype in self.support_relations: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
214 |
del self.support_relations[ertype] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
215 |
if ertype in self.cross_relations: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
216 |
self.cross_relations.remove(ertype) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
217 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
218 |
self.dont_cross_relations.remove(ertype) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
219 |
except Exception: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
220 |
self.error('while updating mapping consequently to removal of %s', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
221 |
schemacfg) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
222 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
223 |
def local_eid(self, cnx, extid, session): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
224 |
etype, dexturi, dextid = cnx.describe(extid) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
225 |
if dexturi == 'system' or not ( |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
226 |
dexturi in self.repo.sources_by_uri or self._skip_externals): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
227 |
assert etype in self.support_entities, etype |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
228 |
eid = self.repo.extid2eid(self, str(extid), etype, session) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
229 |
if eid > 0: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
230 |
return eid, True |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
231 |
elif dexturi in self.repo.sources_by_uri: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
232 |
source = self.repo.sources_by_uri[dexturi] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
233 |
cnx = session.cnxset.connection(source.uri) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
234 |
eid = source.local_eid(cnx, dextid, session)[0] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
235 |
return eid, False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
236 |
return None, None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
237 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
238 |
def synchronize(self, mtime=None): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
239 |
"""synchronize content known by this repository with content in the |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
240 |
external repository |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
241 |
""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
242 |
self.info('synchronizing remote %s source %s', (self.CNX_TYPE, self.uri)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
243 |
cnx = self.get_connection() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
244 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
245 |
extrepo = cnx._repo |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
246 |
except AttributeError: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
247 |
# fake connection wrapper returned when we can't connect to the |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
248 |
# external source (hence we've no chance to synchronize...) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
249 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
250 |
etypes = self.support_entities.keys() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
251 |
if mtime is None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
252 |
mtime = self.latest_retrieval |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
253 |
updatetime, modified, deleted = extrepo.entities_modified_since( |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
254 |
etypes, mtime) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
255 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
256 |
repo = self.repo |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
257 |
session = repo.internal_session() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
258 |
source = repo.system_source |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
259 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
260 |
for etype, extid in modified: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
261 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
262 |
eid = self.local_eid(cnx, extid, session)[0] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
263 |
if eid is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
264 |
rset = session.eid_rset(eid, etype) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
265 |
entity = rset.get_entity(0, 0) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
266 |
entity.complete(entity.e_schema.indexable_attributes()) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
267 |
source.index_entity(session, entity) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
268 |
except Exception: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
269 |
self.exception('while updating %s with external id %s of source %s', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
270 |
etype, extid, self.uri) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
271 |
continue |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
272 |
for etype, extid in deleted: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
273 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
274 |
eid = self.repo.extid2eid(self, str(extid), etype, session, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
275 |
insert=False) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
276 |
# entity has been deleted from external repository but is not known here |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
277 |
if eid is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
278 |
entity = session.entity_from_eid(eid, etype) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
279 |
repo.delete_info(session, entity, self.uri, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
280 |
scleanup=self.eid) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
281 |
except Exception: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
282 |
if self.repo.config.mode == 'test': |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
283 |
raise |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
284 |
self.exception('while updating %s with external id %s of source %s', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
285 |
etype, extid, self.uri) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
286 |
continue |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
287 |
self.latest_retrieval = updatetime |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
288 |
session.execute('SET X latest_retrieval %(date)s WHERE X eid %(x)s', |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
289 |
{'x': self.eid, 'date': self.latest_retrieval}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
290 |
session.commit() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
291 |
finally: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
292 |
session.close() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
293 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
294 |
def get_connection(self): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
295 |
raise NotImplementedError() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
296 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
297 |
def check_connection(self, cnx): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
298 |
"""check connection validity, return None if the connection is still valid |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
299 |
else a new connection |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
300 |
""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
301 |
if not isinstance(cnx, ConnectionWrapper): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
302 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
303 |
cnx.check() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
304 |
return # ok |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
305 |
except (BadConnectionId, ConnectionClosedError): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
306 |
pass |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
307 |
# try to reconnect |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
308 |
return self.get_connection() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
309 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
310 |
def syntax_tree_search(self, session, union, args=None, cachekey=None, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
311 |
varmap=None): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
312 |
assert dbg_st_search(self.uri, union, varmap, args, cachekey) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
313 |
rqlkey = union.as_string(kwargs=args) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
314 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
315 |
results = self._query_cache[rqlkey] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
316 |
except KeyError: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
317 |
results = self._syntax_tree_search(session, union, args) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
318 |
self._query_cache[rqlkey] = results |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
319 |
assert dbg_results(results) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
320 |
return results |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
321 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
322 |
def _syntax_tree_search(self, session, union, args): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
323 |
"""return result from this source for a rql query (actually from a rql |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
324 |
syntax tree and a solution dictionary mapping each used variable to a |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
325 |
possible type). If cachekey is given, the query necessary to fetch the |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
326 |
results (but not the results themselves) may be cached using this key. |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
327 |
""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
328 |
if not args is None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
329 |
args = args.copy() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
330 |
# get cached cursor anyway |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
331 |
cu = session.cnxset[self.uri] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
332 |
if cu is None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
333 |
# this is a ConnectionWrapper instance |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
334 |
msg = session._("can't connect to source %s, some data may be missing") |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
335 |
session.set_shared_data('sources_error', msg % self.uri, txdata=True) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
336 |
return [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
337 |
translator = RQL2RQL(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
338 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
339 |
rql = translator.generate(session, union, args) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
340 |
except UnknownEid, ex: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
341 |
if server.DEBUG: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
342 |
print ' unknown eid', ex, 'no results' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
343 |
return [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
344 |
if server.DEBUG & server.DBG_RQL: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
345 |
print ' translated rql', rql |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
346 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
347 |
rset = cu.execute(rql, args) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
348 |
except Exception, ex: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
349 |
self.exception(str(ex)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
350 |
msg = session._("error while querying source %s, some data may be missing") |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
351 |
session.set_shared_data('sources_error', msg % self.uri, txdata=True) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
352 |
return [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
353 |
descr = rset.description |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
354 |
if rset: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
355 |
needtranslation = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
356 |
rows = rset.rows |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
357 |
for i, etype in enumerate(descr[0]): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
358 |
if (etype is None or not self.schema.eschema(etype).final |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
359 |
or uidtype(union, i, etype, args)): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
360 |
needtranslation.append(i) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
361 |
if needtranslation: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
362 |
cnx = session.cnxset.connection(self.uri) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
363 |
for rowindex in xrange(rset.rowcount - 1, -1, -1): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
364 |
row = rows[rowindex] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
365 |
localrow = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
366 |
for colindex in needtranslation: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
367 |
if row[colindex] is not None: # optional variable |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
368 |
eid, local = self.local_eid(cnx, row[colindex], session) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
369 |
if local: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
370 |
localrow = True |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
371 |
if eid is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
372 |
row[colindex] = eid |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
373 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
374 |
# skip this row |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
375 |
del rows[rowindex] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
376 |
del descr[rowindex] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
377 |
break |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
378 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
379 |
# skip row if it only contains eids of entities which |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
380 |
# are actually from a source we also know locally, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
381 |
# except if some args specified (XXX should actually |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
382 |
# check if there are some args local to the source) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
383 |
if not (translator.has_local_eid or localrow): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
384 |
del rows[rowindex] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
385 |
del descr[rowindex] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
386 |
results = rows |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
387 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
388 |
results = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
389 |
return results |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
390 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
391 |
def _entity_relations_and_kwargs(self, session, entity): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
392 |
relations = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
393 |
kwargs = {'x': self.repo.eid2extid(self, entity.eid, session)} |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
394 |
for key, val in entity.cw_attr_cache.iteritems(): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
395 |
relations.append('X %s %%(%s)s' % (key, key)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
396 |
kwargs[key] = val |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
397 |
return relations, kwargs |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
398 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
399 |
def add_entity(self, session, entity): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
400 |
"""add a new entity to the source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
401 |
raise NotImplementedError() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
402 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
403 |
def update_entity(self, session, entity): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
404 |
"""update an entity in the source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
405 |
relations, kwargs = self._entity_relations_and_kwargs(session, entity) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
406 |
cu = session.cnxset[self.uri] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
407 |
cu.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations), kwargs) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
408 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
409 |
entity.cw_clear_all_caches() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
410 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
411 |
def delete_entity(self, session, entity): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
412 |
"""delete an entity from the source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
413 |
if session.deleted_in_transaction(self.eid): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
414 |
# source is being deleted, don't propagate |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
415 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
416 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
417 |
cu = session.cnxset[self.uri] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
418 |
cu.execute('DELETE %s X WHERE X eid %%(x)s' % entity.__regid__, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
419 |
{'x': self.repo.eid2extid(self, entity.eid, session)}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
420 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
421 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
422 |
def add_relation(self, session, subject, rtype, object): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
423 |
"""add a relation to the source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
424 |
cu = session.cnxset[self.uri] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
425 |
cu.execute('SET X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % rtype, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
426 |
{'x': self.repo.eid2extid(self, subject, session), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
427 |
'y': self.repo.eid2extid(self, object, session)}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
428 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
429 |
session.entity_from_eid(subject).cw_clear_all_caches() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
430 |
session.entity_from_eid(object).cw_clear_all_caches() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
431 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
432 |
def delete_relation(self, session, subject, rtype, object): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
433 |
"""delete a relation from the source""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
434 |
if session.deleted_in_transaction(self.eid): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
435 |
# source is being deleted, don't propagate |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
436 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
437 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
438 |
cu = session.cnxset[self.uri] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
439 |
cu.execute('DELETE X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % rtype, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
440 |
{'x': self.repo.eid2extid(self, subject, session), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
441 |
'y': self.repo.eid2extid(self, object, session)}) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
442 |
self._query_cache.clear() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
443 |
session.entity_from_eid(subject).cw_clear_all_caches() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
444 |
session.entity_from_eid(object).cw_clear_all_caches() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
445 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
446 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
447 |
class RQL2RQL(object): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
448 |
"""translate a local rql query to be executed on a distant repository""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
449 |
def __init__(self, source): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
450 |
self.source = source |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
451 |
self.repo = source.repo |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
452 |
self.current_operator = None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
453 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
454 |
def _accept_children(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
455 |
res = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
456 |
for child in node.children: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
457 |
rql = child.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
458 |
if rql is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
459 |
res.append(rql) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
460 |
return res |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
461 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
462 |
def generate(self, session, rqlst, args): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
463 |
self._session = session |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
464 |
self.kwargs = args |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
465 |
self.need_translation = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
466 |
self.has_local_eid = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
467 |
return self.visit_union(rqlst) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
468 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
469 |
def visit_union(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
470 |
s = self._accept_children(node) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
471 |
if len(s) > 1: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
472 |
return ' UNION '.join('(%s)' % q for q in s) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
473 |
return s[0] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
474 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
475 |
def visit_select(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
476 |
"""return the tree as an encoded rql string""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
477 |
self._varmaker = rqlvar_maker(defined=node.defined_vars.copy()) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
478 |
self._const_var = {} |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
479 |
if node.distinct: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
480 |
base = 'DISTINCT Any' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
481 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
482 |
base = 'Any' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
483 |
s = ['%s %s' % (base, ','.join(v.accept(self) for v in node.selection))] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
484 |
if node.groupby: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
485 |
s.append('GROUPBY %s' % ', '.join(group.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
486 |
for group in node.groupby)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
487 |
if node.orderby: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
488 |
s.append('ORDERBY %s' % ', '.join(self.visit_sortterm(term) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
489 |
for term in node.orderby)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
490 |
if node.limit is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
491 |
s.append('LIMIT %s' % node.limit) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
492 |
if node.offset: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
493 |
s.append('OFFSET %s' % node.offset) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
494 |
restrictions = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
495 |
if node.where is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
496 |
nr = node.where.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
497 |
if nr is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
498 |
restrictions.append(nr) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
499 |
if restrictions: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
500 |
s.append('WHERE %s' % ','.join(restrictions)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
501 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
502 |
if node.having: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
503 |
s.append('HAVING %s' % ', '.join(term.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
504 |
for term in node.having)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
505 |
subqueries = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
506 |
for subquery in node.with_: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
507 |
subqueries.append('%s BEING (%s)' % (','.join(ca.name for ca in subquery.aliases), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
508 |
self.visit_union(subquery.query))) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
509 |
if subqueries: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
510 |
s.append('WITH %s' % (','.join(subqueries))) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
511 |
return ' '.join(s) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
512 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
513 |
def visit_and(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
514 |
res = self._accept_children(node) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
515 |
if res: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
516 |
return ', '.join(res) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
517 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
518 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
519 |
def visit_or(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
520 |
res = self._accept_children(node) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
521 |
if len(res) > 1: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
522 |
return ' OR '.join('(%s)' % rql for rql in res) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
523 |
elif res: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
524 |
return res[0] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
525 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
526 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
527 |
def visit_not(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
528 |
rql = node.children[0].accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
529 |
if rql: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
530 |
return 'NOT (%s)' % rql |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
531 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
532 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
533 |
def visit_exists(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
534 |
rql = node.children[0].accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
535 |
if rql: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
536 |
return 'EXISTS(%s)' % rql |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
537 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
538 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
539 |
def visit_relation(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
540 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
541 |
if isinstance(node.children[0], Constant): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
542 |
# simplified rqlst, reintroduce eid relation |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
543 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
544 |
restr, lhs = self.process_eid_const(node.children[0]) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
545 |
except UnknownEid: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
546 |
# can safely skip not relation with an unsupported eid |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
547 |
if neged_relation(node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
548 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
549 |
raise |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
550 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
551 |
lhs = node.children[0].accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
552 |
restr = None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
553 |
except UnknownEid: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
554 |
# can safely skip not relation with an unsupported eid |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
555 |
if neged_relation(node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
556 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
557 |
# XXX what about optional relation or outer NOT EXISTS() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
558 |
raise |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
559 |
if node.optional in ('left', 'both'): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
560 |
lhs += '?' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
561 |
if node.r_type == 'eid' or not self.source.schema.rschema(node.r_type).final: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
562 |
self.need_translation = True |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
563 |
self.current_operator = node.operator() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
564 |
if isinstance(node.children[0], Constant): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
565 |
self.current_etypes = (node.children[0].uidtype,) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
566 |
else: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
567 |
self.current_etypes = node.children[0].variable.stinfo['possibletypes'] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
568 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
569 |
rhs = node.children[1].accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
570 |
except UnknownEid: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
571 |
# can safely skip not relation with an unsupported eid |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
572 |
if neged_relation(node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
573 |
return |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
574 |
# XXX what about optional relation or outer NOT EXISTS() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
575 |
raise |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
576 |
except ReplaceByInOperator, ex: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
577 |
rhs = 'IN (%s)' % ','.join(eid for eid in ex.eids) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
578 |
self.need_translation = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
579 |
self.current_operator = None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
580 |
if node.optional in ('right', 'both'): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
581 |
rhs += '?' |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
582 |
if restr is not None: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
583 |
return '%s %s %s, %s' % (lhs, node.r_type, rhs, restr) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
584 |
return '%s %s %s' % (lhs, node.r_type, rhs) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
585 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
586 |
def visit_comparison(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
587 |
if node.operator in ('=', 'IS'): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
588 |
return node.children[0].accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
589 |
return '%s %s' % (node.operator.encode(), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
590 |
node.children[0].accept(self)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
591 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
592 |
def visit_mathexpression(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
593 |
return '(%s %s %s)' % (node.children[0].accept(self), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
594 |
node.operator.encode(), |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
595 |
node.children[1].accept(self)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
596 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
597 |
def visit_function(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
598 |
#if node.name == 'IN': |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
599 |
res = [] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
600 |
for child in node.children: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
601 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
602 |
rql = child.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
603 |
except UnknownEid, ex: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
604 |
continue |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
605 |
res.append(rql) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
606 |
if not res: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
607 |
raise ex |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
608 |
return '%s(%s)' % (node.name, ', '.join(res)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
609 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
610 |
def visit_constant(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
611 |
if self.need_translation or node.uidtype: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
612 |
if node.type == 'Int': |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
613 |
self.has_local_eid = True |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
614 |
return str(self.eid2extid(node.value)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
615 |
if node.type == 'Substitute': |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
616 |
key = node.value |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
617 |
# ensure we have not yet translated the value... |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
618 |
if not key in self._const_var: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
619 |
self.kwargs[key] = self.eid2extid(self.kwargs[key]) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
620 |
self._const_var[key] = None |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
621 |
self.has_local_eid = True |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
622 |
return node.as_string() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
623 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
624 |
def visit_variableref(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
625 |
"""get the sql name for a variable reference""" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
626 |
return node.name |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
627 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
628 |
def visit_sortterm(self, node): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
629 |
if node.asc: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
630 |
return node.term.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
631 |
return '%s DESC' % node.term.accept(self) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
632 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
633 |
def process_eid_const(self, const): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
634 |
value = const.eval(self.kwargs) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
635 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
636 |
return None, self._const_var[value] |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
637 |
except Exception: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
638 |
var = self._varmaker.next() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
639 |
self.need_translation = True |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
640 |
restr = '%s eid %s' % (var, self.visit_constant(const)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
641 |
self.need_translation = False |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
642 |
self._const_var[value] = var |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
643 |
return restr, var |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
644 |
|
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
645 |
def eid2extid(self, eid): |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
646 |
try: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
647 |
return self.repo.eid2extid(self.source, eid, self._session) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
648 |
except UnknownEid: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
649 |
operator = self.current_operator |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
650 |
if operator is not None and operator != '=': |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
651 |
# deal with query like "X eid > 12" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
652 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
653 |
# The problem is that eid order in the external source may |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
654 |
# differ from the local source |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
655 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
656 |
# So search for all eids from this source matching the condition |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
657 |
# locally and then to replace the "> 12" branch by "IN (eids)" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
658 |
# |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
659 |
# XXX we may have to insert a huge number of eids...) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
660 |
sql = "SELECT extid FROM entities WHERE source='%s' AND type IN (%s) AND eid%s%s" |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
661 |
etypes = ','.join("'%s'" % etype for etype in self.current_etypes) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
662 |
cu = self._session.system_sql(sql % (self.source.uri, etypes, |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
663 |
operator, eid)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
664 |
# XXX buggy cu.rowcount which may be zero while there are some |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
665 |
# results |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
666 |
rows = cu.fetchall() |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
667 |
if rows: |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
668 |
raise ReplaceByInOperator((b64decode(r[0]) for r in rows)) |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
669 |
raise |
a9984ceebc26
[pyro] Refactor the pyrorql source
Vincent Michel and Alain Leufroy
parents:
diff
changeset
|
670 |