Search in sources :

Example 16 with Column

use of org.molgenis.emx2.Column in project molgenis-emx2 by molgenis.

the class SqlTable method insertBatch.

private static int insertBatch(SqlTable table, List<Row> rows, boolean updateOnConflict, Set<String> updateColumns) {
    boolean inherit = table.getMetadata().getInherit() != null;
    if (inherit) {
        SqlTable inheritedTable = table.getInheritedTable();
        inheritedTable.insertBatch(inheritedTable, rows, updateOnConflict, updateColumns);
    }
    // get metadata
    Set<Column> columns = table.getColumnsToBeUpdated(updateColumns);
    // check that columns exist for validation
    checkForMissingVariablesColumns(columns);
    List<Column> allColumns = table.getMetadata().getMutationColumns();
    List<Field> insertFields = columns.stream().map(c -> c.getJooqField()).collect(Collectors.toList());
    if (!inherit) {
        insertFields.add(field(name(MG_INSERTEDBY)));
        insertFields.add(field(name(MG_INSERTEDON)));
        insertFields.add(field(name(MG_UPDATEDBY)));
        insertFields.add(field(name(MG_UPDATEDON)));
    }
    // define the insert step
    InsertValuesStepN<org.jooq.Record> step = table.getJooq().insertInto(table.getJooqTable(), insertFields.toArray(new Field[0]));
    // add all the rows as steps
    String user = table.getSchema().getDatabase().getActiveUser();
    if (user == null) {
        user = ADMIN_USER;
    }
    LocalDateTime now = LocalDateTime.now();
    for (Row row : rows) {
        // get values
        Map values = SqlTypeUtils.getValuesAsMap(row, columns);
        if (!inherit) {
            values.put(MG_INSERTEDBY, user);
            values.put(MG_INSERTEDON, now);
            values.put(MG_UPDATEDBY, user);
            values.put(MG_UPDATEDON, now);
        }
        // when insert, we should include all columns, not only 'updateColumns'
        if (!row.isDraft()) {
            checkRequired(row, allColumns);
            checkValidation(values, columns);
        }
        step.values(values.values());
    }
    // optionally, add conflict clause
    if (updateOnConflict) {
        InsertOnDuplicateSetStep<org.jooq.Record> step2 = step.onConflict(table.getMetadata().getPrimaryKeyFields().toArray(new Field[0])).doUpdate();
        for (Column column : columns) {
            step2.set(column.getJooqField(), (Object) field(unquotedName("excluded.\"" + column.getName() + "\"")));
        }
        if (!inherit) {
            step2.set(field(name(MG_UPDATEDBY)), user);
            step2.set(field(name(MG_UPDATEDON)), now);
        }
    }
    return step.execute();
}
Also used : EvaluateExpressions.checkValidation(org.molgenis.emx2.sql.EvaluateExpressions.checkValidation) java.util(java.util) DSL(org.jooq.impl.DSL) Logger(org.slf4j.Logger) LocalDateTime(java.time.LocalDateTime) LoggerFactory(org.slf4j.LoggerFactory) Constants(org.molgenis.emx2.Constants) org.molgenis.emx2(org.molgenis.emx2) Collectors(java.util.stream.Collectors) EvaluateExpressions.checkForMissingVariablesColumns(org.molgenis.emx2.sql.EvaluateExpressions.checkForMissingVariablesColumns) ADMIN_USER(org.molgenis.emx2.sql.SqlDatabase.ADMIN_USER) Query(org.molgenis.emx2.Query) MutationType(org.molgenis.emx2.MutationType) StringReader(java.io.StringReader) Table(org.molgenis.emx2.Table) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) org.jooq(org.jooq) Writer(java.io.Writer) BaseConnection(org.postgresql.core.BaseConnection) CopyManager(org.postgresql.copy.CopyManager) SqlTypeUtils.getTypedValue(org.molgenis.emx2.sql.SqlTypeUtils.getTypedValue) Row(org.molgenis.emx2.Row) LocalDateTime(java.time.LocalDateTime) Row(org.molgenis.emx2.Row)

Example 17 with Column

use of org.molgenis.emx2.Column in project molgenis-emx2 by molgenis.

the class SqlTableMetadata method alterNameTransaction.

// ensure the transaction has no side effects on 'this' until completed
private static SqlTableMetadata alterNameTransaction(Database db, String schemaName, String tableName, String newName) {
    SqlTableMetadata tm = (SqlTableMetadata) db.getSchema(schemaName).getMetadata().getTableMetadata(tableName);
    // drop triggers for this table
    for (Column column : tm.getStoredColumns()) {
        SqlColumnExecutor.executeRemoveRefConstraints(tm.getJooq(), column);
    }
    // rename table and triggers
    SqlTableMetadataExecutor.executeAlterName(tm.getJooq(), tm, newName);
    // update metadata
    MetadataUtils.alterTableName(tm.getJooq(), tm, newName);
    tm.tableName = newName;
    // recreate triggers for this table
    for (Column column : tm.getStoredColumns()) {
        SqlColumnExecutor.executeCreateRefConstraints(tm.getJooq(), column);
    }
    return tm;
}
Also used : MetadataUtils.deleteColumn(org.molgenis.emx2.sql.MetadataUtils.deleteColumn)

Example 18 with Column

use of org.molgenis.emx2.Column in project molgenis-emx2 by molgenis.

the class SqlTableMetadata method addTransaction.

// static to ensure we don't touch 'this' until complete
private static SqlTableMetadata addTransaction(Database db, String schemaName, String tableName, Column[] column) {
    SqlTableMetadata tm = (SqlTableMetadata) db.getSchema(schemaName).getMetadata().getTableMetadata(tableName);
    // first per-column actions, then multi-column action such as composite keys/refs
    int position = MetadataUtils.getMaxPosition(tm.getJooq(), schemaName) + 1;
    for (Column c : column) {
        long start = System.currentTimeMillis();
        if (tm.getLocalColumn(c.getName()) != null) {
            tm.alterColumn(c);
        } else {
            Column newColumn = new Column(tm, c);
            if (tm.getInherit() != null && tm.getInheritedTable().getColumn(c.getName()) != null && // this column is replicated in all subclass tables
            !c.getName().equals(MG_TABLECLASS)) {
                throw new MolgenisException("Cannot add column " + tm.getTableName() + "." + c.getName() + ": column exists in inherited class " + tm.getInherit());
            }
            if (!newColumn.isHeading()) {
                validateColumn(newColumn);
                if (newColumn.getPosition() == null) {
                    // positions are asumed to number up in a schema
                    newColumn.setPosition(position++);
                }
                executeCreateColumn(tm.getJooq(), newColumn);
                tm.columns.put(c.getName(), newColumn);
                if (newColumn.getKey() > 0) {
                    createOrReplaceKey(tm.getJooq(), newColumn.getTable(), newColumn.getKey(), newColumn.getTable().getKeyFields(newColumn.getKey()));
                }
                executeCreateRefConstraints(tm.getJooq(), newColumn);
            } else {
                saveColumnMetadata(tm.getJooq(), newColumn);
                tm.columns.put(c.getName(), newColumn);
            }
            log(tm, start, "added column '" + newColumn.getName() + "' to table " + tm.getTableName());
        }
    }
    return tm;
}
Also used : MetadataUtils.deleteColumn(org.molgenis.emx2.sql.MetadataUtils.deleteColumn)

Example 19 with Column

use of org.molgenis.emx2.Column in project molgenis-emx2 by molgenis.

the class SqlTableMetadata method alterColumnTransaction.

// static to ensure we don't touch 'this' until transaction succesfull
private static SqlTableMetadata alterColumnTransaction(String schemaName, String tableName, String columnName, Column column, Database db) {
    SqlTableMetadata tm = (SqlTableMetadata) db.getSchema(schemaName).getMetadata().getTableMetadata(tableName);
    Column newColumn = new Column(tm, column);
    Column oldColumn = tm.getColumn(columnName);
    // primary keys by definition are required
    if (newColumn.getKey() == 1) {
        newColumn.setRequired(true);
    }
    validateColumn(newColumn);
    // check if reference and of different size
    if (newColumn.isRefArray() && !newColumn.getName().equals(oldColumn.getName()) && !newColumn.getColumnType().equals(oldColumn.getColumnType()) && newColumn.getRefTable().getPrimaryKeyFields().size() > 1) {
        throw new MolgenisException("Alter column of '" + oldColumn.getName() + " failed: REF_ARRAY is not supported for composite keys of table " + newColumn.getRefTableName());
    }
    // if changing 'ref' then check if not refBack exists
    if (!oldColumn.getColumnType().equals(newColumn.getColumnType())) {
        tm.checkNotRefback(columnName, oldColumn);
    }
    // drop old key, if touched
    if (oldColumn.getKey() > 0 && newColumn.getKey() != oldColumn.getKey()) {
        executeDropKey(tm.getJooq(), oldColumn.getTable(), oldColumn.getKey());
    }
    // drop referential constraints around this column
    executeRemoveRefConstraints(tm.getJooq(), oldColumn);
    // remove refBacks if exist
    executeRemoveRefback(oldColumn, newColumn);
    // add ontology table if needed
    if (newColumn.isOntology()) {
        createOntologyTable(newColumn);
    }
    // rename and retype if needed
    executeAlterType(tm.getJooq(), oldColumn, newColumn);
    executeAlterName(tm.getJooq(), oldColumn, newColumn);
    // only applies to key=1
    if ((oldColumn.isPrimaryKey() || newColumn.isPrimaryKey()) && oldColumn.isRequired() && !oldColumn.isRequired() == newColumn.isRequired()) {
        executeSetRequired(tm.getJooq(), newColumn);
    }
    // update the metadata so we can use it for new keys and references
    if (column.getPosition() == null) {
        column.setPosition(tm.columns.get(columnName).getPosition());
    }
    // remove the old
    tm.columns.remove(columnName);
    // add the new
    tm.columns.put(column.getName(), column);
    // reapply ref constrainst
    executeCreateRefConstraints(tm.getJooq(), newColumn);
    // check if refBack constraints need updating
    reapplyRefbackContraints(oldColumn, newColumn);
    // create/update key, if touched
    if (newColumn.getKey() != oldColumn.getKey()) {
        createOrReplaceKey(tm.getJooq(), tm, newColumn.getKey(), tm.getKeyFields(newColumn.getKey()));
    }
    // delete old column if name changed, then save any other metadata changes
    if (!oldColumn.getName().equals(newColumn.getName()))
        deleteColumn(tm.getJooq(), oldColumn);
    saveColumnMetadata(tm.getJooq(), newColumn);
    return tm;
}
Also used : MetadataUtils.deleteColumn(org.molgenis.emx2.sql.MetadataUtils.deleteColumn)

Example 20 with Column

use of org.molgenis.emx2.Column in project molgenis-emx2 by molgenis.

the class SqlTableMetadata method alterColumn.

@Override
public TableMetadata alterColumn(String columnName, Column column) {
    // ignore mg_ columns
    if (column.getName().startsWith("mg_"))
        return this;
    Column oldColumn = getColumn(columnName);
    if (oldColumn == null) {
        throw new MolgenisException("Alter column failed: Column  '" + getTableName() + "." + column.getName() + "' does not exist");
    }
    if (getInherit() != null && getInheritedTable().getColumn(columnName) != null) {
        throw new MolgenisException("Alter column " + getTableName() + "." + columnName + " failed: column is part of inherited table " + getInherit());
    }
    if (getInherit() != null && getInheritedTable().getColumn(column.getName()) != null) {
        throw new MolgenisException("Rename column from " + getTableName() + "." + columnName + " to " + getTableName() + "." + column.getName() + " failed: column '" + column.getName() + "' is part of inherited table " + getInherit());
    }
    getDatabase().tx(db -> sync(alterColumnTransaction(getSchemaName(), getTableName(), columnName, column, db)));
    // reload the state
    ((SqlSchemaMetadata) getSchema()).sync(getDatabase().getSchema(getSchemaName()).getMetadata());
    return this;
}
Also used : MetadataUtils.deleteColumn(org.molgenis.emx2.sql.MetadataUtils.deleteColumn)

Aggregations

org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Column (org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Column)21 ArrayList (java.util.ArrayList)20 Test (org.junit.Test)20 Row (org.molgenis.emx2.Row)15 Table (org.molgenis.emx2.Table)14 HashMap (java.util.HashMap)11 Column (org.molgenis.emx2.Column)11 List (java.util.List)10 org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Bigint (org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Bigint)10 org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Smallint (org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Smallint)10 ColumnType (org.molgenis.emx2.ColumnType)10 Column (com.google.bigtable.v2.Column)9 TableMetadata (org.molgenis.emx2.TableMetadata)9 Family (com.google.bigtable.v2.Family)8 org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Tinyint (org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Tinyint)8 Schema (org.molgenis.emx2.Schema)8 MolgenisException (org.molgenis.emx2.MolgenisException)7 Collectors (java.util.stream.Collectors)6 Map (java.util.Map)5 org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Table (org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Table)5