001package io.ebean.config.dbplatform; 002 003/** 004 * Represents a DB type with name, length, precision, and scale. 005 * <p> 006 * The length is for VARCHAR types and precision/scale for DECIMAL types. 007 * </p> 008 */ 009public class DbPlatformType implements ExtraDbTypes { 010 011 /** 012 * The data type name (VARCHAR, INTEGER ...) 013 */ 014 private final String name; 015 016 /** 017 * The default length or precision. 018 */ 019 private final int defaultLength; 020 021 /** 022 * The default scale (decimal). 023 */ 024 private final int defaultScale; 025 026 /** 027 * Set to true if the type should never have a length or scale. 028 */ 029 private final boolean canHaveLength; 030 031 /** 032 * Parse a type definition into a DbPlatformType. 033 * <p> 034 * e.g. "decimal(18,6)" 035 * e.g. "text" 036 * </p> 037 */ 038 public static DbPlatformType parse(String columnDefinition) { 039 return DbPlatformTypeParser.parse(columnDefinition); 040 } 041 042 /** 043 * Construct with no length or scale. 044 */ 045 public DbPlatformType(String name) { 046 this(name, 0, 0); 047 } 048 049 /** 050 * Construct with a given length. 051 */ 052 public DbPlatformType(String name, int defaultLength) { 053 this(name, defaultLength, 0); 054 } 055 056 /** 057 * Construct for Decimal with precision and scale. 058 */ 059 public DbPlatformType(String name, int defaultPrecision, int defaultScale) { 060 this.name = name; 061 this.defaultLength = defaultPrecision; 062 this.defaultScale = defaultScale; 063 this.canHaveLength = true; 064 } 065 066 /** 067 * Use with canHaveLength=false for types that should never have a length. 068 * 069 * @param name the type name 070 * @param canHaveLength set this to false for type that should never have a length 071 */ 072 public DbPlatformType(String name, boolean canHaveLength) { 073 this.name = name; 074 this.defaultLength = 0; 075 this.defaultScale = 0; 076 this.canHaveLength = canHaveLength; 077 } 078 079 /** 080 * Return the type name. 081 */ 082 public String getName() { 083 return name; 084 } 085 086 /** 087 * Return the default length/precision. 088 */ 089 public int getDefaultLength() { 090 return defaultLength; 091 } 092 093 /** 094 * Return the default scale. 095 */ 096 public int getDefaultScale() { 097 return defaultScale; 098 } 099 100 /** 101 * Return the type for a specific property that incorporates the name, length, 102 * precision and scale. 103 * <p> 104 * The deployLength and deployScale are for the property we are rendering the 105 * DB type for. 106 * </p> 107 * 108 * @param deployLength the length or precision defined by deployment on a specific 109 * property. 110 * @param deployScale the scale defined by deployment on a specific property. 111 */ 112 public String renderType(int deployLength, int deployScale) { 113 return renderType(deployLength, deployScale, true); 114 } 115 116 /** 117 * Render the type defining strict mode. 118 * <p> 119 * If strict mode if OFF then this will render with a scale value even if 120 * that is not strictly supported. The reason for supporting this is to enable 121 * use to use types like jsonb(200) as a "logical" type that maps to JSONB for 122 * Postgres and VARCHAR(200) for other databases. 123 * </p> 124 */ 125 public String renderType(int deployLength, int deployScale, boolean strict) { 126 127 StringBuilder sb = new StringBuilder(); 128 sb.append(name); 129 if (canHaveLength || !strict) { 130 renderLengthScale(deployLength, deployScale, sb); 131 } 132 133 return sb.toString(); 134 } 135 136 /** 137 * Render the length and scale part of the column definition. 138 */ 139 protected void renderLengthScale(int deployLength, int deployScale, StringBuilder sb) { 140 // see if there is a precision/scale to add (or not) 141 int len = deployLength != 0 ? deployLength : defaultLength; 142 if (len == Integer.MAX_VALUE) { 143 sb.append("(max)"); // TODO: this is sqlserver specific 144 } else if (len > 0) { 145 sb.append("("); 146 sb.append(len); 147 int scale = deployScale != 0 ? deployScale : defaultScale; 148 if (scale > 0) { 149 sb.append(","); 150 sb.append(scale); 151 } 152 sb.append(")"); 153 } 154 } 155 156 /** 157 * Create a copy of the type with a new default length. 158 */ 159 public DbPlatformType withLength(int defaultLength) { 160 return new DbPlatformType(name, defaultLength); 161 } 162}