Search in sources :

Example 16 with TableRecords

use of io.seata.rm.datasource.sql.struct.TableRecords in project seata by seata.

the class OracleUndoDeleteExecutor method buildUndoSQL.

@Override
protected String buildUndoSQL() {
    TableRecords beforeImage = sqlUndoLog.getBeforeImage();
    List<Row> beforeImageRows = beforeImage.getRows();
    if (CollectionUtils.isEmpty(beforeImageRows)) {
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    Row row = beforeImageRows.get(0);
    List<Field> fields = new ArrayList<>(row.nonPrimaryKeys());
    fields.addAll(getOrderedPkList(beforeImage, row, JdbcConstants.ORACLE));
    // delete sql undo log before image all field come from table meta, need add escape.
    // see BaseTransactionalExecutor#buildTableRecords
    String insertColumns = fields.stream().map(field -> ColumnUtils.addEscape(field.getName(), JdbcConstants.ORACLE)).collect(Collectors.joining(", "));
    String insertValues = fields.stream().map(field -> "?").collect(Collectors.joining(", "));
    return String.format(INSERT_SQL_TEMPLATE, sqlUndoLog.getTableName(), insertColumns, insertValues);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) ColumnUtils(io.seata.rm.datasource.ColumnUtils) List(java.util.List) Field(io.seata.rm.datasource.sql.struct.Field) AbstractUndoExecutor(io.seata.rm.datasource.undo.AbstractUndoExecutor) CollectionUtils(io.seata.common.util.CollectionUtils) Row(io.seata.rm.datasource.sql.struct.Row) JdbcConstants(io.seata.sqlparser.util.JdbcConstants) Collectors(java.util.stream.Collectors) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) SQLUndoLog(io.seata.rm.datasource.undo.SQLUndoLog) ArrayList(java.util.ArrayList) Field(io.seata.rm.datasource.sql.struct.Field) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) ArrayList(java.util.ArrayList) Row(io.seata.rm.datasource.sql.struct.Row)

Example 17 with TableRecords

use of io.seata.rm.datasource.sql.struct.TableRecords in project seata by seata.

the class OracleUndoInsertExecutor method buildUndoSQL.

@Override
protected String buildUndoSQL() {
    TableRecords afterImage = sqlUndoLog.getAfterImage();
    List<Row> afterImageRows = afterImage.getRows();
    if (CollectionUtils.isEmpty(afterImageRows)) {
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    return generateDeleteSql(afterImageRows, afterImage);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Row(io.seata.rm.datasource.sql.struct.Row)

Example 18 with TableRecords

use of io.seata.rm.datasource.sql.struct.TableRecords in project seata by seata.

the class BaseTransactionalExecutor method prepareUndoLog.

/**
 * prepare undo log.
 *
 * @param beforeImage the before image
 * @param afterImage  the after image
 * @throws SQLException the sql exception
 */
protected void prepareUndoLog(TableRecords beforeImage, TableRecords afterImage) throws SQLException {
    if (beforeImage.getRows().isEmpty() && afterImage.getRows().isEmpty()) {
        return;
    }
    if (SQLType.UPDATE == sqlRecognizer.getSQLType()) {
        if (beforeImage.getRows().size() != afterImage.getRows().size()) {
            throw new ShouldNeverHappenException("Before image size is not equaled to after image size, probably because you updated the primary keys.");
        }
    }
    ConnectionProxy connectionProxy = statementProxy.getConnectionProxy();
    TableRecords lockKeyRecords = sqlRecognizer.getSQLType() == SQLType.DELETE ? beforeImage : afterImage;
    String lockKeys = buildLockKey(lockKeyRecords);
    if (null != lockKeys) {
        connectionProxy.appendLockKey(lockKeys);
        SQLUndoLog sqlUndoLog = buildUndoItem(beforeImage, afterImage);
        connectionProxy.appendUndoLog(sqlUndoLog);
    }
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) SQLUndoLog(io.seata.rm.datasource.undo.SQLUndoLog) ConnectionProxy(io.seata.rm.datasource.ConnectionProxy)

Example 19 with TableRecords

use of io.seata.rm.datasource.sql.struct.TableRecords in project seata by seata.

the class AbstractUndoExecutor method executeOn.

/**
 * Execute on.
 *
 * @param conn the conn
 * @throws SQLException the sql exception
 */
public void executeOn(Connection conn) throws SQLException {
    if (IS_UNDO_DATA_VALIDATION_ENABLE && !dataValidationAndGoOn(conn)) {
        return;
    }
    try {
        String undoSQL = buildUndoSQL();
        PreparedStatement undoPST = conn.prepareStatement(undoSQL);
        TableRecords undoRows = getUndoRows();
        for (Row undoRow : undoRows.getRows()) {
            ArrayList<Field> undoValues = new ArrayList<>();
            List<Field> pkValueList = getOrderedPkList(undoRows, undoRow, getDbType(conn));
            for (Field field : undoRow.getFields()) {
                if (field.getKeyType() != KeyType.PRIMARY_KEY) {
                    undoValues.add(field);
                }
            }
            undoPrepare(undoPST, undoValues, pkValueList);
            undoPST.executeUpdate();
        }
    } catch (Exception ex) {
        if (ex instanceof SQLException) {
            throw (SQLException) ex;
        } else {
            throw new SQLException(ex);
        }
    }
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) Field(io.seata.rm.datasource.sql.struct.Field) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) Row(io.seata.rm.datasource.sql.struct.Row) SQLException(java.sql.SQLException)

Example 20 with TableRecords

use of io.seata.rm.datasource.sql.struct.TableRecords in project seata by seata.

the class MySQLUndoDeleteExecutor method buildUndoSQL.

/**
 * Undo delete.
 *
 * Notice: PK is at last one.
 * @see AbstractUndoExecutor#undoPrepare
 *
 * @return sql
 */
@Override
protected String buildUndoSQL() {
    TableRecords beforeImage = sqlUndoLog.getBeforeImage();
    List<Row> beforeImageRows = beforeImage.getRows();
    if (CollectionUtils.isEmpty(beforeImageRows)) {
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    Row row = beforeImageRows.get(0);
    List<Field> fields = new ArrayList<>(row.nonPrimaryKeys());
    fields.addAll(getOrderedPkList(beforeImage, row, JdbcConstants.MYSQL));
    // delete sql undo log before image all field come from table meta, need add escape.
    // see BaseTransactionalExecutor#buildTableRecords
    String insertColumns = fields.stream().map(field -> ColumnUtils.addEscape(field.getName(), JdbcConstants.MYSQL)).collect(Collectors.joining(", "));
    String insertValues = fields.stream().map(field -> "?").collect(Collectors.joining(", "));
    return String.format(INSERT_SQL_TEMPLATE, sqlUndoLog.getTableName(), insertColumns, insertValues);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) ColumnUtils(io.seata.rm.datasource.ColumnUtils) List(java.util.List) Field(io.seata.rm.datasource.sql.struct.Field) AbstractUndoExecutor(io.seata.rm.datasource.undo.AbstractUndoExecutor) CollectionUtils(io.seata.common.util.CollectionUtils) Row(io.seata.rm.datasource.sql.struct.Row) JdbcConstants(io.seata.sqlparser.util.JdbcConstants) Collectors(java.util.stream.Collectors) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) SQLUndoLog(io.seata.rm.datasource.undo.SQLUndoLog) ArrayList(java.util.ArrayList) Field(io.seata.rm.datasource.sql.struct.Field) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) ArrayList(java.util.ArrayList) Row(io.seata.rm.datasource.sql.struct.Row)

Aggregations

TableRecords (io.seata.rm.datasource.sql.struct.TableRecords)52 Row (io.seata.rm.datasource.sql.struct.Row)29 Test (org.junit.jupiter.api.Test)25 ArrayList (java.util.ArrayList)23 Field (io.seata.rm.datasource.sql.struct.Field)21 SQLUndoLog (io.seata.rm.datasource.undo.SQLUndoLog)19 TableMeta (io.seata.rm.datasource.sql.struct.TableMeta)14 List (java.util.List)13 ShouldNeverHappenException (io.seata.common.exception.ShouldNeverHappenException)12 SQLException (java.sql.SQLException)9 Collectors (java.util.stream.Collectors)7 CollectionUtils (io.seata.common.util.CollectionUtils)6 ColumnUtils (io.seata.rm.datasource.ColumnUtils)6 AbstractUndoExecutor (io.seata.rm.datasource.undo.AbstractUndoExecutor)6 JdbcConstants (io.seata.sqlparser.util.JdbcConstants)6 SQLRecognizer (io.seata.sqlparser.SQLRecognizer)4 BeforeAll (org.junit.jupiter.api.BeforeAll)4 ConnectionProxy (io.seata.rm.datasource.ConnectionProxy)3 SqlGenerateUtils (io.seata.rm.datasource.SqlGenerateUtils)3 UndoExecutorTest (io.seata.rm.datasource.undo.UndoExecutorTest)3