use of io.seata.rm.datasource.sql.struct.ColumnMeta in project seata by seata.
the class MysqlTableMetaCache method resultSetMetaToSchema.
private TableMeta resultSetMetaToSchema(ResultSetMetaData rsmd, DatabaseMetaData dbmd) throws SQLException {
// always "" for mysql
String schemaName = rsmd.getSchemaName(1);
String catalogName = rsmd.getCatalogName(1);
/*
* 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
*/
String tableName = rsmd.getTableName(1);
TableMeta tm = new TableMeta();
tm.setTableName(tableName);
try (ResultSet rsColumns = dbmd.getColumns(catalogName, schemaName, tableName, "%");
ResultSet rsIndex = dbmd.getIndexInfo(catalogName, schemaName, tableName, false, true)) {
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.getInt("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");
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 ("PRIMARY".equalsIgnoreCase(indexName)) {
index.setIndextype(IndexType.PRIMARY);
} else if (!index.isNonUnique()) {
index.setIndextype(IndexType.UNIQUE);
} else {
index.setIndextype(IndexType.NORMAL);
}
tm.getAllIndexes().put(indexName, index);
}
}
if (tm.getAllIndexes().isEmpty()) {
throw new ShouldNeverHappenException("Could not found any index in the table: " + tableName);
}
}
return tm;
}
use of io.seata.rm.datasource.sql.struct.ColumnMeta in project seata by seata.
the class MySQLInsertExecutor method getPkValuesByAuto.
/**
* the modify for test
*/
public Map<String, List<Object>> getPkValuesByAuto() throws SQLException {
// PK is just auto generated
Map<String, List<Object>> pkValuesMap = new HashMap<>(8);
Map<String, ColumnMeta> pkMetaMap = getTableMeta().getPrimaryKeyMap();
String autoColumnName = null;
for (Map.Entry<String, ColumnMeta> entry : pkMetaMap.entrySet()) {
if (entry.getValue().isAutoincrement()) {
autoColumnName = entry.getKey();
break;
}
}
if (StringUtils.isBlank(autoColumnName)) {
throw new ShouldNeverHappenException();
}
ResultSet genKeys;
try {
genKeys = statementProxy.getGeneratedKeys();
} catch (SQLException e) {
// Statement.executeUpdate() or Connection.prepareStatement().
if (ERR_SQL_STATE.equalsIgnoreCase(e.getSQLState())) {
LOGGER.error("Fail to get auto-generated keys, use 'SELECT LAST_INSERT_ID()' instead. Be cautious, " + "statement could be polluted. Recommend you set the statement to return generated keys.");
int updateCount = statementProxy.getUpdateCount();
ResultSet firstId = genKeys = statementProxy.getTargetStatement().executeQuery("SELECT LAST_INSERT_ID()");
// do auto increment base LAST_INSERT_ID and variable `auto_increment_increment`
if (updateCount > 1 && canAutoIncrement(pkMetaMap)) {
firstId.next();
return autoGeneratePks(new BigDecimal(firstId.getString(1)), autoColumnName, updateCount);
}
} else {
throw e;
}
}
List<Object> pkValues = new ArrayList<>();
while (genKeys.next()) {
Object v = genKeys.getObject(1);
pkValues.add(v);
}
try {
genKeys.beforeFirst();
} catch (SQLException e) {
LOGGER.warn("Fail to reset ResultSet cursor. can not get primary key value");
}
pkValuesMap.put(autoColumnName, pkValues);
return pkValuesMap;
}
use of io.seata.rm.datasource.sql.struct.ColumnMeta in project seata by seata.
the class PostgresqlInsertExecutor method getPkValuesByDefault.
/**
* get primary key values by default
* @return
* @throws SQLException
*/
@Override
public List<Object> getPkValuesByDefault() throws SQLException {
// current version 1.2 only support postgresql.
Map<String, ColumnMeta> pkMetaMap = getTableMeta().getPrimaryKeyMap();
ColumnMeta pkMeta = pkMetaMap.values().iterator().next();
String columnDef = pkMeta.getColumnDef();
// sample: nextval('test_id_seq'::regclass)
String seq = org.apache.commons.lang.StringUtils.substringBetween(columnDef, "'", "'");
String function = org.apache.commons.lang.StringUtils.substringBetween(columnDef, "", "(");
if (StringUtils.isBlank(seq)) {
throw new ShouldNeverHappenException("get primary key value failed, cause columnDef is " + columnDef);
}
return getPkValuesBySequence(new SqlSequenceExpr("'" + seq + "'", function));
}
Aggregations