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();
}
}
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();
}
}
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);
}
}
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);
}
}
Aggregations