Work on presence API
This commit is contained in:
parent
03fc593cb9
commit
bb637c5433
|
@ -326,7 +326,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
|||
});
|
||||
txTemplate.execute(t -> {
|
||||
doExpungeEverythingQuery("DELETE from " + SearchParamPresent.class.getSimpleName() + " d");
|
||||
doExpungeEverythingQuery("DELETE from " + SearchParam.class.getSimpleName() + " d");
|
||||
doExpungeEverythingQuery("DELETE from " + ForcedId.class.getSimpleName() + " d");
|
||||
doExpungeEverythingQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d");
|
||||
doExpungeEverythingQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d");
|
||||
|
|
|
@ -297,11 +297,10 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
private void addPredicateParamMissing(String theResourceName, String theParamName, boolean theMissing) {
|
||||
Join<ResourceTable, SearchParamPresent> paramPresentJoin = myResourceTableRoot.join("mySearchParamPresents", JoinType.LEFT);
|
||||
Join<SearchParamPresent, SearchParam> paramJoin = paramPresentJoin.join("mySearchParam", JoinType.LEFT);
|
||||
|
||||
myPredicates.add(myBuilder.equal(paramJoin.get("myResourceName"), theResourceName));
|
||||
myPredicates.add(myBuilder.equal(paramJoin.get("myParamName"), theParamName));
|
||||
myPredicates.add(myBuilder.equal(paramPresentJoin.get("myPresent"), !theMissing));
|
||||
Expression<Long> hashPresence = paramPresentJoin.get("myHashPresence").as(Long.class);
|
||||
Long hash = SearchParamPresent.calculateHashPresence(theResourceName, theParamName, !theMissing);
|
||||
myPredicates.add(myBuilder.equal(hashPresence, hash));
|
||||
}
|
||||
|
||||
private void addPredicateParamMissing(String theResourceName, String theParamName, boolean theMissing, Join<ResourceTable, ? extends BaseResourceIndexedSearchParam> theJoin) {
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.dao.data;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.SearchParam;
|
||||
|
||||
public interface ISearchParamDao extends JpaRepository<SearchParam, Long> {
|
||||
|
||||
@Query("SELECT s FROM SearchParam s WHERE s.myResourceName = :resname AND s.myParamName = :parmname")
|
||||
public SearchParam findForResource(@Param("resname") String theResourceType, @Param("parmname") String theParamName);
|
||||
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_SEARCH_PARM", uniqueConstraints= {
|
||||
@UniqueConstraint(name="IDX_SEARCHPARM_RESTYPE_SPNAME", columnNames= {"RES_TYPE", "PARAM_NAME"})
|
||||
})
|
||||
public class SearchParam {
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name = "SEQ_SEARCHPARM_ID", sequenceName = "SEQ_SEARCHPARM_ID")
|
||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SEARCHPARM_ID")
|
||||
@Column(name = "PID")
|
||||
private Long myId;
|
||||
|
||||
@Column(name="PARAM_NAME", length=BaseResourceIndexedSearchParam.MAX_SP_NAME, nullable=false, updatable=false)
|
||||
private String myParamName;
|
||||
|
||||
@Column(name="RES_TYPE", length=ResourceTable.RESTYPE_LEN, nullable=false, updatable=false)
|
||||
private String myResourceName;
|
||||
|
||||
public String getParamName() {
|
||||
return myParamName;
|
||||
}
|
||||
|
||||
public void setParamName(String theParamName) {
|
||||
myParamName = theParamName;
|
||||
}
|
||||
|
||||
public void setResourceName(String theResourceName) {
|
||||
myResourceName = theResourceName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,18 +20,16 @@ package ca.uhn.fhir.jpa.entity;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_RES_PARAM_PRESENT", indexes = {
|
||||
@Index(name = "IDX_RESPARMPRESENT_RESID", columnList = "RES_ID")
|
||||
}, uniqueConstraints = {
|
||||
@UniqueConstraint(name = "IDX_RESPARMPRESENT_SPID_RESID", columnNames = { "SP_ID", "RES_ID" })
|
||||
@Index(name = "IDX_RESPARMPRESENT_RESID", columnList = "RES_ID"),
|
||||
@Index(name = "IDX_RESPARMPRESENT_HASHPRES", columnList = "HASH_PRESENCE")
|
||||
})
|
||||
public class SearchParamPresent implements Serializable {
|
||||
|
||||
|
@ -42,17 +40,15 @@ public class SearchParamPresent implements Serializable {
|
|||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_RESPARMPRESENT_ID")
|
||||
@Column(name = "PID")
|
||||
private Long myId;
|
||||
|
||||
@Column(name = "SP_PRESENT", nullable = false)
|
||||
private boolean myPresent;
|
||||
|
||||
@ManyToOne()
|
||||
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, foreignKey = @ForeignKey(name = "FK_RESPARMPRES_RESID"))
|
||||
private ResourceTable myResource;
|
||||
|
||||
@ManyToOne()
|
||||
@JoinColumn(name = "SP_ID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_RESPARMPRES_SPID"))
|
||||
private SearchParam mySearchParam;
|
||||
@Transient
|
||||
private transient String myParamName;
|
||||
@Column(name = "HASH_PRESENCE")
|
||||
private Long myHashPresence;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -61,12 +57,39 @@ public class SearchParamPresent implements Serializable {
|
|||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@PrePersist
|
||||
public void calculateHashes() {
|
||||
if (myHashPresence == null) {
|
||||
String resourceType = getResource().getResourceType();
|
||||
String paramName = getParamName();
|
||||
boolean present = myPresent;
|
||||
setHashPresence(calculateHashPresence(resourceType, paramName, present));
|
||||
}
|
||||
}
|
||||
|
||||
public Long getHashPresence() {
|
||||
return myHashPresence;
|
||||
}
|
||||
|
||||
public void setHashPresence(Long theHashPresence) {
|
||||
myHashPresence = theHashPresence;
|
||||
}
|
||||
|
||||
public String getParamName() {
|
||||
return myParamName;
|
||||
}
|
||||
|
||||
public void setParamName(String theParamName) {
|
||||
myParamName = theParamName;
|
||||
}
|
||||
|
||||
public ResourceTable getResource() {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
public SearchParam getSearchParam() {
|
||||
return mySearchParam;
|
||||
public void setResource(ResourceTable theResourceTable) {
|
||||
myResource = theResourceTable;
|
||||
}
|
||||
|
||||
public boolean isPresent() {
|
||||
|
@ -77,22 +100,18 @@ public class SearchParamPresent implements Serializable {
|
|||
myPresent = thePresent;
|
||||
}
|
||||
|
||||
public void setResource(ResourceTable theResourceTable) {
|
||||
myResource = theResourceTable;
|
||||
}
|
||||
|
||||
public void setSearchParam(SearchParam theSearchParam) {
|
||||
mySearchParam = theSearchParam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
|
||||
b.append("res_pid", myResource.getIdDt().toUnqualifiedVersionless().getValue());
|
||||
b.append("param", mySearchParam.getParamName());
|
||||
b.append("resPid", myResource.getIdDt().toUnqualifiedVersionless().getValue());
|
||||
b.append("paramName", myParamName);
|
||||
b.append("present", myPresent);
|
||||
return b.build();
|
||||
}
|
||||
|
||||
public static long calculateHashPresence(String theResourceType, String theParamName, boolean thePresent) {
|
||||
return BaseResourceIndexedSearchParam.hash(theResourceType, theParamName, Boolean.toString(thePresent));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,14 +20,12 @@ package ca.uhn.fhir.jpa.sp;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ISearchParamPresenceSvc {
|
||||
|
||||
void updatePresence(ResourceTable theResource, Map<String, Boolean> theParamNameToPresence);
|
||||
|
||||
void flushCachesForUnitTest();
|
||||
|
||||
}
|
||||
|
|
|
@ -20,29 +20,17 @@ package ca.uhn.fhir.jpa.sp;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.SearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.SearchParamPresent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamPresenceSvcImpl.class);
|
||||
|
||||
private Map<Pair<String, String>, SearchParam> myResourceTypeToSearchParamToEntity = new ConcurrentHashMap<Pair<String, String>, SearchParam>();
|
||||
|
||||
@Autowired
|
||||
private ISearchParamDao mySearchParamDao;
|
||||
|
||||
@Autowired
|
||||
private ISearchParamPresentDao mySearchParamPresentDao;
|
||||
|
||||
|
@ -55,62 +43,48 @@ public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
|||
return;
|
||||
}
|
||||
|
||||
Map<String, Boolean> presenceMap = new HashMap<String, Boolean>(theParamNameToPresence);
|
||||
List<SearchParamPresent> entitiesToSave = new ArrayList<SearchParamPresent>();
|
||||
List<SearchParamPresent> entitiesToDelete = new ArrayList<SearchParamPresent>();
|
||||
Map<String, Boolean> presenceMap = new HashMap<>(theParamNameToPresence);
|
||||
|
||||
// Find existing entries
|
||||
Collection<SearchParamPresent> existing;
|
||||
existing = mySearchParamPresentDao.findAllForResource(theResource);
|
||||
|
||||
Map<Long, SearchParamPresent> existingHashToPresence = new HashMap<>();
|
||||
for (SearchParamPresent nextExistingEntity : existing) {
|
||||
String nextSearchParamName = nextExistingEntity.getSearchParam().getParamName();
|
||||
Boolean existingValue = presenceMap.remove(nextSearchParamName);
|
||||
if (existingValue == null) {
|
||||
entitiesToDelete.add(nextExistingEntity);
|
||||
} else if (existingValue.booleanValue() == nextExistingEntity.isPresent()) {
|
||||
ourLog.trace("No change for search param {}", nextSearchParamName);
|
||||
} else {
|
||||
nextExistingEntity.setPresent(existingValue);
|
||||
entitiesToSave.add(nextExistingEntity);
|
||||
}
|
||||
existingHashToPresence.put(nextExistingEntity.getHashPresence(), nextExistingEntity);
|
||||
}
|
||||
|
||||
// Find newly wanted set of entries
|
||||
Map<Long, SearchParamPresent> newHashToPresence = new HashMap<>();
|
||||
for (Entry<String, Boolean> next : presenceMap.entrySet()) {
|
||||
String resourceType = theResource.getResourceType();
|
||||
String paramName = next.getKey();
|
||||
Pair<String, String> key = Pair.of(resourceType, paramName);
|
||||
|
||||
SearchParam searchParam = myResourceTypeToSearchParamToEntity.get(key);
|
||||
if (searchParam == null) {
|
||||
searchParam = mySearchParamDao.findForResource(resourceType, paramName);
|
||||
if (searchParam != null) {
|
||||
myResourceTypeToSearchParamToEntity.put(key, searchParam);
|
||||
} else {
|
||||
searchParam = new SearchParam();
|
||||
searchParam.setResourceName(resourceType);
|
||||
searchParam.setParamName(paramName);
|
||||
searchParam = mySearchParamDao.save(searchParam);
|
||||
ourLog.info("Added search param {} with pid {}", paramName, searchParam.getId());
|
||||
// Don't add the newly saved entity to the map in case the save fails
|
||||
}
|
||||
}
|
||||
|
||||
SearchParamPresent present = new SearchParamPresent();
|
||||
present.setResource(theResource);
|
||||
present.setSearchParam(searchParam);
|
||||
present.setParamName(paramName);
|
||||
present.setPresent(next.getValue());
|
||||
entitiesToSave.add(present);
|
||||
present.calculateHashes();
|
||||
|
||||
newHashToPresence.put(present.getHashPresence(), present);
|
||||
}
|
||||
|
||||
// Delete any that should be deleted
|
||||
List<SearchParamPresent> toDelete = new ArrayList<>();
|
||||
for (Entry<Long, SearchParamPresent> nextEntry : existingHashToPresence.entrySet()) {
|
||||
if (newHashToPresence.containsKey(nextEntry.getKey()) == false) {
|
||||
toDelete.add(nextEntry.getValue());
|
||||
}
|
||||
}
|
||||
mySearchParamPresentDao.deleteInBatch(toDelete);
|
||||
|
||||
// Add any that should be added
|
||||
List<SearchParamPresent> toAdd = new ArrayList<>();
|
||||
for (Entry<Long, SearchParamPresent> nextEntry : newHashToPresence.entrySet()) {
|
||||
if (existingHashToPresence.containsKey(nextEntry.getKey()) == false) {
|
||||
toAdd.add(nextEntry.getValue());
|
||||
}
|
||||
}
|
||||
mySearchParamPresentDao.saveAll(toAdd);
|
||||
|
||||
}
|
||||
|
||||
mySearchParamPresentDao.deleteInBatch(entitiesToDelete);
|
||||
mySearchParamPresentDao.saveAll(entitiesToSave);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushCachesForUnitTest() {
|
||||
myResourceTypeToSearchParamToEntity.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -156,3 +156,8 @@ drop index IDX_FORCEDID_TYPE_FORCEDID;
|
|||
create index IDX_FORCEDID_TYPE_FID;
|
||||
drop index IDX_SP_NUMBER;
|
||||
create index IDX_SP_NUMBER_HASH_VAL;
|
||||
|
||||
drop column SP_ID from table HFJ_RES_PARAM_PRESENT;
|
||||
drop index IDX_SEARCHPARM_RESTYPE_SPNAME;
|
||||
drop index IDX_RESPARMPRESENT_SPID_RESID;
|
||||
drop table HFJ_SEARCH_PARM;
|
||||
|
|
Loading…
Reference in New Issue