From 6d58f8f362bcbcaf3d7d142fbb86d32003fbef49 Mon Sep 17 00:00:00 2001 From: Gaofei Zhao <15748980+dippindots@users.noreply.github.com> Date: Thu, 19 Dec 2024 11:34:39 -0500 Subject: [PATCH] Custom sample filtering performance and security improvement (#11296) * Use prepared statements to avoid injection attack and clickhouse native array to improve performance * Dynamically calculate sample identifiers in study view filter helper --- .../helper/StudyViewFilterHelper.java | 10 +++++++++ .../web/parameter/CustomSampleIdentifier.java | 11 ++++++++++ .../StudyViewFilterMapper.xml | 21 +++++++++++-------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/cbioportal/persistence/helper/StudyViewFilterHelper.java b/src/main/java/org/cbioportal/persistence/helper/StudyViewFilterHelper.java index 23615be0ef4..2ee580f133f 100644 --- a/src/main/java/org/cbioportal/persistence/helper/StudyViewFilterHelper.java +++ b/src/main/java/org/cbioportal/persistence/helper/StudyViewFilterHelper.java @@ -79,6 +79,16 @@ public List customDataSamples() { return this.customDataSamples; } + public String[] filteredSampleIdentifiers() { + if (studyViewFilter != null && studyViewFilter.getSampleIdentifiers() != null) { + return studyViewFilter.getSampleIdentifiers().stream() + .map(sampleIdentifier -> sampleIdentifier.getStudyId() + "_" + sampleIdentifier.getSampleId()) + .toArray(String[]::new); + } else { + return new String[0]; + } + } + public List involvedCancerStudies() { return involvedCancerStudies; } diff --git a/src/main/java/org/cbioportal/web/parameter/CustomSampleIdentifier.java b/src/main/java/org/cbioportal/web/parameter/CustomSampleIdentifier.java index 9f5f4e0bfe0..51692168fcb 100644 --- a/src/main/java/org/cbioportal/web/parameter/CustomSampleIdentifier.java +++ b/src/main/java/org/cbioportal/web/parameter/CustomSampleIdentifier.java @@ -6,6 +6,7 @@ public class CustomSampleIdentifier extends SampleIdentifier implements Serializ private boolean isFilteredOut = false; private String value; + private String uniqueSampleId; public boolean getIsFilteredOut() { return isFilteredOut; @@ -22,4 +23,14 @@ public String getValue() { public void setValue(String value) { this.value = value; } + + // Generating unique SampleId by concatenating studyId and sampleId + public String getUniqueSampleId() { + // Assuming studyId and sampleId are available in SampleIdentifier + // Concatenate with "_" in between if both values are not null + if (getStudyId() != null && getSampleId() != null) { + return getStudyId() + "_" + getSampleId(); + } + return null; // or return null if either studyId or sampleId is null + } } diff --git a/src/main/resources/org/cbioportal/persistence/mybatisclickhouse/StudyViewFilterMapper.xml b/src/main/resources/org/cbioportal/persistence/mybatisclickhouse/StudyViewFilterMapper.xml index 584f8cf95bd..74eca303a81 100644 --- a/src/main/resources/org/cbioportal/persistence/mybatisclickhouse/StudyViewFilterMapper.xml +++ b/src/main/resources/org/cbioportal/persistence/mybatisclickhouse/StudyViewFilterMapper.xml @@ -60,15 +60,15 @@ ) - - - INTERSECT + + + INTERSECT SELECT sample_unique_id FROM sample_derived WHERE sample_unique_id IN - - '${sampleIdentifier.studyId}_${sampleIdentifier.sampleId}' - + ( + #{filteredSampleIdentifiers, typeHandler=org.apache.ibatis.type.ArrayTypeHandler} + ) INTERSECT @@ -86,8 +86,8 @@ sample_unique_id IN ( '', - - '${sampleIdentifier.studyId}_${sampleIdentifier.sampleId}' + + #{sampleIdentifier.uniqueSampleId} ) @@ -97,8 +97,11 @@ OR sample_unique_id NOT IN ( + '', - '${sampleIdentifier.studyId}_${sampleIdentifier.sampleId}' + + #{sampleIdentifier.uniqueSampleId} + )