/*
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// You must accept the terms of that agreement to use this software.
//
// Copyright (C) 2006-2011 Pentaho and others
// Copyright (C) 2006-2007 Cincom Systems, Inc.
// Copyright (C) 2006-2007 JasperSoft
// All Rights Reserved.
*/
package mondrian.gui;
import org.apache.log4j.Logger;
import java.sql.*;
import java.util.*;
/**
*/
public class JdbcMetaData {
private static final Logger LOGGER = Logger.getLogger(JdbcMetaData.class);
// E.g. "org.postgresql.Driver"
String jdbcDriverClassName = null;
// E.g. "jdbc:postgresql://localhost:5432/hello?user=postgres&password=post"
String jdbcUsername = null;
String jdbcConnectionUrl = null;
String jdbcPassword = null;
String jdbcSchema = null;
boolean requireSchema = false;
Connection conn = null;
DatabaseMetaData md = null;
Workbench workbench;
public static final String LEVEL_SEPARATOR = "->";
private String errMsg = null;
private Database db = new Database();
public JdbcMetaData(
Workbench wb,
String jdbcDriverClassName,
String jdbcConnectionUrl,
String jdbcUsername,
String jdbcPassword,
String jdbcSchema,
boolean requireSchema)
{
this.workbench = wb;
this.jdbcConnectionUrl = jdbcConnectionUrl;
this.jdbcDriverClassName = jdbcDriverClassName;
this.jdbcUsername = jdbcUsername;
this.jdbcPassword = jdbcPassword;
this.jdbcSchema = jdbcSchema;
this.requireSchema = requireSchema;
if (initConnection() == null) {
setAllSchemas();
closeConnection();
}
}
public boolean getRequireSchema() {
return requireSchema;
}
/**
* @return the workbench i18n converter
*/
public I18n getResourceConverter() {
return workbench.getResourceConverter();
}
/**
* Tests database connection. Called from Preferences dialog button test
* connection.
*/
public JdbcMetaData(
String jdbcDriverClassName,
String jdbcConnectionUrl,
String jdbcUsername,
String jdbcPassword)
{
this.jdbcConnectionUrl = jdbcConnectionUrl;
this.jdbcDriverClassName = jdbcDriverClassName;
this.jdbcUsername = jdbcUsername;
this.jdbcPassword = jdbcPassword;
if (initConnection() == null) {
closeConnection();
}
}
/* Creates a database connection and initializes the meta data details */
public String initConnection() {
LOGGER.debug("JdbcMetaData: initConnection");
try {
if (jdbcDriverClassName == null
|| jdbcDriverClassName.trim().length() == 0
|| jdbcConnectionUrl == null
|| jdbcConnectionUrl.trim().length() == 0)
{
errMsg = getResourceConverter().getFormattedString(
"jdbcMetaData.blank.exception",
"Driver={0}\nConnection URL={1}\nUse Preferences to set Database Connection parameters first and then open a Schema",
jdbcDriverClassName,
jdbcConnectionUrl);
return errMsg;
}
Class.forName(jdbcDriverClassName);
if (jdbcUsername != null && jdbcUsername.length() > 0) {
conn = DriverManager.getConnection(
jdbcConnectionUrl, jdbcUsername, jdbcPassword);
} else {
conn = DriverManager.getConnection(jdbcConnectionUrl);
}
LOGGER.debug("JDBC connection OPEN");
md = conn.getMetaData();
db.productName = md.getDatabaseProductName();
db.productVersion = md.getDatabaseProductVersion();
db.catalogName = conn.getCatalog();
LOGGER.debug("Catalog name = " + db.catalogName);
LOGGER.debug("Database Product Name: " + db.productName);
LOGGER.debug("Database Product Version: " + db.productVersion);
LOGGER.debug("JdbcMetaData: initConnection - no error");
return null;
} catch (Exception e) {
errMsg =
e.getClass().getSimpleName() + " : " + e.getLocalizedMessage();
LOGGER.error("Database connection exception : " + errMsg, e);
return errMsg;
//e.printStackTrace();
}
}
public void closeConnection() {
if (conn == null) {
return;
}
md = null;
try {
conn.close();
LOGGER.debug("JDBC connection CLOSE");
} catch (Exception e) {
LOGGER.error(e);
}
conn = null;
}
/**
* Check to see if the schemaName is in the list of allowed jdbc schemas
*
* @param schemaName the name of the schmea
* @return true if found, or if jdbcSchema is null
*/
private boolean inJdbcSchemas(String schemaName) {
if (jdbcSchema == null || jdbcSchema.trim().length() == 0) {
return true;
}
String schemas[] = jdbcSchema.split("[,;]");
for (String schema : schemas) {
if (schema.trim().equalsIgnoreCase(schemaName)) {
return true;
}
}
return false;
}
/* list all schemas in the currently connected database */
public List<String> listAllSchemas() {
LOGGER.debug("JdbcMetaData: listAllSchemas");
if (initConnection() != null) {
return null;
}
List<String> schemaNames = new ArrayList<String>();
ResultSet rs = null;
try {
rs = md.getSchemas();
while (rs.next()) {
String schemaName = rs.getString("TABLE_SCHEM");
schemaNames.add(schemaName);
}
} catch (Exception e) {
LOGGER.debug(
"Exception : Database does not support schemas." + e
.getMessage());
return null;
} finally {
try {
rs.close();
closeConnection();
} catch (Exception e) {
// ignore
}
}
return schemaNames;
}
/* set all schemas in the currently connected database */
private void setAllSchemas() {
LOGGER.debug("JdbcMetaData: setAllSchemas");
ResultSet rs = null;
boolean gotSchema = false;
try {
rs = md.getSchemas();
while (rs.next()) {
String schemaName = rs.getString("TABLE_SCHEM");
if (inJdbcSchemas(schemaName)) {
DbSchema dbs = new DbSchema();
dbs.name = schemaName;
LOGGER.debug("JdbcMetaData: setAllTables - " + dbs.name);
setAllTables(dbs);
db.addDbSchema(dbs);
gotSchema = true;
}
}
} catch (Exception e) {
LOGGER.debug(
"Exception : Database does not support schemas." + e
.getMessage());
} finally {
try {
rs.close();
} catch (Exception e) {
// ignore
}
}
if (!gotSchema) {
LOGGER.debug(
"JdbcMetaData: setAllSchemas - tables with no schema name");
DbSchema dbs = new DbSchema();
dbs.name = null; //tables with no schema name
setAllTables(dbs);
db.addDbSchema(dbs);
}
}
/* set all tables in the currently connected database */
private void setAllTables(DbSchema dbs) {
LOGGER.debug("JdbcMetaData: Loading schema: '" + dbs.name + "'");
ResultSet rs = null;
try {
// Tables and views can be used
try {
rs = md.getTables(
null, dbs.name, null, new String[]{"TABLE", "VIEW"});
} catch (Exception e) {
// this is a workaround for databases that throw an exception
// when views are requested.
rs = md.getTables(null, dbs.name, null, new String[]{"TABLE"});
}
while (rs.next()) {
// Oracle 10g Driver returns bogus BIN$ tables that cause
// exceptions
String tbname = rs.getString("TABLE_NAME");
if (!tbname.matches("(?!BIN\\$).+")) {
continue;
}
DbTable dbt = null;
/* Note: Imported keys are foreign keys which are primary keys
* of in some other tables; Exported keys are primary keys which
* are referenced as foreign keys in other tables.
*/
try {
ResultSet rs_fks = md.getImportedKeys(null, dbs.name, tbname);
try {
if (rs_fks.next()) {
dbt = new FactTable();
do {
((FactTable) dbt).addFks(
rs_fks.getString("FKCOLUMN_NAME"),
rs_fks.getString("pktable_name"));
} while (rs_fks.next());
} else {
dbt = new DbTable();
}
} finally {
try {
rs_fks.close();
} catch (Exception e) {
// ignore
}
}
} catch (Exception e) {
// this fails in some cases (Redshift)
LOGGER.warn("unable to process foreign keys", e);
if (dbt == null) {
dbt = new FactTable();
}
}
dbt.schemaName = dbs.name;
dbt.name = tbname;
setPKey(dbt);
// Lazy loading
// setColumns(dbt);
dbs.addDbTable(dbt);
db.addDbTable(dbt);
}
} catch (Exception e) {
LOGGER.error("setAllTables", e);
} finally {
try {
rs.close();
} catch (Exception e) {
// ignore
}
}
}
/**
* Gets the Primary key name for a given table name.
* This key may be a composite key made of multiple columns.
*/
private void setPKey(DbTable dbt) {
ResultSet rs = null;
try {
rs = md.getPrimaryKeys(null, dbt.schemaName, dbt.name);
if (rs.next()) {
// // a column may have been given a primary key name
//===dbt.pk = rs.getString("PK_NAME");
// We need the column name which is primary key for the given
// table.
dbt.pk = rs.getString("column_name");
}
} catch (Exception e) {
LOGGER.error("setPKey", e);
} finally {
try {
rs.close();
} catch (Exception e) {
// ignore
}
}
}
private void setColumns(String schemaName, String tableName) {
LOGGER.debug(
"setColumns: <" + tableName + "> in schema <" + schemaName + ">");
DbTable dbt = db.getTable(schemaName, tableName);
if (dbt == null) {
LOGGER.debug(
"No table with name: <"
+ tableName
+ "> in schema <"
+ schemaName
+ ">");
return;
}
if (initConnection() != null) {
return;
}
try {
setColumns(dbt);
LOGGER.debug("got " + dbt.colsDataType.size() + " columns");
} finally {
closeConnection();
}
}
/**
* Gets all columns for a given table name.
*
* Assumes that the caller has acquired a connection using
* {@link #initConnection()}.
*/
private void setColumns(DbTable dbt) {
ResultSet rs = null;
try {
rs = md.getColumns(null, dbt.schemaName, dbt.name, null);
while (rs.next()) {
DbColumn col = new DbColumn();
col.dataType = rs.getInt("DATA_TYPE");
col.name = rs.getString("COLUMN_NAME");
col.typeName = rs.getString("TYPE_NAME");
col.columnSize = rs.getInt("COLUMN_SIZE");
col.decimalDigits = rs.getInt("DECIMAL_DIGITS");
dbt.addColsDataType(col);
}
} catch (Exception e) {
LOGGER.error("setColumns", e);
} finally {
try {
rs.close();
} catch (Exception e) {
// ignore
}
}
}
////////////////////////////////////////////////////////////////////////////
// The following functions provide an interface to JdbcMetaData class to
// retrieve the meta data details
public List<String> getAllSchemas() {
return db.getAllSchemas();
}
/**
* Returns all tables in a given schema.
*/
public List<String> getAllTables(String schemaName) {
return db.getAllTables(schemaName);
}
/**
* Returns all tables in given schema minus the given table name.
*/
public List<String> getAllTables(String schemaName, String minusTable) {
if (minusTable == null) {
return getAllTables(schemaName);
} else {
List<String> allTablesMinusOne = new ArrayList<String>();
for (String s : getAllTables(schemaName)) {
if (s.endsWith(minusTable)) {
// startsWith and endsWith cannot be compared with
// null argument, throws exception
if ((schemaName == null) || s.startsWith(schemaName)) {
continue;
}
}
allTablesMinusOne.add(s);
}
return allTablesMinusOne;
}
}
/* get all possible cases of fact tables in a schema */
public List<String> getFactTables(String schemaName) {
return db.getFactTables(schemaName);
}
/**
* Gets all possible cases of dimension tables which are linked to given
* fact table by foreign keys.
*/
public List<String> getDimensionTables(
String schemaName,
String factTable)
{
List<String> dimeTables = new ArrayList<String>();
if (factTable == null) {
return dimeTables;
} else {
return db.getDimensionTables(schemaName, factTable);
}
}
public boolean isTableExists(String schemaName, String tableName) {
if (tableName == null) {
return true;
} else {
return db.tableExists(schemaName, tableName);
}
}
public boolean isColExists(
String schemaName, String tableName, String colName)
{
if (tableName == null || colName == null) {
return true;
} else {
if (!db.hasColumns(schemaName, tableName)) {
setColumns(schemaName, tableName);
}
return db.colExists(schemaName, tableName, colName);
}
}
/* get all foreign keys in given fact table */
public List<String> getFactTableFKs(String schemaName, String factTable) {
List<String> fks = new ArrayList<String>();
if (factTable == null) {
return fks;
} else {
return db.getFactTableFKs(schemaName, factTable);
}
}
public String getTablePK(String schemaName, String tableName) {
if (tableName == null) {
return null;
} else {
return db.getTablePK(schemaName, tableName);
}
}
/**
* Gets all columns of given table in schema.
* column string is formatted.
*/
public List<String> getAllColumns(String schemaName, String tableName) {
List<String> allcols = new ArrayList<String>();
if (tableName == null) {
List<String> allTables = getAllTables(schemaName);
for (int i = 0; i < allTables.size(); i++) {
String tab = allTables.get(i);
List<String> cols;
if (tab.indexOf(LEVEL_SEPARATOR) == -1) {
cols = getAllColumns(schemaName, tab);
} else {
String[] names = tab.split(LEVEL_SEPARATOR);
cols = getAllColumns(names[0], names[1]);
}
for (int j = 0; j < cols.size(); j++) {
String col = cols.get(j);
allcols.add(tab + LEVEL_SEPARATOR + col);
}
}
return allcols;
} else {
if (!db.hasColumns(schemaName, tableName)) {
setColumns(schemaName, tableName);
}
return db.getAllColumns(schemaName, tableName);
}
}
/**
* Returns all columns of given table in schema.
* Column string is formatted.
*/
public List<DbColumn> getAllDbColumns(String schemaName, String tableName) {
List<DbColumn> allcols = new ArrayList<DbColumn>();
if (tableName == null) {
List<String> allTables = getAllTables(schemaName);
for (int i = 0; i < allTables.size(); i++) {
String tab = allTables.get(i);
List<DbColumn> cols;
if (tab.indexOf(LEVEL_SEPARATOR) == -1) {
cols = getAllDbColumns(schemaName, tab);
} else {
String[] names = tab.split(LEVEL_SEPARATOR);
cols = getAllDbColumns(names[0], names[1]);
}
allcols.addAll(cols);
}
return allcols;
} else {
if (!db.hasColumns(schemaName, tableName)) {
setColumns(schemaName, tableName);
}
return db.getAllDbColumns(schemaName, tableName);
}
}
// get column data type of given table and its col
public int getColumnDataType(
String schemaName, String tableName, String colName)
{
if (tableName == null || colName == null) {
return -1;
} else {
if (!db.hasColumns(schemaName, tableName)) {
setColumns(schemaName, tableName);
}
return db.getColumnDataType(schemaName, tableName, colName);
}
}
/**
* Gets column definition of given table and its col.
*
* @param schemaName Schema name
* @param tableName Table name
* @param colName Column name
* @return Column definition
*/
public DbColumn getColumnDefinition(
String schemaName, String tableName, String colName)
{
if (tableName == null || colName == null) {
return null;
} else {
if (!db.hasColumns(schemaName, tableName)) {
setColumns(schemaName, tableName);
}
return db.getColumnDefinition(schemaName, tableName, colName);
}
}
public String getDbCatalogName() {
return db.catalogName;
}
public String getDatabaseProductName() {
return db.productName;
}
public String getJdbcConnectionUrl() {
return jdbcConnectionUrl;
}
public String getErrMsg() {
return errMsg;
}
public static void main(String[] args) {
if (args.length < 2) {
throw new RuntimeException(
"need at least 2 args: driver class and jdbcUrl");
}
String driverClass = args[0];
String jdbcUrl = args[1];
String username = null;
String password = null;
if (args.length > 2) {
if (args.length != 4) {
throw new RuntimeException(
"need 4 args: including user name and password");
}
username = args[2];
password = args[3];
}
JdbcMetaData sb = new JdbcMetaData(
null, driverClass, jdbcUrl, username, password, "", false);
List<String> foundSchemas = sb.getAllSchemas();
System.out.println("allSchemas = " + foundSchemas);
for (String schemaName : foundSchemas) {
List<String> foundTables = sb.getAllTables(schemaName);
if (foundTables != null && foundTables.size() > 0) {
System.out.println("schema = " + schemaName);
for (String tableName : foundTables) {
System.out.println("\t" + tableName);
List<String> foundColumns = sb.getAllColumns(
schemaName, tableName);
for (String columnName : foundColumns) {
System.out.println("\t\t" + columnName);
}
}
}
}
}
/**
* Database metadata.
*/
class Database {
String catalogName = ""; // database name.
String productName = "Unknown";
String productVersion = "";
// list of all schemas in database
Map<String, DbSchema> schemas = new TreeMap<String, DbSchema>();
//ordered collection, allows duplicates and null
Map<String, TableTracker> tables = new TreeMap<String, TableTracker>();
// list of all tables in all schemas in database
List<String> allSchemas;
private void addDbSchema(DbSchema dbs) {
schemas.put(
dbs.name != null
? dbs.name
: "", dbs);
}
class TableTracker {
List<DbTable> namedTable = new ArrayList<DbTable>();
public void add(DbTable table) {
namedTable.add(table);
}
public int count() {
return namedTable.size();
}
}
private void addDbTable(DbTable dbs) {
TableTracker tracker = tables.get(dbs.name);
if (tracker == null) {
tracker = new TableTracker();
tables.put(dbs.name, tracker);
}
tracker.add(dbs);
}
private boolean schemaNameEquals(String a, String b) {
return (a != null && a.equals(b));
}
private DbSchema getSchema(String schemaName) {
return schemas.get(
schemaName != null
? schemaName
: "");
}
private List<String> getAllSchemas() {
if (allSchemas == null) {
allSchemas = new ArrayList<String>();
allSchemas.addAll(schemas.keySet());
}
return allSchemas;
}
private boolean tableExists(String sname, String tableName) {
return getTable(sname, tableName) != null;
}
private DbTable getTable(String sname, String tableName) {
if (sname == null || sname.equals("")) {
TableTracker t = tables.get(tableName);
if (t != null) {
return t.namedTable.get(0);
} else {
return null;
}
} else {
DbSchema s = schemas.get(sname);
if (s == null) {
return null;
}
return s.getTable(tableName);
}
}
private boolean hasColumns(String schemaName, String tableName) {
DbTable table = getTable(schemaName, tableName);
if (table != null) {
return table.hasColumns();
}
return false;
}
private boolean colExists(
String sname, String tableName, String colName)
{
DbTable t = getTable(sname, tableName);
if (t == null) {
return false;
}
return t.getColumn(colName) != null;
}
private List<String> getAllTables(String sname) {
return getAllTables(sname, false);
}
private List<String> getFactTables(String sname) {
return getAllTables(sname, true);
}
private List<String> getAllTables(String sname, boolean factOnly) {
List<String> v = new ArrayList<String>();
if (sname == null || sname.equals("")) {
// return a list of "schemaname -> table name" string objects
for (TableTracker tt : tables.values()) {
for (DbTable t : tt.namedTable) {
if (!factOnly || (factOnly && t instanceof FactTable)) {
if (t.schemaName == null) {
v.add(t.name);
} else {
v.add(t.schemaName + LEVEL_SEPARATOR + t.name);
}
}
}
}
} else {
// return a list of "tablename" string objects
DbSchema s = getSchema(sname);
if (s != null) {
for (DbTable t : s.tables.values()) {
if (!factOnly || (factOnly && t instanceof FactTable)) {
v.add(t.name);
}
}
}
}
return v;
}
/* get all foreign keys in given fact table */
private List<String> getFactTableFKs(String sname, String factTable) {
List<String> f = new ArrayList<String>();
if (sname == null || sname.equals("")) {
TableTracker tracker = tables.get(factTable);
if (tracker == null) {
return f;
}
// return a list of "schemaname -> table name -> fk col" string
// objects if schema is not given
boolean duplicate = tracker.count() > 1;
for (DbTable t : tracker.namedTable) {
if (t instanceof FactTable) {
if (duplicate) {
for (String fk : ((FactTable) t).fks.keySet()) {
if (t.schemaName == null) {
f.add(t.name + LEVEL_SEPARATOR + fk);
} else {
f.add(
t.schemaName
+ LEVEL_SEPARATOR
+ t.name
+ LEVEL_SEPARATOR
+ fk);
}
}
} else {
f.addAll(((FactTable) t).fks.keySet());
}
}
}
} else {
DbSchema s = getSchema(sname);
if (s == null) {
return f;
}
DbTable t = s.getTable(factTable);
if (t == null) {
return f;
}
// return a list of "fk col name" string objects if schema is
// given
if (t instanceof FactTable && t.name.equals(factTable)) {
f.addAll(((FactTable) t).fks.keySet());
}
}
return f;
}
private List<String> getDimensionTables(
String sname, String factTable)
{
List<String> f = new ArrayList<String>();
if (sname == null || sname.equals("")) {
TableTracker tracker = tables.get(factTable);
if (tracker == null) {
return f;
}
// return a list of "schemaname -> table name -> fk col" string
// objects if schema is not given
boolean duplicate = tracker.count() > 1;
for (DbTable t : tracker.namedTable) {
if (t instanceof FactTable) {
if (duplicate) {
for (String fkt : ((FactTable) t).fks.values()) {
if (t.schemaName == null) {
f.add(t.name + LEVEL_SEPARATOR + fkt);
} else {
f.add(
t.schemaName
+ LEVEL_SEPARATOR
+ t.name
+ LEVEL_SEPARATOR
+ fkt);
}
}
} else {
f.addAll(((FactTable) t).fks.keySet());
}
}
}
} else {
DbSchema s = getSchema(sname);
if (s == null) {
return f;
}
DbTable t = s.getTable(factTable);
if (t == null) {
return f;
}
// return a list of "fk col name" string objects if schema is
// given
if (t instanceof FactTable && t.name.equals(factTable)) {
f.addAll(((FactTable) t).fks.values());
}
}
return f;
}
private String getTablePK(String sname, String tableName) {
if (sname == null || sname.equals("")) {
TableTracker tracker = tables.get(tableName);
if (tracker == null) {
return null;
}
// return a list of "schemaname -> table name ->
// dimension table name" string objects if schema is not given
return tracker.namedTable.get(0).pk;
} else {
DbTable t = getTable(sname, tableName);
if (t == null) {
return null;
}
return t.pk;
}
}
private List<String> getAllColumns(String sname, String tableName) {
List<String> f = new ArrayList<String>();
if (sname == null || sname.equals("")) {
TableTracker tracker = tables.get(tableName);
if (tracker == null) {
return f;
}
// return a list of "schemaname -> table name -> cols"
// string objects if schema is not given
boolean duplicate = tracker.count() > 1;
for (DbTable t : tracker.namedTable) {
for (Map.Entry<String, DbColumn> c : t.colsDataType
.entrySet())
{
StringBuffer sb = new StringBuffer();
if (t.schemaName != null && !duplicate) {
sb.append(t.schemaName).append(LEVEL_SEPARATOR);
}
sb.append(t.name)
.append(LEVEL_SEPARATOR)
.append(c.getKey())
.append(" - ")
.append(c.getValue().displayType());
f.add(sb.toString());
}
}
} else {
DbTable t = getTable(sname, tableName);
if (t == null) {
return f;
}
// return a list of "col name" string objects if schema is given
f.addAll(t.colsDataType.keySet());
}
return f;
}
private List<DbColumn> getAllDbColumns(String sname, String tableName) {
List<DbColumn> f = new ArrayList<DbColumn>();
if (sname == null || sname.equals("")) {
TableTracker tracker = tables.get(tableName);
if (tracker == null) {
return f;
}
for (DbTable t : tracker.namedTable) {
for (Map.Entry<String, DbColumn> c : t.colsDataType
.entrySet())
{
f.add(c.getValue());
}
}
} else {
DbTable t = getTable(sname, tableName);
if (t == null) {
return f;
}
for (Map.Entry<String, DbColumn> c : t.colsDataType
.entrySet())
{
f.add(c.getValue());
}
}
return f;
}
private int getColumnDataType(
String sname, String tableName, String colName)
{
DbColumn result = getColumnDefinition(sname, tableName, colName);
if (result == null) {
return -1;
}
return result.dataType;
}
private DbColumn getColumnDefinition(
String sname, String tableName, String colName)
{
DbTable t = getTable(sname, tableName);
if (t == null) {
return null;
}
return t.colsDataType.get(colName);
}
}
class DbSchema {
String name;
/**
* ordered collection, allows duplicates and null
*/
final Map<String, DbTable> tables = new TreeMap<String, DbTable>();
private DbTable getTable(String tableName) {
return tables.get(tableName);
}
private void addDbTable(DbTable dbt) {
tables.put(dbt.name, dbt);
}
}
public class DbColumn {
public String name;
public int dataType;
public String typeName;
public int columnSize;
public int decimalDigits;
public String displayType() {
StringBuffer sb = new StringBuffer();
switch (dataType) {
case Types.ARRAY:
sb.append("ARRAY(" + columnSize + ")");
break;
case Types.BIGINT:
sb.append("BIGINT");
break;
case Types.BINARY:
sb.append("BINARY(" + columnSize + ")");
break;
case Types.BLOB:
sb.append("BLOB(" + columnSize + ")");
break;
case Types.BIT:
sb.append("BIT");
break;
case Types.BOOLEAN:
sb.append("BOOLEAN");
break;
case Types.CHAR:
sb.append("CHAR");
break;
case Types.CLOB:
sb.append("CLOB(" + columnSize + ")");
break;
case Types.DATE:
sb.append("DATE");
break;
case Types.DECIMAL:
sb.append("DECIMAL(" + columnSize + ", " + decimalDigits + ")");
break;
case Types.DISTINCT:
sb.append("DISTINCT");
break;
case Types.DOUBLE:
sb.append("DOUBLE(" + columnSize + ", " + decimalDigits + ")");
break;
case Types.FLOAT:
sb.append("FLOAT(" + columnSize + ", " + decimalDigits + ")");
break;
case Types.INTEGER:
sb.append("INTEGER(" + columnSize + ")");
break;
case Types.JAVA_OBJECT:
sb.append("JAVA_OBJECT(" + columnSize + ")");
break;
/*
* No Java 1.6 SQL types for now
case Types.LONGNVARCHAR:
sb.append("LONGNVARCHAR(" + columnSize + ")");
break;
case Types.LONGVARBINARY:
sb.append("LONGVARBINARY(" + columnSize + ")");
break;
case Types.LONGVARCHAR:
sb.append("LONGVARCHAR(" + columnSize + ")");
break;
case Types.NCHAR:
sb.append("NCHAR(" + columnSize + ")");
break;
case Types.NCLOB:
sb.append("NCLOB(" + columnSize + ")");
break;
*/
case Types.NULL:
sb.append("NULL");
break;
case Types.NUMERIC:
sb.append("NUMERIC(" + columnSize + ", " + decimalDigits + ")");
break;
/*
* No Java 1.6 SQL types for now
case Types.NVARCHAR:
sb.append("NCLOB(" + columnSize + ")");
break;
*/
case Types.OTHER:
sb.append("OTHER");
break;
case Types.REAL:
sb.append("REAL(" + columnSize + ", " + decimalDigits + ")");
break;
case Types.REF:
sb.append("REF");
break;
/*
* No Java 1.6 SQL types for now
case Types.ROWID:
sb.append("ROWID");
break;
*/
case Types.SMALLINT:
sb.append("SMALLINT(" + columnSize + ")");
break;
/*
* No Java 1.6 SQL types for now
case Types.SQLXML:
sb.append("SQLXML(" + columnSize + ")");
break;
*/
case Types.STRUCT:
sb.append("STRUCT");
break;
case Types.TIME:
sb.append("TIME");
break;
case Types.TIMESTAMP:
sb.append("TIMESTAMP");
break;
case Types.TINYINT:
sb.append("TINYINT(" + columnSize + ")");
break;
case Types.VARBINARY:
sb.append("VARBINARY(" + columnSize + ")");
break;
case Types.VARCHAR:
sb.append("VARCHAR(" + columnSize + ")");
break;
}
return sb.toString();
}
}
class DbTable {
String schemaName;
String name;
String pk;
/**
* sorted map key=column, value=data type of column
*/
final Map<String, DbColumn> colsDataType =
new TreeMap<String, DbColumn>();
private void addColsDataType(DbColumn columnDefinition) {
colsDataType.put(columnDefinition.name, columnDefinition);
}
private DbColumn getColumn(String cname) {
return colsDataType.get(cname);
}
private boolean hasColumns() {
return colsDataType.size() > 0;
}
}
class FactTable extends DbTable {
/**
* Sorted map key = foreign key col, value=primary key table associated
* with this fk.
*/
final Map<String, String> fks = new TreeMap<String, String>();
private void addFks(String fk, String pkt) {
fks.put(fk, pkt);
}
}
}
// End JdbcMetaData.java