use of com.helger.genericode.v10.Column in project molgenis-emx2 by molgenis.
the class TableSort method sortTableByDependency.
public static void sortTableByDependency(List<TableMetadata> tableList) {
ArrayList<TableMetadata> result = new ArrayList<>();
ArrayList<TableMetadata> todo = new ArrayList<>(tableList);
// ensure deterministic order
todo.sort(new Comparator<TableMetadata>() {
@Override
public int compare(TableMetadata o1, TableMetadata o2) {
return o1.getTableName().compareTo(o2.getTableName());
}
});
while (!todo.isEmpty()) {
int size = todo.size();
for (int i = 0; i < todo.size(); i++) {
TableMetadata current = todo.get(i);
boolean depends = false;
for (int j = 0; j < todo.size(); j++) {
if (current.getInherit() != null && current.getImportSchema() == null && todo.get(j).equals(current.getInheritedTable())) {
depends = true;
break;
}
}
if (!depends)
for (Column c : current.getColumns()) {
if (c.getRefTableName() != null && !c.isRefback()) {
for (int j = 0; j < todo.size(); j++) {
if (i != j && (todo.get(j).getTableName().equals(c.getRefTableName()))) {
depends = true;
break;
}
}
}
}
if (!depends) {
result.add(todo.get(i));
todo.remove(i);
}
}
// check for circular relationship
if (size == todo.size()) {
throw new MolgenisException("circular dependency error: following tables have circular dependency: " + todo.stream().map(TableMetadata::getTableName).collect(Collectors.joining(",")));
}
}
tableList.clear();
tableList.addAll(result);
}
use of com.helger.genericode.v10.Column in project molgenis-emx2 by molgenis.
the class EvaluateExpressionsTest method testCheckValidationColumnsSuccess.
@Test
public void testCheckValidationColumnsSuccess() {
Collection<Column> columns = new ArrayList<>();
Column column1 = new Column("columnName1");
column1.setValidation("{columnName2}");
Column column2 = new Column("columnName2");
columns.add(column1);
columns.add(column2);
checkForMissingVariablesColumns(columns);
}
use of com.helger.genericode.v10.Column in project molgenis-emx2 by molgenis.
the class EvaluateExpressionsTest method testCheckValidationSuccess.
@Test
public void testCheckValidationSuccess() {
Map<String, Object> values = new HashMap<>();
Collection<Column> columns = new ArrayList<>();
String validation = "true && true";
Column column = new Column("name");
column.setValidation(validation);
columns.add(column);
checkValidation(values, columns);
}
use of com.helger.genericode.v10.Column in project molgenis-emx2 by molgenis.
the class EvaluateExpressionsTest method testCheckValidationInvalidExpression.
@Test
public void testCheckValidationInvalidExpression() {
Map<String, Object> values = new HashMap<>();
Collection<Column> columns = new ArrayList<>();
String validation = "this is very invalid";
Column column = new Column("name");
column.setValidation(validation);
columns.add(column);
try {
checkValidation(values, columns);
} catch (MolgenisException exception) {
assertEquals("Cannot execute expression: this is very invalid", exception.getMessage());
}
}
use of com.helger.genericode.v10.Column in project molgenis-emx2 by molgenis.
the class SqlColumnRefArrayExecutor method createReferenceExistsCheck.
/**
* trigger on this column to check if foreign key exists. Might be composite key, i.e., list of
* columns
*/
private static void createReferenceExistsCheck(DSLContext jooq, Column column) {
String schemaName = column.getSchema().getName();
Name thisTable = name(schemaName, column.getTable().getTableName());
Name toTable = name(column.getRefSchema(), column.getRefTableName());
String functionName = getReferenceExistsCheckName(column);
List<Reference> references = column.getReferences();
String fromColumns = references.stream().map(r -> name(r.getName()).toString()).collect(Collectors.joining(","));
String toColumns = references.stream().map(r -> name(r.getRefTo()).toString()).collect(Collectors.joining(","));
String errorColumns = references.stream().map(r -> "COALESCE(error_row." + name(r.getRefTo()).toString() + ",'NULL')").collect(Collectors.joining("||','||"));
String exceptFilter = references.stream().map(r -> {
if (r.isOverlappingRef()) {
return name(r.getRefTo()) + " = NEW." + name(r.getName());
} else {
return name(r.getRefTo()) + " = ANY (NEW." + name(r.getName()) + ")";
}
}).collect(Collectors.joining(" AND "));
String unnestRefs = references.stream().map(r -> {
// can be overlapping with non_array reference
if (r.isOverlappingRef()) {
return "NEW." + name(r.getName()) + " AS " + name(r.getRefTo());
} else {
return "UNNEST(NEW." + name(r.getName()) + ") AS " + name(r.getRefTo());
}
}).collect(Collectors.joining(","));
String nonRefLinkFieldsAreNotNull = references.stream().filter(r -> !r.isOverlapping()).map(r2 -> "error_row." + name(r2.getRefTo()) + " IS NOT NULL ").collect(Collectors.joining(" OR "));
jooq.execute("CREATE OR REPLACE FUNCTION {0}() RETURNS trigger AS $BODY$ " + "\nDECLARE error_row RECORD;" + "\nBEGIN" + "\n\tFOR error_row IN SELECT {1} EXCEPT SELECT {2} FROM {3} WHERE {10} LOOP" + // exclude if only refLink fields are set
"\n\t\tIF {11} THEN" + "\n\t\t\tRAISE EXCEPTION USING ERRCODE='23503', MESSAGE = 'insert or update on table \"'||{9}||'\" violates foreign key (ref_array) constraint'" + " , DETAIL = 'Key ('||{6}||')=('|| {5} ||') is not present in table \"'||{7}||'\", column(s)('||{8}||')';" + "\n\t\tEND IF;" + "\n\tEND LOOP;" + "\n\tRETURN NEW;" + "\nEND; $BODY$ LANGUAGE plpgsql;", // 0
name(schemaName, functionName), // 1
keyword(unnestRefs), // 2
keyword(toColumns), // 3
toTable, // 4
thisTable, // 5
keyword(errorColumns), // 6
inline(fromColumns), // 7
inline(column.getRefTableName()), // 8
inline(toColumns), // 9
inline(column.getTableName()), // 10
keyword(exceptFilter), // 11
keyword(nonRefLinkFieldsAreNotNull));
// add the trigger
jooq.execute("CREATE CONSTRAINT TRIGGER {0} " + "\n\tAFTER INSERT OR UPDATE OF {1} ON {2} FROM {3}" + "\n\tDEFERRABLE INITIALLY IMMEDIATE " + "\n\tFOR EACH ROW EXECUTE PROCEDURE {4}()", name(functionName), keyword(fromColumns), thisTable, toTable, name(column.getTable().getSchema().getName(), functionName));
}
Aggregations