/*
 * Copyright (C) 2004 TiongHiang Lee
 *
 * 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.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not,  write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Email: thlee@onemindsoft.org
 */

package org.onemind.commons.java.sql;

import java.math.BigDecimal;
import java.sql.*;
import java.util.*;
import java.util.Date;
/**
 * JDBC utilities
 * @author TiongHiang Lee (thlee@onemindsoft.org)
 * @version $Id: JdbcUtils.java,v 1.3 2004/10/23 15:25:44 thlee Exp $ $Name:  $
 */
public final class JdbcUtils
{

    /** map the java classes to jdbc type int * */
    public static final Map CLASS_TO_TYPE_MAP;
    static
    {
        Map m = new HashMap();
        m.put(String.class, new Integer(Types.CHAR));
        m.put(String.class, new Integer(Types.VARCHAR));
        m.put(String.class, new Integer(Types.LONGVARCHAR));
        m.put(BigDecimal.class, new Integer(Types.NUMERIC));
        m.put(Boolean.class, new Integer(Types.BIT));
        m.put(Boolean.TYPE, new Integer(Types.BIT));
        m.put(Integer.class, new Integer(Types.INTEGER));
        m.put(Integer.TYPE, new Integer(Types.INTEGER));
        m.put(Long.class, new Integer(Types.BIGINT));
        m.put(Long.TYPE, new Integer(Types.BIGINT));
        m.put(Float.class, new Integer(Types.REAL));
        m.put(Float.TYPE, new Integer(Types.REAL));
        m.put(Double.class, new Integer(Types.DOUBLE));
        m.put(Double.TYPE, new Integer(Types.DOUBLE));
        m.put(byte[].class, new Integer(Types.BINARY));
        m.put(byte[].class, new Integer(Types.VARBINARY));
        m.put(byte[].class, new Integer(Types.LONGVARBINARY));
        m.put(Date.class, new Integer(Types.DATE));
        m.put(Time.class, new Integer(Types.TIME));
        m.put(Timestamp.class, new Integer(Types.TIMESTAMP));
        m.put(Clob.class, new Integer(Types.CLOB));
        m.put(Blob.class, new Integer(Types.BLOB));
        m.put(Array.class, new Integer(Types.ARRAY));
        m.put(Struct.class, new Integer(Types.STRUCT));
        m.put(Ref.class, new Integer(Types.REF));
        m.put(Class.class, new Integer(Types.JAVA_OBJECT));
        CLASS_TO_TYPE_MAP = Collections.unmodifiableMap(m);
    }

    /**
     * {@inheritDoc}
     */
    private JdbcUtils()
    {
    }

    /**
     * Get the MetaData from the resultset
     * @param rst the result set
     * @param name the name of metadata to create
     * @return the metadata
     * @throws SQLException if there's database problem
     */
    public static MetaData getMetaData(ResultSet rst, String name) throws SQLException
    {
        return getMetaData(rst.getMetaData(), name);
    }

    /**
     * return the MetaData
     * @param meta the resultset metadata
     * @param name the name
     * @return the meta data
     * @throws SQLException if there's database problem
     */
    public static MetaData getMetaData(ResultSetMetaData meta, String name) throws SQLException
    {
        MetaData metaData = new MetaData(name);
        int n = meta.getColumnCount();
        for (int i = 1; i <= n; i++)
        {
            String cname = meta.getColumnName(i);
            int ctype = meta.getColumnType(i);
            metaData.addField(new Field(cname, ctype));
        }
        return metaData;
    }

    /**
     * Return the jdbc type given the java type (based on JDBC spec)
     * @param c the java class
     * @return the jdbc type
     */
    public static int toJdbcType(Class c)
    {
        Integer i = (Integer) CLASS_TO_TYPE_MAP.get(c);
        if (i != null)
        {
            return i.intValue();
        } else
        {
            throw new IllegalArgumentException("Unknown class type" + c);
        }
    }

    /**
     * Return whether a java type is a jdbc type
     * @param c the class
     * @return true if it's jdbc type
     */
    public static boolean isJdbcType(Class c)
    {
        return CLASS_TO_TYPE_MAP.containsKey(c);
    }
}