86 try: |
86 try: |
87 self.repo.glob_add_relation(self, fromeid, rtype, toeid) |
87 self.repo.glob_add_relation(self, fromeid, rtype, toeid) |
88 finally: |
88 finally: |
89 self.is_super_session = False |
89 self.is_super_session = False |
90 |
90 |
|
91 def update_rel_cache_add(self, subject, rtype, object, symetric=False): |
|
92 self._update_entity_rel_cache_add(subject, rtype, 'subject', object) |
|
93 if symetric: |
|
94 self._update_entity_rel_cache_add(object, rtype, 'subject', subject) |
|
95 else: |
|
96 self._update_entity_rel_cache_add(object, rtype, 'object', subject) |
|
97 |
|
98 def update_rel_cache_del(self, subject, rtype, object, symetric=False): |
|
99 self._update_entity_rel_cache_del(subject, rtype, 'subject', object) |
|
100 if symetric: |
|
101 self._update_entity_rel_cache_del(object, rtype, 'object', object) |
|
102 else: |
|
103 self._update_entity_rel_cache_del(object, rtype, 'object', subject) |
|
104 |
|
105 def _rel_cache(self, eid, rtype, role): |
|
106 try: |
|
107 entity = self.entity_cache(eid) |
|
108 except KeyError: |
|
109 return |
|
110 return entity.relation_cached(rtype, role) |
|
111 |
|
112 def _update_entity_rel_cache_add(self, eid, rtype, role, targeteid): |
|
113 rcache = self._rel_cache(eid, rtype, role) |
|
114 if rcache is not None: |
|
115 rset, entities = rcache |
|
116 rset.rows.append([targeteid]) |
|
117 if isinstance(rset.description, list): # else description not set |
|
118 rset.description.append([self.describe(targeteid)[0]]) |
|
119 rset.rowcount += 1 |
|
120 targetentity = self.entity_from_eid(targeteid) |
|
121 entities.append(targetentity) |
|
122 |
|
123 def _update_entity_rel_cache_del(self, eid, rtype, role, targeteid): |
|
124 rcache = self._rel_cache(eid, rtype, role) |
|
125 if rcache is not None: |
|
126 rset, entities = rcache |
|
127 for idx, row in enumerate(rset.rows): |
|
128 if row[0] == targeteid: |
|
129 break |
|
130 else: |
|
131 raise Exception('cache inconsistency for %s %s %s %s' % |
|
132 (eid, rtype, role, targeteid)) |
|
133 del rset.rows[idx] |
|
134 if isinstance(rset.description, list): # else description not set |
|
135 del rset.description[idx] |
|
136 del entities[idx] |
|
137 rset.rowcount -= 1 |
|
138 |
91 # resource accessors ###################################################### |
139 # resource accessors ###################################################### |
92 |
140 |
93 def actual_session(self): |
141 def actual_session(self): |
94 """return the original parent session if any, else self""" |
142 """return the original parent session if any, else self""" |
95 return self |
143 return self |
219 self.data[key] = value |
267 self.data[key] = value |
220 |
268 |
221 # request interface ####################################################### |
269 # request interface ####################################################### |
222 |
270 |
223 def set_entity_cache(self, entity): |
271 def set_entity_cache(self, entity): |
224 # no entity cache in the server, too high risk of inconsistency |
272 # XXX session level caching may be a pb with multiple repository |
225 # between pre/post hooks |
273 # instances, but 1. this is probably not the only one :$ and 2. it |
226 pass |
274 # may be an acceptable risk. Anyway we could activate it or not |
|
275 # according to a configuration option |
|
276 try: |
|
277 self.transaction_data['ecache'].setdefault(entity.eid, entity) |
|
278 except KeyError: |
|
279 self.transaction_data['ecache'] = ecache = {} |
|
280 ecache[entity.eid] = entity |
227 |
281 |
228 def entity_cache(self, eid): |
282 def entity_cache(self, eid): |
229 raise KeyError(eid) |
283 try: |
|
284 return self.transaction_data['ecache'][eid] |
|
285 except: |
|
286 raise |
|
287 |
|
288 def cached_entities(self): |
|
289 return self.transaction_data.get('ecache', {}).values() |
|
290 |
|
291 def drop_entity_cache(self, eid=None): |
|
292 if eid is None: |
|
293 self.transaction_data.pop('ecache', None) |
|
294 else: |
|
295 del self.transaction_data['ecache'][eid] |
230 |
296 |
231 def base_url(self): |
297 def base_url(self): |
232 url = self.repo.config['base-url'] |
298 url = self.repo.config['base-url'] |
233 if not url: |
299 if not url: |
234 try: |
300 try: |
274 self._threaddata.childsession = csession |
340 self._threaddata.childsession = csession |
275 # need shared pool set |
341 # need shared pool set |
276 self.set_pool() |
342 self.set_pool() |
277 return csession |
343 return csession |
278 |
344 |
279 def unsafe_execute(self, rql, kwargs=None, eid_key=None, build_descr=False, |
345 def unsafe_execute(self, rql, kwargs=None, eid_key=None, build_descr=True, |
280 propagate=False): |
346 propagate=False): |
281 """like .execute but with security checking disabled (this method is |
347 """like .execute but with security checking disabled (this method is |
282 internal to the server, it's not part of the db-api) |
348 internal to the server, it's not part of the db-api) |
283 |
349 |
284 if `propagate` is true, the super_session will be attached to the result |
350 if `propagate` is true, the super_session will be attached to the result |