You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
411 lines
17 KiB
411 lines
17 KiB
package de.superx.bianalysis; |
|
|
|
import static org.junit.Assert.assertArrayEquals; |
|
import static org.junit.Assert.assertEquals; |
|
|
|
import java.sql.Types; |
|
import java.util.ArrayList; |
|
import java.util.Arrays; |
|
import java.util.List; |
|
import java.util.StringJoiner; |
|
|
|
import org.junit.Test; |
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException; |
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
import com.fasterxml.jackson.databind.JsonMappingException; |
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import de.superx.bianalysis.models.CriteriaGroup; |
|
import de.superx.bianalysis.sqlgeneration.AttributeGroupQueryBuilder; |
|
import de.superx.bianalysis.sqlgeneration.SqlQuery; |
|
|
|
@SuppressWarnings("static-method") |
|
public class AttributeGroupQueryBuilderTest { |
|
|
|
@Test |
|
public void testInOperator() throws JsonMappingException, JsonProcessingException { |
|
String criteriaGroupsJson = """ |
|
[ |
|
{ |
|
"caption":"2001 - 2005", |
|
"conditions": [ |
|
{ |
|
"column" : "year_of_birth", |
|
"operator": "IN", |
|
"values": [ "2001", "2002", "2003", "2004", "2005" ] |
|
} |
|
] |
|
}, |
|
{ |
|
"caption":"2006 - 2010", |
|
"conditions": [ |
|
{ |
|
"column" : "year_of_birth", |
|
"operator": "IN", |
|
"values": [ "2006", "2007", "2008", "2009" ] |
|
} |
|
] |
|
}, |
|
{ |
|
"caption":"n.a", |
|
"isElse" : true |
|
} |
|
] |
|
"""; |
|
|
|
List<CriteriaGroup> criteriaGroups = new ObjectMapper() |
|
.readValue(criteriaGroupsJson, new TypeReference<List<CriteriaGroup>>(){}); |
|
String tableName = "presentation.dim_person"; |
|
String columname = "myagegroup"; |
|
SqlQuery query = AttributeGroupQueryBuilder |
|
.buildColumnQuery(criteriaGroups, tableName, false, columname); |
|
|
|
Object[] expectedParams = Arrays.asList( |
|
"2001", "2002", "2003", "2004", "2005", |
|
"2001 - 2005", "2006", "2007", "2008", "2009", |
|
"2006 - 2010", "n.a" |
|
).toArray(); |
|
|
|
String expectedSql = "UPDATE presentation.dim_person" |
|
+ " SET myagegroup = CASE" |
|
+ " WHEN year_of_birth IN ( ?, ?, ?, ?, ? ) THEN ?" |
|
+ " WHEN year_of_birth IN ( ?, ?, ?, ? ) THEN ?" |
|
+ " ELSE ? END"; |
|
|
|
int[] expectedTypes = new int[12]; |
|
Arrays.fill(expectedTypes, Types.VARCHAR); |
|
|
|
assertArrayEquals(expectedParams, query.getParams()); |
|
assertEquals(expectedSql, query.getSql()); |
|
assertArrayEquals(expectedTypes, query.getTypes()); |
|
} |
|
|
|
@Test |
|
public void testComparisonOperator() throws JsonMappingException, JsonProcessingException { |
|
String criteriaGroupsJson = """ |
|
[ |
|
{ |
|
"caption" : "Unter 18", |
|
"conditions" : [ |
|
{ "column" : "age", "operator" : "<", "value" : "18" } |
|
] |
|
}, |
|
{ |
|
"logic" : "AND", |
|
"caption" : "Ab 18 bis 50", |
|
"conditions" : [ |
|
{ "column" : "age", "operator" : ">=", "value" : "18" }, |
|
{ "column" : "age", "operator" : "<=", "value" : "50" } |
|
] |
|
}, |
|
{ |
|
"caption" : "Über 50", |
|
"conditions" : [ |
|
{ "column" : "age", "operator" : ">", "value" : "50" } |
|
] |
|
} |
|
] |
|
"""; |
|
|
|
List<CriteriaGroup> criteriaGroups = new ObjectMapper() |
|
.readValue(criteriaGroupsJson, new TypeReference<List<CriteriaGroup>>(){}); |
|
String tableName = "presentation.dim_age"; |
|
String columname = "myagegroup"; |
|
SqlQuery query = AttributeGroupQueryBuilder |
|
.buildColumnQuery(criteriaGroups, tableName, false, columname); |
|
|
|
Object[] expectedParams = Arrays.asList( |
|
"18", "Unter 18", "18", "50", |
|
"Ab 18 bis 50", "50", "Über 50", "n.v.").toArray(); |
|
|
|
String expectedSql = "UPDATE presentation.dim_age" |
|
+ " SET myagegroup = CASE" |
|
+ " WHEN age ~ E'^-?\\\\d+$' AND age::int < ? THEN ?" |
|
+ " WHEN age ~ E'^-?\\\\d+$' AND age::int >= ?" |
|
+ " AND age ~ E'^-?\\\\d+$' AND age::int <= ? THEN ?" |
|
+ " WHEN age ~ E'^-?\\\\d+$' AND age::int > ? THEN ? ELSE ? END"; |
|
|
|
int[] expectedTypes = { Types.INTEGER, Types.VARCHAR, Types.INTEGER, Types.INTEGER, |
|
Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.VARCHAR }; |
|
|
|
assertArrayEquals(expectedParams, query.getParams()); |
|
assertEquals(expectedSql, query.getSql()); |
|
assertArrayEquals(expectedTypes, query.getTypes()); |
|
|
|
} |
|
|
|
@Test |
|
public void testNestedConditions() throws JsonMappingException, JsonProcessingException { |
|
String criteriaGroupJson = """ |
|
{ |
|
"caption":"(Teens AND High Income) OR VIP", |
|
"logic":"OR", |
|
"conditions":[ |
|
{ |
|
"logic":"AND", |
|
"conditions":[ |
|
{ |
|
"column":"age", |
|
"operator":">=", |
|
"value":"13" |
|
}, |
|
{ |
|
"column":"age", |
|
"operator":"<", |
|
"value":"20" |
|
}, |
|
{ |
|
"column":"income", |
|
"operator":">", |
|
"value":"50000" |
|
} |
|
] |
|
}, |
|
{ |
|
"column": "status", |
|
"operator": "=", |
|
"value": "VIP" |
|
} |
|
] |
|
} |
|
"""; |
|
|
|
CriteriaGroup criteriaGroup = new ObjectMapper() |
|
.readValue(criteriaGroupJson, CriteriaGroup.class); |
|
|
|
StringJoiner joiner = AttributeGroupQueryBuilder |
|
.buildConditionClause(new ArrayList<String>(), new ArrayList<Integer>(), criteriaGroup); |
|
|
|
String sql = "(age ~ E'^-?\\\\d+$'" |
|
+ " AND age::int >= ? AND age ~ E'^-?\\\\d+$' " |
|
+ "AND age::int < ? AND income ~ E'^-?\\\\d+$' " |
|
+ "AND income::int > ?) OR status = ?"; |
|
assertEquals(sql , joiner.toString()); |
|
} |
|
|
|
|
|
@Test |
|
public void testValidationQuery() throws JsonMappingException, JsonProcessingException { |
|
String json = """ |
|
[ |
|
{ |
|
"caption": "erste", |
|
"conditions": [ |
|
{ |
|
"column": "first_nationality", |
|
"operator": "NOT IN", |
|
"value": "", |
|
"values": [ |
|
"Afghanistan", |
|
"Bulgarien" |
|
] |
|
} |
|
] |
|
}, |
|
{ |
|
"caption": "zweite", |
|
"conditions": [ |
|
{ |
|
"column": "first_nationality", |
|
"operator": "NOT IN", |
|
"value": "", |
|
"values": [ |
|
"Bulgarien", |
|
"Ägypten" |
|
] |
|
}, |
|
{ |
|
"column": "first_nationality", |
|
"operator": "NOT IN", |
|
"value": "", |
|
"values": [ |
|
"Frankreich" |
|
] |
|
} |
|
] |
|
} |
|
], |
|
"""; |
|
|
|
List<CriteriaGroup> groups = new ObjectMapper() |
|
.readValue(json, new TypeReference<List<CriteriaGroup>>(){}); |
|
String tableName = "presentation.dim_person_applicant"; |
|
String colList = "first_nationality"; |
|
|
|
List<SqlQuery> queries = AttributeGroupQueryBuilder.buildValidationQuery(tableName, colList, groups); |
|
assertEquals(1, queries.size()); |
|
SqlQuery query = queries.get(0); |
|
|
|
String expectedSql = "SELECT first_nationality" |
|
+ " FROM presentation.dim_person_applicant" |
|
+ " WHERE first_nationality NOT IN ( ?, ? )" |
|
+ " INTERSECT" |
|
+ " SELECT first_nationality" |
|
+ " FROM presentation.dim_person_applicant" |
|
+ " WHERE first_nationality NOT IN ( ?, ? )" |
|
+ " AND first_nationality NOT IN ( ? )"; |
|
|
|
Object[] expectedParams = Arrays.asList( |
|
"Afghanistan", "Bulgarien", "Bulgarien", "Ägypten", "Frankreich" |
|
).toArray(); |
|
|
|
int[] expectedTypes = { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, |
|
Types.VARCHAR, Types.VARCHAR }; |
|
|
|
assertArrayEquals(expectedParams, query.getParams()); |
|
assertEquals(expectedSql, query.getSql()); |
|
assertArrayEquals(expectedTypes, query.getTypes()); |
|
} |
|
|
|
@Test |
|
public void testValidationQueryForThree() throws JsonMappingException, JsonProcessingException { |
|
String json = """ |
|
[ |
|
{ |
|
"caption": "Unter 18", |
|
"conditions": [ |
|
{ |
|
"column": "age", |
|
"operator": "<", |
|
"value": "18" |
|
} |
|
], |
|
"isElse": false, |
|
"logic": null |
|
}, |
|
{ |
|
"caption": "Ab 18 bis 50", |
|
"conditions": [ |
|
{ |
|
"column": "age", |
|
"columnCaption": "Alter", |
|
"operator": ">=", |
|
"value": "16" |
|
}, |
|
{ |
|
"column": "age", |
|
"columnCaption": "Alter", |
|
"operator": "<=", |
|
"value": "50" |
|
} |
|
], |
|
"isElse": false, |
|
"logic": "AND" |
|
}, |
|
{ |
|
"caption": "Über 50", |
|
"conditions": [ |
|
{ |
|
"column": "age", |
|
"operator": ">", |
|
"value": "50" |
|
} |
|
], |
|
"isElse": false, |
|
"logic": null |
|
} |
|
] |
|
"""; |
|
|
|
List<CriteriaGroup> groups = new ObjectMapper() |
|
.readValue(json, new TypeReference<List<CriteriaGroup>>(){}); |
|
String tableName = "presentation.dim_age"; |
|
String columname = "age"; |
|
|
|
List<SqlQuery> queries = AttributeGroupQueryBuilder.buildValidationQuery(tableName, columname, groups); |
|
assertEquals(3, queries.size()); |
|
|
|
String expectedSqlFirst = "SELECT age FROM presentation.dim_age" |
|
+ " WHERE age ~ E'^-?\\\\d+$' AND age::int >= ?" |
|
+ " AND age ~ E'^-?\\\\d+$' AND age::int <= ?" |
|
+ " INTERSECT SELECT age FROM presentation.dim_age" |
|
+ " WHERE age ~ E'^-?\\\\d+$' AND age::int > ?"; |
|
String expectedSqlSecond = "SELECT age FROM presentation.dim_age" |
|
+ " WHERE age ~ E'^-?\\\\d+$' AND age::int < ?" |
|
+ " INTERSECT SELECT age FROM presentation.dim_age" |
|
+ " WHERE age ~ E'^-?\\\\d+$' AND age::int > ?"; |
|
String expectedSqlThird = "SELECT age FROM presentation.dim_age" |
|
+ " WHERE age ~ E'^-?\\\\d+$' AND age::int < ?" |
|
+ " INTERSECT SELECT age FROM presentation.dim_age" |
|
+ " WHERE age ~ E'^-?\\\\d+$' AND age::int >= ?" |
|
+ " AND age ~ E'^-?\\\\d+$' AND age::int <= ?"; |
|
|
|
Object[] expectedParamsFirst = Arrays.asList("16", "50", "50").toArray(); |
|
Object[] expectedParamsSecond = Arrays.asList("18", "50").toArray(); |
|
Object[] expectedParamsThird = Arrays.asList("18", "16", "50").toArray(); |
|
|
|
int[] expectedTypesFirst = {Types.INTEGER, Types.INTEGER, Types.INTEGER}; |
|
int[] expectedTypesSecond = {Types.INTEGER, Types.INTEGER}; |
|
int[] expectedTypesThird = {Types.INTEGER, Types.INTEGER, Types.INTEGER}; |
|
|
|
assertArrayEquals(expectedParamsFirst, queries.get(0).getParams()); |
|
assertEquals(expectedSqlFirst, queries.get(0).getSql()); |
|
assertArrayEquals(expectedTypesFirst, queries.get(0).getTypes()); |
|
|
|
assertArrayEquals(expectedParamsSecond, queries.get(1).getParams()); |
|
assertEquals(expectedSqlSecond, queries.get(1).getSql()); |
|
assertArrayEquals(expectedTypesSecond, queries.get(1).getTypes()); |
|
|
|
assertArrayEquals(expectedParamsThird, queries.get(2).getParams()); |
|
assertEquals(expectedSqlThird, queries.get(2).getSql()); |
|
assertArrayEquals(expectedTypesThird, queries.get(2).getTypes()); |
|
} |
|
|
|
@Test |
|
public void testValidationQueryWithNV() throws JsonMappingException, JsonProcessingException { |
|
String json = """ |
|
[ |
|
{ |
|
"caption": "n. v.", |
|
"isElse": true |
|
}, |
|
{ |
|
"caption": "Männlich", |
|
"conditions": [ |
|
{ |
|
"column": "gender", |
|
"columnCaption": "Geschlecht", |
|
"operator": "=", |
|
"value": "männlich", |
|
"values": [] |
|
} |
|
], |
|
"isElse": false |
|
}, |
|
{ |
|
"caption": "Weiblich", |
|
"conditions": [ |
|
{ |
|
"column": "gender", |
|
"columnCaption": "Geschlecht", |
|
"operator": "=", |
|
"value": "weiblich", |
|
"values": [] |
|
} |
|
], |
|
"isElse": false |
|
} |
|
] |
|
"""; |
|
|
|
List<CriteriaGroup> groups = new ObjectMapper() |
|
.readValue(json, new TypeReference<List<CriteriaGroup>>(){}); |
|
String tableName = "presentation.dim_person_applicant"; |
|
String columname = "gender"; |
|
|
|
List<SqlQuery> queries = AttributeGroupQueryBuilder.buildValidationQuery(tableName, columname, groups); |
|
assertEquals(1, queries.size()); |
|
|
|
String expectedSql = "SELECT gender FROM presentation.dim_person_applicant" |
|
+ " WHERE gender = ? INTERSECT SELECT gender" |
|
+ " FROM presentation.dim_person_applicant WHERE gender = ?"; |
|
Object[] expectedParams= Arrays.asList("männlich", "weiblich").toArray(); |
|
int[] expectedTypes = {Types.VARCHAR, Types.VARCHAR}; |
|
|
|
assertArrayEquals(expectedParams, queries.get(0).getParams()); |
|
assertEquals(expectedSql, queries.get(0).getSql()); |
|
assertArrayEquals(expectedTypes, queries.get(0).getTypes()); |
|
} |
|
|
|
}
|
|
|