package org.maachang.mimdb.jdbc ;

import java.sql.SQLException;
import java.sql.Types;

import org.maachang.mimdb.core.MimdbIndex;
import org.maachang.mimdb.core.MimdbMetaData;
import org.maachang.mimdb.core.MimdbResult;

/**
 * Mimdb-JDBC ResultSet.
 * 
 * @version 2013/11/19
 * @author masahito suzuki
 * @since MasterInMemDB 1.00
 */
public class MimdbJdbcResultSetMetaData implements java.sql.ResultSetMetaData {
    protected MimdbMetaData meta ;
    
    protected MimdbJdbcResultSetMetaData( MimdbResult result ) {
        meta = result.getMetaData() ;
    }
    
    public String getCatalogName(int column) throws SQLException {
        return "" ;
    }
    public String getColumnClassName(int column) throws SQLException {
        return _getColumnClassName( meta.getColumnType( column-1 ) ) ;
    }
    public int getColumnCount() throws SQLException {
        return meta.getColumnSize() ;
    }
    public int getColumnDisplaySize(int column) throws SQLException {
        return getPrecision( column ) ;
    }
    public String getColumnLabel(int column) throws SQLException {
        return meta.getColumnName( column-1 ) ;
    }
    public String getColumnName(int column) throws SQLException {
         return meta.getColumnName( column-1 ) ;
   }
    public int getColumnType(int column) throws SQLException {
        return _getColumnType( meta.getColumnType( column-1 ) ) ;
    }
    public String getColumnTypeName(int column) throws SQLException {
        return getColumnClassName( column ) ;
    }
    public int getPrecision(int column) throws SQLException {
        return _getPrecision( meta.getColumnType( column-1 ) ) ;
    }
    public int getScale(int column) throws SQLException {
        return _getScale( meta.getColumnType( column-1 ) ) ;
    }
    public String getSchemaName(int column) throws SQLException {
        return "" ;
    }
    public String getTableName(int column) throws SQLException {
        return meta.getName() ;
    }
    public boolean isAutoIncrement(int column) throws SQLException {
        return false ;
    }
    public boolean isCaseSensitive(int column) throws SQLException {
        return false ;
    }
    public boolean isCurrency(int column) throws SQLException {
        return false ;
    }
    public boolean isDefinitelyWritable(int column) throws SQLException {
        return false ;
    }
    public int isNullable(int column) throws SQLException {
        return -1 ;
    }
    public boolean isReadOnly(int column) throws SQLException {
        return true ;
    }
    public boolean isSearchable(int column) throws SQLException {
        return meta.getTable().isIndex( column ) ;
    }
    public boolean isSigned(int column) throws SQLException {
        return _isSigned( meta.getColumnType( column-1 ) ) ;
    }
    public boolean isWritable(int column) throws SQLException {
        return false ;
    }
    
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false ;
    }
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null ;
    }
    
    protected static final String _getColumnClassName(int type) throws SQLException {
        switch( type ) {
            case MimdbIndex.COLUMN_BOOL :
                return "java.lang.Boolean" ;
            case MimdbIndex.COLUMN_INT :
                return "java.lang.Integer" ;
            case MimdbIndex.COLUMN_LONG :
                return "java.lang.Long" ;
            case MimdbIndex.COLUMN_FLOAT :
                return "java.lang.Double" ;
            case MimdbIndex.COLUMN_STRING :
                return "java.lang.String" ;
            case MimdbIndex.COLUMN_DATE :
                return "java.sql.Date" ;
            case MimdbIndex.COLUMN_TIME :
                return "java.sql.Time" ;
            case MimdbIndex.COLUMN_TIMESTAMP :
                return "java.sql.Timestamp" ;
        }
        throw new SQLException( "パラメータ範囲外か不明な型:" + type ) ;
    }
    protected static final int _getColumnType(int type) throws SQLException {
        switch( type ) {
            case MimdbIndex.COLUMN_BOOL :
                return Types.BOOLEAN ;
            case MimdbIndex.COLUMN_INT :
                return Types.INTEGER ;
            case MimdbIndex.COLUMN_LONG :
                return Types.BIGINT ;
            case MimdbIndex.COLUMN_FLOAT :
                return Types.FLOAT ;
            case MimdbIndex.COLUMN_STRING :
                return Types.VARCHAR ;
            case MimdbIndex.COLUMN_DATE :
                return Types.DATE ;
            case MimdbIndex.COLUMN_TIME :
                return Types.TIME ;
            case MimdbIndex.COLUMN_TIMESTAMP :
                return Types.TIMESTAMP ;
        }
        throw new SQLException( "パラメータ範囲外か不明な型:" + type ) ;
    }
    protected static final int _getPrecision(int type) throws SQLException {
        switch( type ) {
            case MimdbIndex.COLUMN_BOOL :
                return 1 ;
            case MimdbIndex.COLUMN_INT :
                return 10 ;
            case MimdbIndex.COLUMN_LONG :
                return 19 ;
            case MimdbIndex.COLUMN_FLOAT :
                return 21 ;
            case MimdbIndex.COLUMN_STRING :
                return 0x00ffffff ;
            case MimdbIndex.COLUMN_DATE :
                return 255 ;
            case MimdbIndex.COLUMN_TIME :
                return 255 ;
            case MimdbIndex.COLUMN_TIMESTAMP :
                return 255 ;
        }
        return -1 ;
    }
    protected static final int _getScale(int type) throws SQLException {
        switch( type ) {
            case MimdbIndex.COLUMN_FLOAT :
                return 20 ;
            case MimdbIndex.COLUMN_BOOL :
            case MimdbIndex.COLUMN_INT :
            case MimdbIndex.COLUMN_LONG :
            case MimdbIndex.COLUMN_STRING :
            case MimdbIndex.COLUMN_DATE :
            case MimdbIndex.COLUMN_TIME :
            case MimdbIndex.COLUMN_TIMESTAMP :
                return 0 ;
        }
        return -1 ;
    }
    protected static final boolean _isSigned(int type) throws SQLException {
        switch( type ) {
            case MimdbIndex.COLUMN_INT :
            case MimdbIndex.COLUMN_LONG :
            case MimdbIndex.COLUMN_FLOAT :
                return true ;
            case MimdbIndex.COLUMN_BOOL :
            case MimdbIndex.COLUMN_STRING :
            case MimdbIndex.COLUMN_DATE :
            case MimdbIndex.COLUMN_TIME :
            case MimdbIndex.COLUMN_TIMESTAMP :
                return false ;
        }
        return false ;
    }
    
}
