From 807c07c882c79467893c75b2148d62c25660bebe Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Thu, 27 May 2010 07:38:05 +0000
Subject: [PATCH] LMS-1544 Added ability to search for samples by sample codes.

SVN: 16132
---
 .../bo/samplelister/ISampleListingQuery.java  | 26 +++--
 .../bo/samplelister/SampleListingWorker.java  | 11 +++
 .../dataaccess/db/SimpleSQLStringArray.java   | 98 +++++++++++++++++++
 .../db/SimpleSQLStringArrayString.java        | 53 ++++++++++
 .../dataaccess/db/StringArrayMapper.java      | 54 ++++++++++
 .../basic/dto/ListOrSearchSampleCriteria.java | 20 +++-
 6 files changed, 255 insertions(+), 7 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArray.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArrayString.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/StringArrayMapper.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
index ba087160e66..54eae526952 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
@@ -38,6 +38,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.common.MaterialEntity
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.VocabularyTermRecord;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.entity.ExperimentProjectGroupCodeRecord;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.LongSetMapper;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.StringArrayMapper;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 
 /**
@@ -151,8 +152,7 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
             + "       s.samp_id_generated_from, s.registration_timestamp, s.modification_timestamp, "
             + "       s.pers_id_registerer, s.samp_id_part_of, s.inva_id "
             + "   from samples s join groups g on s.grou_id=g.id "
-            + "   where s.expe_id is not null and g.dbin_id=?{1} " 
-            + "   order by s.code", fetchSize = FETCH_SIZE)
+            + "   where s.expe_id is not null and g.dbin_id=?{1} " + "   order by s.code", fetchSize = FETCH_SIZE)
     public DataIterator<SampleRecord> getAllGroupSamplesWithExperiment(long dbInstanceId);
 
     /**
@@ -162,8 +162,7 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
             + "       s.registration_timestamp, s.pers_id_registerer, "
             + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
             + "   from samples s join groups g on s.grou_id=g.id "
-            + "   where g.dbin_id=?{1} and s.saty_id=?{2}" 
-            + "      order by s.code", fetchSize = FETCH_SIZE)
+            + "   where g.dbin_id=?{1} and s.saty_id=?{2}" + "      order by s.code", fetchSize = FETCH_SIZE)
     public DataIterator<SampleRecord> getAllGroupSamplesForSampleType(long dbInstanceId,
             long sampleTypeId);
 
@@ -222,8 +221,7 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
             + "       select samp_id from sample_properties sp where sp.stpt_id in ("
             + "              select id from sample_type_property_types stpt where stpt.prty_id = "
             + "                     (select id from property_types where code=?{2})"
-            + "              ) and value=?{3}" 
-            + "       ) and not id = any(?{4})", parameterBindings =
+            + "              ) and value=?{3}" + "       ) and not id = any(?{4})", parameterBindings =
         { TypeMapper.class, TypeMapper.class, TypeMapper.class, LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<SampleRecord> getSamplesWithPropertyValue(long sampleTypeId,
             String propertyTypeCode, String propertyValue, LongSet sampleIds);
@@ -299,6 +297,22 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
         { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<SampleRecord> getSamples(LongSet sampleIds);
 
+    /**
+     * Returns the samples for the given <var>sampleCodes</var>.
+     */
+    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, s.dbin_id, "
+            + "       s.registration_timestamp, s.pers_id_registerer, "
+            + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
+            + "   from samples s where s.code = any(?{1})", parameterBindings =
+        { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
+    public DataIterator<SampleRecord> getSamplesForCodes(String[] sampleCodes);
+
+    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, s.dbin_id, "
+            + "       s.registration_timestamp, s.pers_id_registerer, "
+            + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
+            + "   from samples s where s.code in (?{1})", fetchSize = FETCH_SIZE)
+    public DataIterator<SampleRecord> getSamples(String sampleCodesString);
+
     //
     // Sample Properties
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
index 0fc6ce7eb91..bcce95c1723 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
@@ -209,6 +209,7 @@ final class SampleListingWorker
         loadGroups();
         loadSampleTypes();
         retrievePrimaryBasicSamples(tryGetIteratorForSamplesByIds());
+        retrievePrimaryBasicSamples(tryGetIteratorForSamplesByCodes());
         retrievePrimaryBasicSamples(tryGetIteratorForGroupSamples());
         retrievePrimaryBasicSamples(tryGetIteratorForSharedSamples());
         retrievePrimaryBasicSamples(tryGetIteratorForExperimentSamples());
@@ -335,6 +336,16 @@ final class SampleListingWorker
         return query.getSamples(new LongOpenHashSet(ids));
     }
 
+    private Iterable<SampleRecord> tryGetIteratorForSamplesByCodes()
+    {
+        String[] codes = criteria.trySampleCodes();
+        if (codes == null)
+        {
+            return null;
+        }
+        return query.getSamplesForCodes(codes);
+    }
+
     private Iterable<SampleRecord> tryGetIteratorForGroupSamples()
     {
         if (criteria.isIncludeSpace() == false)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArray.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArray.java
new file mode 100644
index 00000000000..1734fb13f8f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArray.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+/**
+ * A simple implementation of {@link java.sql.Array} for <code>String[]</code>.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+class SimpleSQLStringArray extends AbstractSQLArray
+{
+
+    private final String[] value;
+
+    SimpleSQLStringArray(String[] array)
+    {
+        value = array;
+    }
+
+    /**
+     * Get the object array.
+     * 
+     * @return the object array
+     */
+    public Object getArray()
+    {
+        return value;
+    }
+
+    /**
+     * Get the base type of this array.
+     * 
+     * @return VARCHAR
+     */
+    public int getBaseType()
+    {
+        return Types.VARCHAR;
+    }
+
+    /**
+     * Get the base type name of this array.
+     * 
+     * @return "varchar"
+     */
+    public String getBaseTypeName()
+    {
+        return "varchar";
+    }
+
+    @Override
+    public void free() throws SQLException
+    {
+        // do nothing
+    }
+
+    @Override
+    /*
+     * * For the PostgreSQL JDBC driver to work with this class, this method needs to return
+     * '{x,y,z,...}'.
+     */
+    public String toString()
+    {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("{");
+        for (String v : value)
+        {
+            builder.append("\"");
+            builder.append(v);
+            builder.append("\"");
+            builder.append(',');
+        }
+        // Remove the trailing ','
+        if (value.length > 0)
+        {
+            builder.setLength(builder.length() - 1);
+        }
+        builder.append("}");
+        return builder.toString();
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArrayString.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArrayString.java
new file mode 100644
index 00000000000..116cf71a474
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SimpleSQLStringArrayString.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
+
+
+/**
+ * A helper class for converting a <code>String[]</code> to a valid array String in SQL.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class SimpleSQLStringArrayString
+{
+
+    private final String[] value;
+
+    public SimpleSQLStringArrayString(String[] array)
+    {
+        value = array;
+    }
+
+    @Override
+    public String toString()
+    {
+        final StringBuilder builder = new StringBuilder();
+        for (String v : value)
+        {
+            builder.append("\'");
+            builder.append(v);
+            builder.append("\'");
+            builder.append(',');
+        }
+        if (value.length > 0)
+        {
+            builder.setLength(builder.length() - 1);
+        }
+        return builder.toString();
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/StringArrayMapper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/StringArrayMapper.java
new file mode 100644
index 00000000000..f63528433b6
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/StringArrayMapper.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import net.lemnik.eodsql.TypeMapper;
+
+/**
+ * A class for mapping <code>String[]</code> to {@link java.sql.Array}.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class StringArrayMapper implements TypeMapper<String[]>
+{
+    public String[] get(ResultSet results, int column) throws SQLException
+    {
+        return (String[]) results.getArray(column).getArray();
+    }
+
+    public void set(PreparedStatement statement, int column, String[] obj) throws SQLException
+    {
+        if (obj != null)
+        {
+            statement.setArray(column, new SimpleSQLStringArray(obj));
+        } else
+        {
+            statement.setNull(column, Types.ARRAY);
+        }
+    }
+
+    public void set(ResultSet results, int column, String[] obj) throws SQLException
+    {
+        results.updateArray(column, new SimpleSQLStringArray(obj));
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java
index 422357613c3..3cd6c6b8740 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ListOrSearchSampleCriteria.java
@@ -43,6 +43,8 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
 
     private Collection<Long> sampleIds;
 
+    private final String[] sampleCodes;
+
     private boolean enrichDependentSamplesWithProperties = false;
 
     /** Creates criteria that delegates to given {@link ListSampleCriteria}. */
@@ -50,6 +52,7 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
     {
         assert listCriteria != null;
         this.listCriteria = listCriteria;
+        this.sampleCodes = null;
     }
 
     /** Creates criteria that delegates to given {@link TrackingSampleCriteria}. */
@@ -57,6 +60,7 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
     {
         assert newTrackingCriteria != null;
         this.newTrackingCriteria = newTrackingCriteria;
+        this.sampleCodes = null;
     }
 
     /** Creates criteria for detailed search of samples with given ids. */
@@ -64,6 +68,16 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
     {
         assert sampleIds != null;
         this.sampleIds = sampleIds;
+        this.sampleCodes = null;
+    }
+
+    /** Creates criteria for detailed search of samples with codes. */
+    public ListOrSearchSampleCriteria(final String[] sampleCodes)
+    {
+        // Need to add the type to disambiguate method signatures for erased generic types.
+        assert sampleCodes != null;
+
+        this.sampleCodes = sampleCodes;
     }
 
     // search
@@ -73,6 +87,11 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
         return sampleIds;
     }
 
+    public String[] trySampleCodes()
+    {
+        return sampleCodes;
+    }
+
     // delegation to NewTrackingSampleCriteria
 
     public String getSampleTypeCode()
@@ -149,5 +168,4 @@ public final class ListOrSearchSampleCriteria extends ListSampleCriteria
     {
         this.enrichDependentSamplesWithProperties = enrichDependentSamplesWithProperties;
     }
-
 }
-- 
GitLab