1 56 package org.objectstyle.cayenne.dba; 57 58 import java.sql.DatabaseMetaData ; 59 import java.sql.ResultSet ; 60 import java.sql.SQLException ; 61 import java.sql.Types ; 62 import java.util.ArrayList ; 63 import java.util.HashMap ; 64 import java.util.Iterator ; 65 import java.util.List ; 66 import java.util.Map ; 67 import java.util.Set ; 68 69 78 public class TypesMapping { 79 public static final int NOT_DEFINED = Integer.MAX_VALUE; 82 83 public static final String SQL_ARRAY = "ARRAY"; 85 public static final String SQL_BIGINT = "BIGINT"; 86 public static final String SQL_BINARY = "BINARY"; 87 public static final String SQL_BIT = "BIT"; 88 public static final String SQL_BLOB = "BLOB"; 89 public static final String SQL_CLOB = "CLOB"; 90 public static final String SQL_CHAR = "CHAR"; 91 public static final String SQL_DATE = "DATE"; 92 public static final String SQL_DECIMAL = "DECIMAL"; 93 public static final String SQL_DOUBLE = "DOUBLE"; 94 public static final String SQL_FLOAT = "FLOAT"; 95 public static final String SQL_INTEGER = "INTEGER"; 96 public static final String SQL_LONGVARCHAR = "LONGVARCHAR"; 97 public static final String SQL_LONGVARBINARY = "LONGVARBINARY"; 98 public static final String SQL_NUMERIC = "NUMERIC"; 99 public static final String SQL_REAL = "REAL"; 100 public static final String SQL_SMALLINT = "SMALLINT"; 101 public static final String SQL_TINYINT = "TINYINT"; 102 public static final String SQL_TIME = "TIME"; 103 public static final String SQL_TIMESTAMP = "TIMESTAMP"; 104 public static final String SQL_VARBINARY = "VARBINARY"; 105 public static final String SQL_VARCHAR = "VARCHAR"; 106 public static final String SQL_OTHER = "OTHER"; 107 108 public static final String JAVA_LONG = "java.lang.Long"; 110 public static final String JAVA_BYTES = "byte[]"; 111 public static final String JAVA_BOOLEAN = "java.lang.Boolean"; 112 public static final String JAVA_STRING = "java.lang.String"; 113 public static final String JAVA_SQLDATE = "java.sql.Date"; 114 public static final String JAVA_UTILDATE = "java.util.Date"; 115 public static final String JAVA_BIGDECIMAL = "java.math.BigDecimal"; 116 public static final String JAVA_DOUBLE = "java.lang.Double"; 117 public static final String JAVA_FLOAT = "java.lang.Float"; 118 public static final String JAVA_INTEGER = "java.lang.Integer"; 119 public static final String JAVA_SHORT = "java.lang.Short"; 120 public static final String JAVA_BYTE = "java.lang.Byte"; 121 public static final String JAVA_TIME = "java.sql.Time"; 122 public static final String JAVA_TIMESTAMP = "java.sql.Timestamp"; 123 124 126 private static final Map sqlStringType = new HashMap (); 127 128 130 private static final Map sqlEnumType = new HashMap (); 131 132 134 private static final Map sqlEnumJava = new HashMap (); 135 136 138 private static final Map javaSqlEnum = new HashMap (); 139 140 static { 141 sqlStringType.put(SQL_ARRAY, new Integer (Types.ARRAY)); 142 sqlStringType.put(SQL_BIGINT, new Integer (Types.BIGINT)); 143 sqlStringType.put(SQL_BINARY, new Integer (Types.BINARY)); 144 sqlStringType.put(SQL_BIT, new Integer (Types.BIT)); 145 sqlStringType.put(SQL_BLOB, new Integer (Types.BLOB)); 146 sqlStringType.put(SQL_CLOB, new Integer (Types.CLOB)); 147 sqlStringType.put(SQL_CHAR, new Integer (Types.CHAR)); 148 sqlStringType.put(SQL_DATE, new Integer (Types.DATE)); 149 sqlStringType.put(SQL_DECIMAL, new Integer (Types.DECIMAL)); 150 sqlStringType.put(SQL_DOUBLE, new Integer (Types.DOUBLE)); 151 sqlStringType.put(SQL_FLOAT, new Integer (Types.FLOAT)); 152 sqlStringType.put(SQL_INTEGER, new Integer (Types.INTEGER)); 153 sqlStringType.put(SQL_LONGVARCHAR, new Integer (Types.LONGVARCHAR)); 154 sqlStringType.put(SQL_LONGVARBINARY, new Integer (Types.LONGVARBINARY)); 155 sqlStringType.put(SQL_NUMERIC, new Integer (Types.NUMERIC)); 156 sqlStringType.put(SQL_REAL, new Integer (Types.REAL)); 157 sqlStringType.put(SQL_SMALLINT, new Integer (Types.SMALLINT)); 158 sqlStringType.put(SQL_TINYINT, new Integer (Types.TINYINT)); 159 sqlStringType.put(SQL_TIME, new Integer (Types.TIME)); 160 sqlStringType.put(SQL_TIMESTAMP, new Integer (Types.TIMESTAMP)); 161 sqlStringType.put(SQL_VARBINARY, new Integer (Types.VARBINARY)); 162 sqlStringType.put(SQL_VARCHAR, new Integer (Types.VARCHAR)); 163 sqlStringType.put(SQL_OTHER, new Integer (Types.OTHER)); 164 165 sqlEnumType.put(new Integer (Types.ARRAY), SQL_ARRAY); 166 sqlEnumType.put(new Integer (Types.BIGINT), SQL_BIGINT); 167 sqlEnumType.put(new Integer (Types.BINARY), SQL_BINARY); 168 sqlEnumType.put(new Integer (Types.BIT), SQL_BIT); 169 sqlEnumType.put(new Integer (Types.BLOB), SQL_BLOB); 170 sqlEnumType.put(new Integer (Types.CLOB), SQL_CLOB); 171 sqlEnumType.put(new Integer (Types.CHAR), SQL_CHAR); 172 sqlEnumType.put(new Integer (Types.DATE), SQL_DATE); 173 sqlEnumType.put(new Integer (Types.DECIMAL), SQL_DECIMAL); 174 sqlEnumType.put(new Integer (Types.DOUBLE), SQL_DOUBLE); 175 sqlEnumType.put(new Integer (Types.FLOAT), SQL_FLOAT); 176 sqlEnumType.put(new Integer (Types.INTEGER), SQL_INTEGER); 177 sqlEnumType.put(new Integer (Types.LONGVARCHAR), SQL_LONGVARCHAR); 178 sqlEnumType.put(new Integer (Types.LONGVARBINARY), SQL_LONGVARBINARY); 179 sqlEnumType.put(new Integer (Types.NUMERIC), SQL_NUMERIC); 180 sqlEnumType.put(new Integer (Types.REAL), SQL_REAL); 181 sqlEnumType.put(new Integer (Types.SMALLINT), SQL_SMALLINT); 182 sqlEnumType.put(new Integer (Types.TINYINT), SQL_TINYINT); 183 sqlEnumType.put(new Integer (Types.TIME), SQL_TIME); 184 sqlEnumType.put(new Integer (Types.TIMESTAMP), SQL_TIMESTAMP); 185 sqlEnumType.put(new Integer (Types.VARBINARY), SQL_VARBINARY); 186 sqlEnumType.put(new Integer (Types.VARCHAR), SQL_VARCHAR); 187 sqlEnumType.put(new Integer (Types.OTHER), SQL_OTHER); 188 189 sqlEnumJava.put(new Integer (Types.BIGINT), JAVA_LONG); 190 sqlEnumJava.put(new Integer (Types.BINARY), JAVA_BYTES); 191 sqlEnumJava.put(new Integer (Types.BIT), JAVA_BOOLEAN); 192 sqlEnumJava.put(new Integer (Types.BLOB), JAVA_BYTES); 193 sqlEnumJava.put(new Integer (Types.CLOB), JAVA_STRING); 194 sqlEnumJava.put(new Integer (Types.CHAR), JAVA_STRING); 195 sqlEnumJava.put(new Integer (Types.DATE), JAVA_UTILDATE); 196 sqlEnumJava.put(new Integer (Types.DECIMAL), JAVA_BIGDECIMAL); 197 sqlEnumJava.put(new Integer (Types.DOUBLE), JAVA_DOUBLE); 198 sqlEnumJava.put(new Integer (Types.FLOAT), JAVA_FLOAT); 199 sqlEnumJava.put(new Integer (Types.INTEGER), JAVA_INTEGER); 200 sqlEnumJava.put(new Integer (Types.LONGVARCHAR), JAVA_STRING); 201 sqlEnumJava.put(new Integer (Types.LONGVARBINARY), JAVA_BYTES); 202 sqlEnumJava.put(new Integer (Types.NUMERIC), JAVA_BIGDECIMAL); 203 sqlEnumJava.put(new Integer (Types.REAL), JAVA_FLOAT); 204 sqlEnumJava.put(new Integer (Types.SMALLINT), JAVA_SHORT); 205 sqlEnumJava.put(new Integer (Types.TINYINT), JAVA_BYTE); 206 sqlEnumJava.put(new Integer (Types.TIME), JAVA_UTILDATE); 207 sqlEnumJava.put(new Integer (Types.TIMESTAMP), JAVA_UTILDATE); 208 sqlEnumJava.put(new Integer (Types.VARBINARY), JAVA_BYTES); 209 sqlEnumJava.put(new Integer (Types.VARCHAR), JAVA_STRING); 210 211 javaSqlEnum.put(JAVA_LONG, new Integer (Types.BIGINT)); 212 javaSqlEnum.put(JAVA_BYTES, new Integer (Types.BINARY)); 213 javaSqlEnum.put(JAVA_BOOLEAN, new Integer (Types.BIT)); 214 javaSqlEnum.put(JAVA_STRING, new Integer (Types.VARCHAR)); 215 javaSqlEnum.put(JAVA_SQLDATE, new Integer (Types.DATE)); 216 javaSqlEnum.put(JAVA_TIMESTAMP, new Integer (Types.TIMESTAMP)); 217 javaSqlEnum.put(JAVA_BIGDECIMAL, new Integer (Types.DECIMAL)); 218 javaSqlEnum.put(JAVA_DOUBLE, new Integer (Types.DOUBLE)); 219 javaSqlEnum.put(JAVA_FLOAT, new Integer (Types.FLOAT)); 220 javaSqlEnum.put(JAVA_INTEGER, new Integer (Types.INTEGER)); 221 javaSqlEnum.put(JAVA_SHORT, new Integer (Types.SMALLINT)); 222 javaSqlEnum.put(JAVA_BYTE, new Integer (Types.TINYINT)); 223 javaSqlEnum.put(JAVA_TIME, new Integer (Types.TIME)); 224 javaSqlEnum.put(JAVA_TIMESTAMP, new Integer (Types.TIMESTAMP)); 225 } 226 227 231 public static boolean supportsLength(int type) { 232 return type == Types.BINARY 233 || type == Types.CHAR 234 || type == Types.DECIMAL 235 || type == Types.DOUBLE 236 || type == Types.FLOAT 237 || type == Types.NUMERIC 238 || type == Types.REAL 239 || type == Types.VARBINARY 240 || type == Types.VARCHAR; 241 } 242 243 246 public static boolean isNumeric(int type) { 247 return type == Types.BIGINT 248 || type == Types.BIT 249 || type == Types.DECIMAL 250 || type == Types.DOUBLE 251 || type == Types.FLOAT 252 || type == Types.INTEGER 253 || type == Types.NUMERIC 254 || type == Types.REAL 255 || type == Types.SMALLINT 256 || type == Types.TINYINT; 257 } 258 259 262 public static boolean isDecimal(int type) { 263 return type == Types.DECIMAL 264 || type == Types.DOUBLE 265 || type == Types.FLOAT 266 || type == Types.REAL 267 || type == Types.NUMERIC; 268 } 269 270 271 public static String [] getDatabaseTypes() { 272 Set keys = sqlStringType.keySet(); 273 int len = keys.size(); 274 String [] types = new String [len]; 275 276 Iterator it = keys.iterator(); 277 for (int i = 0; i < len; i++) { 278 types[i] = (String ) it.next(); 279 } 280 281 return types; 282 } 283 284 286 protected static String pickDataType(int jdbcType, TypeInfo[] alts) { 287 int len = alts.length; 288 289 if (len == 0) 290 return null; 291 292 if (len == 1) 293 return alts[0].name; 294 295 297 String jdbcName = getSqlNameByType(jdbcType).toUpperCase(); 298 299 for (int i = 0; i < len; i++) { 301 if (jdbcName.equalsIgnoreCase(alts[i].name)) 302 return alts[i].name; 303 } 304 305 long maxPrec = 0; 307 for (int i = 0; i < len; i++) { 308 if (maxPrec < alts[i].precision) { 309 maxPrec = alts[i].precision; 310 } 311 } 312 313 List list = new ArrayList (); 314 for (int i = 0; i < len; i++) { 315 if (maxPrec == alts[i].precision) { 316 list.add(alts[i]); 317 } 318 } 319 320 int slen = list.size(); 322 if (slen == 1) 323 return ((TypeInfo) list.get(0)).name; 324 325 for (int i = 0; i < slen; i++) { 327 String uppercase = ((TypeInfo) list.get(i)).name.toUpperCase(); 328 if (uppercase.startsWith(jdbcName) || uppercase.endsWith(jdbcName)) 329 return ((TypeInfo) list.get(i)).name; 330 } 331 332 for (int i = 0; i < slen; i++) { 334 String uppercase = ((TypeInfo) list.get(i)).name.toUpperCase(); 335 336 if (uppercase.indexOf(jdbcName) >= 0) 337 return ((TypeInfo) list.get(i)).name; 338 } 339 340 return ((TypeInfo) list.get(0)).name; 342 } 343 344 347 public static int getSqlTypeByName(String typeName) { 348 Integer tmp = (Integer ) sqlStringType.get(typeName); 349 return (null == tmp) ? NOT_DEFINED : tmp.intValue(); 350 } 351 352 355 public static String getSqlNameByType(int type) { 356 return (String ) sqlEnumType.get(new Integer (type)); 357 } 358 359 365 public static int getSqlTypeByJava(String javaTypeName) { 366 Integer temp = (Integer ) javaSqlEnum.get(javaTypeName); 367 return (null == temp) ? NOT_DEFINED : temp.intValue(); 368 } 369 370 375 public static int getSqlTypeByJava(Class javaClass) { 376 while (javaClass != null) { 377 Object type = javaSqlEnum.get(javaClass.getName()); 378 if (type != null) { 379 return ((Number ) type).intValue(); 380 } 381 382 javaClass = javaClass.getSuperclass(); 383 } 384 385 return NOT_DEFINED; 386 } 387 388 393 public static String getJavaBySqlType(int type) { 394 return (String ) sqlEnumJava.get(new Integer (type)); 395 } 396 397 402 public static String getJavaBySqlType(int type, int length, int precision) { 403 404 if (type == Types.NUMERIC && precision == 0) { 405 type = Types.INTEGER; 406 } 407 return (String ) sqlEnumJava.get(new Integer (type)); 408 } 409 410 414 protected Map databaseTypes = new HashMap (); 415 416 public TypesMapping(DatabaseMetaData metaData) throws SQLException { 417 ResultSet rs = metaData.getTypeInfo(); 419 420 try { 421 while (rs.next()) { 422 TypeInfo info = new TypeInfo(); 423 info.name = rs.getString("TYPE_NAME"); 424 info.jdbcType = rs.getInt("DATA_TYPE"); 425 info.precision = rs.getLong("PRECISION"); 426 427 Integer key = new Integer (info.jdbcType); 428 List infos = (List ) databaseTypes.get(key); 429 430 if (infos == null) { 431 infos = new ArrayList (); 432 databaseTypes.put(key, infos); 433 } 434 435 infos.add(info); 436 } 437 } 438 finally { 439 rs.close(); 440 } 441 442 444 Integer ts = new Integer (Types.TIMESTAMP); 446 Integer dt = new Integer (Types.DATE); 447 List tsInfo = (List ) databaseTypes.get(ts); 448 List dtInfo = (List ) databaseTypes.get(dt); 449 450 if (tsInfo != null && dtInfo == null) 451 databaseTypes.put(dt, tsInfo); 452 453 if (dtInfo != null && tsInfo == null) 454 databaseTypes.put(ts, dtInfo); 455 456 Integer clob = new Integer (Types.CLOB); 458 Integer lvc = new Integer (Types.LONGVARCHAR); 459 List clobInfo = (List ) databaseTypes.get(clob); 460 List lvcInfo = (List ) databaseTypes.get(lvc); 461 462 if (clobInfo != null && lvcInfo == null) 463 databaseTypes.put(lvc, clobInfo); 464 465 if (lvcInfo != null && clobInfo == null) 466 databaseTypes.put(clob, lvcInfo); 467 468 Integer blob = new Integer (Types.BLOB); 470 Integer lvb = new Integer (Types.LONGVARBINARY); 471 List blobInfo = (List ) databaseTypes.get(blob); 472 List lvbInfo = (List ) databaseTypes.get(lvb); 473 474 if (blobInfo != null && lvbInfo == null) 475 databaseTypes.put(lvb, blobInfo); 476 477 if (lvbInfo != null && blobInfo == null) 478 databaseTypes.put(blob, lvbInfo); 479 } 480 481 482 static class TypeInfo { 483 String name; 484 int jdbcType; 485 long precision; 486 487 public String toString() { 488 StringBuffer buf = new StringBuffer (); 489 buf.append("[ TypeInfo: ").append(name); 490 buf.append("\n JDBC Type: ").append( 491 TypesMapping.getSqlNameByType(jdbcType)); 492 buf.append("\n Precision: ").append(precision); 493 buf.append("\n]"); 494 return buf.toString(); 495 } 496 } 497 498 } | Popular Tags |