/** * 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 int rollback = session.getUndoLogPos(); // remove the old rows int rowScanCount = 0; for (rows.reset(); rows.hasNext(); ) { if ((++rowScanCount & 127) == 0) { prepared.checkCanceled(); } Row o = rows.next(); rows.next(); removeRow(session, o); 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); } throw e; } session.log(this, UndoLogRecord.INSERT, n); } }
private void merge(Row row) { ArrayList<Parameter> k = update.getParameters(); for (int i = 0; i < columns.length; i++) { Column col = columns[i]; Value v = row.getValue(col.getColumnId()); Parameter p = k.get(i); p.setValue(v); } for (int i = 0; i < keys.length; i++) { Column col = keys[i]; Value v = row.getValue(col.getColumnId()); if (v == null) { throw DbException.get(ErrorCode.COLUMN_CONTAINS_NULL_VALUES_1, col.getSQL()); } Parameter p = k.get(columns.length + i); p.setValue(v); } int count = update.update(); if (count == 0) { try { table.validateConvertUpdateSequence(session, row); boolean done = table.fireBeforeRow(session, null, row); if (!done) { table.lock(session, true, false); table.addRow(session, row); session.log(table, UndoLogRecord.INSERT, row); table.fireAfterRow(session, null, row, false); } } catch (DbException e) { if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) { // possibly a concurrent merge or insert Index index = (Index) e.getSource(); if (index != null) { // verify the index columns match the key Column[] indexColumns = index.getColumns(); boolean indexMatchesKeys = false; if (indexColumns.length <= keys.length) { for (int i = 0; i < indexColumns.length; i++) { if (indexColumns[i] != keys[i]) { indexMatchesKeys = false; break; } } } if (indexMatchesKeys) { throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, table.getName()); } } } throw e; } } else if (count != 1) { throw DbException.get(ErrorCode.DUPLICATE_KEY_1, table.getSQL()); } }