diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/condition/ControlledVocabularyPropertySearchConditionTranslator.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/condition/ControlledVocabularyPropertySearchConditionTranslator.java index d6c8fd32c48816d7c39e2308e167fd8d29e10da0..599fcf653987ea8da29ef0ffe7e9733e2a7f4e58 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/condition/ControlledVocabularyPropertySearchConditionTranslator.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/search/translator/condition/ControlledVocabularyPropertySearchConditionTranslator.java @@ -20,7 +20,9 @@ import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLL import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.EQ; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.FROM; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.IN; +import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.LEFT_JOIN; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.LP; +import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.ON; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.PERIOD; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.QU; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.RP; @@ -28,8 +30,10 @@ import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLL import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.SP; import static ch.ethz.sis.openbis.generic.server.asapi.v3.search.translator.SQLLexemes.WHERE; import static ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames.CODE_COLUMN; +import static ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames.CONTROLLED_VOCABULARY_COLUMN; import static ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames.ID_COLUMN; import static ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames.VOCABULARY_TERM_COLUMN; +import static ch.systemsx.cisd.openbis.generic.shared.dto.TableNames.CONTROLLED_VOCABULARY_TABLE; import static ch.systemsx.cisd.openbis.generic.shared.dto.TableNames.CONTROLLED_VOCABULARY_TERM_TABLE; import java.util.List; @@ -86,29 +90,42 @@ public class ControlledVocabularyPropertySearchConditionTranslator final List<Object> args, final StringBuilder sqlBuilder, final Map<String, JoinInformation> aliases) { final String value = criterion.getFieldValue(); + final String name = criterion.getFieldName(); final String valuesTableAlias = aliases.get(tableMapper.getValuesTable()).getSubTableAlias(); TranslatorUtils.appendPropertiesExist(sqlBuilder, valuesTableAlias); sqlBuilder.append(SP).append(AND).append(SP).append(LP); - appendControlledVocabularySubselectConstraint(args, sqlBuilder, value, valuesTableAlias); + appendControlledVocabularySubselectConstraint(args, sqlBuilder, name, value, valuesTableAlias); sqlBuilder.append(RP); } private static void appendControlledVocabularySubselectConstraint(final List<Object> args, - final StringBuilder sqlBuilder, final String value, final String propertyTableAlias) + final StringBuilder sqlBuilder, final String name, final String value, final String propertyTableAlias) { + final String controlledVocabularyTableAlias = "cv"; + final String controlledVocabularyTermTableAlias = "cvt"; + sqlBuilder.append(propertyTableAlias).append(PERIOD).append(VOCABULARY_TERM_COLUMN) .append(SP).append(IN).append(SP); sqlBuilder.append(LP); - sqlBuilder.append(SELECT).append(SP).append(ID_COLUMN).append(SP) + sqlBuilder.append(SELECT).append(SP).append(controlledVocabularyTermTableAlias).append(PERIOD) + .append(ID_COLUMN).append(SP) .append(FROM).append(SP).append(CONTROLLED_VOCABULARY_TERM_TABLE).append(SP) - .append(WHERE).append(SP); - sqlBuilder.append(CODE_COLUMN); - - sqlBuilder.append(SP).append(EQ).append(SP).append(QU); + .append(controlledVocabularyTermTableAlias).append(SP) + .append(LEFT_JOIN).append(SP).append(CONTROLLED_VOCABULARY_TABLE).append(SP) + .append(controlledVocabularyTableAlias).append(SP).append(ON).append(SP) + .append(controlledVocabularyTermTableAlias).append(PERIOD).append(CONTROLLED_VOCABULARY_COLUMN) + .append(SP).append(EQ).append(SP).append(controlledVocabularyTableAlias).append(PERIOD) + .append(ID_COLUMN).append(SP) + .append(WHERE) + .append(SP).append(controlledVocabularyTableAlias).append(PERIOD).append(CODE_COLUMN) + .append(SP).append(EQ).append(SP).append(QU).append(SP).append(AND).append(SP) + .append(controlledVocabularyTermTableAlias).append(PERIOD).append(CODE_COLUMN) + .append(SP).append(EQ).append(SP).append(QU); + args.add(name); args.add(value); sqlBuilder.append(RP); diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractSearchPropertyTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractSearchPropertyTest.java index 094a217ad5bbe378416ab124515be59e73750508..2789d1aba2e74c8c4e65beda3674f934d3f8b777 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractSearchPropertyTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractSearchPropertyTest.java @@ -883,7 +883,8 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest vocabularyTermCreation4.setCode("AUTUMN"); final VocabularyCreation vocabularyCreation = new VocabularyCreation(); - vocabularyCreation.setCode("SEASONS"); + final String vocabularyCode = "SEASONS"; + vocabularyCreation.setCode(vocabularyCode); vocabularyCreation.setTerms(Arrays.asList(vocabularyTermCreation1, vocabularyTermCreation2, vocabularyTermCreation3, vocabularyTermCreation4)); final VocabularyPermId vocabularyPermId = @@ -893,7 +894,7 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest vocabularyPermId); final ObjectPermId entityPermId = createEntity(sessionToken, propertyTypeId, value); final AbstractEntitySearchCriteria<?> searchCriteria = createSearchCriteria(); - new VocabularyQueryInjector(searchCriteria, propertyTypeId).buildCriteria(queryString); + new VocabularyQueryInjector(searchCriteria, vocabularyCode).buildCriteria(queryString); // When final List<? extends IPermIdHolder> entities = search(sessionToken, searchCriteria); @@ -936,7 +937,7 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest final PropertyTypePermId samplePropertyTypeId2 = createASamplePropertyType(sessionToken, propertySampleType, samplePropertyCode2); - final EntityTypePermId searchTest1EntityTypeId = createEntityType(sessionToken, samplePropertyTypeId1, + final EntityTypePermId searchTest1EntityTypeId = createEntityType(sessionToken, null, samplePropertyTypeId1, samplePropertyTypeId2); final SamplePermId sample1 = createSample(sessionToken, samplePropertyCode1, propertySampleType, Map.of()); @@ -946,7 +947,7 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest new HashMap<>(Map.of(samplePropertyTypeId1.getPermId(), sample1.getPermId(), samplePropertyTypeId2.getPermId(), sample2.getPermId()))); - final EntityTypePermId searchTest2EntityTypeId = createEntityType(sessionToken, samplePropertyTypeId1, + final EntityTypePermId searchTest2EntityTypeId = createEntityType(sessionToken, null, samplePropertyTypeId1, samplePropertyTypeId2); final ObjectPermId entity2 = createEntity(sessionToken, "Sample4", searchTest2EntityTypeId, new HashMap<>(Map.of(samplePropertyTypeId1.getPermId(), sample1.getPermId()))); @@ -997,38 +998,43 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest } @Test - public void testSearchWithEnumProperty() + public void testSearchWithControlledVocabularyProperty() { final String sessionToken = v3api.login(TEST_USER, PASSWORD); final String term1 = "TERM1"; final String term2 = "TERM2"; final String term3 = "TERM3"; - final VocabularyPermId vocabulary = createVocabulary(sessionToken, "TERMS", term1, term2, term3); + final String vocabularyCode1 = "TERMS1"; + final String vocabularyCode2 = "TERMS2"; + final VocabularyPermId vocabulary1 = createVocabulary(sessionToken, vocabularyCode1, term1, term2, term3); + final VocabularyPermId vocabulary2 = createVocabulary(sessionToken, vocabularyCode2, term1, term2, term3); final EntityTypePermId propertySampleType = createASampleType(sessionToken, false); final PropertyTypePermId vocabularyPropertyTypeId1 = createAVocabularyPropertyType(sessionToken, - vocabulary, "Vocabulary1"); + vocabulary1, "Vocabulary1"); final PropertyTypePermId vocabularyPropertyTypeId2 = createAVocabularyPropertyType(sessionToken, - vocabulary, "Vocabulary2"); + vocabulary1, "Vocabulary2"); + final PropertyTypePermId vocabularyPropertyTypeId3 = createAVocabularyPropertyType(sessionToken, + vocabulary2, "Vocabulary3"); - final EntityTypePermId searchTest1EntityTypeId = createEntityType(sessionToken, vocabularyPropertyTypeId1, - vocabularyPropertyTypeId2); + final EntityTypePermId searchTest1EntityTypeId = createEntityType(sessionToken, "ET1", + vocabularyPropertyTypeId1, vocabularyPropertyTypeId2); final ObjectPermId entity1 = createEntity(sessionToken, "Entity", searchTest1EntityTypeId, new HashMap<>(Map.of(vocabularyPropertyTypeId1.getPermId(), term1, vocabularyPropertyTypeId2.getPermId(), term2))); - final EntityTypePermId searchTest2EntityTypeId = createEntityType(sessionToken, vocabularyPropertyTypeId1, - vocabularyPropertyTypeId2); + final EntityTypePermId searchTest2EntityTypeId = createEntityType(sessionToken, "ET2", + vocabularyPropertyTypeId3); final ObjectPermId entity2 = createEntity(sessionToken, "Sample4", searchTest2EntityTypeId, - new HashMap<>(Map.of(vocabularyPropertyTypeId1.getPermId(), term1))); + new HashMap<>(Map.of(vocabularyPropertyTypeId3.getPermId(), term1))); try { final AbstractEntitySearchCriteria<?> searchCriteria1 = createSearchCriteria(); searchCriteria1.withOrOperator(); - searchCriteria1.withVocabularyProperty(searchTest1EntityTypeId.getPermId()).thatEquals(term1); + searchCriteria1.withVocabularyProperty(vocabularyCode1).thatEquals(term1); final List<? extends IPermIdHolder> entities1 = search(sessionToken, searchCriteria1); assertEquals(entities1.size(), 1); @@ -1291,11 +1297,11 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest private ObjectPermId createEntity(String sessionToken, PropertyTypePermId propertyTypeId, String value) { - EntityTypePermId entityTypeId = createEntityType(sessionToken, propertyTypeId); + EntityTypePermId entityTypeId = createEntityType(sessionToken, null, propertyTypeId); return createEntity(sessionToken, "ENTITY_TO_BE_DELETED", entityTypeId, propertyTypeId.getPermId(), value); } - protected abstract EntityTypePermId createEntityType(String sessionToken, PropertyTypePermId... propertyTypeIds); + protected abstract EntityTypePermId createEntityType(String sessionToken, final String code, PropertyTypePermId... propertyTypeIds); protected abstract void deleteEntityTypes(String sessionToken, IEntityTypeId... entityTypeIds); @@ -1642,17 +1648,20 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest static final class VocabularyQueryInjector extends AbstractQueryInjector { + + private final String vocabularyCode; + VocabularyQueryInjector(final AbstractEntitySearchCriteria<?> searchCriteria, - final PropertyTypePermId propertyTypeId) + final String vocabularyCode) { - super(searchCriteria, propertyTypeId); + super(searchCriteria, null); + this.vocabularyCode = vocabularyCode; } - @Override - protected void injectQuery(final Operator operator, final String operand) + public void injectQuery(final Operator operator, final String operand) { final ControlledVocabularyPropertySearchCriteria criteria = - searchCriteria.withVocabularyProperty(propertyTypeId.getPermId()); + searchCriteria.withVocabularyProperty(vocabularyCode); if (operator == Operator.EQUAL) { criteria.thatEquals(operand); @@ -1661,5 +1670,7 @@ public abstract class AbstractSearchPropertyTest extends AbstractTest throw new IllegalArgumentException("Unsupported operator " + operator); } } + } + } diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java index 47ae164b2c9a1c8d0ff11630dfc3cbaa83515730..14bc284815449f27d6ae57409277478c5096b4b5 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java @@ -1538,9 +1538,15 @@ public class AbstractTest extends SystemTestCase protected EntityTypePermId createASampleType(String sessionToken, boolean mandatory, PropertyTypePermId... propertyTypes) + { + return createASampleType(sessionToken, "SAMPLE-TYPE-" + System.currentTimeMillis(), mandatory, propertyTypes); + } + + protected EntityTypePermId createASampleType(final String sessionToken, final String code, boolean mandatory, + PropertyTypePermId... propertyTypes) { SampleTypeCreation creation = new SampleTypeCreation(); - creation.setCode("SAMPLE-TYPE-" + System.currentTimeMillis()); + creation.setCode(code); List<PropertyAssignmentCreation> assignments = new ArrayList<>(); for (PropertyTypePermId propertyType : propertyTypes) { @@ -1576,10 +1582,18 @@ public class AbstractTest extends SystemTestCase v3api.deleteSampleTypes(sessionToken, List.of(entityTypeIds), deletionOptions); } - protected EntityTypePermId createAnExperimentType(String sessionToken, boolean mandatory, PropertyTypePermId... propertyTypes) + protected EntityTypePermId createAnExperimentType(final String sessionToken, final boolean mandatory, + final PropertyTypePermId... propertyTypes) + { + return createAnExperimentType(sessionToken, "EXPERIMENT-TYPE-" + System.currentTimeMillis(), mandatory, + propertyTypes); + } + + protected EntityTypePermId createAnExperimentType(final String sessionToken, final String code, + final boolean mandatory, final PropertyTypePermId... propertyTypes) { ExperimentTypeCreation creation = new ExperimentTypeCreation(); - creation.setCode("EXPERIMENT-TYPE-" + System.currentTimeMillis()); + creation.setCode(code); List<PropertyAssignmentCreation> assignments = new ArrayList<>(); for (PropertyTypePermId propertyType : propertyTypes) { @@ -1592,10 +1606,18 @@ public class AbstractTest extends SystemTestCase return v3api.createExperimentTypes(sessionToken, Arrays.asList(creation)).get(0); } - protected EntityTypePermId createADataSetType(String sessionToken, boolean mandatory, PropertyTypePermId... propertyTypes) + protected EntityTypePermId createADataSetType(final String sessionToken, final boolean mandatory, + final PropertyTypePermId... propertyTypes) + { + return createADataSetType(sessionToken, "DATA-SET-TYPE-" + System.currentTimeMillis(), mandatory, + propertyTypes); + } + + protected EntityTypePermId createADataSetType(final String sessionToken, final String code, + final boolean mandatory, final PropertyTypePermId... propertyTypes) { DataSetTypeCreation creation = new DataSetTypeCreation(); - creation.setCode("DATA-SET-TYPE-" + System.currentTimeMillis()); + creation.setCode(code); List<PropertyAssignmentCreation> assignments = new ArrayList<>(); for (PropertyTypePermId propertyType : propertyTypes) { diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetSearchPropertyTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetSearchPropertyTest.java index 5782ad8eb25abeb5a12e566edcb6ac849c3c6143..e7850a813aa627be7343805fb4e57bd7b6f21288 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetSearchPropertyTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetSearchPropertyTest.java @@ -44,7 +44,7 @@ public class DataSetSearchPropertyTest extends AbstractSearchPropertyTest { @Override - protected EntityTypePermId createEntityType(final String sessionToken, final PropertyTypePermId... propertyTypeIds) + protected EntityTypePermId createEntityType(final String sessionToken, final String code, final PropertyTypePermId... propertyTypeIds) { return createADataSetType(sessionToken, false, propertyTypeIds); } diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentSearchPropertyTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentSearchPropertyTest.java index 12ad1fc8dcc02dde88a408af1bb4c58040a9a8f3..800f458d528ec532e05867b9da2cb05b5e297b94 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentSearchPropertyTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentSearchPropertyTest.java @@ -45,7 +45,7 @@ public class ExperimentSearchPropertyTest extends AbstractSearchPropertyTest { @Override - protected EntityTypePermId createEntityType(final String sessionToken, final PropertyTypePermId... propertyTypeIds) + protected EntityTypePermId createEntityType(final String sessionToken, final String code, final PropertyTypePermId... propertyTypeIds) { return createAnExperimentType(sessionToken, false, propertyTypeIds); } diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleSearchPropertyTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleSearchPropertyTest.java index 9c6bb172f29d6f7a91e12aeb0f7211a26e4497b2..559b73a91cabc16d6d6eb1ebf0a84dde02c43920 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleSearchPropertyTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleSearchPropertyTest.java @@ -45,7 +45,8 @@ public class SampleSearchPropertyTest extends AbstractSearchPropertyTest { @Override - protected EntityTypePermId createEntityType(final String sessionToken, final PropertyTypePermId... propertyTypeIds) + protected EntityTypePermId createEntityType(final String sessionToken, final String code, + final PropertyTypePermId... propertyTypeIds) { return createASampleType(sessionToken, false, propertyTypeIds); }