Skip to content

Commit

Permalink
MODSOURCE-783 Add search by qualifiers to non-external ids field
Browse files Browse the repository at this point in the history
  • Loading branch information
dmytrokrutii committed Jul 22, 2024
1 parent cdf47a8 commit bd2e7d5
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ public class RecordDaoImpl implements RecordDao {
static final int INDEXERS_DELETION_LOCK_NAMESPACE_ID = "delete_marc_indexers".hashCode();

public static final String CONTROL_FIELD_CONDITION_TEMPLATE = "\"{partition}\".\"value\" in ({value})";
public static final String CONTROL_FIELD_CONDITION_TEMPLATE_WITH_QUALIFIER = "\"{partition}\".\"value\" IN ({value}) AND \"{partition}\".\"value\" LIKE {qualifier}";
public static final String DATA_FIELD_CONDITION_TEMPLATE = "\"{partition}\".\"value\" in ({value}) and \"{partition}\".\"ind1\" LIKE '{ind1}' and \"{partition}\".\"ind2\" LIKE '{ind2}' and \"{partition}\".\"subfield_no\" = '{subfield}'";
public static final String DATA_FIELD_CONDITION_TEMPLATE_WITH_QUALIFIER = "\"{partition}\".\"value\" IN ({value}) AND \"{partition}\".\"value\" LIKE {qualifier} AND \"{partition}\".\"ind1\" LIKE '{ind1}' AND \"{partition}\".\"ind2\" LIKE '{ind2}' AND \"{partition}\".\"subfield_no\" = '{subfield}'";
private static final String VALUE_IN_SINGLE_QUOTES = "'%s'";
private static final String RECORD_NOT_FOUND_BY_ID_TYPE = "Record with %s id: %s was not found";
private static final String INVALID_PARSED_RECORD_MESSAGE_TEMPLATE = "Record %s has invalid parsed record; %s";
Expand Down Expand Up @@ -352,18 +354,26 @@ public Future<List<Record>> getMatchedRecordsWithoutIndexersVersionUsage(MatchFi

private Condition getMatchedFieldCondition(MatchField matchedField, String partition) {
Map<String, String> params = new HashMap<>();
var qualifierSearch = false;
params.put("partition", partition);
params.put("value", getValueInSqlFormat(matchedField.getValue()));
if (matchedField.getQualifierMatch() != null) {
qualifierSearch = true;
params.put("qualifier", getSqlQualifier(matchedField.getQualifierMatch()));
}
String sql;
Condition condition;
if (matchedField.isControlField()) {
String sql = StrSubstitutor.replace(CONTROL_FIELD_CONDITION_TEMPLATE, params, "{", "}");
return condition(sql);
sql = qualifierSearch ? StrSubstitutor.replace(CONTROL_FIELD_CONDITION_TEMPLATE_WITH_QUALIFIER, params, "{", "}")
: StrSubstitutor.replace(CONTROL_FIELD_CONDITION_TEMPLATE, params, "{", "}");
} else {
params.put("ind1", getSqlInd(matchedField.getInd1()));
params.put("ind2", getSqlInd(matchedField.getInd2()));
params.put("subfield", matchedField.getSubfield());
String sql = StrSubstitutor.replace(DATA_FIELD_CONDITION_TEMPLATE, params, "{", "}");
return condition(sql);
sql = qualifierSearch ? sql = StrSubstitutor.replace(DATA_FIELD_CONDITION_TEMPLATE_WITH_QUALIFIER, params, "{", "}")
: StrSubstitutor.replace(DATA_FIELD_CONDITION_TEMPLATE, params, "{", "}");
}
return condition(sql);
}

private String getSqlInd(String ind) {
Expand All @@ -372,6 +382,19 @@ private String getSqlInd(String ind) {
return ind;
}

private String getSqlQualifier(MatchField.QualifierMatch qualifierMatch) {
if (qualifierMatch == null) {
return null;
}
var value = qualifierMatch.value();

return switch (qualifierMatch.qualifier()) {
case BEGINS_WITH -> "'" + value + "%'";
case ENDS_WITH -> "'%" + value + "'";
case CONTAINS -> "'%" + value + "%'";
};
}

private String getValueInSqlFormat(Value value) {
if (Value.ValueType.STRING.equals(value.getType())) {
return format(VALUE_IN_SINGLE_QUOTES, value.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public class RecordsMatchingApiTest extends AbstractRestVerticleTest {
private static final String PARSED_MARC_HOLDINGS_WITH_999_FIELD_SAMPLE_PATH = "src/test/resources/mock/parsedContents/marcHoldingsContentWith999field.json";
private static final String PARSED_MARC_WITH_035_FIELD_SAMPLE_PATH = "src/test/resources/parsedMarcRecordContent.sample";
private static final String INSTANCE_ID = "681394b4-10d8-4cb1-a618-0f9bd6152119";
private static final String HR_ID = "12345";
private static final String FIELD_035 = "12569";
private static final String FIELD_007 = "12345";
private static final int SPLIT_INDEX = 2;

private static String rawRecordContent;
Expand Down Expand Up @@ -276,14 +277,39 @@ public void shouldMatchRecordByInstanceHridField() {

@Test
public void shouldMatchRecordByInstanceHridFieldAndQualifier() {
var beginWith = new MatchField.QualifierMatch(Filter.Qualifier.BEGINS_WITH, HR_ID.substring(0, SPLIT_INDEX));
var endWith = new MatchField.QualifierMatch(Filter.Qualifier.ENDS_WITH, HR_ID.substring(SPLIT_INDEX));
var contains = new MatchField.QualifierMatch(Filter.Qualifier.CONTAINS, HR_ID.substring(SPLIT_INDEX, SPLIT_INDEX + SPLIT_INDEX));
var hrId = existingRecord.getExternalIdsHolder().getInstanceHrid();
var beginWith = new MatchField.QualifierMatch(Filter.Qualifier.BEGINS_WITH, hrId.substring(0, SPLIT_INDEX));
var endWith = new MatchField.QualifierMatch(Filter.Qualifier.ENDS_WITH, hrId.substring(SPLIT_INDEX));
var contains = new MatchField.QualifierMatch(Filter.Qualifier.CONTAINS, hrId.substring(SPLIT_INDEX, SPLIT_INDEX + SPLIT_INDEX));
shouldMatchRecordByInstanceHridFieldAndQualifier(beginWith);
shouldMatchRecordByInstanceHridFieldAndQualifier(endWith);
shouldMatchRecordByInstanceHridFieldAndQualifier(contains);
}

@Test
public void shouldNotMatchMarcBibRecordByInstanceIdFieldAndQualifier(){
var externalId = RecordDaoUtil.getExternalId(existingRecord.getExternalIdsHolder(), existingRecord.getRecordType());
var qualifier = new MatchField.QualifierMatch(Filter.Qualifier.CONTAINS, "ABC");
RestAssured.given()
.spec(spec)
.when()
.body(new RecordMatchingDto()
.withRecordType(RecordMatchingDto.RecordType.valueOf(existingRecord.getRecordType().name()))
.withFilters(List.of(new Filter()
.withValues(List.of(externalId))
.withField("999")
.withIndicator1("f")
.withIndicator2("f")
.withSubfield("i")
.withQualifier(qualifier.qualifier())
.withQualifierValue(qualifier.value()))))
.post(RECORDS_MATCHING_PATH)
.then()
.statusCode(HttpStatus.SC_OK)
.body("totalRecords", is(0))
.body("identifiers.size()", is(0));
}

@Test
public void shouldMatchRecordByMultipleDataFields() {
RestAssured.given()
Expand All @@ -306,6 +332,29 @@ public void shouldMatchRecordByMultipleDataFields() {
.body("identifiers[0].externalId", is(existingRecord.getExternalIdsHolder().getInstanceId()));
}

public void shouldMatchRecordByMultipleDataFieldsAndQualifier(MatchField.QualifierMatch qualifier) {
RestAssured.given()
.spec(spec)
.when()
.body(new RecordMatchingDto()
.withRecordType(RecordMatchingDto.RecordType.MARC_BIB)
.withFilters(List.of(new Filter()
.withValues(List.of("12345", "oclc1234567"))
.withQualifier(qualifier.qualifier())
.withQualifierValue(qualifier.value())
.withField("035")
.withIndicator1("")
.withIndicator2("")
.withSubfield("a"))))
.post(RECORDS_MATCHING_PATH)
.then()
.statusCode(HttpStatus.SC_OK)
.body("totalRecords", is(1))
.body("identifiers.size()", is(1))
.body("identifiers[0].recordId", is(existingRecord.getId()))
.body("identifiers[0].externalId", is(existingRecord.getExternalIdsHolder().getInstanceId()));
}

@Test
public void shouldMatchRecordByMultipleControlledFields() {
RestAssured.given()
Expand All @@ -325,6 +374,87 @@ public void shouldMatchRecordByMultipleControlledFields() {
.body("identifiers[0].externalId", is(existingRecord.getExternalIdsHolder().getInstanceId()));
}

@Test
public void shouldMatchRecordByMultipleDataFieldsAndQualifier() {
var beginWith = new MatchField.QualifierMatch(Filter.Qualifier.BEGINS_WITH, FIELD_007.substring(0, SPLIT_INDEX));
var endWith = new MatchField.QualifierMatch(Filter.Qualifier.ENDS_WITH, FIELD_007.substring(SPLIT_INDEX));
var contains = new MatchField.QualifierMatch(Filter.Qualifier.CONTAINS, FIELD_007.substring(SPLIT_INDEX, SPLIT_INDEX + SPLIT_INDEX));
shouldMatchRecordByMultipleDataFieldsAndQualifier(beginWith);
shouldMatchRecordByMultipleDataFieldsAndQualifier(endWith);
shouldMatchRecordByMultipleDataFieldsAndQualifier(contains);
}

@Test
public void shouldNotMatchRecordByMultipleDataFieldsAndQualifier() {
RestAssured.given()
.spec(spec)
.when()
.body(new RecordMatchingDto()
.withRecordType(RecordMatchingDto.RecordType.MARC_BIB)
.withFilters(List.of(new Filter()
.withValues(List.of("12345", "oclc1234567"))
.withQualifier(Filter.Qualifier.BEGINS_WITH)
.withQualifierValue("ABC")
.withField("035")
.withIndicator1("")
.withIndicator2("")
.withSubfield("a"))))
.post(RECORDS_MATCHING_PATH)
.then()
.statusCode(HttpStatus.SC_OK)
.body("totalRecords", is(0))
.body("identifiers.size()", is(0));
}

private void shouldMatchRecordByMultipleControlledFieldsAndQualifier(MatchField.QualifierMatch qualifier){
RestAssured.given()
.spec(spec)
.when()
.body(new RecordMatchingDto()
.withRecordType(RecordMatchingDto.RecordType.MARC_BIB)
.withFilters(List.of(new Filter()
.withValues(List.of("12569", "364345"))
.withQualifier(qualifier.qualifier())
.withQualifierValue(qualifier.value())
.withField("007"))))
.post(RECORDS_MATCHING_PATH)
.then()
.statusCode(HttpStatus.SC_OK)
.body("totalRecords", is(1))
.body("identifiers.size()", is(1))
.body("identifiers[0].recordId", is(existingRecord.getId()))
.body("identifiers[0].externalId", is(existingRecord.getExternalIdsHolder().getInstanceId()));
}

@Test
public void shouldMatchRecordByMultipleControlledFieldsAndQualifier() {
var beginWith = new MatchField.QualifierMatch(Filter.Qualifier.BEGINS_WITH, FIELD_035.substring(0, SPLIT_INDEX));
var endWith = new MatchField.QualifierMatch(Filter.Qualifier.ENDS_WITH, FIELD_035.substring(SPLIT_INDEX));
var contains = new MatchField.QualifierMatch(Filter.Qualifier.CONTAINS, FIELD_035.substring(SPLIT_INDEX, SPLIT_INDEX + SPLIT_INDEX));
shouldMatchRecordByMultipleControlledFieldsAndQualifier(beginWith);
shouldMatchRecordByMultipleControlledFieldsAndQualifier(endWith);
shouldMatchRecordByMultipleControlledFieldsAndQualifier(contains);
}

@Test
public void shouldNotMatchRecordByMultipleControlledFieldsAndQualifier(){
RestAssured.given()
.spec(spec)
.when()
.body(new RecordMatchingDto()
.withRecordType(RecordMatchingDto.RecordType.MARC_BIB)
.withFilters(List.of(new Filter()
.withValues(List.of("12569", "364345"))
.withQualifier(Filter.Qualifier.BEGINS_WITH)
.withQualifierValue("ABC")
.withField("007"))))
.post(RECORDS_MATCHING_PATH)
.then()
.statusCode(HttpStatus.SC_OK)
.body("totalRecords", is(0))
.body("identifiers.size()", is(0));
}

@Test
public void shouldMatchRecordByMultiple024FieldsWithWildcardsInd() {
RestAssured.given()
Expand Down

0 comments on commit bd2e7d5

Please sign in to comment.