628 |
628 |
629 def add_entity(self, session, entity): |
629 def add_entity(self, session, entity): |
630 """add a new entity to the source""" |
630 """add a new entity to the source""" |
631 with self._storage_handler(entity, 'added'): |
631 with self._storage_handler(entity, 'added'): |
632 attrs = self.preprocess_entity(entity) |
632 attrs = self.preprocess_entity(entity) |
633 sql = self.sqlgen.insert(SQL_PREFIX + entity.__regid__, attrs) |
633 sql = self.sqlgen.insert(SQL_PREFIX + entity.cw_etype, attrs) |
634 self.doexec(session, sql, attrs) |
634 self.doexec(session, sql, attrs) |
635 if session.ertype_supports_undo(entity.__regid__): |
635 if session.ertype_supports_undo(entity.cw_etype): |
636 self._record_tx_action(session, 'tx_entity_actions', 'C', |
636 self._record_tx_action(session, 'tx_entity_actions', 'C', |
637 etype=entity.__regid__, eid=entity.eid) |
637 etype=entity.cw_etype, eid=entity.eid) |
638 |
638 |
639 def update_entity(self, session, entity): |
639 def update_entity(self, session, entity): |
640 """replace an entity in the source""" |
640 """replace an entity in the source""" |
641 with self._storage_handler(entity, 'updated'): |
641 with self._storage_handler(entity, 'updated'): |
642 attrs = self.preprocess_entity(entity) |
642 attrs = self.preprocess_entity(entity) |
643 if session.ertype_supports_undo(entity.__regid__): |
643 if session.ertype_supports_undo(entity.cw_etype): |
644 changes = self._save_attrs(session, entity, attrs) |
644 changes = self._save_attrs(session, entity, attrs) |
645 self._record_tx_action(session, 'tx_entity_actions', 'U', |
645 self._record_tx_action(session, 'tx_entity_actions', 'U', |
646 etype=entity.__regid__, eid=entity.eid, |
646 etype=entity.cw_etype, eid=entity.eid, |
647 changes=self._binary(dumps(changes))) |
647 changes=self._binary(dumps(changes))) |
648 sql = self.sqlgen.update(SQL_PREFIX + entity.__regid__, attrs, |
648 sql = self.sqlgen.update(SQL_PREFIX + entity.cw_etype, attrs, |
649 ['cw_eid']) |
649 ['cw_eid']) |
650 self.doexec(session, sql, attrs) |
650 self.doexec(session, sql, attrs) |
651 |
651 |
652 def delete_entity(self, session, entity): |
652 def delete_entity(self, session, entity): |
653 """delete an entity from the source""" |
653 """delete an entity from the source""" |
654 with self._storage_handler(entity, 'deleted'): |
654 with self._storage_handler(entity, 'deleted'): |
655 if session.ertype_supports_undo(entity.__regid__): |
655 if session.ertype_supports_undo(entity.cw_etype): |
656 attrs = [SQL_PREFIX + r.type |
656 attrs = [SQL_PREFIX + r.type |
657 for r in entity.e_schema.subject_relations() |
657 for r in entity.e_schema.subject_relations() |
658 if (r.final or r.inlined) and not r in VIRTUAL_RTYPES] |
658 if (r.final or r.inlined) and not r in VIRTUAL_RTYPES] |
659 changes = self._save_attrs(session, entity, attrs) |
659 changes = self._save_attrs(session, entity, attrs) |
660 self._record_tx_action(session, 'tx_entity_actions', 'D', |
660 self._record_tx_action(session, 'tx_entity_actions', 'D', |
661 etype=entity.__regid__, eid=entity.eid, |
661 etype=entity.cw_etype, eid=entity.eid, |
662 changes=self._binary(dumps(changes))) |
662 changes=self._binary(dumps(changes))) |
663 attrs = {'cw_eid': entity.eid} |
663 attrs = {'cw_eid': entity.eid} |
664 sql = self.sqlgen.delete(SQL_PREFIX + entity.__regid__, attrs) |
664 sql = self.sqlgen.delete(SQL_PREFIX + entity.cw_etype, attrs) |
665 self.doexec(session, sql, attrs) |
665 self.doexec(session, sql, attrs) |
666 |
666 |
667 def add_relation(self, session, subject, rtype, object, inlined=False): |
667 def add_relation(self, session, subject, rtype, object, inlined=False): |
668 """add a relation to the source""" |
668 """add a relation to the source""" |
669 self._add_relations(session, rtype, [(subject, object)], inlined) |
669 self._add_relations(session, rtype, [(subject, object)], inlined) |
976 # begin by inserting eid/type/source/extid into the entities table |
976 # begin by inserting eid/type/source/extid into the entities table |
977 if extid is not None: |
977 if extid is not None: |
978 assert isinstance(extid, str) |
978 assert isinstance(extid, str) |
979 extid = b64encode(extid) |
979 extid = b64encode(extid) |
980 uri = 'system' if source.copy_based_source else source.uri |
980 uri = 'system' if source.copy_based_source else source.uri |
981 attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': extid, |
981 attrs = {'type': entity.cw_etype, 'eid': entity.eid, 'extid': extid, |
982 'source': uri, 'asource': source.uri, 'mtime': datetime.utcnow()} |
982 'source': uri, 'asource': source.uri, 'mtime': datetime.utcnow()} |
983 self._handle_insert_entity_sql(session, self.sqlgen.insert('entities', attrs), attrs) |
983 self._handle_insert_entity_sql(session, self.sqlgen.insert('entities', attrs), attrs) |
984 # insert core relations: is, is_instance_of and cw_source |
984 # insert core relations: is, is_instance_of and cw_source |
985 try: |
985 try: |
986 self._handle_is_relation_sql(session, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)', |
986 self._handle_is_relation_sql(session, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)', |
995 (entity.eid, eschema_eid(session, eschema))) |
995 (entity.eid, eschema_eid(session, eschema))) |
996 if 'CWSource' in self.schema and source.eid is not None: # else, cw < 3.10 |
996 if 'CWSource' in self.schema and source.eid is not None: # else, cw < 3.10 |
997 self._handle_is_relation_sql(session, 'INSERT INTO cw_source_relation(eid_from,eid_to) VALUES (%s,%s)', |
997 self._handle_is_relation_sql(session, 'INSERT INTO cw_source_relation(eid_from,eid_to) VALUES (%s,%s)', |
998 (entity.eid, source.eid)) |
998 (entity.eid, source.eid)) |
999 # now we can update the full text index |
999 # now we can update the full text index |
1000 if self.do_fti and self.need_fti_indexation(entity.__regid__): |
1000 if self.do_fti and self.need_fti_indexation(entity.cw_etype): |
1001 if complete: |
1001 if complete: |
1002 entity.complete(entity.e_schema.indexable_attributes()) |
1002 entity.complete(entity.e_schema.indexable_attributes()) |
1003 self.index_entity(session, entity=entity) |
1003 self.index_entity(session, entity=entity) |
1004 |
1004 |
1005 def update_info(self, session, entity, need_fti_update): |
1005 def update_info(self, session, entity, need_fti_update): |
1007 if self.do_fti and need_fti_update: |
1007 if self.do_fti and need_fti_update: |
1008 # reindex the entity only if this query is updating at least |
1008 # reindex the entity only if this query is updating at least |
1009 # one indexable attribute |
1009 # one indexable attribute |
1010 self.index_entity(session, entity=entity) |
1010 self.index_entity(session, entity=entity) |
1011 # update entities.mtime. |
1011 # update entities.mtime. |
1012 # XXX Only if entity.__regid__ in self.multisources_etypes? |
1012 # XXX Only if entity.cw_etype in self.multisources_etypes? |
1013 attrs = {'eid': entity.eid, 'mtime': datetime.utcnow()} |
1013 attrs = {'eid': entity.eid, 'mtime': datetime.utcnow()} |
1014 self.doexec(session, self.sqlgen.update('entities', attrs, ['eid']), attrs) |
1014 self.doexec(session, self.sqlgen.update('entities', attrs, ['eid']), attrs) |
1015 |
1015 |
1016 def delete_info_multi(self, session, entities, uri): |
1016 def delete_info_multi(self, session, entities, uri): |
1017 """delete system information on deletion of a list of entities with the |
1017 """delete system information on deletion of a list of entities with the |
1189 def _save_attrs(self, session, entity, attrs): |
1189 def _save_attrs(self, session, entity, attrs): |
1190 """return a pickleable dictionary containing current values for given |
1190 """return a pickleable dictionary containing current values for given |
1191 attributes of the entity |
1191 attributes of the entity |
1192 """ |
1192 """ |
1193 restr = {'cw_eid': entity.eid} |
1193 restr = {'cw_eid': entity.eid} |
1194 sql = self.sqlgen.select(SQL_PREFIX + entity.__regid__, restr, attrs) |
1194 sql = self.sqlgen.select(SQL_PREFIX + entity.cw_etype, restr, attrs) |
1195 cu = self.doexec(session, sql, restr) |
1195 cu = self.doexec(session, sql, restr) |
1196 values = dict(zip(attrs, cu.fetchone())) |
1196 values = dict(zip(attrs, cu.fetchone())) |
1197 # ensure backend specific binary are converted back to string |
1197 # ensure backend specific binary are converted back to string |
1198 eschema = entity.e_schema |
1198 eschema = entity.e_schema |
1199 for column in attrs: |
1199 for column in attrs: |
1300 sql = self.sqlgen.insert(SQL_PREFIX + etype, action.changes) |
1300 sql = self.sqlgen.insert(SQL_PREFIX + etype, action.changes) |
1301 self.doexec(session, sql, action.changes) |
1301 self.doexec(session, sql, action.changes) |
1302 # restore record in entities (will update fti if needed) |
1302 # restore record in entities (will update fti if needed) |
1303 self.add_info(session, entity, self, None, True) |
1303 self.add_info(session, entity, self, None, True) |
1304 # remove record from deleted_entities if entity's type is multi-sources |
1304 # remove record from deleted_entities if entity's type is multi-sources |
1305 if entity.__regid__ in self.multisources_etypes: |
1305 if entity.cw_etype in self.multisources_etypes: |
1306 self.doexec(session, |
1306 self.doexec(session, |
1307 'DELETE FROM deleted_entities WHERE eid=%s' % eid) |
1307 'DELETE FROM deleted_entities WHERE eid=%s' % eid) |
1308 self.repo.hm.call_hooks('after_add_entity', session, entity=entity) |
1308 self.repo.hm.call_hooks('after_add_entity', session, entity=entity) |
1309 return errors |
1309 return errors |
1310 |
1310 |
1363 self.doexec(session, 'DELETE FROM is_instance_of_relation WHERE eid_from=%s' % eid) |
1363 self.doexec(session, 'DELETE FROM is_instance_of_relation WHERE eid_from=%s' % eid) |
1364 self.doexec(session, 'DELETE FROM cw_source_relation WHERE eid_from=%s' % self.eid) |
1364 self.doexec(session, 'DELETE FROM cw_source_relation WHERE eid_from=%s' % self.eid) |
1365 # XXX check removal of inlined relation? |
1365 # XXX check removal of inlined relation? |
1366 # delete the entity |
1366 # delete the entity |
1367 attrs = {'cw_eid': eid} |
1367 attrs = {'cw_eid': eid} |
1368 sql = self.sqlgen.delete(SQL_PREFIX + entity.__regid__, attrs) |
1368 sql = self.sqlgen.delete(SQL_PREFIX + entity.cw_etype, attrs) |
1369 self.doexec(session, sql, attrs) |
1369 self.doexec(session, sql, attrs) |
1370 # remove record from entities (will update fti if needed) |
1370 # remove record from entities (will update fti if needed) |
1371 self.delete_info_multi(session, [entity], self.uri) |
1371 self.delete_info_multi(session, [entity], self.uri) |
1372 self.repo.hm.call_hooks('after_delete_entity', session, entity=entity) |
1372 self.repo.hm.call_hooks('after_delete_entity', session, entity=entity) |
1373 return () |
1373 return () |