Skip to content

Commit

Permalink
Merge tag '2024.2.1' into pcheung/2024.2.1-jchem-23.4.0-commons-lang-…
Browse files Browse the repository at this point in the history
…3.12
  • Loading branch information
philippcheung committed Sep 18, 2024
2 parents 6ab53e8 + 3c0d297 commit e90820b
Show file tree
Hide file tree
Showing 30 changed files with 506 additions and 146 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
-
name: Docker meta
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: |
Expand All @@ -31,19 +31,19 @@ jobs:
type=ref,event=tag,suffix=-${{ matrix.chemistry_package }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
uses: docker/build-push-action@v5
with:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/trigger-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
# Checkout this repo
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
# Get branch name
Expand All @@ -24,11 +24,11 @@ jobs:
# and 2022.1.1-dev9 will become 2022.1.1-dev10
- name: Get next dev tag name
run: |
LAST_TAG=$(git tag --sort=v:refname --merged ${{ env.BRANCH_NAME }} | grep -e '-dev' | tail -1)
LAST_TAG=$(git tag --sort=v:refname --merged ${{ env.BRANCH_NAME }} | grep -E '^[0-9]{4}\.[0-9]+\.[0-9]+-dev[0-9]+$' | tail -1)
echo "NEXT_TAG=$(echo $LAST_TAG | awk -F-dev -v OFS=-dev '{$NF += 1 ; print}')" >> $GITHUB_ENV
# Trigger the build
- name: Trigger the tagger workflow with branch ${{env.BRANCH_NAME}} and tag ${{ env.NEXT_TAG }}
uses: actions/github-script@v5
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ACAS_WORKFLOWS_TOKEN }}
script: |
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-multistage
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ RUN apt-get update && \

# Add nodejs for prepare config files
ENV NPM_CONFIG_LOGLEVEL warn
ENV NODE_VERSION 18.x
ENV NODE_VERSION 20.x

# Second Slowest Step
RUN curl -fsSL https://deb.nodesource.com/setup_$NODE_VERSION | bash - && \
Expand Down
38 changes: 38 additions & 0 deletions find-sort-flywaymigration.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# /bin/bash

# Find all the flyway migration files and sort them in order of version number (semantically)
# write them out as tab separated values with version\tfile

java_files=$( find src/main/java/com/labsynch/labseer/db/migration -name "V*.java" )

# Loop through the files and get the version from the beginning of the file name
# e.g. src/main/java/com/labsynch/labseer/db/migration/postgres/V1_0_6_6__copy_author_value_blob_values.java -> 1_0_6_6
all_versions=""
for java_file in $java_files
do
file_name=$( basename $java_file )
version=$( echo $file_name | sed -e 's/V\([0-9_]*\)__.*/\1/' | sed -e 's/_/./g' )
# add java to the end of the version
version="$version\t$java_file"
all_versions="$all_versions $version"
done

# Get teh sql files in src/main/resources/db/migration/postgres
sql_files=$( find src/main/resources/db/migration -name "*.sql" )

# Loop through the files and get the version from the beginning of the file name
# e.g. src/main/resources/db/migration/postgres/V1_0_6_6__copy_author_value_blob_values.sql -> 1_0_6_6
for sql_file in $sql_files
do
file_name=$( basename $sql_file )
version=$( echo $file_name | sed -e 's/V\([0-9.]*\)__.*/\1/' )
version="$version\t$sql_file"
all_versions="$all_versions $version"
done


# Do a semantically sorted list of the versions
# Use printf to get the tabs to work
printf "version\tfile"
printf "$all_versions" | tr ' ' '\n' | sort -V

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.Collection;
import java.util.List;

import javax.persistence.TypedQuery;

import com.labsynch.labseer.domain.DDictValue;
import com.labsynch.labseer.dto.CodeTableDTO;
import com.labsynch.labseer.exceptions.ErrorMessage;
Expand Down Expand Up @@ -322,7 +324,10 @@ public ResponseEntity<String> listJson(
public ResponseEntity<java.lang.String> getDDictValuesByTypeKindFormat(
@PathVariable("lsType") String lsType,
@PathVariable("lsKind") String lsKind,
@PathVariable("format") String format) {
@PathVariable("format") String format,
@RequestParam(value = "maxHits", required = false) Integer maxHits,
@RequestParam(value = "shortName", defaultValue = "", required = false) String shortName,
@RequestParam(value = "labelTextSearchTerm", defaultValue = "", required = false) String labelTextSearchTerm) {

HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
Expand All @@ -331,12 +336,37 @@ public ResponseEntity<java.lang.String> getDDictValuesByTypeKindFormat(
return new ResponseEntity<String>(headers, HttpStatus.BAD_REQUEST);
}

List<DDictValue> dDictResults = DDictValue.findDDictValuesByLsTypeEqualsAndLsKindEquals(lsType, lsKind)
.getResultList();
// throw an error if the user tries to search by codeName and label text
if (!shortName.isEmpty() && !labelTextSearchTerm.isEmpty()) {
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.setErrorLevel("error");
errorMessage.setMessage("Cannot search by codeName and labelTextSearchTerm at the same time");
return new ResponseEntity<String>(errorMessage.toJson(), headers, HttpStatus.BAD_REQUEST);
}

List<DDictValue> dDictResults;
if (labelTextSearchTerm.isEmpty() && shortName.isEmpty()) {
TypedQuery<DDictValue> dDictResultsQuery = DDictValue.findDDictValuesByLsTypeEqualsAndLsKindEquals(lsType, lsKind);
if (maxHits != null) {
dDictResultsQuery = dDictResultsQuery.setMaxResults(maxHits);
}
dDictResults = dDictResultsQuery.getResultList();
} else if (!shortName.isEmpty()) {
TypedQuery<DDictValue> dDictResultsQuery = DDictValue.findDDictValuesByLsTypeEqualsAndLsKindEqualsAndShortNameEquals(lsType, lsKind, shortName);
if (maxHits != null) {
dDictResultsQuery = dDictResultsQuery.setMaxResults(maxHits);
}
dDictResults = dDictResultsQuery.getResultList();
} else {
dDictResults = DDictValue.findDDictValuesByLsTypeEqualsAndLsKindEqualsAndLabelTextSearch(lsType, lsKind, labelTextSearchTerm, maxHits);
}

if (format != null && format.equalsIgnoreCase("codeTable")) {
List<CodeTableDTO> codeTables = dataDictionaryService.convertToCodeTables(dDictResults);
codeTables = CodeTableDTO.sortCodeTables(codeTables);
// labelText searches have their own sort order so we don't need to sort them
if (labelTextSearchTerm.isEmpty()) {
codeTables = CodeTableDTO.sortCodeTables(codeTables);
}
return new ResponseEntity<String>(CodeTableDTO.toJsonArray(codeTables), headers, HttpStatus.OK);
} else if (format != null && format.equalsIgnoreCase("csv")) {
String outputString = dataDictionaryService.getCsvList(dDictResults);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.labsynch.labseer.dto.TsvLoaderResponseDTO;
import com.labsynch.labseer.exceptions.ErrorMessage;
import com.labsynch.labseer.exceptions.NotFoundException;
import com.labsynch.labseer.exceptions.TooManyResultsException;
import com.labsynch.labseer.exceptions.UniqueNameException;
import com.labsynch.labseer.service.AnalysisGroupService;
import com.labsynch.labseer.service.AnalysisGroupValueService;
Expand Down Expand Up @@ -1634,20 +1635,19 @@ public ResponseEntity<java.lang.String> jsonFindExperimentByNameGet(@RequestPara
@RequestMapping(value = "/protocol/{codeName}", method = RequestMethod.GET, headers = "Accept=application/json")
@ResponseBody
public ResponseEntity<java.lang.String> jsonFindExperimentsByProtocolCodeName(
@PathVariable("codeName") String codeName, @RequestParam(value = "with", required = false) String with) {
@PathVariable("codeName") String codeName, @RequestParam(value = "projects", required = false) List<String> projects, @RequestParam(value = "with", required = false) String with) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
List<Protocol> protocols = Protocol.findProtocolsByCodeNameEqualsAndIgnoredNot(codeName, true).getResultList();
if (protocols.size() == 1) {
try {
Collection<Experiment> experiments = experimentService.findExperimentsByProtocolCodeName(codeName, projects);
return new ResponseEntity<String>(
Experiment.toJsonArrayStub(Experiment.findExperimentsByProtocol(protocols.get(0)).getResultList()),
Experiment.toJsonArrayStub(experiments),
headers, HttpStatus.OK);
} else if (protocols.size() > 1) {
logger.error("ERROR: multiple protocols found with the same code name");
return new ResponseEntity<String>("[ ]", headers, HttpStatus.CONFLICT);
} else {
logger.warn("WARN: no protocols found with the query code name");
} catch (NoResultException e) {
return new ResponseEntity<String>("[ ]", headers, HttpStatus.NOT_FOUND);

} catch (TooManyResultsException e) {
return new ResponseEntity<String>("[ ]", headers, HttpStatus.CONFLICT);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static List<BBChemParentStructure> findBBChemParentStructuresBySubstructu
EntityManager em = BBChemParentStructure.entityManager();
String fingerprintString = SimpleUtil.bitSetToString(substructure);
Query q = em.createNativeQuery(
"SELECT o.* FROM bbchem_parent_structure AS o WHERE (o.substructure \\& CAST(:fingerprintString AS bit(2048))) = CAST(:fingerprintString AS bit(2048)) ",
"SELECT o.* FROM bbchem_parent_structure AS o WHERE (o.substructure \\& CAST(:fingerprintString AS bit(2112))) = CAST(:fingerprintString AS bit(2112)) ",
BBChemParentStructure.class);
q.setParameter("fingerprintString", fingerprintString);
if (maxResults > -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static List<BBChemSaltFormStructure> findBBChemSaltFormStructuresBySubstr
EntityManager em = BBChemSaltFormStructure.entityManager();
String fingerprintString = SimpleUtil.bitSetToString(substructure);
Query q = em.createNativeQuery(
"SELECT o.* FROM bbchem_salt_form_structure AS o WHERE (o.substructure \\& CAST(:fingerprintString AS bit(2048))) = CAST(:fingerprintString AS bit(2048)) ",
"SELECT o.* FROM bbchem_salt_form_structure AS o WHERE (o.substructure \\& CAST(:fingerprintString AS bit(2112))) = CAST(:fingerprintString AS bit(2112)) ",
BBChemSaltFormStructure.class);
q.setParameter("fingerprintString", fingerprintString);
if (maxResults > -1) {
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/com/labsynch/labseer/domain/DDictValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.SequenceGenerator;
import javax.persistence.TypedQuery;
import javax.persistence.Version;
Expand Down Expand Up @@ -568,6 +569,45 @@ public static TypedQuery<DDictValue> findDDictValuesByLsTypeEqualsAndLsKindEqual
return q;
}

public static List<DDictValue> findDDictValuesByLsTypeEqualsAndLsKindEqualsAndLabelTextSearch(String lsType, String lsKind, String labelText, Integer maxHits) {
if (lsType == null || lsType.length() == 0)
throw new IllegalArgumentException("The lsType argument is required");
if (lsKind == null || lsKind.length() == 0)
throw new IllegalArgumentException("The lsKind argument is required");
EntityManager em = DDictValue.entityManager();

// Format the search text to match any word in the label text
// e.g. "word1 word2" -> "word1:* & word2:*"
String[] parts = labelText.trim().split("\\s+");
for (int i = 0; i < parts.length; i++) {
parts[i] = parts[i] + ":*";
}
String formattedLabelText = String.join(" & ", parts);

// Native query to use full text search
String sql =
"SELECT * " +
"FROM ddict_value " +
"WHERE ls_type = :lsType " +
"AND ls_kind = :lsKind " +
"AND to_tsvector('english', lower(label_text)) @@ to_tsquery('english', :formattedLabelText) " +
"ORDER BY (lower(label_text) = :labelText) DESC, " +
"ts_rank(to_tsvector('english', lower(label_text)), to_tsquery('english', :formattedLabelText)) DESC";

Query q = em.createNativeQuery(sql, DDictValue.class);
q.setParameter("lsType", lsType);
q.setParameter("lsKind", lsKind);
q.setParameter("labelText", labelText.toLowerCase());
q.setParameter("formattedLabelText", formattedLabelText);
if (maxHits != null) {
q = q.setMaxResults(maxHits);
}

@SuppressWarnings("unchecked")
List<DDictValue> results = q.getResultList();
return results;
}

public static TypedQuery<DDictValue> findDDictValuesByLsTypeEqualsAndLsKindEquals(String lsType, String lsKind,
String sortFieldName, String sortOrder) {
if (lsType == null || lsType.length() == 0)
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/com/labsynch/labseer/domain/Lot.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public class Lot {

@Size(max = 255)
@Column(name = "vendorid")
private String vendorId;
private String vendorID;

@ManyToOne
@JoinColumn(name = "salt_form")
Expand Down Expand Up @@ -618,10 +618,11 @@ public static TypedQuery<LotsByProjectDTO> findLotsByProjectsList(List<String> p

EntityManager em = Lot.entityManager();
String query = "SELECT new com.labsynch.labseer.dto.LotsByProjectDTO( "
+ "lt.id as id, lt.corpName as lotCorpName, lt.lotNumber as lotNumber, lt.registrationDate as registrationDate, prnt.corpName as parentCorpName, lt.project as project) "
+ "lt.id as id, lt.corpName as lotCorpName, lt.lotNumber as lotNumber, lt.registrationDate as registrationDate, prnt.corpName as parentCorpName, lt.project as project, lt.chemist as chemist, vnd.name as vendorName, vnd.code as vendorCode, lt.supplier as supplier) "
+ "FROM Lot AS lt "
+ "JOIN lt.saltForm sltfrm "
+ "JOIN sltfrm.parent prnt "
+ "LEFT JOIN lt.vendor vnd "
+ "WHERE lt.project in (:projects) ";

logger.debug("sql query " + query);
Expand Down Expand Up @@ -898,12 +899,12 @@ public void setVendor(Vendor vendor) {
this.vendor = vendor;
}

public String getVendorId() {
return this.vendorId;
public String getVendorID() {
return this.vendorID;
}

public void setVendorId(String vendorId) {
this.vendorId = vendorId;
public void setVendorID(String vendorID) {
this.vendorID = vendorID;
}

public Set<FileList> getFileLists() {
Expand Down Expand Up @@ -1074,7 +1075,7 @@ public void setLotAliases(Set<LotAlias> lotAliases) {
"registeredBy", "modifiedDate", "modifiedBy", "barcode", "color", "notebookPage", "amount", "amountUnits",
"solutionAmount", "solutionAmountUnits", "supplier", "supplierID", "purity", "purityOperator",
"purityMeasuredBy", "chemist", "percentEE", "comments", "isVirtual", "ignore", "physicalState", "vendor",
"vendorId", "saltForm", "fileLists", "retain", "retainUnits", "retainLocation", "meltingPoint",
"vendorID", "saltForm", "fileLists", "retain", "retainUnits", "retainLocation", "meltingPoint",
"boilingPoint", "supplierLot", "project", "parent", "bulkLoadFile", "lambda", "absorbance", "stockSolvent",
"stockLocation", "observedMassOne", "observedMassTwo", "tareWeight", "tareWeightUnits", "totalAmountStored",
"totalAmountStoredUnits", "lotAliases", "storageLocation");
Expand Down
36 changes: 34 additions & 2 deletions src/main/java/com/labsynch/labseer/domain/SaltForm.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Order;
import javax.validation.constraints.Size;

import com.labsynch.labseer.dto.SearchFormDTO;
Expand Down Expand Up @@ -239,6 +241,7 @@ public static TypedQuery<SaltForm> findSaltFormsByMeta(SearchFormDTO searchParam

Predicate[] predicates = new Predicate[0];
List<Predicate> predicateList = new ArrayList<Predicate>();
List<Order> orderList = new ArrayList<Order>();

if (searchParams.getChemist() != null && !searchParams.getChemist().equals("anyone")) {
logger.debug("incoming chemist :" + searchParams.getChemist().toString());
Expand Down Expand Up @@ -279,9 +282,37 @@ public static TypedQuery<SaltForm> findSaltFormsByMeta(SearchFormDTO searchParam
predicateList.add(predicate);
}
if (searchParams.getFormattedCorpNameList() != null) {
logger.debug("incoming corpNameList :" + searchParams.getFormattedCorpNameList().toString());
Predicate predicate = saltFormParent.get("corpName").in(searchParams.getFormattedCorpNameList());
List<String> corpNames = searchParams.getFormattedCorpNameList();
logger.debug("incoming corpNameList :" + corpNames.toString());
ArrayList<Predicate> corpNameLikePredicates = new ArrayList<Predicate>();
Expression<Double> maxSimilarity = null;
for (String corpName : corpNames) {
Predicate predicate = criteriaBuilder.like(saltFormParent.get("corpName"), '%' + corpName);
corpNameLikePredicates.add(predicate);
// Using pg_trgm.similarity to order results based on how similar the value is to
// the formatted corporate names.
Expression<Double> similarity = criteriaBuilder.function(
"similarity",
Double.class,
saltFormParent.get("corpName"),
criteriaBuilder.literal(corpName)
);
if (maxSimilarity == null) {
maxSimilarity = similarity;
}
else {
maxSimilarity = criteriaBuilder.selectCase()
.when(criteriaBuilder.greaterThan(similarity, maxSimilarity), similarity)
.otherwise(maxSimilarity)
.as(Double.class);
}
}
Predicate predicate = criteriaBuilder.or(corpNameLikePredicates.toArray(new Predicate[0]));
predicateList.add(predicate);
if (maxSimilarity != null) {
// Rows with a higher similarity will be ordered first.
orderList.add(criteriaBuilder.desc(maxSimilarity));
}
}
if (searchParams.getAlias() != null && !searchParams.getAlias().equals("")) {
Predicate predicate = null;
Expand Down Expand Up @@ -329,6 +360,7 @@ public static TypedQuery<SaltForm> findSaltFormsByMeta(SearchFormDTO searchParam

predicates = predicateList.toArray(predicates);
criteria.where(criteriaBuilder.and(predicates));
criteria.orderBy(orderList);
TypedQuery<SaltForm> q = em.createQuery(criteria);

if (searchParams.getMaxSynthDate() != null) {
Expand Down
Loading

0 comments on commit e90820b

Please sign in to comment.