66 class SetCreatorOp(hook.DataOperationMixIn, hook.Operation): |
67 class SetCreatorOp(hook.DataOperationMixIn, hook.Operation): |
67 |
68 |
68 def precommit_event(self): |
69 def precommit_event(self): |
69 session = self.session |
70 session = self.session |
70 relations = [(eid, session.user.eid) for eid in self.get_data() |
71 relations = [(eid, session.user.eid) for eid in self.get_data() |
71 # don't consider entities that have been created and |
72 # don't consider entities that have been created and deleted in |
72 # deleted in the same transaction |
73 # the same transaction, nor ones where created_by has been |
|
74 # explicitly set |
73 if not session.deleted_in_transaction(eid) and \ |
75 if not session.deleted_in_transaction(eid) and \ |
74 not session.entity_from_eid(eid).created_by] |
76 not session.entity_from_eid(eid).created_by] |
75 session.add_relations([('created_by', relations)]) |
77 session.add_relations([('created_by', relations)]) |
76 |
78 |
77 |
79 |
139 session, session.entity_from_eid(self.eidfrom)) |
141 session, session.entity_from_eid(self.eidfrom)) |
140 elif ftcontainer == 'object': |
142 elif ftcontainer == 'object': |
141 session.repo.system_source.index_entity( |
143 session.repo.system_source.index_entity( |
142 session, session.entity_from_eid(self.eidto)) |
144 session, session.entity_from_eid(self.eidto)) |
143 |
145 |
|
146 |
|
147 |
|
148 # entity source handling ####################################################### |
|
149 |
|
150 class ChangeEntityUpdateCaches(hook.Operation): |
|
151 def postcommit_event(self): |
|
152 self.oldsource.reset_caches() |
|
153 repo = self.session.repo |
|
154 entity = self.entity |
|
155 extid = entity.cw_metainformation()['extid'] |
|
156 repo._type_source_cache[entity.eid] = ( |
|
157 entity.__regid__, self.newsource.uri, None, self.newsource.uri) |
|
158 if self.oldsource.copy_based_source: |
|
159 uri = 'system' |
|
160 else: |
|
161 uri = self.oldsource.uri |
|
162 repo._extid_cache[(extid, uri)] = -entity.eid |
|
163 |
|
164 class ChangeEntitySourceDeleteHook(MetaDataHook): |
|
165 """support for moving an entity from an external source by watching 'Any |
|
166 cw_source CWSource' relation |
|
167 """ |
|
168 |
|
169 __regid__ = 'cw.metadata.source-change' |
|
170 __select__ = MetaDataHook.__select__ & hook.match_rtype('cw_source') |
|
171 events = ('before_delete_relation',) |
|
172 |
|
173 def __call__(self): |
|
174 if (self._cw.deleted_in_transaction(self.eidfrom) |
|
175 or self._cw.deleted_in_transaction(self.eidto)): |
|
176 return |
|
177 schange = self._cw.transaction_data.setdefault('cw_source_change', {}) |
|
178 schange[self.eidfrom] = self.eidto |
|
179 |
|
180 |
|
181 class ChangeEntitySourceAddHook(MetaDataHook): |
|
182 __regid__ = 'cw.metadata.source-change' |
|
183 __select__ = MetaDataHook.__select__ & hook.match_rtype('cw_source') |
|
184 events = ('before_add_relation',) |
|
185 |
|
186 def __call__(self): |
|
187 schange = self._cw.transaction_data.get('cw_source_change') |
|
188 if schange is not None and self.eidfrom in schange: |
|
189 newsource = self._cw.entity_from_eid(self.eidto) |
|
190 if newsource.name != 'system': |
|
191 raise Exception('changing source to something else than the ' |
|
192 'system source is unsupported') |
|
193 syssource = newsource.repo_source |
|
194 oldsource = self._cw.entity_from_eid(schange[self.eidfrom]) |
|
195 entity = self._cw.entity_from_eid(self.eidfrom) |
|
196 # copy entity if necessary |
|
197 if not oldsource.repo_source.copy_based_source: |
|
198 entity.complete(skip_bytes=False) |
|
199 entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache) |
|
200 syssource.add_entity(self._cw, entity) |
|
201 # we don't want the moved entity to be reimported later. To |
|
202 # distinguish this state, the trick is to change the associated |
|
203 # record in the 'entities' system table with eid=-eid while leaving |
|
204 # other fields unchanged, and to add a new record with eid=eid, |
|
205 # source='system'. External source will then have consider case |
|
206 # where `extid2eid` return a negative eid as 'this entity was known |
|
207 # but has been moved, ignore it'. |
|
208 self._cw.system_sql('UPDATE entities SET eid=-eid,source=%(source)s ' |
|
209 'WHERE eid=%(eid)s', |
|
210 {'eid': self.eidfrom, 'source': newsource.name}) |
|
211 attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': None, |
|
212 'source': 'system', 'asource': 'system', |
|
213 'mtime': datetime.now()} |
|
214 self._cw.system_sql(syssource.sqlgen.insert('entities', attrs), attrs) |
|
215 # register an operation to update repository/sources caches |
|
216 ChangeEntityUpdateCaches(self._cw, entity=entity, |
|
217 oldsource=oldsource.repo_source, |
|
218 newsource=syssource) |