Skip to content

Commit

Permalink
# IGNITE-32: WIP on Oracle metadata dialect.
Browse files Browse the repository at this point in the history
  • Loading branch information
akuznetsov-gridgain committed Feb 3, 2015
1 parent ed2af98 commit 4ac7ab9
Showing 1 changed file with 76 additions and 14 deletions.
Expand Up @@ -29,12 +29,18 @@
*/ */
public class OracleMetadataDialect extends DatabaseMetadataDialect { public class OracleMetadataDialect extends DatabaseMetadataDialect {
/** SQL to get columns metadata. */ /** SQL to get columns metadata. */
private static final String SQL_COLUMNS = "SELECT a.owner, a.table_name, a.column_name, a.nullable, a.data_type" + private static final String SQL_COLUMNS = "SELECT a.owner, a.table_name, a.column_name, a.nullable," +
" FROM all_tab_columns a" + " a.data_type, a.data_precision, a.data_scale " +
" %s" + "FROM all_tab_columns a %s" +
" WHERE a.owner = '%s'" + " WHERE a.owner = '%s'" +
" ORDER BY a.owner, a.table_name, a.column_id"; " ORDER BY a.owner, a.table_name, a.column_id";


/** SQL to get list of PRIMARY KEYS columns. */
private static final String SQL_PRIMARY_KEYS = "SELECT b.column_name" +
" FROM all_constraints a" +
" INNER JOIN all_cons_columns b ON a.owner = b.owner AND a.constraint_name = b.constraint_name" +
" WHERE a.table_name = ? AND a.constraint_type = 'P'";

/** Owner index. */ /** Owner index. */
private static final int OWNER_IDX = 1; private static final int OWNER_IDX = 1;


Expand All @@ -50,12 +56,19 @@ public class OracleMetadataDialect extends DatabaseMetadataDialect {
/** Data type index. */ /** Data type index. */
private static final int DATA_TYPE_IDX = 5; private static final int DATA_TYPE_IDX = 5;


/** Numeric precision index. */
private static final int DATA_PRECISION_IDX = 6;

/** Numeric scale index. */
private static final int DATA_SCALE_IDX = 7;

/** /**
* @param type Column type from Oracle database. * @param rs Result set with column type metadata from Oracle database.
* @return JDBC type. * @return JDBC type.
* @throws SQLException If failed to decode type.
*/ */
private static int decodeType(String type) { private static int decodeType(ResultSet rs) throws SQLException {
switch (type) { switch (rs.getString(DATA_TYPE_IDX)) {
case "CHAR": case "CHAR":
case "NCHAR": case "NCHAR":
return CHAR; return CHAR;
Expand All @@ -74,7 +87,39 @@ private static int decodeType(String type) {
return FLOAT; return FLOAT;


case "NUMBER": case "NUMBER":
return NUMERIC; int precision = rs.getInt(DATA_PRECISION_IDX);
int scale = rs.getInt(DATA_SCALE_IDX);

if (scale > 0) {
if (scale < 4 && precision < 19)
return FLOAT;

if (scale > 4 || precision > 19)
return DOUBLE;

return NUMERIC;
}
else {
if (precision < 1)
return INTEGER;

if (precision < 2)
return BOOLEAN;

if (precision < 4)
return TINYINT;

if (precision < 6)
return SMALLINT;

if (precision < 11)
return INTEGER;

if (precision < 20)
return BIGINT;

return NUMERIC;
}


case "DATE": case "DATE":
return DATE; return DATE;
Expand Down Expand Up @@ -107,20 +152,37 @@ private static boolean decodeNullable(String nullable) {
@Override public Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException { @Override public Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException {
Collection<DbTable> tbls = new ArrayList<>(); Collection<DbTable> tbls = new ArrayList<>();


try (Statement stmt = conn.createStatement()) { PreparedStatement pkStmt = conn.prepareStatement(SQL_PRIMARY_KEYS);

try (Statement colsStmt = conn.createStatement()) {
Collection<DbColumn> cols = new ArrayList<>(); Collection<DbColumn> cols = new ArrayList<>();


Set<String> pkCols = new HashSet<>();

String owner = conn.getMetaData().getUserName().toUpperCase();

String sql = String.format(SQL_COLUMNS, String sql = String.format(SQL_COLUMNS,
tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name" : "", "TEST"); tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name" : "", owner);


try (ResultSet colsRs = stmt.executeQuery(sql)) { try (ResultSet colsRs = colsStmt.executeQuery(sql)) {
String prevSchema = ""; String prevSchema = "";
String prevTbl = ""; String prevTbl = "";


while (colsRs.next()) { while (colsRs.next()) {
String schema = colsRs.getString(OWNER_IDX); String schema = colsRs.getString(OWNER_IDX);
String tbl = colsRs.getString(TABLE_NAME_IDX); String tbl = colsRs.getString(TABLE_NAME_IDX);


if (!prevSchema.equals(schema) || !prevTbl.equals(tbl)) {
pkCols.clear();

pkStmt.setString(1, tbl);

try (ResultSet pkRs = pkStmt.executeQuery()) {
while(pkRs.next())
pkCols.add(pkRs.getString(1));
}
}

if (prevSchema.isEmpty()) { if (prevSchema.isEmpty()) {
prevSchema = schema; prevSchema = schema;
prevTbl = tbl; prevTbl = tbl;
Expand All @@ -135,10 +197,10 @@ private static boolean decodeNullable(String nullable) {
cols = new ArrayList<>(); cols = new ArrayList<>();
} }


cols.add(new DbColumn(colsRs.getString(COLUMN_NAME_IDX), String colName = colsRs.getString(COLUMN_NAME_IDX);
decodeType(colsRs.getString(DATA_TYPE_IDX)),
false, cols.add(new DbColumn(colName, decodeType(colsRs), pkCols.contains(colName),
decodeNullable(colsRs.getString(NULLABLE_IDX)))); !"N".equals(colsRs.getString(NULLABLE_IDX))));
} }


if (!cols.isEmpty()) if (!cols.isEmpty())
Expand Down

0 comments on commit 4ac7ab9

Please sign in to comment.