Search in sources :

Example 1 with IndexType

use of com.wplatform.ddal.dbobject.index.IndexType 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);
    }
}
Also used : Statement(java.sql.Statement) DatabaseMetaData(java.sql.DatabaseMetaData) SQLException(java.sql.SQLException) DbException(com.wplatform.ddal.message.DbException) ResultSetMetaData(java.sql.ResultSetMetaData) RuleColumn(com.wplatform.ddal.dispatch.rule.RuleColumn) RuleColumn(com.wplatform.ddal.dispatch.rule.RuleColumn) ResultSet(java.sql.ResultSet) IndexMate(com.wplatform.ddal.dbobject.index.IndexMate) IndexType(com.wplatform.ddal.dbobject.index.IndexType)

Aggregations

IndexMate (com.wplatform.ddal.dbobject.index.IndexMate)1 IndexType (com.wplatform.ddal.dbobject.index.IndexType)1 RuleColumn (com.wplatform.ddal.dispatch.rule.RuleColumn)1 DbException (com.wplatform.ddal.message.DbException)1 DatabaseMetaData (java.sql.DatabaseMetaData)1 ResultSet (java.sql.ResultSet)1 ResultSetMetaData (java.sql.ResultSetMetaData)1 SQLException (java.sql.SQLException)1 Statement (java.sql.Statement)1