package org.maachang.dao.dbms;

import java.sql.ResultSetMetaData;

/**
 * カラム用メタデータ.
 * 
 * @version 2007/10/18
 * @author masahito suzuki
 * @since MaachangDao 1.00
 */
public class MetaColumn {

    /**
     * テーブル名.
     */
    private String table = null;

    /**
     * カラム群.
     */
    private ColumnChild[] columns = null;

    /**
     * metaカラムと対で保持するオブジェクト.
     */
    private Object object = null ;

    /**
     * コンストラクタ.
     */
    private MetaColumn() {

    }

    /**
     * コンストラクタ. <BR>
     * <BR>
     * メタデータを設定してオブジェクトを生成します. <BR>
     * 
     * @param table
     *            対象のテーブル名を設定します.
     * @param meta
     *            対象のメタデータを設定します.
     * @exception Exception
     *                例外.
     */
    public MetaColumn(String table, ResultSetMetaData meta) throws Exception {
        int len = meta.getColumnCount();
        if (table == null || (table.trim().toLowerCase()).length() <= 0
                || len <= 0) {
            throw new IllegalArgumentException("引数は不正です");
        }
        this.table = table;
        this.columns = new ColumnChild[len];
        for (int i = 0; i < len; i++) {
            int n = i + 1;
            this.columns[i] = new ColumnChild();
            this.columns[i].name = meta.getColumnName(n).trim().toLowerCase();
            this.columns[i].type = meta.getColumnType(n);
        }
    }

    /**
     * テーブル名を取得. <BR>
     * <BR>
     * テーブル名を取得します. <BR>
     * 
     * @return String テーブル名が返されます.
     */
    public String getTable() {
        return this.table;
    }

    /**
     * カラム名を取得. <BR>
     * <BR>
     * カラム名を取得します. <BR>
     * 
     * @param no
     *            対象の項番を設定します.
     * @return String カラム名が返されます.
     */
    public String getColumnName(int no) {
        return getColumnName( false,no ) ;
    }

    /**
     * カラム名を取得. <BR>
     * <BR>
     * カラム名を取得します. <BR>
     * 
     * @param mode [true]の場合、Java名に変換して処理します.
     * @param no
     *            対象の項番を設定します.
     * @return String カラム名が返されます.
     */
    public String getColumnName(boolean mode,int no) {
        if (columns == null || no < 0 || no >= columns.length) {
            return null;
        }
        if( mode ) {
            return DbUtil.convertDBNameByJavaName( false,columns[no].name );
        }
        return columns[no].name;
    }

    /**
     * カラムタイプを取得. <BR>
     * <BR>
     * カラムタイプを取得します. <BR>
     * 
     * @param no
     *            対象の項番を設定します.
     * @return int カラムタイプが返されます.
     */
    public int getColumnType(int no) {
        if (columns == null || no < 0 || no >= columns.length) {
            return -1;
        }
        return columns[no].type;
    }

    /**
     * 一致するカラム名に対する項番を取得. <BR>
     * <BR>
     * 一致するカラム名に対する項番を取得します. <BR>
     * 
     * @param column
     *            対象のカラム名を設定します.
     * @return int 対象の項番が返されます.
     */
    public int getColumnNameByNumber(String column) {
        return getColumnNameByNumber( false,column ) ;
    }

    /**
     * 一致するカラム名に対する項番を取得. <BR>
     * <BR>
     * 一致するカラム名に対する項番を取得します. <BR>
     * 
     * @param mode [true]の場合、DB名に変換して処理します.
     * @param column
     *            対象のカラム名を設定します.
     * @return int 対象の項番が返されます.
     */
    public int getColumnNameByNumber(boolean mode,String column) {
        if (columns == null || column == null
                || (column = column.trim().toLowerCase()).length() <= 0) {
            return -1;
        }
        if( mode ) {
            column = DbUtil.convertJavaNameByDBName( column ) ;
        }
        int len = columns.length;
        for (int i = 0; i < len; i++) {
            if (column.equals(columns[i].name)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * カラム数を取得. <BR>
     * <BR>
     * カラム数が返されます. <BR>
     * 
     * @return String カラム数が返されます.
     */
    public int size() {
        if (columns == null) {
            return 0;
        }
        return columns.length;
    }

    /**
     * オブジェクトを設定.
     * <BR><BR>
     * オブジェクトを設定します.
     * <BR>
     * @param object 対象のオブジェクトを設定します.
     */
    public void setObject( Object object ) {
        this.object = object ;
    }

    /**
     * オブジェクトを取得.
     * <BR><BR>
     * オブジェクトを取得します.
     * <BR>
     * @return Object オブジェクト情報が返されます.
     */
    public Object getObject() {
        return object ;
    }

    /**
     * 文字列に変換.
     */
    public String toString() {
        if (columns == null) {
            return "null";
        }
        StringBuilder buf = new StringBuilder();
        buf.append("table:").append(table);
        int len = columns.length;
        buf.append(" {");
        for (int i = 0; i < len; i++) {
            buf.append(" [").append((i + 1)).append("]");
            buf.append(" name:").append(columns[i].name);
            buf.append(" type:").append(columns[i].type);
        }
        buf.append(" }");
        return buf.toString();
    }
}

/**
 * カラムメタデータ子要素.
 */
class ColumnChild {
    public String name = null;

    public int type = -1;
}
