40 BadConnectionId, Unauthorized, ValidationError, |
40 BadConnectionId, Unauthorized, ValidationError, |
41 typed_eid) |
41 typed_eid) |
42 from cubicweb import cwvreg, schema, server |
42 from cubicweb import cwvreg, schema, server |
43 from cubicweb.server import utils, hook, pool, querier, sources |
43 from cubicweb.server import utils, hook, pool, querier, sources |
44 from cubicweb.server.session import Session, InternalSession, security_enabled |
44 from cubicweb.server.session import Session, InternalSession, security_enabled |
45 |
|
46 |
|
47 class CleanupEidTypeCacheOp(hook.SingleLastOperation): |
|
48 """on rollback of a insert query or commit of delete query, we have to |
|
49 clear repository's cache from no more valid entries |
|
50 |
|
51 NOTE: querier's rqlst/solutions cache may have been polluted too with |
|
52 queries such as Any X WHERE X eid 32 if 32 has been rollbacked however |
|
53 generated queries are unpredictable and analysing all the cache probably |
|
54 too expensive. Notice that there is no pb when using args to specify eids |
|
55 instead of giving them into the rql string. |
|
56 """ |
|
57 |
|
58 def commit_event(self): |
|
59 """the observed connections pool has been rollbacked, |
|
60 remove inserted eid from repository type/source cache |
|
61 """ |
|
62 try: |
|
63 self.session.repo.clear_caches( |
|
64 self.session.transaction_data['pendingeids']) |
|
65 except KeyError: |
|
66 pass |
|
67 |
|
68 def rollback_event(self): |
|
69 """the observed connections pool has been rollbacked, |
|
70 remove inserted eid from repository type/source cache |
|
71 """ |
|
72 try: |
|
73 self.session.repo.clear_caches( |
|
74 self.session.transaction_data['neweids']) |
|
75 except KeyError: |
|
76 pass |
|
77 |
45 |
78 |
46 |
79 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto): |
47 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto): |
80 """delete existing relation when adding a new one if card is 1 or ? |
48 """delete existing relation when adding a new one if card is 1 or ? |
81 |
49 |
931 def add_info(self, session, entity, source, extid=None, complete=True): |
899 def add_info(self, session, entity, source, extid=None, complete=True): |
932 """add type and source info for an eid into the system table, |
900 """add type and source info for an eid into the system table, |
933 and index the entity with the full text index |
901 and index the entity with the full text index |
934 """ |
902 """ |
935 # begin by inserting eid/type/source/extid into the entities table |
903 # begin by inserting eid/type/source/extid into the entities table |
936 new = session.transaction_data.setdefault('neweids', set()) |
904 hook.set_operation(session, 'neweids', entity.eid, |
937 new.add(entity.eid) |
905 hook.CleanupNewEidsCacheOp) |
938 self.system_source.add_info(session, entity, source, extid, complete) |
906 self.system_source.add_info(session, entity, source, extid, complete) |
939 CleanupEidTypeCacheOp(session) |
|
940 |
907 |
941 def delete_info(self, session, entity, sourceuri, extid): |
908 def delete_info(self, session, entity, sourceuri, extid): |
942 """called by external source when some entity known by the system source |
909 """called by external source when some entity known by the system source |
943 has been deleted in the external source |
910 has been deleted in the external source |
944 """ |
911 """ |
945 self._prepare_delete_info(session, entity, sourceuri) |
912 # mark eid as being deleted in session info and setup cache update |
|
913 # operation |
|
914 hook.set_operation(session, 'pendingeids', entity.eid, |
|
915 hook.CleanupDeletedEidsCacheOp) |
946 self._delete_info(session, entity, sourceuri, extid) |
916 self._delete_info(session, entity, sourceuri, extid) |
947 |
|
948 def _prepare_delete_info(self, session, entity, sourceuri): |
|
949 """prepare the repository for deletion of an entity: |
|
950 * update the fti |
|
951 * mark eid as being deleted in session info |
|
952 * setup cache update operation |
|
953 * if undoable, get back all entity's attributes and relation |
|
954 """ |
|
955 eid = entity.eid |
|
956 self.system_source.fti_unindex_entity(session, eid) |
|
957 pending = session.transaction_data.setdefault('pendingeids', set()) |
|
958 pending.add(eid) |
|
959 CleanupEidTypeCacheOp(session) |
|
960 |
917 |
961 def _delete_info(self, session, entity, sourceuri, extid): |
918 def _delete_info(self, session, entity, sourceuri, extid): |
962 # attributes=None, relations=None): |
919 # attributes=None, relations=None): |
963 """delete system information on deletion of an entity: |
920 """delete system information on deletion of an entity: |
964 * delete all remaining relations from/to this entity |
921 * delete all remaining relations from/to this entity |
1148 |
1105 |
1149 def glob_delete_entity(self, session, eid): |
1106 def glob_delete_entity(self, session, eid): |
1150 """delete an entity and all related entities from the repository""" |
1107 """delete an entity and all related entities from the repository""" |
1151 entity = session.entity_from_eid(eid) |
1108 entity = session.entity_from_eid(eid) |
1152 etype, sourceuri, extid = self.type_and_source_from_eid(eid, session) |
1109 etype, sourceuri, extid = self.type_and_source_from_eid(eid, session) |
1153 self._prepare_delete_info(session, entity, sourceuri) |
|
1154 if server.DEBUG & server.DBG_REPO: |
1110 if server.DEBUG & server.DBG_REPO: |
1155 print 'DELETE entity', etype, eid |
1111 print 'DELETE entity', etype, eid |
1156 source = self.sources_by_uri[sourceuri] |
1112 source = self.sources_by_uri[sourceuri] |
1157 if source.should_call_hooks: |
1113 if source.should_call_hooks: |
1158 self.hm.call_hooks('before_delete_entity', session, entity=entity) |
1114 self.hm.call_hooks('before_delete_entity', session, entity=entity) |