Search in sources :

Example 21 with TableRecords

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

the class MySQLUndoUpdateExecutor method buildUndoSQL.

/**
 * Undo Update.
 *
 * @return sql
 */
@Override
protected String buildUndoSQL() {
    TableRecords beforeImage = sqlUndoLog.getBeforeImage();
    List<Row> beforeImageRows = beforeImage.getRows();
    if (CollectionUtils.isEmpty(beforeImageRows)) {
        // TODO
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    Row row = beforeImageRows.get(0);
    List<Field> nonPkFields = row.nonPrimaryKeys();
    // update sql undo log before image all field come from table meta. need add escape.
    // see BaseTransactionalExecutor#buildTableRecords
    String updateColumns = nonPkFields.stream().map(field -> ColumnUtils.addEscape(field.getName(), JdbcConstants.MYSQL) + " = ?").collect(Collectors.joining(", "));
    List<String> pkNameList = getOrderedPkList(beforeImage, row, JdbcConstants.MYSQL).stream().map(e -> e.getName()).collect(Collectors.toList());
    String whereSql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, JdbcConstants.MYSQL);
    return String.format(UPDATE_SQL_TEMPLATE, sqlUndoLog.getTableName(), updateColumns, whereSql);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) List(java.util.List) ColumnUtils(io.seata.rm.datasource.ColumnUtils) Field(io.seata.rm.datasource.sql.struct.Field) AbstractUndoExecutor(io.seata.rm.datasource.undo.AbstractUndoExecutor) CollectionUtils(io.seata.common.util.CollectionUtils) SqlGenerateUtils(io.seata.rm.datasource.SqlGenerateUtils) 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) Field(io.seata.rm.datasource.sql.struct.Field) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Row(io.seata.rm.datasource.sql.struct.Row)

Example 22 with TableRecords

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

the class BaseTransactionalExecutorTest method testBuildLockKey.

@Test
public void testBuildLockKey() {
    // build expect data
    String tableName = "test_name";
    String fieldOne = "1";
    String fieldTwo = "2";
    String split1 = ":";
    String split2 = ",";
    String pkColumnName = "id";
    // test_name:1,2
    String buildLockKeyExpect = tableName + split1 + fieldOne + split2 + fieldTwo;
    // mock field
    Field field1 = mock(Field.class);
    when(field1.getValue()).thenReturn(fieldOne);
    Field field2 = mock(Field.class);
    when(field2.getValue()).thenReturn(fieldTwo);
    List<Map<String, Field>> pkRows = new ArrayList<>();
    pkRows.add(Collections.singletonMap(pkColumnName, field1));
    pkRows.add(Collections.singletonMap(pkColumnName, field2));
    // mock tableMeta
    TableMeta tableMeta = mock(TableMeta.class);
    when(tableMeta.getTableName()).thenReturn(tableName);
    when(tableMeta.getPrimaryKeyOnlyName()).thenReturn(Arrays.asList(new String[] { pkColumnName }));
    // mock tableRecords
    TableRecords tableRecords = mock(TableRecords.class);
    when(tableRecords.getTableMeta()).thenReturn(tableMeta);
    when(tableRecords.size()).thenReturn(pkRows.size());
    when(tableRecords.pkRows()).thenReturn(pkRows);
    // mock executor
    BaseTransactionalExecutor executor = mock(BaseTransactionalExecutor.class);
    when(executor.buildLockKey(tableRecords)).thenCallRealMethod();
    when(executor.getTableMeta()).thenReturn(tableMeta);
    assertThat(executor.buildLockKey(tableRecords)).isEqualTo(buildLockKeyExpect);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) Field(io.seata.rm.datasource.sql.struct.Field) TableMeta(io.seata.rm.datasource.sql.struct.TableMeta) Test(org.junit.jupiter.api.Test)

Example 23 with TableRecords

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

the class BaseTransactionalExecutorTest method testBuildLockKeyWithMultiPk.

@Test
public void testBuildLockKeyWithMultiPk() {
    // build expect data
    String tableName = "test_name";
    String pkOneValue1 = "1";
    String pkOneValue2 = "2";
    String pkTwoValue1 = "one";
    String pkTwoValue2 = "two";
    String split1 = ":";
    String split2 = ",";
    String split3 = "_";
    String pkOneColumnName = "id";
    String pkTwoColumnName = "userId";
    // test_name:1_one,2_two
    String buildLockKeyExpect = tableName + split1 + pkOneValue1 + split3 + pkTwoValue1 + split2 + pkOneValue2 + split3 + pkTwoValue2;
    // mock field
    Field pkOneField1 = mock(Field.class);
    when(pkOneField1.getValue()).thenReturn(pkOneValue1);
    Field pkOneField2 = mock(Field.class);
    when(pkOneField2.getValue()).thenReturn(pkOneValue2);
    Field pkTwoField1 = mock(Field.class);
    when(pkTwoField1.getValue()).thenReturn(pkTwoValue1);
    Field pkTwoField2 = mock(Field.class);
    when(pkTwoField2.getValue()).thenReturn(pkTwoValue2);
    List<Map<String, Field>> pkRows = new ArrayList<>();
    Map<String, Field> row1 = new HashMap<String, Field>() {

        {
            put(pkOneColumnName, pkOneField1);
            put(pkTwoColumnName, pkTwoField1);
        }
    };
    pkRows.add(row1);
    Map<String, Field> row2 = new HashMap<String, Field>() {

        {
            put(pkOneColumnName, pkOneField2);
            put(pkTwoColumnName, pkTwoField2);
        }
    };
    pkRows.add(row2);
    // mock tableMeta
    TableMeta tableMeta = mock(TableMeta.class);
    when(tableMeta.getTableName()).thenReturn(tableName);
    when(tableMeta.getPrimaryKeyOnlyName()).thenReturn(Arrays.asList(new String[] { pkOneColumnName, pkTwoColumnName }));
    // mock tableRecords
    TableRecords tableRecords = mock(TableRecords.class);
    when(tableRecords.getTableMeta()).thenReturn(tableMeta);
    when(tableRecords.size()).thenReturn(pkRows.size());
    when(tableRecords.pkRows()).thenReturn(pkRows);
    // mock executor
    BaseTransactionalExecutor executor = mock(BaseTransactionalExecutor.class);
    when(executor.buildLockKey(tableRecords)).thenCallRealMethod();
    when(executor.getTableMeta()).thenReturn(tableMeta);
    assertThat(executor.buildLockKey(tableRecords)).isEqualTo(buildLockKeyExpect);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) Field(io.seata.rm.datasource.sql.struct.Field) TableMeta(io.seata.rm.datasource.sql.struct.TableMeta) Test(org.junit.jupiter.api.Test)

Example 24 with TableRecords

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

the class DeleteExecutorTest method testAfterImage.

@Test
public void testAfterImage() throws SQLException {
    TableRecords tableRecords = deleteExecutor.beforeImage();
    Assertions.assertEquals(0, deleteExecutor.afterImage(tableRecords).size());
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) Test(org.junit.jupiter.api.Test)

Example 25 with TableRecords

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

the class MySQLInsertExecutorTest method testAfterImage_Exception.

@Test
public void testAfterImage_Exception() {
    Assertions.assertThrows(SQLException.class, () -> {
        doReturn(false).when(insertExecutor).containsPK();
        doReturn(true).when(insertExecutor).containsColumns();
        Map<String, List<Object>> pkValuesMap = new HashMap<>();
        pkValuesMap.put("id", Arrays.asList(new Object[] { PK_VALUE }));
        doReturn(pkValuesMap).when(insertExecutor).getPkValuesByAuto();
        doReturn(null).when(insertExecutor).buildTableRecords(pkValuesMap);
        doReturn(tableMeta).when(insertExecutor).getTableMeta();
        when(tableMeta.getPrimaryKeyOnlyName()).thenReturn(Arrays.asList(new String[] { ID_COLUMN }));
        insertExecutor.afterImage(new TableRecords());
    });
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List) Mockito.anyString(org.mockito.Mockito.anyString) Test(org.junit.jupiter.api.Test)

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