/*
 * blancoDb
 * Copyright (C) 2004-2005 Yasuo Nakanishi
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.db.collector;

import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import blanco.commons.util.BlancoStringUtil;
import blanco.db.conf.BlancoDbDatabaseConnectionSettingDef;

/**
 * @author Yasuo Nakanishi
 */
public class DatabaseService {
    private BlancoDbDatabaseConnection _connection = null;

    private BlancoDbDatabaseConnectionSettingDef _jdbcSetting = null;

    private DatabaseMetaData _databaseMetadata = null;

    public DatabaseService(BlancoDbDatabaseConnectionSettingDef setting,
            BlancoDbDatabaseConnection conn) {
        _jdbcSetting = setting;
        _connection = conn;
    }

    public DatabaseMetaData getDatabaseMetaData() throws SQLException {
        if (_databaseMetadata == null) {
            _databaseMetadata = _connection.getConnection().getMetaData();
        }
        return _databaseMetadata;
    }

    public List getTableNameList() throws SQLException {
        List result = new ArrayList();
        ResultSet resultSet = null;

        try {
            // 2005.04.15 t.iga 変更。
            // Oracleの場合には、ユーザ名をスキーマ名として与える必要がある。
            // これを行わないと、システムテーブルを含む全てのテーブルを取得してしまう。
            resultSet = getDatabaseMetaData().getTables(null,
                    _jdbcSetting.getSchema(), null, null);
            while (resultSet.next()) {
                if (BlancoStringUtil.null2Blank(
                        resultSet.getString("TABLE_TYPE")).equals("TABLE")) {
                    final String tableName = BlancoStringUtil
                            .null2Blank(resultSet.getString("TABLE_NAME"));
                    if (tableName.indexOf('$') >= 0) {
                        // 表名に[$]が付いているものは blancoDbでは処理しません。
                        System.out.println("表[" + tableName
                                + "]は表名に$が付いているため、処理を行いません。");
                        continue;
                    }
                    result.add(tableName);
                }
            }
        } finally {
            if (resultSet != null) {
                resultSet.close();
            }
        }
        return result;
    }

    public String getCatalog() throws SQLException {
        return _connection.getConnection().getCatalog();
    }

    public BlancoDbDatabaseConnectionSettingDef getJdbcSetting() {
        return _jdbcSetting;
    }

    public BlancoDbDatabaseConnection getConnection() {
        return _connection;
    }

    public final Map getPrimaryKeyMap(final String tableName)
            throws SQLException {
        // assert _connection != null;

        final Map result = new Hashtable();
        final String catalog = getCatalog();

        ResultSet resultSet = null;
        String columnName = "";
        Short sequence = null;
        try {
            resultSet = getDatabaseMetaData().getPrimaryKeys(catalog, null,
                    tableName);
            while (resultSet.next()) {
                columnName = resultSet.getString("COLUMN_NAME");
                sequence = new Short(resultSet.getShort("KEY_SEQ"));
                result.put(columnName, sequence);
            }
        } finally {
            if (resultSet != null) {
                resultSet.close();
            }
        }
        return result;
    }

    public void setConnection(final BlancoDbDatabaseConnection conn) {
        _connection = conn;
    }

    public PreparedStatement createStatement(final String sql)
            throws SQLException {
        return _connection.getConnection().prepareStatement(sql);
    }
}