use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.
the class CompositionServiceImp method internalUpdate.
/**
* Update of an existing composition. With optional custom contribution, or existing one will be
* updated.
*
* @param compositionId ID of existing composition
* @param composition RMObject instance of the given Composition which represents the new
* version
* @param systemId Audit system; or NULL if contribution is given
* @param committerId Audit committer; or NULL if contribution is given
* @param description (Optional) Audit description; or NULL if contribution is given
* @param contributionId NULL if new one should be created; or ID of given custom contribution
* @return Version UID pointing to updated composition
*/
private ObjectVersionId internalUpdate(UUID compositionId, Composition composition, UUID systemId, UUID committerId, String description, UUID contributionId) {
boolean result;
try {
var compositionAccess = I_CompositionAccess.retrieveInstance(getDataAccess(), compositionId);
if (compositionAccess == null) {
throw new ObjectNotFoundException(I_CompositionAccess.class.getName(), "Could not find composition: " + compositionId);
}
// validate RM composition
validationService.check(composition);
// Check if template ID is not the same in existing and given data -> error
String existingTemplateId = compositionAccess.getContent().get(0).getTemplateId();
String inputTemplateId = composition.getArchetypeDetails().getTemplateId().getValue();
if (!existingTemplateId.equals(inputTemplateId)) {
// check if base template ID doesn't match (template ID schema: "$NAME.$LANG.v$VER")
if (!existingTemplateId.split("\\.")[0].equals(inputTemplateId.split("\\.")[0])) {
throw new InvalidApiParameterException("Can't update composition to have different template.");
}
// if base matches, check if given template ID is just a new version of the correct template
int existingTemplateIdVersion = Integer.parseInt(existingTemplateId.split("\\.v")[1]);
int inputTemplateIdVersion = Integer.parseInt(inputTemplateId.substring(inputTemplateId.lastIndexOf("\\.v") + 1));
if (inputTemplateIdVersion < existingTemplateIdVersion) {
throw new InvalidApiParameterException("Can't update composition with wrong template version bump.");
}
}
// to keep reference to entry to update: pull entry out of composition access and replace
// composition content with input, then write back to the original access
List<I_EntryAccess> contentList = compositionAccess.getContent();
contentList.get(0).setCompositionData(composition);
compositionAccess.setContent(contentList);
compositionAccess.setComposition(composition);
if (contributionId != null) {
// if custom contribution should be set
compositionAccess.setContributionId(contributionId);
result = compositionAccess.update(LocalDateTime.now(), contributionId);
} else {
// else existing one will be updated
if (committerId == null || systemId == null) {
throw new InternalServerException("Failed to update composition, missing mandatory audit meta data.");
}
result = compositionAccess.update(LocalDateTime.now(), committerId, systemId, description, ContributionChangeType.MODIFICATION);
}
} catch (ObjectNotFoundException | InvalidApiParameterException e) {
// otherwise exceptions would always get sucked up by the catch below
throw e;
} catch (Exception e) {
throw new InternalServerException(e);
}
if (!result) {
throw new InternalServerException("Update failed on composition:" + compositionId);
}
return new ObjectVersionId(compositionId.toString(), this.getServerConfig().getNodename(), getLastVersionNumber(compositionId).toString());
}
use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.
the class CompositionAccess method retrieveCompositionVersion.
/**
* @throws IllegalArgumentException when version number is not greater 0
* @throws ObjectNotFoundException when no composition could be found with given input
*/
public static I_CompositionAccess retrieveCompositionVersion(I_DomainAccess domainAccess, UUID id, int version) {
if (version < 1) {
throw new IllegalArgumentException("Version number must be > 0 please check your code");
}
// check if this version number matches the current version
if (getLastVersionNumber(domainAccess, id) == version) {
// current version
return retrieveInstance(domainAccess, id);
}
// FIXME make jooq compliant
String versionQuery = "select " + "row_id, " + "in_contribution, " + "ehr_id, " + "language, " + "territory, " + "composer, " + "sys_transaction, " + "has_audit," + "attestation_ref, " + "feeder_audit, " + "links from \n" + " (select ROW_NUMBER() OVER (ORDER BY sys_transaction ASC ) AS row_id, * from ehr.composition_history " + " WHERE id = ?) \n" + " AS Version WHERE row_id = ?;";
Connection connection = domainAccess.getConnection();
I_CompositionAccess compositionHistoryAccess = null;
try (PreparedStatement preparedStatement = connection.prepareStatement(versionQuery)) {
preparedStatement.setObject(1, id);
preparedStatement.setInt(2, version);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
CompositionRecord compositionRecord1 = domainAccess.getContext().newRecord(COMPOSITION);
compositionRecord1.setId(id);
compositionRecord1.setInContribution(UUID.fromString(resultSet.getString("in_contribution")));
compositionRecord1.setEhrId(UUID.fromString(resultSet.getString("ehr_id")));
compositionRecord1.setLanguage(resultSet.getString("language"));
compositionRecord1.setTerritory(resultSet.getInt("territory"));
compositionRecord1.setComposer(UUID.fromString(resultSet.getString("composer")));
compositionRecord1.setSysTransaction(resultSet.getTimestamp("sys_transaction"));
compositionRecord1.setHasAudit(UUID.fromString(resultSet.getString("has_audit")));
compositionRecord1.setFeederAudit(JSONB.valueOf(resultSet.getString("feeder_audit")));
/* TODO: uncomment when links encode/decode is fully implemented
compositionRecord1.setLinks(JSONB.valueOf(resultSet.getString("links")));
*/
compositionHistoryAccess = new CompositionAccess(domainAccess, compositionRecord1);
}
}
} catch (SQLException e) {
throw new ObjectNotFoundException(COMPOSITION_LITERAL, "Composition not found or or invalid DB content", e);
}
if (compositionHistoryAccess != null) {
compositionHistoryAccess.setContent(I_EntryAccess.retrieveInstanceInCompositionVersion(domainAccess, compositionHistoryAccess, version));
// retrieve the corresponding contribution
I_ContributionAccess contributionAccess = I_ContributionAccess.retrieveInstance(domainAccess, compositionHistoryAccess.getContributionId());
compositionHistoryAccess.setContributionAccess(contributionAccess);
I_AuditDetailsAccess auditDetailsAccess = new AuditDetailsAccess(domainAccess.getDataAccess()).retrieveInstance(domainAccess.getDataAccess(), compositionHistoryAccess.getAuditDetailsId());
compositionHistoryAccess.setAuditDetailsAccess(auditDetailsAccess);
// retrieve versioned context
EventContext historicalEventContext = I_ContextAccess.retrieveHistoricalEventContext(domainAccess, id, compositionHistoryAccess.getSysTransaction());
// adjust context for entries
if (historicalEventContext != null) {
for (I_EntryAccess entryAccess : compositionHistoryAccess.getContent()) {
entryAccess.getComposition().setContext(historicalEventContext);
}
}
}
domainAccess.releaseConnection(connection);
return compositionHistoryAccess;
}
use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.
the class CompositionAccess method internalCreate.
private UUID internalCreate(LocalDateTime timestamp, UUID committerId, UUID systemId, String description, UUID contribution) {
// check if custom contribution is already set, because changing it would yield updating in DB which is not desired (creates wrong new "version")
if (contribution != null) {
// Retrieve audit metadata from given contribution
var newContributionAccess = I_ContributionAccess.retrieveInstance(this.getDataAccess(), contribution);
systemId = newContributionAccess.getAuditsSystemId();
committerId = newContributionAccess.getAuditsCommitter();
description = newContributionAccess.getAuditsDescription();
} else {
// if not set, create DB entry of contribution so it can get referenced in this composition
// prepare contribution with given values
contributionAccess.setDataType(ContributionDataType.composition);
contributionAccess.setState(ContributionDef.ContributionState.COMPLETE);
contributionAccess.setAuditDetailsValues(committerId, systemId, description, I_ConceptAccess.ContributionChangeType.CREATION);
UUID contributionId = this.contributionAccess.commit();
setContributionId(contributionId);
}
// create DB entry of prepared auditDetails so it can get referenced in this composition
auditDetailsAccess.setChangeType(I_ConceptAccess.fetchContributionChangeType(this, I_ConceptAccess.ContributionChangeType.CREATION));
// prepare composition audit with given values
auditDetailsAccess.setSystemId(systemId);
auditDetailsAccess.setCommitter(committerId);
auditDetailsAccess.setDescription(description);
UUID auditId = this.auditDetailsAccess.commit();
compositionRecord.setHasAudit(auditId);
compositionRecord.setSysTransaction(Timestamp.valueOf(timestamp));
compositionRecord.store();
if (content.isEmpty()) {
logger.warn("Composition has no content:");
}
try {
for (I_EntryAccess entryAccess : content) {
entryAccess.commit(Timestamp.valueOf(timestamp));
}
} catch (Exception exception) {
logger.error("Problem in committing content, rolling back, exception:" + exception);
throw new IllegalArgumentException("Could not commit content:" + exception);
}
if (!composition.getCategory().getDefiningCode().getCodeString().equals("431")) {
EventContext eventContext = composition.getContext();
I_ContextAccess contextAccess = I_ContextAccess.getInstance(this, eventContext);
if (!contextAccess.isVoid()) {
contextAccess.setCompositionId(compositionRecord.getId());
contextAccess.commit(Timestamp.valueOf(timestamp));
}
}
return compositionRecord.getId();
}
use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.
the class EntryAccess method retrieveInstanceInCompositionVersion.
public static List<I_EntryAccess> retrieveInstanceInCompositionVersion(I_DomainAccess domainAccess, I_CompositionAccess compositionHistoryAccess, int version) {
Result<EntryHistoryRecord> entryHistoryRecords = domainAccess.getContext().selectFrom(ENTRY_HISTORY).where(ENTRY_HISTORY.COMPOSITION_ID.eq(compositionHistoryAccess.getId())).and(ENTRY_HISTORY.SYS_TRANSACTION.eq(compositionHistoryAccess.getSysTransaction())).fetch();
// build the list of parameters to recreate the composition
Map<SystemValue, Object> values = new HashMap<>();
values.put(SystemValue.COMPOSER, new PersistedPartyProxy(domainAccess).retrieve(compositionHistoryAccess.getComposerId()));
EventContext context = I_ContextAccess.retrieveHistoricalEventContext(domainAccess, compositionHistoryAccess.getId(), compositionHistoryAccess.getSysTransaction());
if (context == null) {
// unchanged context use the current one!
// also optional handling of context, because persistent compositions don't have a context
compositionHistoryAccess.getContextId().ifPresent(uuid -> I_ContextAccess.retrieveInstance(domainAccess, uuid).mapRmEventContext());
}
values.put(SystemValue.CONTEXT, context);
values.put(SystemValue.LANGUAGE, new CodePhrase(new TerminologyId("ISO_639-1"), compositionHistoryAccess.getLanguageCode()));
String territory2letters = domainAccess.getContext().fetchOne(TERRITORY, TERRITORY.CODE.eq(compositionHistoryAccess.getTerritoryCode())).getTwoletter();
values.put(SystemValue.TERRITORY, new CodePhrase(new TerminologyId("ISO_3166-1"), territory2letters));
values.put(SystemValue.FEEDER_AUDIT, new FeederAuditEncoding().fromDB(compositionHistoryAccess.getFeederAudit()));
List<I_EntryAccess> content = new ArrayList<>();
try {
EntryAccess entryAccess = new EntryAccess(domainAccess);
for (EntryHistoryRecord record : entryHistoryRecords) {
// set the record UID in the composition
UUID compositionId = compositionHistoryAccess.getId();
values.put(SystemValue.UID, new ObjectVersionId(compositionId.toString() + "::" + domainAccess.getServerConfig().getNodename() + "::" + version));
entryAccess.entryRecord = domainAccess.getContext().newRecord(ENTRY);
entryAccess.entryRecord.from(record);
entryAccess.composition = new RawJson().unmarshal(record.getEntry().data(), Composition.class);
setCompositionAttributes(entryAccess.composition, values);
buildArchetypeDetails(entryAccess);
content.add(entryAccess);
}
} catch (Exception e) {
throw new IllegalArgumentException(DB_INCONSISTENCY + e);
}
return content;
}
use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.
the class EntryAccess method retrieveInstanceInComposition.
/**
* @throws IllegalArgumentException if DB is inconsistent or operation fails
*/
public static List<I_EntryAccess> retrieveInstanceInComposition(I_DomainAccess domainAccess, I_CompositionAccess compositionAccess) {
Result<EntryRecord> entryRecords = domainAccess.getContext().selectFrom(ENTRY).where(ENTRY.COMPOSITION_ID.eq(compositionAccess.getId())).fetch();
// build the list of parameters to recreate the composition
Map<SystemValue, Object> values = new HashMap<>();
values.put(SystemValue.COMPOSER, new PersistedPartyProxy(domainAccess).retrieve(compositionAccess.getComposerId()));
// optional handling for persistent compositions that do not have a context
Optional<I_ContextAccess> opContextAccess = compositionAccess.getContextId().map(id -> I_ContextAccess.retrieveInstance(domainAccess, id));
opContextAccess.ifPresent(context -> values.put(SystemValue.CONTEXT, context.mapRmEventContext()));
values.put(SystemValue.LANGUAGE, new CodePhrase(new TerminologyId("ISO_639-1"), compositionAccess.getLanguageCode()));
String territory2letters = domainAccess.getContext().fetchOne(TERRITORY, TERRITORY.CODE.eq(compositionAccess.getTerritoryCode())).getTwoletter();
values.put(SystemValue.TERRITORY, new CodePhrase(new TerminologyId("ISO_3166-1"), territory2letters));
if (compositionAccess.getFeederAudit() != null) {
values.put(SystemValue.FEEDER_AUDIT, new FeederAuditEncoding().fromDB(compositionAccess.getFeederAudit()));
}
if (compositionAccess.getLinks() != null) {
values.put(SystemValue.LINKS, new LinksEncoding().fromDB(compositionAccess.getLinks()));
}
List<I_EntryAccess> content = new ArrayList<>();
try {
EntryAccess entryAccess = new EntryAccess(domainAccess);
for (EntryRecord record : entryRecords) {
// set the record UID in the composition with matching version number
Integer version = I_CompositionAccess.getLastVersionNumber(domainAccess, compositionAccess.getId());
values.put(SystemValue.UID, new ObjectVersionId(compositionAccess.getId().toString() + "::" + domainAccess.getServerConfig().getNodename() + "::" + version));
entryAccess.entryRecord = record;
String value = record.getEntry().data();
entryAccess.composition = new RawJson().unmarshal(value, Composition.class);
// continuing optional handling for persistent compositions
opContextAccess.map(I_ContextAccess::mapRmEventContext).ifPresent(ec -> values.put(SystemValue.CONTEXT, ec));
values.put(SystemValue.CATEGORY, new RecordedDvCodedText().fromDB(record, ENTRY.CATEGORY));
setCompositionAttributes(entryAccess.composition, values);
buildArchetypeDetails(entryAccess);
content.add(entryAccess);
}
} catch (Exception e) {
throw new IllegalArgumentException(DB_INCONSISTENCY + e);
}
return content;
}
Aggregations