/*
 * Copyright (C) 2005 NTT DATA Corporation
 * 
 */
package org.postgresforest.tool.action;

import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;

import org.postgresforest.tool.bean.TableInfo;
import org.postgresforest.tool.db.GSCdata;
import org.postgresforest.tool.db.UserData;

/**
 * パーティション情報生成アクション
 * 
 * <pre>
 * 
 *  GSCから、
 *  サーバ情報を生成し、テーブル情報リストを生成する。
 *  テーブル名が指定されている場合、指定されたテーブルの詳細情報（カラム情報）
 *  、設定用のフォームも生成しする。
 *  生成した情報をbeanとして格納する。
 *  
 * </pre>
 *  
 */
public class TableList extends ActionBase {

	protected static DecimalFormat m_dcFmt = new DecimalFormat("00");

	/**
	 * @param gsc
	 */
	public TableList(GSCdata gsc) {
		super(gsc);
	}

	/**
	 * パーティション情報生成メイン処理
	 * 
	 * @see org.postgresforest.tool.action.UserActionBase#executeMain(org.apache.struts.action.ActionMapping,
	 *      org.apache.struts.action.ActionForm,
	 *      javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse,
	 *      javax.servlet.http.HttpSession, org.postgresforest.tool.db.GSCdata,
	 *      org.postgresforest.tool.db.UserData)
	 */
	public ArrayList getTableList(String dbName) throws Exception {

		//ユーザーデータクラスを取得
		UserData userData = new UserLoginMng(m_gsc).getUserDb(dbName);
		if (userData == null) {
			throw new Exception();
		}

		try {
			if (!connectSelect(m_gsc)) {
				throw new Exception();
			}

			if (!connectSelect(userData)) {
				throw new Exception();
			}

			//テーブル一覧情報作成
			ArrayList tableList = m_gsc.getTableList(dbName );

			
			for (Iterator iter = tableList.iterator(); iter.hasNext();) {
                TableInfo tableInfo = (TableInfo) iter.next();

                
    			if (!tableInfo.isPartition()) {
    				String tableName = tableInfo.getName();
    				
    				//VIEW かどうかをチェックする
    				ArrayList conList = userData.checkTable(tableName,
    						UserData.TYPE_VIEW);
    				if (conList.size() > 0) {
    					tableInfo.setCanPartition(true);
    				} else {
    					//VIEWのため、パーティション化はできません
    					tableInfo.setPartMultiType(TableInfo.TYPE_MULTI_VIEW);
    					tableInfo.setCanPartition(false);
    				}

    				//プライマリーキーの存在チェック
    				ArrayList primaryKeyList = userData.getPrimaryKey(tableName);
    				if (tableInfo.isCanPartition() && primaryKeyList.size() == 0) {
    					//プライマリーキーが設定されていないため、パーティション化はできません
    					tableInfo.setPartMultiType(TableInfo.TYPE_MULTI_NOT_PRIMARY);
    					tableInfo.setCanPartition(false);
    				}
    			}
                
                
            }
			
			
			return tableList;

		} catch (SQLException e) {
			setAccessErrs(m_gsc);
			throw e;

		} finally {
			userData.close();
			m_gsc.close();
		}

	}

	/**
	 * パーティション情報生成メイン処理
	 * 
	 * @see org.postgresforest.tool.action.UserActionBase#executeMain(org.apache.struts.action.ActionMapping,
	 *      org.apache.struts.action.ActionForm,
	 *      javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse,
	 *      javax.servlet.http.HttpSession, org.postgresforest.tool.db.GSCdata,
	 *      org.postgresforest.tool.db.UserData)
	 */
	public TableInfo getTableInfo(String dbName, TableInfo tableInfo)
			throws Exception {

		//ユーザーデータクラスを取得
		UserData userData = new UserLoginMng(m_gsc).getUserDb(dbName);
		if (userData == null) {
			throw new Exception();
		}

		String tableName = tableInfo.getName();

		try {
			if (!connectSelect(m_gsc)) {
				throw new Exception();
			}

			if (!connectSelect(userData)) {
				throw new Exception();
			}

			//インスタンスリスト作成
			ArrayList serverList = m_gsc.getServerList(dbName);

			//カラム情報を取得して、格納する。
			if (tableInfo.isPartition()) {
				
			    for (int j = 0; j < serverList.size(); j++) {
                    
			        //パーティション化テーブルの場合、実テーブル(**_00)のカラムタイプを取得
					//Viewではタイプがちゃんと取得できないため。
					//実テーブル(**_00〜nn)を順次検索するように変更
					ArrayList columnList = null;
					for (int i = 0; i < tableInfo.getPartCount(); i++) {
						columnList = userData.getColumnList(tableName + "_"
								+ m_dcFmt.format(i));
						if (columnList.size() != 0)
							break;
					}
					
					if (columnList.size() != 0){
					    tableInfo.setColumn(columnList);
						break;
				    }
					
					//実テーブルが存在しないインスタンスの可能性があるので、
					//別のインスタンスで取得を試みる
					userData.close();
					if (!connectSelect(userData)) {
						throw new Exception();
					}
					
			    
			    }
				
				
				tableInfo.setCanPartition(false);
			}else{
			    tableInfo.setColumn(userData.getColumnList(tableName));
			}
			
			
			if (tableInfo.isPartition()) {
				//パーティション化テーブルの場合、パーティション属性を取得して、設定
				tableInfo.setPartitionColumn(m_gsc.getPartitionColumn(dbName,
						tableName));
			}

			
			ArrayList priorityList = m_gsc.getPriorityList(dbName, tableName,
					serverList);
			tableInfo.setServer(priorityList);
			return tableInfo;

		} catch (SQLException e) {
			setAccessErrs(m_gsc);
			throw e;

		} finally {
			userData.close();
			m_gsc.close();
		}

	}
}