package com.asksunny.schema.parser;

import java.lang.reflect.Field;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

public final class JdbcSqlTypeMap {
	private static final JdbcSqlTypeMap instance = new JdbcSqlTypeMap();
	private Map<String, Integer> jdbcTypeMap = new HashMap<>();

	private JdbcSqlTypeMap() {
		try {
			Class<Types> typesClzz = Types.class;
			Field[] fields = typesClzz.getFields();
			for (Field field : fields) {
				jdbcTypeMap.put(String.format("%s", field.getName()), field.getInt(null));
			}
		} catch (Exception e) {
			throw new RuntimeException("Failed to extact type info from JDBC types");
		}
	}

	public Integer findJdbcType(String name) {
		String lname = name;
		if (name.equalsIgnoreCase("VARCHAR2")) {
			lname = "VARCHAR";
		} else if (name.equalsIgnoreCase("NUMBER")) {
			lname = "NUMERIC";
		}else if (name.equalsIgnoreCase("INT")) {
			lname = "INTEGER";
		}else if (name.equalsIgnoreCase("LONG")) {
			lname = "BIGINT";
		}
		Integer t = jdbcTypeMap.get(lname.toUpperCase());
		if (t == null) {
			t = Types.OTHER;
		}
		return t;
	}
	
	public static String toJavaTypeName(int jdbcType) {
		String ret = "String";
		switch (jdbcType) {
		case Types.BIT:
			ret = "boolean";
			break;

		case Types.TINYINT:
		case Types.SMALLINT:
			ret = "int";
			break;
		case Types.INTEGER:
		case Types.BIGINT:
			ret = "long";
			break;
		case Types.FLOAT:
		case Types.REAL:
		case Types.DOUBLE:
		case Types.NUMERIC:
		case Types.DECIMAL:
			ret = "double";
			break;

		case Types.CHAR:
		case Types.VARCHAR:
		case Types.LONGVARCHAR:
			ret = "String";
			break;

		case Types.DATE:
			ret = "java.sql.Date";
			break;

		case Types.TIME:
			ret = "java.sql.Time";
			break;

		case Types.TIMESTAMP:
			ret = "java.sql.Timestamp";
			break;

		case Types.BINARY:
			ret = "byte[]";
			break;

		case Types.VARBINARY:
			ret = "byte[]";
			break;

		case Types.LONGVARBINARY:
			ret = "byte[]";
			break;

		case Types.BLOB:
			ret = "byte[]";
			break;

		case Types.CLOB:
			ret = "String";
			break;
		case Types.BOOLEAN:
			ret = "boolean";
			break;

		case Types.ROWID:
			ret = "String";
			break;

		case Types.NCHAR:
			ret = "String";
			break;

		case Types.NVARCHAR:
			ret = "String";
			break;

		case Types.LONGNVARCHAR:
			ret = "String";
			break;

		case Types.NCLOB:
			ret = "String";
			break;

		case Types.SQLXML:
			ret = "String";
			break;
		case Types.TIME_WITH_TIMEZONE:
			ret = "java.sql.Time";
			break;

		case Types.TIMESTAMP_WITH_TIMEZONE:
			ret = "java.sql.Timestamp";
			break;
		}

		return ret;
	}


	public static JdbcSqlTypeMap getInstance() {
		return instance;
	}

}

@@ -310,16 +310,87 @@
 ap%3C%3E();%0D
+%0A%09%0D%0A%09private Map%3CInteger, String%3E jdbcTypeInvertMap = new HashMap%3C%3E();%0D
 %0A%0D%0A%09priv
@@ -621,16 +621,106 @@
 ull));%0D%0A
+%09%09%09%09jdbcTypeInvertMap.put(field.getInt(null), String.format(%22%25s%22, field.getName()));%09%09%09%09%0D%0A
 %09%09%09%7D%0D%0A%09%09
@@ -827,19 +827,111 @@
 ;%0D%0A%09%09%7D%0D%0A
-
 %09%7D%0D
+%0A%09%0D%0A%09public String findJdbcTypeName(int jt)%0D%0A%09%7B%0D%0A%09%09return jdbcTypeInvertMap.get(jt);%0D%0A%09%7D%0D%0A%09%0D
 %0A%0D%0A%09publ
@@ -2794,32 +2794,34 @@
 g%22;%0D%0A%09%09%09break;%0D%0A
+//
 %09%09case Types.TIM
@@ -2830,32 +2830,34 @@
 WITH_TIMEZONE:%0D%0A
+//
 %09%09%09ret = %22java.s
@@ -2859,32 +2859,34 @@
 ava.sql.Time%22;%0D%0A
+//
 %09%09%09break;%0D%0A%0D%0A%09%09c
@@ -2872,34 +2872,38 @@
 ;%0D%0A//%09%09%09break;%0D%0A
-%0D%0A
+//%0D%0A//
 %09%09case Types.TIM
@@ -2921,24 +2921,26 @@
 _TIMEZONE:%0D%0A
+//
 %09%09%09ret = %22ja
@@ -2951,32 +2951,34 @@
 ql.Timestamp%22;%0D%0A
+//
 %09%09%09break;%0D%0A%09%09%7D%0D%0A
@@ -2977,18 +2977,16 @@
 ;%0D%0A%09%09%7D%0D%0A
-%0D%0A
 %09%09return
@@ -3073,11 +3073,13 @@
 %0D%0A%09%7D%0D%0A%0D%0A
-
 %7D%0D%0A
+%0D%0A

Update JdbcSqlTypeMap.java