Search in sources :

Example 1 with ColumnMeta

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

the class PostgresqlInsertExecutorTest method testInsertDefault_ByDefault.

@Test
public void testInsertDefault_ByDefault() throws Exception {
    mockInsertColumns();
    mockInsertRows();
    mockParametersPkWithDefault();
    Map<String, ColumnMeta> pkMap = new HashMap<>();
    ColumnMeta columnMeta = mock(ColumnMeta.class);
    doReturn("nextval('test_id_seq'::regclass)").when(columnMeta).getColumnDef();
    pkMap.put(ID_COLUMN, columnMeta);
    doReturn(pkMap).when(tableMeta).getPrimaryKeyMap();
    doReturn(tableMeta).when(insertExecutor).getTableMeta();
    List<Object> pkValuesAuto = new ArrayList<>();
    pkValuesAuto.add(PK_VALUE);
    // mock getPkValuesByAuto
    doReturn(pkValuesAuto).when(insertExecutor).getGeneratedKeys();
    Map<String, List<Object>> pkValuesMap = insertExecutor.getPkValuesByColumn();
    // pk value = DEFAULT so getPkValuesByDefault
    doReturn(new ArrayList<>()).when(insertExecutor).getPkValuesByDefault();
    verify(insertExecutor).getPkValuesByDefault();
    Assertions.assertEquals(pkValuesMap.get(ID_COLUMN), pkValuesAuto);
}
Also used : ColumnMeta(io.seata.rm.datasource.sql.struct.ColumnMeta) Test(org.junit.jupiter.api.Test)

Example 2 with ColumnMeta

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

the class BaseInsertExecutor method getPkIndex.

/**
 * get pk index
 * @return the key is pk column name and the value is index of the pk column
 */
protected Map<String, Integer> getPkIndex() {
    Map<String, Integer> pkIndexMap = new HashMap<>();
    SQLInsertRecognizer recognizer = (SQLInsertRecognizer) sqlRecognizer;
    List<String> insertColumns = recognizer.getInsertColumns();
    if (CollectionUtils.isNotEmpty(insertColumns)) {
        final int insertColumnsSize = insertColumns.size();
        for (int paramIdx = 0; paramIdx < insertColumnsSize; paramIdx++) {
            String sqlColumnName = insertColumns.get(paramIdx);
            if (containPK(sqlColumnName)) {
                pkIndexMap.put(getStandardPkColumnName(sqlColumnName), paramIdx);
            }
        }
        return pkIndexMap;
    }
    int pkIndex = -1;
    Map<String, ColumnMeta> allColumns = getTableMeta().getAllColumns();
    for (Map.Entry<String, ColumnMeta> entry : allColumns.entrySet()) {
        pkIndex++;
        if (containPK(entry.getValue().getColumnName())) {
            pkIndexMap.put(ColumnUtils.delEscape(entry.getValue().getColumnName(), getDbType()), pkIndex);
        }
    }
    return pkIndexMap;
}
Also used : ColumnMeta(io.seata.rm.datasource.sql.struct.ColumnMeta) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map) SQLInsertRecognizer(io.seata.sqlparser.SQLInsertRecognizer)

Example 3 with ColumnMeta

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

the class PostgresqlTableMetaCache method resultSetMetaToSchema.

private TableMeta resultSetMetaToSchema(DatabaseMetaData dbmd, String tableName) throws SQLException {
    TableMeta tm = new TableMeta();
    tm.setTableName(tableName);
    String[] schemaTable = tableName.split("\\.");
    String schemaName = schemaTable.length > 1 ? schemaTable[0] : null;
    tableName = schemaTable.length > 1 ? schemaTable[1] : tableName;
    /*
         * use ResultSetMetaData to get the pure table name
         * can avoid the problem below
         *
         * select * from account_tbl
         * select * from account_TBL
         * select * from account_tbl
         * select * from account.account_tbl
         * select * from "select"
         * select * from "Select"
         * select * from "Sel""ect"
         * select * from "Sel'ect"
         * select * from TEST.test
         * select * from test.TEST
         * select * from "Test".test
         * select * from "Test"."Select"
         */
    if (schemaName != null) {
        if (schemaName.startsWith("\"") && schemaName.endsWith("\"")) {
            schemaName = schemaName.replaceAll("(^\")|(\"$)", "");
        } else {
            schemaName = schemaName.toLowerCase();
        }
    }
    if (tableName.startsWith("\"") && tableName.endsWith("\"")) {
        tableName = tableName.replaceAll("(^\")|(\"$)", "");
    } else {
        tableName = tableName.toLowerCase();
    }
    try (ResultSet rsColumns = dbmd.getColumns(null, schemaName, tableName, "%");
        ResultSet rsIndex = dbmd.getIndexInfo(null, schemaName, tableName, false, true);
        ResultSet rsPrimary = dbmd.getPrimaryKeys(null, schemaName, tableName)) {
        while (rsColumns.next()) {
            ColumnMeta col = new ColumnMeta();
            col.setTableCat(rsColumns.getString("TABLE_CAT"));
            col.setTableSchemaName(rsColumns.getString("TABLE_SCHEM"));
            col.setTableName(rsColumns.getString("TABLE_NAME"));
            col.setColumnName(rsColumns.getString("COLUMN_NAME"));
            col.setDataType(rsColumns.getInt("DATA_TYPE"));
            col.setDataTypeName(rsColumns.getString("TYPE_NAME"));
            col.setColumnSize(rsColumns.getInt("COLUMN_SIZE"));
            col.setDecimalDigits(rsColumns.getInt("DECIMAL_DIGITS"));
            col.setNumPrecRadix(rsColumns.getInt("NUM_PREC_RADIX"));
            col.setNullAble(rsColumns.getInt("NULLABLE"));
            col.setRemarks(rsColumns.getString("REMARKS"));
            col.setColumnDef(rsColumns.getString("COLUMN_DEF"));
            col.setSqlDataType(rsColumns.getInt("SQL_DATA_TYPE"));
            col.setSqlDatetimeSub(rsColumns.getInt("SQL_DATETIME_SUB"));
            col.setCharOctetLength(rsColumns.getObject("CHAR_OCTET_LENGTH"));
            col.setOrdinalPosition(rsColumns.getInt("ORDINAL_POSITION"));
            col.setIsNullAble(rsColumns.getString("IS_NULLABLE"));
            col.setIsAutoincrement(rsColumns.getString("IS_AUTOINCREMENT"));
            tm.getAllColumns().put(col.getColumnName(), col);
        }
        while (rsIndex.next()) {
            String indexName = rsIndex.getString("index_name");
            if (StringUtils.isNullOrEmpty(indexName)) {
                continue;
            }
            String colName = rsIndex.getString("column_name");
            ColumnMeta col = tm.getAllColumns().get(colName);
            if (tm.getAllIndexes().containsKey(indexName)) {
                IndexMeta index = tm.getAllIndexes().get(indexName);
                index.getValues().add(col);
            } else {
                IndexMeta index = new IndexMeta();
                index.setIndexName(indexName);
                index.setNonUnique(rsIndex.getBoolean("non_unique"));
                index.setIndexQualifier(rsIndex.getString("index_qualifier"));
                index.setIndexName(rsIndex.getString("index_name"));
                index.setType(rsIndex.getShort("type"));
                index.setOrdinalPosition(rsIndex.getShort("ordinal_position"));
                index.setAscOrDesc(rsIndex.getString("asc_or_desc"));
                index.setCardinality(rsIndex.getInt("cardinality"));
                index.getValues().add(col);
                if (!index.isNonUnique()) {
                    index.setIndextype(IndexType.UNIQUE);
                } else {
                    index.setIndextype(IndexType.NORMAL);
                }
                tm.getAllIndexes().put(indexName, index);
            }
        }
        while (rsPrimary.next()) {
            String pkIndexName = rsPrimary.getString("pk_name");
            if (tm.getAllIndexes().containsKey(pkIndexName)) {
                IndexMeta index = tm.getAllIndexes().get(pkIndexName);
                index.setIndextype(IndexType.PRIMARY);
            }
        }
        if (tm.getAllIndexes().isEmpty()) {
            throw new ShouldNeverHappenException("Could not found any index in the table: " + tableName);
        }
    }
    return tm;
}
Also used : ColumnMeta(io.seata.rm.datasource.sql.struct.ColumnMeta) ResultSet(java.sql.ResultSet) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) IndexMeta(io.seata.rm.datasource.sql.struct.IndexMeta) TableMeta(io.seata.rm.datasource.sql.struct.TableMeta)

Example 4 with ColumnMeta

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

the class MySQLInsertExecutor method getPkValues.

@Override
public Map<String, List<Object>> getPkValues() throws SQLException {
    Map<String, List<Object>> pkValuesMap = null;
    List<String> pkColumnNameList = getTableMeta().getPrimaryKeyOnlyName();
    Boolean isContainsPk = containsPK();
    // when there is only one pk in the table
    if (getTableMeta().getPrimaryKeyOnlyName().size() == 1) {
        if (isContainsPk) {
            pkValuesMap = getPkValuesByColumn();
        } else if (containsColumns()) {
            pkValuesMap = getPkValuesByAuto();
        } else {
            pkValuesMap = getPkValuesByColumn();
        }
    } else {
        // when there is multiple pk in the table
        // 1,all pk columns are filled value.
        // 2,the auto increment pk column value is null, and other pk value are not null.
        pkValuesMap = getPkValuesByColumn();
        for (String columnName : pkColumnNameList) {
            if (!pkValuesMap.containsKey(columnName)) {
                ColumnMeta pkColumnMeta = getTableMeta().getColumnMeta(columnName);
                if (Objects.nonNull(pkColumnMeta) && pkColumnMeta.isAutoincrement()) {
                    // 3,the auto increment pk column is not exits in sql, and other pk are exits also the value is not null.
                    pkValuesMap.putAll(getPkValuesByAuto());
                }
            }
        }
    }
    return pkValuesMap;
}
Also used : ColumnMeta(io.seata.rm.datasource.sql.struct.ColumnMeta) ArrayList(java.util.ArrayList) List(java.util.List)

Example 5 with ColumnMeta

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

the class OracleInsertExecutorTest method testStatement_pkValueByAuto_NotSupportYetException.

@Test
public void testStatement_pkValueByAuto_NotSupportYetException() throws Exception {
    mockInsertColumns();
    mockStatementInsertRows();
    statementProxy = mock(StatementProxy.class);
    when(statementProxy.getConnectionProxy()).thenReturn(connectionProxy);
    when(connectionProxy.getDbType()).thenReturn(JdbcConstants.ORACLE);
    insertExecutor = Mockito.spy(new OracleInsertExecutor(statementProxy, statementCallback, sqlInsertRecognizer));
    doReturn(tableMeta).when(insertExecutor).getTableMeta();
    Map<String, ColumnMeta> map = new HashMap<>();
    map.put(ID_COLUMN, mock(ColumnMeta.class));
    doReturn(map).when(tableMeta).getPrimaryKeyMap();
    ResultSet rs = mock(ResultSet.class);
    doReturn(rs).when(statementProxy).getGeneratedKeys();
    doReturn(false).when(rs).next();
    Assertions.assertThrows(NotSupportYetException.class, () -> {
        insertExecutor.getGeneratedKeys();
    });
    doReturn(pkIndexMap).when(insertExecutor).getPkIndex();
    Assertions.assertThrows(NotSupportYetException.class, () -> {
        insertExecutor.getPkValuesByColumn();
    });
}
Also used : ColumnMeta(io.seata.rm.datasource.sql.struct.ColumnMeta) HashMap(java.util.HashMap) OracleInsertExecutor(io.seata.rm.datasource.exec.oracle.OracleInsertExecutor) StatementProxy(io.seata.rm.datasource.StatementProxy) PreparedStatementProxy(io.seata.rm.datasource.PreparedStatementProxy) ResultSet(java.sql.ResultSet) Test(org.junit.jupiter.api.Test)

Aggregations

ColumnMeta (io.seata.rm.datasource.sql.struct.ColumnMeta)18 ResultSet (java.sql.ResultSet)10 HashMap (java.util.HashMap)9 Test (org.junit.jupiter.api.Test)9 ArrayList (java.util.ArrayList)7 List (java.util.List)7 Mockito.anyString (org.mockito.Mockito.anyString)7 ShouldNeverHappenException (io.seata.common.exception.ShouldNeverHappenException)5 MockResultSet (io.seata.rm.datasource.mock.MockResultSet)5 PreparedStatement (java.sql.PreparedStatement)5 TableMeta (io.seata.rm.datasource.sql.struct.TableMeta)4 SQLException (java.sql.SQLException)4 IndexMeta (io.seata.rm.datasource.sql.struct.IndexMeta)3 Map (java.util.Map)2 PreparedStatementProxy (io.seata.rm.datasource.PreparedStatementProxy)1 StatementProxy (io.seata.rm.datasource.StatementProxy)1 OracleInsertExecutor (io.seata.rm.datasource.exec.oracle.OracleInsertExecutor)1 SQLInsertRecognizer (io.seata.sqlparser.SQLInsertRecognizer)1 SqlSequenceExpr (io.seata.sqlparser.struct.SqlSequenceExpr)1 BigDecimal (java.math.BigDecimal)1