Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/main/java/org/folio/fqm/utils/MarcSqlFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public static EntityType addSyntheticColumns(EntityType entityType, Collection<S

public static Optional<EntityTypeColumn> createSyntheticColumn(EntityType entityType, String fieldName, String tenantId) {
Optional<MarcFieldName> parsedField = MarcFieldFactory.parse(fieldName);
Optional<EntityTypeColumn> placeholder = MarcFieldFactory.findMarcPlaceholder(entityType);
Optional<EntityTypeColumn> placeholder =
parsedField.flatMap(field -> MarcFieldFactory.findMarcPlaceholder(entityType, field));

if (parsedField.isEmpty() || placeholder.isEmpty()) {
return Optional.empty();
Expand Down Expand Up @@ -100,7 +101,8 @@ public static Optional<EntityTypeColumn> createSyntheticColumn(EntityType entity

public static Optional<MarcQueryContext> createQueryContext(EntityType entityType, String fieldName) {
Optional<MarcFieldName> parsedField = MarcFieldFactory.parse(fieldName);
Optional<EntityTypeColumn> placeholder = MarcFieldFactory.findMarcPlaceholder(entityType);
Optional<EntityTypeColumn> placeholder =
parsedField.flatMap(field -> MarcFieldFactory.findMarcPlaceholder(entityType, field));
Optional<EntityTypeColumn> syntheticField = EntityTypeUtils.findColumn(entityType, fieldName);

if (parsedField.isEmpty() || placeholder.isEmpty() || syntheticField.isEmpty()) {
Expand Down
58 changes: 58 additions & 0 deletions src/test/java/org/folio/fqm/utils/MarcSqlFactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
class MarcSqlFactoryTest {

private static final String MARC_RECORD_ID_GETTER = "\"record_lb\".id";
private static final String MARC_BIB_ID_GETTER = "\"bib_record_lb\".id";
private static final String MARC_AUTHORITY_ID_GETTER = "\"authority_record_lb\".id";

// ---- Synthetic column SQL -------------------------------------------------------------------------------

Expand Down Expand Up @@ -95,6 +97,28 @@ void shouldInterpolateTenantIdWhenProvided() {
assertFalse(column.getValueGetter().contains("${tenant_id}"));
}

@Test
void shouldCreateSourcePrefixedSyntheticColumnUsingItsSourceCorrelation() {
EntityTypeColumn column = MarcSqlFactory.createSyntheticColumn(
compositeEntityTypeWithMarcSupport(), "marc_authority.marc_100_a", "diku").orElseThrow();

// Keeps the fully-qualified name; label is the (un-prefixed) MARC label.
assertEquals("marc_authority.marc_100_a", column.getName());
assertEquals("MARC 100$a", column.getLabelAlias());
// Correlates against the *authority* source's id-getter, not the bib one — the field's prefix selects it.
assertTrue(column.getValueGetter().contains("marc.marc_id = " + MARC_AUTHORITY_ID_GETTER));
assertFalse(column.getValueGetter().contains("bib_record_lb"));
assertTrue(column.getValueGetter().contains("marc.field_no = '100'"));
assertTrue(column.getValueGetter().contains("marc.subfield_no = 'a'"));
}

@Test
void shouldReturnEmptyForSourcePrefixedFieldWithUndeclaredSource() {
// marc_holdings has no placeholder on this composite, so the field is not synthesizable.
assertEquals(Optional.empty(),
MarcSqlFactory.createSyntheticColumn(compositeEntityTypeWithMarcSupport(), "marc_holdings.marc_245_a", "diku"));
}

@Test
void shouldReturnEmptyForInvalidMarcFieldName() {
assertEquals(Optional.empty(), MarcSqlFactory.createSyntheticColumn(entityTypeWithMarcSupport(), "marc_24_a", null));
Expand Down Expand Up @@ -289,6 +313,23 @@ void shouldBuildQueryContextAndItsClauses() {
);
}

@Test
void shouldBuildQueryContextForSourcePrefixedField() {
EntityType entityType = MarcSqlFactory.addSyntheticColumns(
compositeEntityTypeWithMarcSupport(), List.of("marc_bib.marc_245_a"), "diku");

MarcQueryContext context = MarcSqlFactory.createQueryContext(entityType, "marc_bib.marc_245_a").orElseThrow();

assertEquals("245", context.marcField().tag());
assertEquals("a", context.marcField().subfield());
// Correlation uses the bib source's id-getter (the field's prefix selected the bib placeholder).
assertEquals(MARC_BIB_ID_GETTER, context.marcIdGetter());
assertEquals(
"marc.marc_id = " + MARC_BIB_ID_GETTER + " and marc.field_no = '245' and marc.subfield_no = 'a'",
context.whereClause()
);
}

@Test
void shouldBuildIndicatorQueryContext() {
EntityType entityType = MarcSqlFactory.addSyntheticColumns(entityTypeWithMarcSupport(), List.of("marc_245_ind1"), "diku");
Expand Down Expand Up @@ -415,6 +456,23 @@ private static EntityType entityTypeWithMarcSupport() {
));
}

// Composite entity type declaring two MARC sources, each with its own source-prefixed placeholder + getter.
private static EntityType compositeEntityTypeWithMarcSupport() {
return new EntityType()
.id(UUID.randomUUID().toString())
.name("composite_instance_srs_bib")
.columns(List.of(
new EntityTypeColumn()
.name("marc_bib.marc")
.dataType(new MarcType().dataType("marcType"))
.valueGetter(MARC_BIB_ID_GETTER),
new EntityTypeColumn()
.name("marc_authority.marc")
.dataType(new MarcType().dataType("marcType"))
.valueGetter(MARC_AUTHORITY_ID_GETTER)
));
}

private static EntityType entityTypeForContext(String placeholderValueGetter, String syntheticValueGetter) {
EntityTypeColumn placeholder = new EntityTypeColumn().name("marc").dataType(new MarcType().dataType("marcType"));
if (placeholderValueGetter != null) {
Expand Down
Loading