org.ralasafe.db.DBView.java Source code

Java tutorial

Introduction

Here is the source code for org.ralasafe.db.DBView.java

Source

/**
 * Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com
 * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
 */
package org.ralasafe.db;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ralasafe.util.DBUtil;
import org.ralasafe.util.StringUtil;

/**
 * Reflect schema's table and view infos.
 * The table or view is omited which name starts with '$'. 
 * We think it's a system table. 
 * 
 * @author back
 * 
 */
public class DBView {
    private static final String[] tableType = new String[] { "TABLE" };
    private static final String[] viewType = new String[] { "VIEW" };
    private static final Log log = LogFactory.getLog(DBView.class);

    public static String getDefaultSchema(String dsName) {
        Connection conn = DBPower.getConnection(dsName);
        try {
            return DBUtil.getDefaultSchema(conn);
        } catch (SQLException e) {
            log.error("", e);
            return "";
        } finally {
            DBUtil.close(conn);
        }
    }

    public static TableView getTable(String dsName, String tableName) {
        Connection conn = null;

        try {
            conn = DBPower.getConnection(dsName);

            return getTable(conn, dsName, null, tableName);
        } catch (SQLException e) {
            log.error("Failed to get definition of " + "table/view '" + tableName, e);
            throw new DBLevelException(e);
        } finally {
            DBUtil.close(conn);
        }
    }

    public static TableView getTable(String dsName, String schema, String tableName) {
        Connection conn = null;

        try {
            conn = DBPower.getConnection(dsName);

            return getTable(conn, dsName, schema, tableName);
        } catch (SQLException e) {
            log.error("Failed to get definition of " + "table/view '" + schema + "." + tableName, e);
            throw new DBLevelException(e);
        } finally {
            DBUtil.close(conn);
        }
    }

    private static TableView getTable(Connection conn, String dsName, String schema, String tableName)
            throws SQLException {
        String mySchema = "";
        if (!StringUtil.isEmpty(schema)) {
            mySchema = schema + ".";
        }

        if (log.isDebugEnabled()) {
            log.debug("Get table/view definition: dsName=" + dsName + ", table/view Name=" + mySchema + tableName);
        }

        Statement stmt = null;
        ResultSet rs = null;
        ResultSet primaryKeys = null;

        try {
            stmt = conn.createStatement();

            rs = stmt.executeQuery("select * from " + mySchema + tableName + " where 1=2");
            ResultSetMetaData metaData = rs.getMetaData();

            TableView table = new TableView();
            table.setSchema(schema);
            table.setName(tableName);

            DatabaseMetaData metaData2 = conn.getMetaData();
            String databaseProductName = DBUtil.getDatabaseProductName(conn);

            if (databaseProductName == DBUtil.MYSQL) {
                primaryKeys = metaData2.getPrimaryKeys(schema, null, tableName);
            } else {
                primaryKeys = metaData2.getPrimaryKeys(null, null, tableName);
            }

            Map pkColumnViewMap = new HashMap();
            while (primaryKeys.next()) {
                pkColumnViewMap.put(primaryKeys.getString("COLUMN_NAME"), null);
            }

            List columnList = new ArrayList(metaData.getColumnCount());
            for (int i = 1, columnCount = metaData.getColumnCount(); i <= columnCount; i++) {
                ColumnView column = new ColumnView();
                String columnName = metaData.getColumnName(i);
                column.setName(columnName);
                String sqlType = metaData.getColumnTypeName(i);

                if (sqlType.equalsIgnoreCase("blob") || sqlType.equalsIgnoreCase("clob")
                        || sqlType.equalsIgnoreCase("text")) {
                    // DO NOTHING
                } else {
                    int precision = metaData.getPrecision(i);
                    int scale = metaData.getScale(i);

                    if (precision != 0) {
                        if (scale == 0) {
                            sqlType = sqlType + "(" + precision + ")";
                        } else {
                            sqlType = sqlType + "(" + precision + "," + scale + ")";
                        }
                    }
                }
                column.setSqlType(sqlType);
                columnList.add(column);

                // it's a primary key?
                if (pkColumnViewMap.containsKey(columnName)) {
                    pkColumnViewMap.put(columnName, column);
                }
            }

            table.setColumnViews(columnList);

            // sometimes, oracle jdbc driver returns pk info is redundance, 
            // actually the column does exist at all.  Clear them.
            clearInvalidPK(pkColumnViewMap);

            if (pkColumnViewMap.size() > 0) {
                table.setPkColumnViews(pkColumnViewMap.values());
            }
            return table;
        } finally {
            DBUtil.close(primaryKeys);
            DBUtil.close(rs);
            DBUtil.close(stmt);
        }
    }

    private static void clearInvalidPK(Map pkColumnViewMap) {
        Iterator itr = pkColumnViewMap.entrySet().iterator();
        while (itr.hasNext()) {
            Map.Entry entry = (Map.Entry) itr.next();
            if (entry.getValue() == null) {
                itr.remove();
            }
        }
    }

    public static String[] getSchemas(String dsName) {
        DataSource ds = DBPower.getDataSource(dsName);
        if (ds.isShowAllSchemas()) {
            return getAllSchemasFromDB(dsName);
        } else {
            return ds.getSchemas();
        }
    }

    public static String[] getAllSchemasFromDB(String dsName) {
        Connection conn = null;
        ResultSet rs = null;

        try {
            conn = DBPower.getConnection(dsName);

            DatabaseMetaData metaData = conn.getMetaData();

            String databaseProductName = DBUtil.getDatabaseProductName(conn);
            if (databaseProductName == DBUtil.MYSQL || databaseProductName == DBUtil.SQLSERVER) {
                rs = metaData.getCatalogs();
            } else {
                rs = metaData.getSchemas();
            }

            List result = new LinkedList();
            while (rs.next()) {
                String name = rs.getString(1);
                result.add(name);
            }

            String[] names = new String[result.size()];
            Iterator itr = result.iterator();
            for (int i = 0; i < names.length; i++) {
                names[i] = (String) itr.next();
            }
            return names;
        } catch (SQLException e) {
            log.error("", e);
            throw new DBLevelException(e);
        } finally {
            DBUtil.close(rs);
            DBUtil.close(conn);
        }
    }

    public static String[] getTableNames(String dsName, String schema) {
        return getObjectNames(dsName, schema, tableType);
    }

    private static String[] getObjectNames(String dsName, String schema, String[] objectTypes) {
        Connection conn = null;
        ResultSet tables = null;

        try {
            conn = DBPower.getConnection(dsName);

            DatabaseMetaData metaData = conn.getMetaData();

            String databaseProductName = DBUtil.getDatabaseProductName(conn);
            if (databaseProductName == DBUtil.MYSQL || databaseProductName == DBUtil.SQLSERVER) {
                tables = metaData.getTables(schema, null, null, objectTypes);
            } else if (databaseProductName == DBUtil.ORACLE) {
                tables = metaData.getTables(null, null, null, objectTypes);
            } else {
                tables = metaData.getTables(null, schema, null, objectTypes);
            }

            List result = new LinkedList();
            while (tables.next()) {
                String tableName = tables.getString("TABLE_NAME");

                if (databaseProductName == DBUtil.ORACLE) {
                    String s = tables.getString("TABLE_SCHEM");
                    if (s.equalsIgnoreCase(schema)) {
                        result.add(tableName);
                    }
                } else if (databaseProductName == DBUtil.SQLSERVER) {
                    String s = tables.getString("TABLE_SCHEM");
                    tableName = s + "." + tableName;
                    result.add(tableName);
                } else {
                    result.add(tableName);
                }
            }

            String[] names = new String[result.size()];
            Iterator itr = result.iterator();
            for (int i = 0; i < names.length; i++) {
                names[i] = (String) itr.next();
            }
            return names;
        } catch (SQLException e) {
            log.error("", e);
            throw new DBLevelException(e);
        } finally {
            DBUtil.close(tables);
            DBUtil.close(conn);
        }
    }

    public static Collection getTables(String dsName, String schema) {
        String[] tableNames = getTableNames(dsName, schema);
        return getTables(dsName, schema, tableNames);
    }

    public static Collection getTables(String dsName, String schema, String[] tableNames) {
        Connection conn = DBPower.getConnection(dsName);
        try {
            List tables = new ArrayList();
            for (int i = 0; i < tableNames.length; i++) {
                // omit system tables like $sys_
                if (tableNames[i].indexOf("$") >= 0) {
                    continue;
                }

                try {
                    TableView table = getTable(conn, dsName, schema, tableNames[i]);
                    tables.add(table);
                } catch (SQLException e) {
                    log.error(
                            "Failed to get definition in schema '" + schema + "'." + "table/view:" + tableNames[i],
                            e);
                }
            }
            return tables;
        } finally {
            DBUtil.close(conn);
        }
    }

    public static String[] getViewNames(String dsName, String schema) {
        return getObjectNames(dsName, schema, viewType);
    }

    public static Collection getViewTables(String dsName, String schema, String[] viewNames) {
        return getTables(dsName, schema, viewNames);
    }

    public static Collection getViewTables(String dsName, String schema) {
        String[] viewNames = getViewNames(dsName, schema);
        return getTables(dsName, schema, viewNames);
    }
}