def save_roots(obj, eng): """Save and update the head roots and delete the update roots from the db. If both head and update have a root from a given source, then the older one is removed and the newer one is assigned tot the head. Otherwise, assign the update roots from sources that are missing among the head roots to the head. i.e. it is an union-like operation. Args: obj: a workflow object. eng: a workflow engine. Returns: None """ def _merge_roots(new_uuid, head_roots, update_roots): """Return the new roots to link to head.""" head_sources = {h.source: h for h in head_roots} for update_root in update_roots: if update_root.source not in head_sources: head_roots.append( WorkflowsRecordSources( source=update_root.source, record_uuid=new_uuid, json=update_root.json ) ) elif head_sources[update_root.source].updated < update_root.updated: head_roots.remove(head_sources[update_root.source]) head_roots.append( WorkflowsRecordSources( source=update_root.source, record_uuid=new_uuid, json=update_root.json ) ) db.session.delete(update_root) return head_roots head_uuid, update_uuid = obj.extra_data['head_uuid'], obj.extra_data['update_uuid'] obj.save() # XXX: otherwise obj.extra_data will be wiped by a db session commit below. head_roots = read_all_wf_record_sources(head_uuid) update_roots = read_all_wf_record_sources(update_uuid) updated_head_rooots = _merge_roots(head_uuid, head_roots, update_roots) for head_root in updated_head_rooots: db.session.merge(head_root) db.session.commit()
def test_merge_without_conflicts_handles_update_without_acquisition_source_and_acts_as_rootless( mocked_api_request_magpie, mocked_beard_api, workflow_app, mocked_external_services, disable_file_upload, enable_merge_on_update, ): with patch('inspire_json_merger.config.PublisherOnArxivOperations.conflict_filters', ['acquisition_source.source']): factory = TestRecordMetadata.create_from_file( __name__, 'merge_record_arxiv.json', index_name='records-hep') update_workflow_id = build_workflow(RECORD_WITHOUT_ACQUISITION_SOURCE_AND_NO_CONFLICTS).id eng_uuid = start('article', object_id=update_workflow_id) eng = WorkflowEngine.from_uuid(eng_uuid) obj = eng.objects[0] conflicts = obj.extra_data.get('conflicts') assert obj.status == ObjectStatus.COMPLETED assert not conflicts assert obj.extra_data.get('callback_url') is None assert obj.extra_data.get('is-update') is True assert obj.extra_data['merger_head_revision'] == 0 assert obj.extra_data['merger_original_root'] == {} # source us unknown, so no new root is saved. roots = read_all_wf_record_sources(factory.record_metadata.id) assert not roots
def save_roots(obj, eng): """Save and update the head roots and delete the update roots from the db. If both head and update have a root from a given source, then the older one is removed and the newer one is assigned tot the head. Otherwise, assign the update roots from sources that are missing among the head roots to the head. i.e. it is an union-like operation. Args: obj: a workflow object. eng: a workflow engine. Returns: None """ def _merge_roots(new_uuid, head_roots, update_roots): """Return the new roots to link to head.""" head_sources = {h.source: h for h in head_roots} for update_root in update_roots: if update_root.source not in head_sources: head_roots.append( WorkflowsRecordSources(source=update_root.source, record_uuid=new_uuid, json=update_root.json)) elif head_sources[ update_root.source].updated < update_root.updated: head_roots.remove(head_sources[update_root.source]) head_roots.append( WorkflowsRecordSources(source=update_root.source, record_uuid=new_uuid, json=update_root.json)) db.session.delete(update_root) return head_roots head_uuid, update_uuid = obj.extra_data['head_uuid'], obj.extra_data[ 'update_uuid'] obj.save( ) # XXX: otherwise obj.extra_data will be wiped by a db session commit below. head_roots = read_all_wf_record_sources(head_uuid) update_roots = read_all_wf_record_sources(update_uuid) updated_head_rooots = _merge_roots(head_uuid, head_roots, update_roots) for head_root in updated_head_rooots: db.session.merge(head_root) db.session.commit()
def test_read_all_wf_record_sources(dummy_record): insert_wf_record_source(json=dummy_record, record_uuid=dummy_record.id, source='arxiv') insert_wf_record_source(json=dummy_record, record_uuid=dummy_record.id, source='publisher') db.session.commit() entries = read_all_wf_record_sources(dummy_record.id) assert len(entries) == 2
def save_roots(obj, eng): """Save the head and update roots in the db. Merge the head and update roots in according to their sources and link them to the merged record. If both head and update have a root with a given source, than the head's one is taken and the update's one skipped. Args: obj: a workflow object. eng: a workflow engine. Returns: None """ def _merge_roots(new_uuid, head_roots, update_roots): """Return the new roots to link to head.""" head_sources = [h.source for h in head_roots] for u in update_roots: if u.source not in head_sources: head_roots.append( WorkflowsRecordSources( source=u.source, record_id=new_uuid, json=u.json ) ) return head_roots head_uuid, update_uuid = obj.extra_data['head_uuid'], obj.extra_data['update_uuid'] obj.save() # XXX: otherwise obj.extra_data will be wiped by a db session commit below. head_roots = read_all_wf_record_sources(head_uuid) update_roots = read_all_wf_record_sources(update_uuid) db.session.bulk_save_objects(_merge_roots(head_uuid, head_roots, update_roots)) db.session.commit()
def test_read_all_wf_record_sources(dummy_record): insert_wf_record_source( json=dummy_record, record_uuid=dummy_record.id, source='arXiv' ) insert_wf_record_source( json=dummy_record, record_uuid=dummy_record.id, source='Elsevier' ) db.session.commit() entries = read_all_wf_record_sources(dummy_record.id) assert len(entries) == 2