Search in sources :

Example 1 with MutationType

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();
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Row(org.molgenis.emx2.Row)

Aggregations

AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Row (org.molgenis.emx2.Row)1