use of com.wplatform.ddal.dispatch.rule.RuleColumn in project jdbc-shards by wplatform.
the class TableMate method tryReadMetaData.
private void tryReadMetaData(Connection conn, String tableName) throws SQLException {
DatabaseMetaData meta = conn.getMetaData();
storesLowerCase = meta.storesLowerCaseIdentifiers();
storesMixedCase = meta.storesMixedCaseIdentifiers();
storesMixedCaseQuoted = meta.storesMixedCaseQuotedIdentifiers();
supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers();
ResultSet rs = meta.getTables(null, null, tableName, null);
if (rs.next() && rs.next()) {
throw DbException.get(ErrorCode.SCHEMA_NAME_MUST_MATCH, tableName);
}
rs.close();
rs = meta.getColumns(null, null, tableName, null);
int i = 0;
ArrayList<Column> columnList = New.arrayList();
HashMap<String, Column> columnMap = New.hashMap();
String catalog = null, schema = null;
while (rs.next()) {
String thisCatalog = rs.getString("TABLE_CAT");
if (catalog == null) {
catalog = thisCatalog;
}
String thisSchema = rs.getString("TABLE_SCHEM");
if (schema == null) {
schema = thisSchema;
}
if (!StringUtils.equals(catalog, thisCatalog) || !StringUtils.equals(schema, thisSchema)) {
// if the table exists in multiple schemas or tables,
// use the alternative solution
columnMap.clear();
columnList.clear();
break;
}
String n = rs.getString("COLUMN_NAME");
n = convertColumnName(n);
int sqlType = rs.getInt("DATA_TYPE");
long precision = rs.getInt("COLUMN_SIZE");
precision = convertPrecision(sqlType, precision);
int scale = rs.getInt("DECIMAL_DIGITS");
scale = convertScale(sqlType, scale);
int displaySize = MathUtils.convertLongToInt(precision);
int type = DataType.convertSQLTypeToValueType(sqlType);
Column col = new Column(n, type, precision, scale, displaySize);
col.setTable(this, i++);
columnList.add(col);
columnMap.put(n, col);
}
rs.close();
// check if the table is accessible
Statement stat = null;
try {
stat = conn.createStatement();
rs = stat.executeQuery("SELECT * FROM " + tableName + " T WHERE 1=0");
if (columnList.size() == 0) {
// alternative solution
ResultSetMetaData rsMeta = rs.getMetaData();
for (i = 0; i < rsMeta.getColumnCount(); ) {
String n = rsMeta.getColumnName(i + 1);
n = convertColumnName(n);
int sqlType = rsMeta.getColumnType(i + 1);
long precision = rsMeta.getPrecision(i + 1);
precision = convertPrecision(sqlType, precision);
int scale = rsMeta.getScale(i + 1);
scale = convertScale(sqlType, scale);
int displaySize = rsMeta.getColumnDisplaySize(i + 1);
int type = DataType.getValueTypeFromResultSet(rsMeta, i + 1);
Column col = new Column(n, type, precision, scale, displaySize);
col.setTable(this, i++);
columnList.add(col);
columnMap.put(n, col);
}
}
rs.close();
} catch (Exception e) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, e, tableName + "(" + e.toString() + ")");
} finally {
JdbcUtils.closeSilently(stat);
}
Column[] cols = new Column[columnList.size()];
columnList.toArray(cols);
validationRuleColumn(cols);
setColumns(cols);
// create scan index
int id = getId();
scanIndex = new IndexMate(this, id, null, IndexColumn.wrap(cols), IndexType.createNonUnique());
indexes.add(scanIndex);
// create shardingKey index
if (tableRouter != null) {
ArrayList<Column> shardCol = New.arrayList();
for (RuleColumn ruleCol : tableRouter.getRuleColumns()) {
for (Column column : columns) {
String colName = column.getName();
if (colName.equalsIgnoreCase(ruleCol.getName())) {
shardCol.add(column);
}
}
}
addIndex(shardCol, IndexType.createShardingKey(false));
}
// load primary keys
try {
rs = meta.getPrimaryKeys(null, null, tableName);
} catch (Exception e) {
// Some ODBC bridge drivers don't support it:
// some combinations of "DataDirect SequeLink(R) for JDBC"
// http://www.datadirect.com/index.ssp
rs = null;
}
String pkName = "";
ArrayList<Column> list;
if (rs != null && rs.next()) {
// the problem is, the rows are not sorted by KEY_SEQ
list = New.arrayList();
do {
int idx = rs.getInt("KEY_SEQ");
if (pkName == null) {
pkName = rs.getString("PK_NAME");
}
while (list.size() < idx) {
list.add(null);
}
String col = rs.getString("COLUMN_NAME");
col = convertColumnName(col);
Column column = columnMap.get(col);
if (idx == 0) {
// workaround for a bug in the SQLite JDBC driver
list.add(column);
} else {
list.set(idx - 1, column);
}
} while (rs.next());
addIndex(list, IndexType.createPrimaryKey(false));
rs.close();
}
try {
rs = meta.getIndexInfo(null, null, tableName, false, true);
} catch (Exception e) {
// Oracle throws an exception if the table is not found or is a
// SYNONYM
rs = null;
}
String indexName = null;
list = New.arrayList();
IndexType indexType = null;
if (rs != null) {
while (rs.next()) {
if (rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic) {
// ignore index statistics
continue;
}
String newIndex = rs.getString("INDEX_NAME");
if (pkName.equals(newIndex)) {
continue;
}
if (indexName != null && !indexName.equals(newIndex)) {
addIndex(list, indexType);
indexName = null;
}
if (indexName == null) {
indexName = newIndex;
list.clear();
}
boolean unique = !rs.getBoolean("NON_UNIQUE");
indexType = unique ? IndexType.createUnique(false) : IndexType.createNonUnique();
String col = rs.getString("COLUMN_NAME");
col = convertColumnName(col);
Column column = columnMap.get(col);
list.add(column);
}
rs.close();
}
if (indexName != null) {
addIndex(list, indexType);
}
}
use of com.wplatform.ddal.dispatch.rule.RuleColumn in project jdbc-shards by wplatform.
the class XmlRuleConfigParser method parseRuleExpression.
// 解析<rule>标签的内容
public RuleExpression parseRuleExpression(XNode xNode) {
String stringBody = getStringBody(xNode);
String text = stringBody.replaceAll("\\s", " ");
final List<RuleColumn> ruleColumns = new ArrayList<RuleColumn>();
GenericTokenParser parser = new GenericTokenParser("${", "}", new TokenHandler() {
@Override
public String handleToken(String content) {
content = content.replaceAll("\\s", "");
String name = null;
String required = null;
String type = null;
if (content.contains(",")) {
String[] properties = content.split(",");
name = properties[0];
for (int j = 1; j < properties.length; j++) {
String propety = properties[j];
if (propety.contains("required=")) {
required = propety.split("required=")[1];
}
if (propety.contains("type=")) {
type = propety.split("type=")[1];
}
}
} else {
name = content;
}
ruleColumns.add(newRuleColumn(name, required, type));
return name;
}
});
String expression = parser.parse(text);
RuleExpression rule = new RuleExpression(null);
rule.setExpression(expression);
rule.setRuleColumns(ruleColumns);
return rule;
}
Aggregations