use of org.molgenis.emx2.MutationType in project molgenis-emx2 by molgenis.
the class SqlTable method executeTransaction.
private static int executeTransaction(Database db, String schemaName, String tableName, Iterable<Row> rows, MutationType transactionType) {
long start = System.currentTimeMillis();
final AtomicInteger count = new AtomicInteger(0);
final Map<String, List<Row>> subclassRows = new LinkedHashMap<>();
final Map<String, Set<String>> columnsProvided = new LinkedHashMap<>();
SqlSchema schema = (SqlSchema) db.getSchema(schemaName);
SqlTable table = schema.getTable(tableName);
String tableClass = getMgTableClass(table.getMetadata());
// validate
if (table.getMetadata().getPrimaryKeys().isEmpty())
throw new MolgenisException("Transaction failed: Table " + table.getName() + " cannot process row insert/update/delete requests because no primary key is defined");
db.tx(db2 -> {
for (Row row : rows) {
// set table class if not set, and see for first time
if (row.notNull(MG_TABLECLASS) && !subclassRows.containsKey(row.getString(MG_TABLECLASS))) {
// validate
String rowTableName = row.getString(MG_TABLECLASS);
if (!rowTableName.contains(".")) {
if (schema.getTable(rowTableName) != null) {
row.setString(MG_TABLECLASS, schemaName + "." + rowTableName);
} else {
throw new MolgenisException(MG_TABLECLASS + " value failed in row " + count.get() + ": found '" + rowTableName + "'");
}
} else {
String rowSchemaName = rowTableName.split("\\.")[0];
String rowTableName2 = rowTableName.split("\\.")[1];
if (db.getSchema(rowSchemaName) == null || db.getSchema(rowSchemaName).getTable(rowTableName2) == null) {
throw new MolgenisException("invalid value in column '" + MG_TABLECLASS + "' on row " + count.get() + ": found '" + rowTableName + "'");
}
}
} else {
row.set(MG_TABLECLASS, tableClass);
}
// create batches for each table class
String subclassName = row.getString(MG_TABLECLASS);
if (!subclassRows.containsKey(subclassName)) {
subclassRows.put(subclassName, new ArrayList<>());
}
// check columns provided didn't change
if (columnsProvided.get(subclassName) == null) {
columnsProvided.put(subclassName, new LinkedHashSet<>(row.getColumnNames()));
}
// execute batch if 1000 rows, or columns provided changes
if (columnsProvidedAreDifferent(columnsProvided.get(subclassName), row) || subclassRows.get(subclassName).size() >= 1000) {
executeBatch((SqlSchema) db2.getSchema(subclassName.split("\\.")[0]), transactionType, count, subclassRows, subclassName, columnsProvided.get(subclassName));
// reset columns provided
columnsProvided.get(subclassName).clear();
columnsProvided.get(subclassName).addAll(row.getColumnNames());
}
// add to batch list, and execute if batch is large enough
subclassRows.get(subclassName).add(row);
}
// execute any remaining batches
for (Map.Entry<String, List<Row>> batch : subclassRows.entrySet()) {
if (batch.getValue().size() > 0) {
executeBatch((SqlSchema) db2.getSchema(batch.getKey().split("\\.")[0]), transactionType, count, subclassRows, batch.getKey(), columnsProvided.get(batch.getKey()));
}
}
});
log(db.getActiveUser(), table.getJooqTable().getName(), start, count, transactionType.name().toLowerCase() + "d (incl subclass if applicable)");
return count.get();
}
Aggregations