Rename columns in code mapping
This commit is contained in:
parent
6e20b53979
commit
2a6436af23
|
@ -60,6 +60,7 @@ public class TermCodeSystemVersion implements Serializable {
|
|||
@JoinColumn(name = "CODESYSTEM_PID", referencedColumnName = "PID", nullable = true, foreignKey = @ForeignKey(name = "FK_CODESYSVER_CS_ID"))
|
||||
private TermCodeSystem myCodeSystem;
|
||||
@SuppressWarnings("unused")
|
||||
|
||||
@OneToOne(mappedBy = "myCurrentVersion", optional = true)
|
||||
private TermCodeSystem myCodeSystemHavingThisVersionAsCurrentVersionIfAny;
|
||||
|
||||
|
|
|
@ -56,8 +56,13 @@ public class TermConceptMapGroup implements Serializable {
|
|||
@OneToMany(mappedBy = "myConceptMapGroup")
|
||||
private List<TermConceptMapGroupElement> myConceptMapGroupElements;
|
||||
|
||||
@Column(name= "CONCEPT_MAP_URL", length = 200, nullable = true)
|
||||
private String myConceptMapUrl;
|
||||
|
||||
@Column(name= "SOURCE_VS", length = 200, nullable = true)
|
||||
private String mySourceValueSet;
|
||||
|
||||
@Column(name= "TARGET_VS", length = 200, nullable = true)
|
||||
private String myTargetValueSet;
|
||||
|
||||
public TermConceptMap getConceptMap() {
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.entity;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
@ -54,9 +55,16 @@ public class TermConceptMapGroupElement implements Serializable {
|
|||
@OneToMany(mappedBy = "myConceptMapGroupElement")
|
||||
private List<TermConceptMapGroupElementTarget> myConceptMapGroupElementTargets;
|
||||
|
||||
@Column(name = "CONCEPT_MAP_URL", length = 200)
|
||||
private String myConceptMapUrl;
|
||||
|
||||
@Column(name = "SYSTEM_URL", length = 200)
|
||||
private String mySystem;
|
||||
|
||||
@Column(name = "SYSTEM_VERSION", length = 200)
|
||||
private String mySystemVersion;
|
||||
|
||||
@Column(name = "VALUESET_URL", length = 200)
|
||||
private String myValueSet;
|
||||
|
||||
public String getCode() {
|
||||
|
@ -64,6 +72,7 @@ public class TermConceptMapGroupElement implements Serializable {
|
|||
}
|
||||
|
||||
public void setCode(String theCode) {
|
||||
Validate.notBlank(theCode, "theCode must not be blank");
|
||||
myCode = theCode;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,13 @@ public class TermConceptMapGroupElementTarget implements Serializable {
|
|||
@Column(name = "TARGET_EQUIVALENCE", length = 50)
|
||||
private ConceptMapEquivalence myEquivalence;
|
||||
|
||||
@Column(name = "CONCEPT_MAP_URL", length = 200)
|
||||
private String myConceptMapUrl;
|
||||
@Column(name = "SYSTEM_URL", length = 200)
|
||||
private String mySystem;
|
||||
@Column(name = "SYSTEM_VERSION", length = 200)
|
||||
private String mySystemVersion;
|
||||
@Column(name = "VALUESET_URL", length = 200)
|
||||
private String myValueSet;
|
||||
|
||||
public String getCode() {
|
||||
|
|
|
@ -1288,6 +1288,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
if (group.hasElement()) {
|
||||
TermConceptMapGroupElement termConceptMapGroupElement;
|
||||
for (ConceptMap.SourceElementComponent element : group.getElement()) {
|
||||
if (isBlank(element.getCode())) {
|
||||
// FIXME: JA - send this to an interceptor message so it can be
|
||||
// output
|
||||
continue;
|
||||
}
|
||||
termConceptMapGroupElement = new TermConceptMapGroupElement();
|
||||
termConceptMapGroupElement.setConceptMapGroup(termConceptMapGroup);
|
||||
termConceptMapGroupElement.setCode(element.getCode());
|
||||
|
|
|
@ -27,12 +27,12 @@ import com.google.common.reflect.ClassPath.ClassInfo;
|
|||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.InstantType;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -54,6 +54,7 @@ public class TestUtil {
|
|||
/**
|
||||
* This is really only useful for unit tests, do not call otherwise
|
||||
*/
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public static void scanEntities(String packageName) throws IOException, ClassNotFoundException {
|
||||
ImmutableSet<ClassInfo> classes = ClassPath.from(TestUtil.class.getClassLoader()).getTopLevelClasses(packageName);
|
||||
Set<String> names = new HashSet<String>();
|
||||
|
@ -80,6 +81,10 @@ public class TestUtil {
|
|||
scan(theClazz, theNames, theIsSuperClass);
|
||||
|
||||
for (Field nextField : theClazz.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(nextField.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ourLog.info(" * Scanning field: {}", nextField.getName());
|
||||
scan(nextField, theNames, theIsSuperClass);
|
||||
|
||||
|
@ -90,6 +95,22 @@ public class TestUtil {
|
|||
}
|
||||
}
|
||||
|
||||
boolean isTransient = nextField.getAnnotation(Transient.class) != null;
|
||||
if (!isTransient) {
|
||||
boolean hasColumn = nextField.getAnnotation(Column.class) != null;
|
||||
boolean hasJoinColumn = nextField.getAnnotation(JoinColumn.class) != null;
|
||||
OneToMany oneToMany = nextField.getAnnotation(OneToMany.class);
|
||||
OneToOne oneToOne = nextField.getAnnotation(OneToOne.class);
|
||||
boolean isOtherSideOfOneToManyMapping = oneToMany != null && isNotBlank(oneToMany.mappedBy());
|
||||
boolean isOtherSideOfOneToOneMapping = oneToOne != null && isNotBlank(oneToOne.mappedBy());
|
||||
Validate.isTrue(
|
||||
hasColumn ||
|
||||
hasJoinColumn ||
|
||||
isOtherSideOfOneToManyMapping ||
|
||||
isOtherSideOfOneToOneMapping, "Non-transient has no @Column or @JoinColumn: " + nextField);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (theClazz.getSuperclass().equals(Object.class)) {
|
||||
|
|
|
@ -3,10 +3,10 @@ package ca.uhn.fhir.jpa.config;
|
|||
import ca.uhn.fhir.jpa.util.TestUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
public class IdentifierLengthTest {
|
||||
public class JpaEntityTest {
|
||||
|
||||
@Test
|
||||
public void testIdentifierLength() throws Exception {
|
||||
public void testEntitiesAreValid() throws Exception {
|
||||
TestUtil.scanEntities(ca.uhn.fhir.jpa.model.entity.ResourceTable.class.getPackage().getName());
|
||||
TestUtil.scanEntities(ca.uhn.fhir.jpa.entity.TermConcept.class.getPackage().getName());
|
||||
}
|
|
@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.config.TestR4Config;
|
|||
import ca.uhn.fhir.jpa.dao.*;
|
||||
import ca.uhn.fhir.jpa.dao.data.*;
|
||||
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
|
||||
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
|
||||
import ca.uhn.fhir.jpa.interceptor.PerformanceTracingLoggingInterceptor;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||
|
@ -34,6 +33,7 @@ import ca.uhn.fhir.util.TestUtil;
|
|||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hibernate.search.jpa.FullTextEntityManager;
|
||||
import org.hibernate.search.jpa.Search;
|
||||
|
@ -294,11 +294,13 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
|||
protected ICacheWarmingSvc myCacheWarmingSvc;
|
||||
@Autowired
|
||||
protected SubscriptionRegistry mySubscriptionRegistry;
|
||||
protected IServerInterceptor myInterceptor;
|
||||
@Autowired
|
||||
private JpaValidationSupportChainR4 myJpaValidationSupportChainR4;
|
||||
private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor;
|
||||
private List<Object> mySystemInterceptors;
|
||||
protected IServerInterceptor myInterceptor;
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
@After()
|
||||
public void afterCleanupDao() {
|
||||
|
@ -402,6 +404,19 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void upload(String theClasspath) throws IOException {
|
||||
String resource = loadResource(theClasspath);
|
||||
IParser parser = EncodingEnum.detectEncoding(resource).newParser(myFhirCtx);
|
||||
IBaseResource resourceParsed = parser.parseResource(resource);
|
||||
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceParsed.getIdElement().getResourceType());
|
||||
dao.update(resourceParsed);
|
||||
}
|
||||
|
||||
protected String loadResource(String theClasspath) throws IOException {
|
||||
return IOUtils.toString(FhirResourceDaoR4ValidateTest.class.getResourceAsStream(theClasspath), Charsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContextBaseJpaR4Test() {
|
||||
|
|
|
@ -3,12 +3,13 @@ package ca.uhn.fhir.jpa.dao.r4;
|
|||
import ca.uhn.fhir.jpa.term.TranslationMatch;
|
||||
import ca.uhn.fhir.jpa.term.TranslationRequest;
|
||||
import ca.uhn.fhir.jpa.term.TranslationResult;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.ConceptMap;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
|
||||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -19,6 +20,9 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
|
||||
|
@ -1037,6 +1041,24 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUploadAndApplyR4DemoConceptMap() throws IOException {
|
||||
upload("/r4/ConceptMap-icd-sct.xml");
|
||||
|
||||
CodeableConcept sourceCode = new CodeableConcept();
|
||||
sourceCode.addCoding()
|
||||
.setSystem("http://snomed.info/sct")
|
||||
.setCode("263204007");
|
||||
TranslationRequest request = new TranslationRequest();
|
||||
request.setCodeableConcept(sourceCode);
|
||||
request.setTargetSystem(new UriType("http://hl7.org/fhir/sid/icd-10-us"));
|
||||
TranslationResult outcome = myConceptMapDao.translate(request, mySrd);
|
||||
|
||||
assertEquals("S52.209A", outcome.getMatches().get(1).getConcept().getCode());
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.dao.r4;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
|
@ -13,7 +11,6 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
|||
import ca.uhn.fhir.util.StopWatch;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.validation.IValidatorModule;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -417,21 +414,6 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void upload(String theClasspath) throws IOException {
|
||||
String resource = loadResource(theClasspath);
|
||||
IBaseResource resourceParsed = myFhirCtx.newJsonParser().parseResource(resource);
|
||||
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceParsed.getIdElement().getResourceType());
|
||||
dao.update(resourceParsed);
|
||||
}
|
||||
|
||||
private String loadResource(String theClasspath) throws IOException {
|
||||
return IOUtils.toString(FhirResourceDaoR4ValidateTest.class.getResourceAsStream(theClasspath), Charsets.UTF_8);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
private IBaseResource findResourceByIdInBundle(Bundle vss, String name) {
|
||||
IBaseResource retVal = null;
|
||||
for (BundleEntryComponent next : vss.getEntry()) {
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<ConceptMap xmlns="http://hl7.org/fhir">
|
||||
<id value="sct-icd"/>
|
||||
<url value="http://hl7.org/fhir/ConceptMap/103"/>
|
||||
<identifier>
|
||||
<system value="urn:ietf:rfc:3986"/>
|
||||
<value value="urn:uuid:53cd62ee-033e-414c-9f58-3ca97b5ffc3b"/>
|
||||
</identifier>
|
||||
<version value="4.0.0"/>
|
||||
<name value="SNOMED CT to ICD-10-CM mappings for fracture of ulna"/>
|
||||
<status value="draft"/>
|
||||
<experimental value="true"/>
|
||||
<date value="2012-06-13"/>
|
||||
<publisher value="HL7, Inc"/>
|
||||
<contact>
|
||||
<name value="FHIR project team (example)"/>
|
||||
<telecom>
|
||||
<system value="url"/>
|
||||
<value value="http://hl7.org/fhir"/>
|
||||
</telecom>
|
||||
</contact>
|
||||
<description value="Example rule-based mappings between SNOMED CT to ICD-10-CM for fracture of ulna"/>
|
||||
<jurisdiction>
|
||||
<coding>
|
||||
<system value="http://unstats.un.org/unsd/methods/m49/m49.htm"/>
|
||||
<code value="840"/>
|
||||
<display value="United States of America"/>
|
||||
</coding>
|
||||
</jurisdiction>
|
||||
<purpose value="Show example rule based mappings"/>
|
||||
<copyright value="Creative Commons 0"/>
|
||||
<sourceCanonical value="http://snomed.info/id?fhir_vs"/>
|
||||
<targetCanonical value="http://hl7.org/fhir/sid/icd-10-us"/>
|
||||
<group>
|
||||
<source value="http://snomed.info/sct"/>
|
||||
<sourceVersion value="March 2015 US Edition"/>
|
||||
<target value="http://hl7.org/fhir/sid/icd-10-us"/>
|
||||
<targetVersion value="2015"/>
|
||||
<element>
|
||||
<code value="263204007"/>
|
||||
<target>
|
||||
<code value="S52.209A"/>
|
||||
<equivalence value="narrower"/>
|
||||
<comment value="The target mapping to ICD-10-CM is narrower, since additional patient data on the encounter
|
||||
(initial vs. subsequent) and fracture type is required for a valid ICD-10-CM mapping."/>
|
||||
</target>
|
||||
</element>
|
||||
<element>
|
||||
<target>
|
||||
<code value="S52.209D"/>
|
||||
<equivalence value="narrower"/>
|
||||
<comment value="The target mapping to ICD-10-CM is narrower, since additional patient data on the encounter
|
||||
(initial vs. subsequent), fracture type and healing (for subsequent encounter) is required
|
||||
for a valid ICD-10-CM mapping."/>
|
||||
</target>
|
||||
</element>
|
||||
</group>
|
||||
</ConceptMap>
|
|
@ -30,6 +30,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
public class Migrator {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(Migrator.class);
|
||||
|
@ -83,7 +85,12 @@ public class Migrator {
|
|||
try {
|
||||
next.execute();
|
||||
} catch (SQLException e) {
|
||||
throw new InternalErrorException("Failure executing task \"" + next.getDescription() + "\", aborting! Cause: " + e.toString(), e);
|
||||
String description = next.getDescription();
|
||||
if (isBlank(description)) {
|
||||
description = next.getClass().getSimpleName();
|
||||
}
|
||||
String prefix = "Failure executing task \"" + description + "\", aborting! Cause: ";
|
||||
throw new InternalErrorException(prefix + e.toString(), e);
|
||||
}
|
||||
|
||||
myChangesCount += next.getChangesCount();
|
||||
|
|
|
@ -30,6 +30,7 @@ public abstract class BaseTableTask<T extends BaseTableTask> extends BaseTask {
|
|||
}
|
||||
|
||||
public T setTableName(String theTableName) {
|
||||
Validate.notBlank(theTableName);
|
||||
myTableName = theTableName;
|
||||
return (T) this;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package ca.uhn.fhir.jpa.migrate.taskdef;
|
||||
|
||||
import ca.uhn.fhir.jpa.migrate.JdbcUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Set;
|
||||
|
||||
public class RenameColumnTask extends BaseTableTask<RenameColumnTask> {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RenameColumnTask.class);
|
||||
private String myOldName;
|
||||
private String myNewName;
|
||||
|
||||
public void setOldName(String theOldName) {
|
||||
Validate.notBlank(theOldName);
|
||||
myOldName = theOldName;
|
||||
}
|
||||
|
||||
public void setNewName(String theNewName) {
|
||||
Validate.notBlank(theNewName);
|
||||
myNewName = theNewName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws SQLException {
|
||||
Set<String> columnNames = JdbcUtils.getColumnNames(getConnectionProperties(), getTableName());
|
||||
boolean haveOldName = columnNames.contains(myOldName.toUpperCase());
|
||||
boolean haveNewName = columnNames.contains(myNewName.toUpperCase());
|
||||
if (haveOldName && haveNewName) {
|
||||
throw new SQLException("Can not rename " + getTableName() + "." + myOldName + " to " + myNewName + " because both columns exist!");
|
||||
}
|
||||
if (!haveOldName && !haveNewName) {
|
||||
throw new SQLException("Can not rename " + getTableName() + "." + myOldName + " to " + myNewName + " because neither column exists!");
|
||||
}
|
||||
if (haveNewName) {
|
||||
ourLog.info("Column {} already exists on table {} - No action performed", myNewName, getTableName());
|
||||
return;
|
||||
}
|
||||
|
||||
String sql = "";
|
||||
switch (getDriverType()) {
|
||||
case DERBY_EMBEDDED:
|
||||
sql = "RENAME COLUMN " + getTableName() + "." + myOldName + " TO " + myNewName;
|
||||
break;
|
||||
case MARIADB_10_1:
|
||||
case MYSQL_5_7:
|
||||
sql = "ALTER TABLE " + getTableName() + " CHANGE COLUMN " + myOldName + " TO " + myNewName;
|
||||
break;
|
||||
case POSTGRES_9_4:
|
||||
sql = "ALTER TABLE " + getTableName() + " RENAME COLUMN " + myOldName + " TO " + myNewName;
|
||||
break;
|
||||
case MSSQL_2012:
|
||||
sql = "sp_rename '" + getTableName() + "." + myOldName + "', '" + myNewName + "', 'COLUMN'";
|
||||
break;
|
||||
case ORACLE_12C:
|
||||
sql = "ALTER TABLE " + getTableName() + " RENAME COLUMN " + myOldName + " TO " + myNewName;
|
||||
break;
|
||||
}
|
||||
|
||||
ourLog.info("Renaming column {} on table {} to {}", myOldName, getTableName(), myNewName);
|
||||
executeSql(getTableName(), sql);
|
||||
|
||||
}
|
||||
}
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.migrate.tasks;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -20,13 +20,13 @@ package ca.uhn.fhir.jpa.migrate.tasks;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.model.entity.*;
|
||||
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
|
||||
import ca.uhn.fhir.jpa.migrate.taskdef.AddColumnTask;
|
||||
import ca.uhn.fhir.jpa.migrate.taskdef.ArbitrarySqlTask;
|
||||
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTableColumnTypeTask;
|
||||
import ca.uhn.fhir.jpa.migrate.taskdef.CalculateHashesTask;
|
||||
import ca.uhn.fhir.jpa.migrate.tasks.api.BaseMigrationTasks;
|
||||
import ca.uhn.fhir.jpa.model.entity.*;
|
||||
import ca.uhn.fhir.util.VersionEnum;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -53,8 +53,29 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
init340();
|
||||
init350();
|
||||
init360();
|
||||
init400();
|
||||
}
|
||||
|
||||
private void init400() {
|
||||
Builder version = forVersion(VersionEnum.V4_0_0);
|
||||
|
||||
version.onTable("TRM_CONCEPT_MAP_GROUP")
|
||||
.renameColumn("myConceptMapUrl", "CONCEPT_MAP_URL")
|
||||
.renameColumn("mySourceValueSet", "SOURCE_VS")
|
||||
.renameColumn("myTargetValueSet", "TARGET_VS");
|
||||
|
||||
version.onTable("TRM_CONCEPT_MAP_GRP_ELEMENT")
|
||||
.renameColumn("myConceptMapUrl", "CONCEPT_MAP_URL")
|
||||
.renameColumn("mySystem", "SYSTEM_URL")
|
||||
.renameColumn("mySystemVersion", "SYSTEM_VERSION")
|
||||
.renameColumn("myValueSet", "VALUESET_URL");
|
||||
|
||||
version.onTable("TRM_CONCEPT_MAP_GRP_ELM_TGT")
|
||||
.renameColumn("myConceptMapUrl", "CONCEPT_MAP_URL")
|
||||
.renameColumn("mySystem", "SYSTEM_URL")
|
||||
.renameColumn("mySystemVersion", "SYSTEM_VERSION")
|
||||
.renameColumn("myValueSet", "VALUESET_URL");
|
||||
}
|
||||
|
||||
|
||||
private void init360() {
|
||||
|
|
|
@ -167,6 +167,15 @@ public class BaseMigrationTasks<T extends Enum> {
|
|||
return new BuilderAddForeignKey(theForeignKeyName);
|
||||
}
|
||||
|
||||
public BuilderWithTableName renameColumn(String theOldName, String theNewName) {
|
||||
RenameColumnTask task = new RenameColumnTask();
|
||||
task.setTableName(myTableName);
|
||||
task.setOldName(theOldName);
|
||||
task.setNewName(theNewName);
|
||||
addTask(task);
|
||||
return this;
|
||||
}
|
||||
|
||||
public class BuilderAddIndexWithName {
|
||||
private final String myIndexName;
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package ca.uhn.fhir.jpa.migrate.taskdef;
|
||||
|
||||
import ca.uhn.fhir.jpa.migrate.JdbcUtils;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class RenameColumnTaskTest extends BaseTest {
|
||||
|
||||
@Test
|
||||
public void testColumnAlreadyExists() throws SQLException {
|
||||
executeSql("create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))");
|
||||
|
||||
RenameColumnTask task = new RenameColumnTask();
|
||||
task.setTableName("SOMETABLE");
|
||||
task.setDescription("Drop an index");
|
||||
task.setOldName("myTextCol");
|
||||
task.setNewName("TEXTCOL");
|
||||
getMigrator().addTask(task);
|
||||
|
||||
getMigrator().migrate();
|
||||
|
||||
assertThat(JdbcUtils.getColumnNames(getConnectionProperties(), "SOMETABLE"), containsInAnyOrder("PID", "TEXTCOL"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testColumnDoesntAlreadyExist() throws SQLException {
|
||||
executeSql("create table SOMETABLE (PID bigint not null, myTextCol varchar(255))");
|
||||
|
||||
RenameColumnTask task = new RenameColumnTask();
|
||||
task.setTableName("SOMETABLE");
|
||||
task.setDescription("Drop an index");
|
||||
task.setOldName("myTextCol");
|
||||
task.setNewName("TEXTCOL");
|
||||
getMigrator().addTask(task);
|
||||
|
||||
getMigrator().migrate();
|
||||
|
||||
assertThat(JdbcUtils.getColumnNames(getConnectionProperties(), "SOMETABLE"), containsInAnyOrder("PID", "TEXTCOL"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeitherColumnExists() throws SQLException {
|
||||
executeSql("create table SOMETABLE (PID bigint not null)");
|
||||
|
||||
RenameColumnTask task = new RenameColumnTask();
|
||||
task.setTableName("SOMETABLE");
|
||||
task.setOldName("myTextCol");
|
||||
task.setNewName("TEXTCOL");
|
||||
getMigrator().addTask(task);
|
||||
|
||||
try {
|
||||
getMigrator().migrate();
|
||||
fail();
|
||||
} catch (InternalErrorException e) {
|
||||
assertEquals("Failure executing task \"RenameColumnTask\", aborting! Cause: java.sql.SQLException: Can not rename SOMETABLE.myTextCol to TEXTCOL because neither column exists!", e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBothColumnsExist() throws SQLException {
|
||||
executeSql("create table SOMETABLE (PID bigint not null, PID2 bigint)");
|
||||
|
||||
RenameColumnTask task = new RenameColumnTask();
|
||||
task.setTableName("SOMETABLE");
|
||||
task.setOldName("PID");
|
||||
task.setNewName("PID2");
|
||||
getMigrator().addTask(task);
|
||||
|
||||
try {
|
||||
getMigrator().migrate();
|
||||
fail();
|
||||
} catch (InternalErrorException e) {
|
||||
assertEquals("Failure executing task \"RenameColumnTask\", aborting! Cause: java.sql.SQLException: Can not rename SOMETABLE.PID to PID2 because both columns exist!", e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -24,14 +24,20 @@ import ca.uhn.fhir.context.ConfigurationException;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.hl7.fhir.r4.model.CanonicalType;
|
||||
|
@ -58,6 +64,8 @@ public class ResourceLinkExtractor {
|
|||
private ISearchParamRegistry mySearchParamRegistry;
|
||||
@Autowired
|
||||
private ISearchParamExtractor mySearchParamExtractor;
|
||||
@Autowired
|
||||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||
|
||||
public void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, boolean theFailOnInvalidReference, RequestDetails theRequest) {
|
||||
String resourceType = theEntity.getResourceType();
|
||||
|
@ -111,7 +119,17 @@ public class ResourceLinkExtractor {
|
|||
}
|
||||
|
||||
if (nextObject instanceof CanonicalType) {
|
||||
nextObject = new Reference(((CanonicalType) nextObject).getValueAsString());
|
||||
StorageProcessingMessage msg = new StorageProcessingMessage();
|
||||
msg.setMessage("Ignoring canonical reference (indexing canonidcal is not yet supported): " + ((CanonicalType) nextObject).getValueAsString());
|
||||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, msg);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
|
||||
// nextObject = new Reference(((CanonicalType) nextObject).getValueAsString());
|
||||
// wasCanonical = true;
|
||||
return;
|
||||
}
|
||||
|
||||
IIdType nextId;
|
||||
|
|
|
@ -225,6 +225,20 @@
|
|||
returned that includes the resource ID and the version ID for the deleted
|
||||
resource.
|
||||
</action>
|
||||
<action type="fix">
|
||||
A number of columns in the JPA Terminology Services ConceptMap tables were not
|
||||
explicitly annotated with @Column, so the DB columns that were generated had
|
||||
Java ugly field names as their SQL column names. These have been renamed, and
|
||||
entries in the JPA migrator tool have been added for anyone upgrading.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Field values with a datatype of <![CDATA[<code>canonical</code>]]> were indexed as
|
||||
though they were explicit resource references by the JPA server. This led to
|
||||
errors about external references not being supported when uploading various
|
||||
resources (e.g. Questionnaires with HL7-defined ValueSet references). This has
|
||||
been corrected. Note that at this time, we do not index canonical references
|
||||
at all (as we were previously doing it incorrectly). This will be improved soon.
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.8.0" date="2019-05-30" description="Hippo">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue