1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package liquibase.database.typeconversion.ext;
27
28 import liquibase.database.Database;
29 import liquibase.database.structure.Column;
30 import liquibase.database.core.DerbyDatabase;
31 import liquibase.database.structure.type.*;
32 import liquibase.exception.UnexpectedLiquibaseException;
33 import liquibase.util.StringUtils;
34
35 import java.lang.reflect.Field;
36 import java.sql.Types;
37 import java.text.ParseException;
38 import java.util.Arrays;
39 import java.util.List;
40
41 import static liquibase.ext.Constants.EXTENSION_PRIORITY;
42
43
44
45
46
47
48 public class DerbyTypeConverter extends liquibase.database.typeconversion.core.DerbyTypeConverter {
49 protected static final List<Integer> oneParam = Arrays.asList(
50 Types.CHAR,
51 -15,
52 Types.VARCHAR,
53 -9,
54 Types.VARBINARY,
55 Types.DOUBLE,
56 Types.FLOAT
57 );
58
59 protected static final List<Integer> twoParams = Arrays.asList(
60 Types.DECIMAL,
61 Types.NUMERIC,
62 Types.REAL
63 );
64
65 public int getPriority() {
66 return EXTENSION_PRIORITY;
67 }
68
69 @Override
70 public Object convertDatabaseValueToObject(Object value, int databaseDataType, int firstParameter, int secondParameter, Database database) throws ParseException {
71 if (value == null) {
72 return null;
73 } else if (value instanceof String) {
74 return convertToCorrectObjectType(((String) value).trim().replaceFirst("^'", "").replaceFirst("'$", ""), databaseDataType, firstParameter, secondParameter, database);
75 } else {
76 return value;
77 }
78 }
79
80 @Override
81 public String convertToDatabaseTypeString(Column referenceColumn, Database database) {
82 final StringBuilder retval = new StringBuilder();
83 try {
84 retval.append(getSqlTypeName(referenceColumn.getDataType()));
85 }
86 catch (Exception e) {
87 retval.append(referenceColumn.getTypeName());
88 }
89
90
91 final boolean hasOneParam = oneParam.contains(referenceColumn.getDataType());
92 final boolean hasTwoParams = twoParams.contains(referenceColumn.getDataType());
93
94
95 if (hasOneParam || hasTwoParams) {
96 retval.append("(").append(referenceColumn.getColumnSize());
97 if (hasTwoParams) {
98 retval.append(",").append(referenceColumn.getDecimalDigits());
99 }
100 retval.append(")");
101 }
102
103
104 return retval.toString();
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119 protected String getSqlTypeName(final int type) throws Exception {
120 for (final Field field : Types.class.getFields()) {
121 final int sql_type = field.getInt(null);
122 if (type == sql_type) {
123 return "java.sql.Types." + field.getName();
124 }
125 }
126 return null;
127 }
128
129 @Override
130 protected DataType getDataType(String columnTypeString, Boolean autoIncrement, String dataTypeName, String precision, String additionalInformation) {
131
132 DataType returnTypeName = null;
133 if (dataTypeName.equalsIgnoreCase("BIGINT")) {
134 returnTypeName = getBigIntType();
135 } else if (dataTypeName.equalsIgnoreCase("NUMBER")
136 || dataTypeName.equalsIgnoreCase("DECIMAL")
137 || dataTypeName.equalsIgnoreCase("NUMERIC")) {
138 returnTypeName = getNumberType();
139 } else if (dataTypeName.equalsIgnoreCase("BLOB")) {
140 returnTypeName = getBlobType();
141 } else if (dataTypeName.equalsIgnoreCase("BOOLEAN")) {
142 returnTypeName = getBooleanType();
143 } else if (dataTypeName.equalsIgnoreCase("CHAR")) {
144 returnTypeName = getCharType();
145 } else if (dataTypeName.equalsIgnoreCase("CLOB")) {
146 returnTypeName = getClobType();
147 } else if (dataTypeName.equalsIgnoreCase("CURRENCY")) {
148 returnTypeName = getCurrencyType();
149 } else if (dataTypeName.equalsIgnoreCase("DATE") || dataTypeName.equalsIgnoreCase(getDateType().getDataTypeName())) {
150 returnTypeName = getDateType();
151 } else if (dataTypeName.equalsIgnoreCase("DATETIME") || dataTypeName.equalsIgnoreCase(getDateTimeType().getDataTypeName())) {
152 returnTypeName = getDateTimeType();
153 } else if (dataTypeName.equalsIgnoreCase("DOUBLE")) {
154 returnTypeName = getDoubleType();
155 } else if (dataTypeName.equalsIgnoreCase("FLOAT")) {
156 returnTypeName = getFloatType();
157 } else if (dataTypeName.equalsIgnoreCase("INT")) {
158 returnTypeName = getIntType();
159 } else if (dataTypeName.equalsIgnoreCase("INTEGER")) {
160 returnTypeName = getIntType();
161 } else if (dataTypeName.equalsIgnoreCase("LONGBLOB")) {
162 returnTypeName = getLongBlobType();
163 } else if (dataTypeName.equalsIgnoreCase("LONGVARBINARY")) {
164 returnTypeName = getBlobType();
165 } else if (dataTypeName.equalsIgnoreCase("LONGVARCHAR")) {
166 returnTypeName = getClobType();
167 } else if (dataTypeName.equalsIgnoreCase("SMALLINT")) {
168 returnTypeName = getSmallIntType();
169 } else if (dataTypeName.equalsIgnoreCase("TEXT")) {
170 returnTypeName = getClobType();
171 } else if (dataTypeName.equalsIgnoreCase("TIME") || dataTypeName.equalsIgnoreCase(getTimeType().getDataTypeName())) {
172 returnTypeName = getTimeType();
173 } else if (dataTypeName.toUpperCase().contains("TIMESTAMP")) {
174 returnTypeName = getDateTimeType();
175 } else if (dataTypeName.equalsIgnoreCase("TINYINT")) {
176 returnTypeName = getTinyIntType();
177 } else if (dataTypeName.equalsIgnoreCase("UUID")) {
178 returnTypeName = getUUIDType();
179 } else if (dataTypeName.equalsIgnoreCase("VARCHAR")) {
180 returnTypeName = getVarcharType();
181 } else if (dataTypeName.equalsIgnoreCase("NVARCHAR")) {
182 returnTypeName = getNVarcharType();
183 } else {
184 return new CustomType(columnTypeString,0,2);
185 }
186
187 if (returnTypeName == null) {
188 throw new UnexpectedLiquibaseException("Could not determine " + dataTypeName + " for " + this.getClass().getName());
189 }
190 addPrecisionToType(precision, returnTypeName);
191 returnTypeName.setAdditionalInformation(additionalInformation);
192
193 return returnTypeName;
194 }
195
196 protected void addPrecisionToType(String precision, DataType returnTypeName) throws NumberFormatException {
197 if (precision != null) {
198 String[] params = precision.split(",");
199 if (Integer.parseInt(params[0].trim()) > 31 && params.length > 1) {
200 params[0] = "31";
201 }
202 returnTypeName.setFirstParameter(params[0].trim());
203 if (params.length > 1) {
204 returnTypeName.setSecondParameter(params[1].trim());
205 }
206 }
207 }
208 }