Search in sources :

Example 1 with RowList

use of org.h2.result.RowList in project h2database by h2database.

the class Update method update.

@Override
public int update() {
    targetTableFilter.startQuery(session);
    targetTableFilter.reset();
    RowList rows = new RowList(session);
    try {
        Table table = targetTableFilter.getTable();
        session.getUser().checkRight(table, Right.UPDATE);
        table.fire(session, Trigger.UPDATE, true);
        table.lock(session, true, false);
        int columnCount = table.getColumns().length;
        // get the old rows, compute the new rows
        setCurrentRowNumber(0);
        int count = 0;
        Column[] columns = table.getColumns();
        int limitRows = -1;
        if (limitExpr != null) {
            Value v = limitExpr.getValue(session);
            if (v != ValueNull.INSTANCE) {
                limitRows = v.getInt();
            }
        }
        while (targetTableFilter.next()) {
            setCurrentRowNumber(count + 1);
            if (limitRows >= 0 && count >= limitRows) {
                break;
            }
            if (condition == null || condition.getBooleanValue(session)) {
                Row oldRow = targetTableFilter.get();
                Row newRow = table.getTemplateRow();
                boolean setOnUpdate = false;
                for (int i = 0; i < columnCount; i++) {
                    Expression newExpr = expressionMap.get(columns[i]);
                    Column column = table.getColumn(i);
                    Value newValue;
                    if (newExpr == null) {
                        if (column.getOnUpdateExpression() != null) {
                            setOnUpdate = true;
                        }
                        newValue = oldRow.getValue(i);
                    } else if (newExpr == ValueExpression.getDefault()) {
                        newValue = table.getDefaultValue(session, column);
                    } else {
                        newValue = column.convert(newExpr.getValue(session));
                    }
                    newRow.setValue(i, newValue);
                }
                if (setOnUpdate || updateToCurrentValuesReturnsZero) {
                    setOnUpdate = false;
                    for (int i = 0; i < columnCount; i++) {
                        // Use equals here to detect changes from numeric 0 to 0.0 and similar
                        if (!Objects.equals(oldRow.getValue(i), newRow.getValue(i))) {
                            setOnUpdate = true;
                            break;
                        }
                    }
                    if (setOnUpdate) {
                        for (int i = 0; i < columnCount; i++) {
                            if (expressionMap.get(columns[i]) == null) {
                                Column column = table.getColumn(i);
                                if (column.getOnUpdateExpression() != null) {
                                    newRow.setValue(i, table.getOnUpdateValue(session, column));
                                }
                            }
                        }
                    } else if (updateToCurrentValuesReturnsZero) {
                        count--;
                    }
                }
                table.validateConvertUpdateSequence(session, newRow);
                boolean done = false;
                if (table.fireRow()) {
                    done = table.fireBeforeRow(session, oldRow, newRow);
                }
                if (!done) {
                    rows.add(oldRow);
                    rows.add(newRow);
                }
                count++;
            }
        }
        // TODO self referencing referential integrity constraints
        // don't work if update is multi-row and 'inversed' the condition!
        // probably need multi-row triggers with 'deleted' and 'inserted'
        // at the same time. anyway good for sql compatibility
        // TODO update in-place (but if the key changes,
        // we need to update all indexes) before row triggers
        // the cached row is already updated - we need the old values
        table.updateRows(this, session, rows);
        if (table.fireRow()) {
            rows.invalidateCache();
            for (rows.reset(); rows.hasNext(); ) {
                Row o = rows.next();
                Row n = rows.next();
                table.fireAfterRow(session, o, n, false);
            }
        }
        table.fire(session, Trigger.UPDATE, false);
        return count;
    } finally {
        rows.close();
    }
}
Also used : RowList(org.h2.result.RowList) Table(org.h2.table.Table) Column(org.h2.table.Column) ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) Value(org.h2.value.Value) Row(org.h2.result.Row)

Example 2 with RowList

use of org.h2.result.RowList in project h2database by h2database.

the class Delete method update.

@Override
public int update() {
    targetTableFilter.startQuery(session);
    targetTableFilter.reset();
    Table table = targetTableFilter.getTable();
    session.getUser().checkRight(table, Right.DELETE);
    table.fire(session, Trigger.DELETE, true);
    table.lock(session, true, false);
    RowList rows = new RowList(session);
    int limitRows = -1;
    if (limitExpr != null) {
        Value v = limitExpr.getValue(session);
        if (v != ValueNull.INSTANCE) {
            limitRows = v.getInt();
        }
    }
    try {
        setCurrentRowNumber(0);
        int count = 0;
        while (limitRows != 0 && targetTableFilter.next()) {
            setCurrentRowNumber(rows.size() + 1);
            if (condition == null || condition.getBooleanValue(session)) {
                Row row = targetTableFilter.get();
                boolean done = false;
                if (table.fireRow()) {
                    done = table.fireBeforeRow(session, row, null);
                }
                if (!done) {
                    rows.add(row);
                }
                count++;
                if (limitRows >= 0 && count >= limitRows) {
                    break;
                }
            }
        }
        int rowScanCount = 0;
        for (rows.reset(); rows.hasNext(); ) {
            if ((++rowScanCount & 127) == 0) {
                checkCanceled();
            }
            Row row = rows.next();
            table.removeRow(session, row);
            session.log(table, UndoLogRecord.DELETE, row);
        }
        if (table.fireRow()) {
            for (rows.reset(); rows.hasNext(); ) {
                Row row = rows.next();
                table.fireAfterRow(session, row, null, false);
            }
        }
        table.fire(session, Trigger.DELETE, false);
        return count;
    } finally {
        rows.close();
    }
}
Also used : RowList(org.h2.result.RowList) Table(org.h2.table.Table) Value(org.h2.value.Value) Row(org.h2.result.Row)

Example 3 with RowList

use of org.h2.result.RowList in project h2database by h2database.

the class TableLink method updateRows.

@Override
public void updateRows(Prepared prepared, Session session, RowList rows) {
    boolean deleteInsert;
    checkReadOnly();
    if (emitUpdates) {
        for (rows.reset(); rows.hasNext(); ) {
            prepared.checkCanceled();
            Row oldRow = rows.next();
            Row newRow = rows.next();
            linkedIndex.update(oldRow, newRow);
            session.log(this, UndoLogRecord.DELETE, oldRow);
            session.log(this, UndoLogRecord.INSERT, newRow);
        }
        deleteInsert = false;
    } else {
        deleteInsert = true;
    }
    if (deleteInsert) {
        super.updateRows(prepared, session, rows);
    }
}
Also used : Row(org.h2.result.Row)

Example 4 with RowList

use of org.h2.result.RowList in project h2database by h2database.

the class Table method updateRows.

/**
 * Update a list of rows in this table.
 *
 * @param prepared the prepared statement
 * @param session the session
 * @param rows a list of row pairs of the form old row, new row, old row,
 *            new row,...
 */
public void updateRows(Prepared prepared, Session session, RowList rows) {
    // in case we need to undo the update
    Session.Savepoint rollback = session.setSavepoint();
    // remove the old rows
    int rowScanCount = 0;
    for (rows.reset(); rows.hasNext(); ) {
        if ((++rowScanCount & 127) == 0) {
            prepared.checkCanceled();
        }
        Row o = rows.next();
        rows.next();
        try {
            removeRow(session, o);
        } catch (DbException e) {
            if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
                session.rollbackTo(rollback, false);
                session.startStatementWithinTransaction();
                rollback = session.setSavepoint();
            }
            throw e;
        }
        session.log(this, UndoLogRecord.DELETE, o);
    }
    // add the new rows
    for (rows.reset(); rows.hasNext(); ) {
        if ((++rowScanCount & 127) == 0) {
            prepared.checkCanceled();
        }
        rows.next();
        Row n = rows.next();
        try {
            addRow(session, n);
        } catch (DbException e) {
            if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
                session.rollbackTo(rollback, false);
                session.startStatementWithinTransaction();
                rollback = session.setSavepoint();
            }
            throw e;
        }
        session.log(this, UndoLogRecord.INSERT, n);
    }
}
Also used : Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow) SimpleRow(org.h2.result.SimpleRow) Constraint(org.h2.constraint.Constraint) Session(org.h2.engine.Session) DbException(org.h2.message.DbException)

Aggregations

Row (org.h2.result.Row)4 RowList (org.h2.result.RowList)2 Table (org.h2.table.Table)2 Value (org.h2.value.Value)2 Constraint (org.h2.constraint.Constraint)1 Session (org.h2.engine.Session)1 Expression (org.h2.expression.Expression)1 ValueExpression (org.h2.expression.ValueExpression)1 DbException (org.h2.message.DbException)1 SearchRow (org.h2.result.SearchRow)1 SimpleRow (org.h2.result.SimpleRow)1 Column (org.h2.table.Column)1