001package com.avaje.ebean.config.dbplatform; 002 003import java.sql.Types; 004import java.util.HashMap; 005import java.util.Map; 006 007/** 008 * Used to map bean property types to DB specific types for DDL generation. 009 */ 010public class DbTypeMap { 011 012 private static final DbType JSON_CLOB_PLACEHOLDER = new DbType("jsonClobPlaceholder"); 013 private static final DbType JSON_BLOB_PLACEHOLDER = new DbType("jsonBlobPlaceholder"); 014 private static final DbType JSON_VARCHAR_PLACEHOLDER = new DbType("jsonVarcharPlaceholder"); 015 016 /** 017 * A map to reverse lookup the type by name. 018 * <p> 019 * Used when converting from logical types to platform types which we 020 * want to do with 2 phase DDL generation. 021 */ 022 static Map<String, Integer> lookup = new HashMap<String, Integer>(); 023 024 static { 025 lookup.put("BOOLEAN", Types.BOOLEAN); 026 lookup.put("BIT", Types.BIT); 027 lookup.put("INTEGER", Types.INTEGER); 028 lookup.put("BIGINT", Types.BIGINT); 029 lookup.put("REAL", Types.REAL); 030 // Float is most common REAL mapping to have that as well 031 lookup.put("FLOAT", Types.REAL); 032 033 lookup.put("DOUBLE", Types.DOUBLE); 034 lookup.put("SMALLINT", Types.SMALLINT); 035 lookup.put("TINYINT", Types.TINYINT); 036 lookup.put("DECIMAL", Types.DECIMAL); 037 lookup.put("VARCHAR", Types.VARCHAR); 038 // VARCHAR2 - extra for Oracle specific column definition 039 lookup.put("VARCHAR2", Types.VARCHAR); 040 lookup.put("CHAR", Types.CHAR); 041 lookup.put("BLOB", Types.BLOB); 042 lookup.put("CLOB", Types.CLOB); 043 044 lookup.put("LONGVARBINARY", Types.LONGVARBINARY); 045 lookup.put("LONGVARCHAR", Types.LONGVARCHAR); 046 lookup.put("VARBINARY", Types.VARBINARY); 047 lookup.put("BINARY", Types.BINARY); 048 lookup.put("DATE", Types.DATE); 049 lookup.put("TIME", Types.TIME); 050 lookup.put("TIMESTAMP", Types.TIMESTAMP); 051 052 lookup.put("UUID", DbType.UUID); 053 054 // Not standard java.sql.Types 055 // logical JSON storage types 056 lookup.put("JSON", DbType.JSON); 057 lookup.put("JSONB", DbType.JSONB); 058 lookup.put("JSONCLOB", DbType.JSONClob); 059 lookup.put("JSONBLOB", DbType.JSONBlob); 060 lookup.put("JSONVARCHAR", DbType.JSONVarchar); 061 } 062 063 064 private final Map<Integer, DbType> typeMap = new HashMap<Integer, DbType>(); 065 066 /** 067 * Return the DbTypeMap with standard (not platform specific) types. 068 * 069 * This has some extended JSON types (JSON, JSONB, JSONVarchar, JSONClob, JSONBlob). 070 * These types get translated to specific database platform types during DDL generation. 071 */ 072 public static DbTypeMap logicalTypes() { 073 return new DbTypeMap(true); 074 } 075 076 public DbTypeMap() { 077 loadDefaults(false); 078 } 079 080 private DbTypeMap(boolean logicalTypes) { 081 loadDefaults(logicalTypes); 082 } 083 084 /** 085 * Load the standard types. These can be overridden by DB specific platform. 086 */ 087 private void loadDefaults(boolean logicalTypes) { 088 089 put(Types.BOOLEAN, new DbType("boolean")); 090 put(Types.BIT, new DbType("bit")); 091 092 put(Types.INTEGER, new DbType("integer")); 093 put(Types.BIGINT, new DbType("bigint")); 094 put(Types.REAL, new DbType("float")); 095 put(Types.DOUBLE, new DbType("double")); 096 put(Types.SMALLINT, new DbType("smallint")); 097 put(Types.TINYINT, new DbType("tinyint")); 098 put(Types.DECIMAL, new DbType("decimal", 38)); 099 100 put(Types.VARCHAR, new DbType("varchar", 255)); 101 put(Types.CHAR, new DbType("char", 1)); 102 103 put(Types.BLOB, new DbType("blob")); 104 put(Types.CLOB, new DbType("clob")); 105 106 // DB native UUID support (H2 and Postgres) 107 put(DbType.UUID, new DbType("uuid")); 108 109 if (logicalTypes) { 110 // keep it logical for 2 layer DDL generation 111 put(DbType.HSTORE, new DbType("hstore")); 112 put(DbType.JSON, new DbType("json")); 113 put(DbType.JSONB, new DbType("jsonb")); 114 put(DbType.JSONClob, new DbType("jsonclob")); 115 put(DbType.JSONBlob, new DbType("jsonblob")); 116 put(DbType.JSONVarchar, new DbType("jsonvarchar", 1000)); 117 118 } else { 119 put(DbType.JSON, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSON 120 put(DbType.JSONB, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSONB 121 put(DbType.JSONClob, JSON_CLOB_PLACEHOLDER); 122 put(DbType.JSONBlob, JSON_BLOB_PLACEHOLDER); 123 put(DbType.JSONVarchar, JSON_VARCHAR_PLACEHOLDER); 124 } 125 126 put(Types.LONGVARBINARY, new DbType("longvarbinary")); 127 put(Types.LONGVARCHAR, new DbType("lonvarchar")); 128 put(Types.VARBINARY, new DbType("varbinary", 255)); 129 put(Types.BINARY, new DbType("binary", 255)); 130 131 put(Types.DATE, new DbType("date")); 132 put(Types.TIME, new DbType("time")); 133 put(Types.TIMESTAMP, new DbType("timestamp")); 134 135 } 136 137 /** 138 * Lookup the platform specific DbType given the standard sql type name. 139 */ 140 public DbType lookup(String name) { 141 name = name.trim().toUpperCase(); 142 Integer typeKey = lookup.get(name); 143 if (typeKey == null) { 144 throw new IllegalArgumentException("Unknown type [" + name + "] - not standard sql type"); 145 } 146 // handle JSON types mapped to clob, blob and varchar 147 switch (typeKey) { 148 case DbType.JSONBlob: 149 return get(Types.BLOB); 150 case DbType.JSONClob: 151 return get(Types.CLOB); 152 case DbType.JSONVarchar: 153 return get(Types.VARCHAR); 154 case DbType.JSON: 155 return getJsonType(DbType.JSON); 156 case DbType.JSONB: 157 return getJsonType(DbType.JSONB); 158 default: 159 return get(typeKey); 160 } 161 } 162 163 private DbType getJsonType(int type) { 164 DbType dbType = get(type); 165 if (dbType == JSON_CLOB_PLACEHOLDER) { 166 return get(Types.CLOB); 167 } 168 if (dbType == JSON_BLOB_PLACEHOLDER) { 169 return get(Types.BLOB); 170 } 171 if (dbType == JSON_VARCHAR_PLACEHOLDER) { 172 return get(Types.VARCHAR); 173 } 174 // Postgres has specific type 175 return get(type); 176 } 177 178 /** 179 * Override the type for a given JDBC type. 180 */ 181 public void put(int jdbcType, DbType dbType) { 182 typeMap.put(jdbcType, dbType); 183 } 184 185 /** 186 * Return the type for a given jdbc type. 187 */ 188 public DbType get(int jdbcType) { 189 return typeMap.get(jdbcType); 190 } 191}