Removed MSSQL-specific test skips and fixed buildInsertIgnoreStatement by replacing IF NOT EXISTS logic with MERGE syntax. Adjusted SQL query to include missing GROUP BY fields in CountryPropertyRepository.
This commit is contained in:
parent
861c5e7bbc
commit
1a5a00e111
5 changed files with 16 additions and 54 deletions
|
|
@ -148,49 +148,32 @@ public class MSSQLDialectProvider implements SqlDialectProvider {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds MSSQL INSERT with IF NOT EXISTS check.
|
|
||||||
*
|
|
||||||
* <p>MSSQL doesn't have INSERT IGNORE, so we use IF NOT EXISTS.</p>
|
|
||||||
*
|
|
||||||
* <p>Example generated SQL:</p>
|
|
||||||
* <pre>
|
|
||||||
* IF NOT EXISTS (SELECT 1 FROM table WHERE key1 = ? AND key2 = ?)
|
|
||||||
* INSERT INTO table (col1, col2, col3) VALUES (?, ?, ?)
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param tableName target table name
|
|
||||||
* @param columns columns to insert
|
|
||||||
* @param uniqueColumns columns to check for existence
|
|
||||||
* @return MSSQL INSERT with IF NOT EXISTS
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String buildInsertIgnoreStatement(
|
public String buildInsertIgnoreStatement(
|
||||||
String tableName,
|
String tableName,
|
||||||
List<String> columns,
|
List<String> columns,
|
||||||
List<String> uniqueColumns
|
List<String> uniqueColumns
|
||||||
) {
|
) {
|
||||||
if (tableName == null || columns.isEmpty() || uniqueColumns.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("tableName, columns, and uniqueColumns must not be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
String whereClause = uniqueColumns.stream()
|
|
||||||
.map(col -> col + " = ?")
|
|
||||||
.collect(Collectors.joining(" AND "));
|
|
||||||
|
|
||||||
String columnList = String.join(", ", columns);
|
String columnList = String.join(", ", columns);
|
||||||
String placeholders = columns.stream()
|
String placeholders = columns.stream().map(c -> "?").collect(Collectors.joining(", "));
|
||||||
.map(col -> "?")
|
String uniqueCondition = uniqueColumns.stream()
|
||||||
|
.map(c -> String.format("target.%s = source.%s", c, c))
|
||||||
|
.collect(Collectors.joining(" AND "));
|
||||||
|
String sourceColumns = columns.stream()
|
||||||
|
.map(c -> String.format("source.%s", c))
|
||||||
.collect(Collectors.joining(", "));
|
.collect(Collectors.joining(", "));
|
||||||
|
|
||||||
return String.format(
|
return String.format(
|
||||||
"IF NOT EXISTS (SELECT 1 FROM %s WHERE %s) " +
|
"MERGE INTO %s AS target " +
|
||||||
"INSERT INTO %s (%s) VALUES (%s)",
|
"USING (SELECT %s) AS source (%s) " +
|
||||||
tableName,
|
"ON %s " +
|
||||||
whereClause,
|
"WHEN NOT MATCHED THEN INSERT (%s) VALUES (%s);",
|
||||||
tableName,
|
tableName,
|
||||||
|
placeholders,
|
||||||
columnList,
|
columnList,
|
||||||
placeholders
|
uniqueCondition,
|
||||||
|
columnList,
|
||||||
|
sourceColumns
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,6 @@ public class CountryPropertyRepository {
|
||||||
type.external_mapping_id as externalMappingId,
|
type.external_mapping_id as externalMappingId,
|
||||||
type.validation_rule as validationRule,
|
type.validation_rule as validationRule,
|
||||||
type.is_required as is_required,
|
type.is_required as is_required,
|
||||||
type.is_required as is_required,
|
|
||||||
type.description as description,
|
type.description as description,
|
||||||
type.property_group as propertyGroup,
|
type.property_group as propertyGroup,
|
||||||
type.sequence_number as sequenceNumber,
|
type.sequence_number as sequenceNumber,
|
||||||
|
|
@ -159,7 +158,8 @@ public class CountryPropertyRepository {
|
||||||
FROM country_property_type AS type
|
FROM country_property_type AS type
|
||||||
LEFT JOIN country_property AS cp ON cp.country_property_type_id = type.id AND cp.country_id = ?
|
LEFT JOIN country_property AS cp ON cp.country_property_type_id = type.id AND cp.country_id = ?
|
||||||
LEFT JOIN property_set AS ps ON ps.id = cp.property_set_id AND ps.state IN ('DRAFT', 'VALID')
|
LEFT JOIN property_set AS ps ON ps.id = cp.property_set_id AND ps.state IN ('DRAFT', 'VALID')
|
||||||
GROUP BY type.id, type.name, type.data_type, type.external_mapping_id, type.validation_rule
|
GROUP BY type.id, type.name, type.data_type, type.external_mapping_id, type.validation_rule,
|
||||||
|
type.is_required, type.description, type.property_group, type.sequence_number
|
||||||
HAVING MAX(CASE WHEN ps.state = 'DRAFT' THEN cp.property_value END) IS NOT NULL
|
HAVING MAX(CASE WHEN ps.state = 'DRAFT' THEN cp.property_value END) IS NOT NULL
|
||||||
OR MAX(CASE WHEN ps.state = 'VALID' THEN cp.property_value END) IS NOT NULL;
|
OR MAX(CASE WHEN ps.state = 'VALID' THEN cp.property_value END) IS NOT NULL;
|
||||||
""";
|
""";
|
||||||
|
|
|
||||||
|
|
@ -142,9 +142,6 @@ class CountryPropertyRepositoryIntegrationTest extends AbstractRepositoryIntegra
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testListPropertiesByCountryId() {
|
void testListPropertiesByCountryId() {
|
||||||
// Skip on MSSQL - listPropertiesByCountryId() has incomplete GROUP BY clause (missing is_required, description, property_group, sequence_number)
|
|
||||||
org.junit.Assume.assumeTrue("Skipping listPropertiesByCountryId on MSSQL (SQL GROUP BY bug in repository)", isMysql());
|
|
||||||
|
|
||||||
// Given: Create properties for country
|
// Given: Create properties for country
|
||||||
createTestCountryProperty(testDraftSetId, testCountryId, testPropertyTypeId, "45");
|
createTestCountryProperty(testDraftSetId, testCountryId, testPropertyTypeId, "45");
|
||||||
createTestCountryProperty(testValidSetId, testCountryId, testPropertyTypeId, "30");
|
createTestCountryProperty(testValidSetId, testCountryId, testPropertyTypeId, "30");
|
||||||
|
|
@ -188,9 +185,6 @@ class CountryPropertyRepositoryIntegrationTest extends AbstractRepositoryIntegra
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFillDraft() {
|
void testFillDraft() {
|
||||||
// Skip on MSSQL - buildInsertIgnoreStatement needs fix for parameter ordering in IF NOT EXISTS pattern
|
|
||||||
org.junit.Assume.assumeTrue("Skipping fillDraft on MSSQL (known issue with INSERT IGNORE)", isMysql());
|
|
||||||
|
|
||||||
// Given: Create properties in valid set for multiple property types
|
// Given: Create properties in valid set for multiple property types
|
||||||
Integer propertyType2 = getPropertyTypeId(CountryPropertyMappingId.WAGE.name());
|
Integer propertyType2 = getPropertyTypeId(CountryPropertyMappingId.WAGE.name());
|
||||||
createTestCountryProperty(testValidSetId, testCountryId, testPropertyTypeId, "30");
|
createTestCountryProperty(testValidSetId, testCountryId, testPropertyTypeId, "30");
|
||||||
|
|
|
||||||
|
|
@ -189,9 +189,6 @@ class PropertyRepositoryIntegrationTest extends AbstractRepositoryIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFillDraft() {
|
void testFillDraft() {
|
||||||
// Skip on MSSQL - buildInsertIgnoreStatement needs fix for parameter ordering in IF NOT EXISTS pattern
|
|
||||||
org.junit.Assume.assumeTrue("Skipping fillDraft on MSSQL (known issue with INSERT IGNORE)", isMysql());
|
|
||||||
|
|
||||||
// Given: Create properties in valid set
|
// Given: Create properties in valid set
|
||||||
Integer propertyType2 = getPropertyTypeId(SystemPropertyMappingId.WORKDAYS.name());
|
Integer propertyType2 = getPropertyTypeId(SystemPropertyMappingId.WORKDAYS.name());
|
||||||
createTestProperty(testValidSetId, testPropertyTypeId, "30");
|
createTestProperty(testValidSetId, testPropertyTypeId, "30");
|
||||||
|
|
@ -220,9 +217,6 @@ class PropertyRepositoryIntegrationTest extends AbstractRepositoryIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFillDraftIgnoresDuplicates() {
|
void testFillDraftIgnoresDuplicates() {
|
||||||
// Skip on MSSQL - buildInsertIgnoreStatement needs fix for parameter ordering in IF NOT EXISTS pattern
|
|
||||||
org.junit.Assume.assumeTrue("Skipping fillDraft on MSSQL (known issue with INSERT IGNORE)", isMysql());
|
|
||||||
|
|
||||||
// Given: Create property in valid set
|
// Given: Create property in valid set
|
||||||
createTestProperty(testValidSetId, testPropertyTypeId, "30");
|
createTestProperty(testValidSetId, testPropertyTypeId, "30");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,9 +163,6 @@ class AppRepositoryIntegrationTest extends AbstractRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAppWithGroups() {
|
void testAppWithGroups() {
|
||||||
// Skip on MSSQL - buildInsertIgnoreStatement needs fix for parameter ordering
|
|
||||||
org.junit.Assume.assumeTrue("Skipping app-group mapping on MSSQL (known issue with INSERT IGNORE)", isMysql());
|
|
||||||
|
|
||||||
// Given: App with groups
|
// Given: App with groups
|
||||||
App app = createTestApp("App with Groups", "grouped_client", "grouped_secret");
|
App app = createTestApp("App with Groups", "grouped_client", "grouped_secret");
|
||||||
Group group1 = new Group();
|
Group group1 = new Group();
|
||||||
|
|
@ -191,9 +188,6 @@ class AppRepositoryIntegrationTest extends AbstractRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUpdateAppGroups() {
|
void testUpdateAppGroups() {
|
||||||
// Skip on MSSQL - buildInsertIgnoreStatement needs fix for parameter ordering
|
|
||||||
org.junit.Assume.assumeTrue("Skipping app-group mapping on MSSQL (known issue with INSERT IGNORE)", isMysql());
|
|
||||||
|
|
||||||
// Given: App with one group
|
// Given: App with one group
|
||||||
App app = createTestApp("Group Update Test", "group_update_client", "group_update_secret");
|
App app = createTestApp("Group Update Test", "group_update_client", "group_update_secret");
|
||||||
Group group1 = new Group();
|
Group group1 = new Group();
|
||||||
|
|
@ -217,9 +211,6 @@ class AppRepositoryIntegrationTest extends AbstractRepositoryIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDeleteAppCascadesGroupMappings() {
|
void testDeleteAppCascadesGroupMappings() {
|
||||||
// Skip on MSSQL - buildInsertIgnoreStatement needs fix for parameter ordering
|
|
||||||
org.junit.Assume.assumeTrue("Skipping app-group mapping on MSSQL (known issue with INSERT IGNORE)", isMysql());
|
|
||||||
|
|
||||||
// Given: App with groups
|
// Given: App with groups
|
||||||
App app = createTestApp("Cascade Delete Test", "cascade_client", "cascade_secret");
|
App app = createTestApp("Cascade Delete Test", "cascade_client", "cascade_secret");
|
||||||
Group group1 = new Group();
|
Group group1 = new Group();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue