示例#1
0
 /** @param session */
 public void readMataData(Session session, ObjectNode matadataNode) {
   for (int retry = 0; ; retry++) {
     try {
       Connection conn = null;
       String shardName = matadataNode.getShardName();
       String tableName = matadataNode.getQualifiedObjectName();
       String catalog = matadataNode.getCatalog();
       String schema = matadataNode.getSchema();
       try {
         JdbcRepository dsRepository = (JdbcRepository) database.getRepository();
         DataSource dataSource = dsRepository.getDataSourceByShardName(shardName);
         conn = dataSource.getConnection();
         tableName = database.identifier(tableName);
         if (catalog != null) {
           catalog = database.identifier(catalog);
         }
         if (schema != null) {
           schema = database.identifier(schema);
         }
         tryReadMetaData(conn, catalog, schema, tableName);
         return;
       } catch (Exception e) {
         throw DbException.convert(e);
       } finally {
         JdbcUtils.closeSilently(conn);
       }
     } catch (DbException e) {
       if (retry >= MAX_RETRY) {
         throw e;
       }
     }
   }
 }
示例#2
0
  private void tryReadMetaData(Connection conn, String oCatalog, String oSchema, String tableName)
      throws SQLException {

    DatabaseMetaData meta = conn.getMetaData();
    storesLowerCase = meta.storesLowerCaseIdentifiers();
    storesMixedCase = meta.storesMixedCaseIdentifiers();
    storesMixedCaseQuoted = meta.storesMixedCaseQuotedIdentifiers();
    supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers();

    ResultSet rs = meta.getTables(oCatalog, oSchema, 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);
    setColumns(cols);
    // create scan index

    // 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(pkName, 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(indexName, 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(indexName, list, indexType);
    }
    shardingKeyIndex();
  }