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.core.OracleDatabase;
30 import liquibase.database.structure.Column;
31 import liquibase.database.structure.type.*;
32 import liquibase.exception.UnexpectedLiquibaseException;
33 import liquibase.util.StringUtils;
34
35
36 import java.lang.reflect.Field;
37 import java.sql.Types;
38 import java.text.ParseException;
39 import java.util.Arrays;
40 import java.util.List;
41
42 import static liquibase.ext.Constants.EXTENSION_PRIORITY;
43
44
45
46
47
48 public class OracleTypeConverter extends liquibase.database.typeconversion.core.OracleTypeConverter {
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 public int getPriority() {
65 return EXTENSION_PRIORITY;
66 }
67
68 @Override
69 public Object convertDatabaseValueToObject(Object value, int databaseDataType, int firstParameter, int secondParameter, Database database) throws ParseException {
70 if (value == null) {
71 return null;
72 } else if (value instanceof String) {
73 return convertToCorrectObjectType(((String) value).trim().replaceFirst("^'", "").replaceFirst("'$", ""), databaseDataType, firstParameter, secondParameter, database);
74 } else {
75 return value;
76 }
77 }
78
79 @Override
80 public String convertToDatabaseTypeString(Column referenceColumn, Database database) {
81 final StringBuilder retval = new StringBuilder();
82 try {
83 retval.append(getSqlTypeName(referenceColumn.getDataType()));
84 }
85 catch (Exception e) {
86 retval.append(referenceColumn.getTypeName());
87 }
88
89
90 final boolean hasOneParam = oneParam.contains(referenceColumn.getDataType());
91 final boolean hasTwoParams = twoParams.contains(referenceColumn.getDataType());
92
93
94 if (hasOneParam || hasTwoParams) {
95 retval.append("(").append(referenceColumn.getColumnSize());
96 if (hasTwoParams) {
97 retval.append(",").append(referenceColumn.getDecimalDigits());
98 }
99 retval.append(")");
100 }
101
102
103 return retval.toString();
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118 protected String getSqlTypeName(final int type) throws Exception {
119 for (final Field field : Types.class.getFields()) {
120 final int sql_type = field.getInt(null);
121 if (type == sql_type) {
122 return "java.sql.Types." + field.getName();
123 }
124 }
125 return null;
126 }
127
128 @Override
129 protected DataType getDataType(String columnTypeString, Boolean autoIncrement, String dataTypeName, String precision, String additionalInformation) {
130
131 DataType returnTypeName = null;
132 if (dataTypeName.equalsIgnoreCase("BIGINT")) {
133 returnTypeName = getBigIntType();
134 } else if (dataTypeName.equalsIgnoreCase("NUMBER")
135 || dataTypeName.equalsIgnoreCase("DECIMAL")
136 || dataTypeName.equalsIgnoreCase("NUMERIC")) {
137 returnTypeName = getNumberType();
138 } else if (dataTypeName.equalsIgnoreCase("BLOB")) {
139 returnTypeName = getBlobType();
140 } else if (dataTypeName.equalsIgnoreCase("BOOLEAN")) {
141 returnTypeName = getBooleanType();
142 } else if (dataTypeName.equalsIgnoreCase("CHAR")) {
143 returnTypeName = getCharType();
144 } else if (dataTypeName.equalsIgnoreCase("CLOB")) {
145 returnTypeName = getClobType();
146 } else if (dataTypeName.equalsIgnoreCase("CURRENCY")) {
147 returnTypeName = getCurrencyType();
148 } else if (dataTypeName.equalsIgnoreCase("DATE") || dataTypeName.equalsIgnoreCase(getDateType().getDataTypeName())) {
149 returnTypeName = getDateType();
150 } else if (dataTypeName.equalsIgnoreCase("DATETIME") || dataTypeName.equalsIgnoreCase(getDateTimeType().getDataTypeName())) {
151 returnTypeName = getDateTimeType();
152 } else if (dataTypeName.equalsIgnoreCase("DOUBLE")) {
153 returnTypeName = getDoubleType();
154 } else if (dataTypeName.equalsIgnoreCase("FLOAT")) {
155 returnTypeName = getFloatType();
156 } else if (dataTypeName.equalsIgnoreCase("INT")) {
157 returnTypeName = getIntType();
158 } else if (dataTypeName.equalsIgnoreCase("INTEGER")) {
159 returnTypeName = getIntType();
160 } else if (dataTypeName.equalsIgnoreCase("LONGBLOB")) {
161 returnTypeName = getLongBlobType();
162 } else if (dataTypeName.equalsIgnoreCase("LONGVARBINARY")) {
163 returnTypeName = getBlobType();
164 } else if (dataTypeName.equalsIgnoreCase("LONGVARCHAR")) {
165 returnTypeName = getClobType();
166 } else if (dataTypeName.equalsIgnoreCase("SMALLINT")) {
167 returnTypeName = getSmallIntType();
168 } else if (dataTypeName.equalsIgnoreCase("TEXT")) {
169 returnTypeName = getClobType();
170 } else if (dataTypeName.equalsIgnoreCase("TIME") || dataTypeName.equalsIgnoreCase(getTimeType().getDataTypeName())) {
171 returnTypeName = getTimeType();
172 } else if (dataTypeName.toUpperCase().contains("TIMESTAMP")) {
173 returnTypeName = getDateTimeType();
174 } else if (dataTypeName.equalsIgnoreCase("TINYINT")) {
175 returnTypeName = getTinyIntType();
176 } else if (dataTypeName.equalsIgnoreCase("UUID")) {
177 returnTypeName = getUUIDType();
178 } else if (dataTypeName.equalsIgnoreCase("VARCHAR")) {
179 returnTypeName = getVarcharType();
180 } else if (dataTypeName.equalsIgnoreCase("NVARCHAR")) {
181 returnTypeName = getNVarcharType();
182 } else {
183 return new CustomType(columnTypeString,0,2);
184 }
185
186 if (returnTypeName == null) {
187 throw new UnexpectedLiquibaseException("Could not determine " + dataTypeName + " for " + this.getClass().getName());
188 }
189 addPrecisionToType(precision, returnTypeName);
190 returnTypeName.setAdditionalInformation(additionalInformation);
191
192 return returnTypeName;
193 }
194 }