public static Object parseValue(Database database, Object val, DataType type) { if (!(val instanceof String)) { return val; } int typeId = Integer.MIN_VALUE; if (type.getDataTypeId() != null) { typeId = type.getDataTypeId(); } String typeName = type.getTypeName(); LiquibaseDataType liquibaseDataType = DataTypeFactory.getInstance().from(type, database); String stringVal = (String) val; if (stringVal.isEmpty()) { if (liquibaseDataType instanceof CharType) { return ""; } else { return null; } } if (database instanceof OracleDatabase && !stringVal.startsWith("'") && !stringVal.endsWith("'")) { // oracle returns functions without quotes Object maybeDate = null; if (liquibaseDataType instanceof DateType || typeId == Types.DATE) { if (stringVal.endsWith("'HH24:MI:SS')")) { maybeDate = DataTypeFactory.getInstance() .fromDescription("time", database) .sqlToObject(stringVal, database); } else { maybeDate = DataTypeFactory.getInstance() .fromDescription("date", database) .sqlToObject(stringVal, database); } } else if (liquibaseDataType instanceof DateTimeType || typeId == Types.TIMESTAMP) { maybeDate = DataTypeFactory.getInstance() .fromDescription("datetime", database) .sqlToObject(stringVal, database); } else { return new DatabaseFunction(stringVal); } if (maybeDate != null) { if (maybeDate instanceof java.util.Date) { return maybeDate; } else { return new DatabaseFunction(stringVal); } } } if (stringVal.startsWith("'") && stringVal.endsWith("'")) { stringVal = stringVal.substring(1, stringVal.length() - 1); } else if (stringVal.startsWith("((") && stringVal.endsWith("))")) { stringVal = stringVal.substring(2, stringVal.length() - 2); } else if (stringVal.startsWith("('") && stringVal.endsWith("')")) { stringVal = stringVal.substring(2, stringVal.length() - 2); } else if (stringVal.startsWith("(") && stringVal.endsWith(")")) { return new DatabaseFunction(stringVal.substring(1, stringVal.length() - 1)); } Scanner scanner = new Scanner(stringVal.trim()); if (typeId == Types.ARRAY) { return new DatabaseFunction(stringVal); } else if ((liquibaseDataType instanceof BigIntType || typeId == Types.BIGINT)) { if (scanner.hasNextBigInteger()) { return scanner.nextBigInteger(); } else { return new DatabaseFunction(stringVal); } } else if (typeId == Types.BINARY) { return new DatabaseFunction(stringVal.trim()); } else if (typeId == Types.BIT) { if (stringVal.startsWith("b'")) { // mysql returns boolean values as b'0' and b'1' stringVal = stringVal.replaceFirst("b'", "").replaceFirst("'$", ""); } stringVal = stringVal.trim(); if (scanner.hasNextBoolean()) { return scanner.nextBoolean(); } else { return new Integer(stringVal); } } else if (liquibaseDataType instanceof BlobType || typeId == Types.BLOB) { return new DatabaseFunction(stringVal); } else if ((liquibaseDataType instanceof BooleanType || typeId == Types.BOOLEAN)) { if (scanner.hasNextBoolean()) { return scanner.nextBoolean(); } else { return new DatabaseFunction(stringVal); } } else if (liquibaseDataType instanceof CharType || typeId == Types.CHAR) { return stringVal; } else if (liquibaseDataType instanceof ClobType || typeId == Types.CLOB) { return stringVal; } else if (typeId == Types.DATALINK) { return new DatabaseFunction(stringVal); } else if (liquibaseDataType instanceof DateType || typeId == Types.DATE) { if (typeName.equalsIgnoreCase("year")) { return stringVal.trim(); } return DataTypeFactory.getInstance() .fromDescription("date", database) .sqlToObject(stringVal, database); } else if ((liquibaseDataType instanceof DecimalType || typeId == Types.DECIMAL)) { if (scanner.hasNextBigDecimal()) { return scanner.nextBigDecimal(); } else { return new DatabaseFunction(stringVal); } } else if (typeId == Types.DISTINCT) { return new DatabaseFunction(stringVal); } else if ((liquibaseDataType instanceof DoubleType || typeId == Types.DOUBLE)) { if (scanner.hasNextDouble()) { return scanner.nextDouble(); } else { return new DatabaseFunction(stringVal); } } else if ((liquibaseDataType instanceof FloatType || typeId == Types.FLOAT)) { if (scanner.hasNextFloat()) { return scanner.nextFloat(); } else { return new DatabaseFunction(stringVal); } } else if ((liquibaseDataType instanceof IntType || typeId == Types.INTEGER)) { if (scanner.hasNextInt()) { return scanner.nextInt(); } else { return new DatabaseFunction(stringVal); } } else if (typeId == Types.JAVA_OBJECT) { return new DatabaseFunction(stringVal); } else if (typeId == Types.LONGNVARCHAR) { return stringVal; } else if (typeId == Types.LONGVARBINARY) { return new DatabaseFunction(stringVal); } else if (typeId == Types.LONGVARCHAR) { return stringVal; } else if (liquibaseDataType instanceof NCharType || typeId == Types.NCHAR) { return stringVal; } else if (typeId == Types.NCLOB) { return stringVal; } else if (typeId == Types.NULL) { return null; } else if ((liquibaseDataType instanceof NumberType || typeId == Types.NUMERIC)) { if (scanner.hasNextBigDecimal()) { return scanner.nextBigDecimal(); } else { return new DatabaseFunction(stringVal); } } else if (liquibaseDataType instanceof NVarcharType || typeId == Types.NVARCHAR) { return stringVal; } else if (typeId == Types.OTHER) { if (database instanceof DB2Database && typeName.equalsIgnoreCase("DECFLOAT")) { return new BigDecimal(stringVal); } return new DatabaseFunction(stringVal); } else if (typeId == Types.REAL) { return new BigDecimal(stringVal.trim()); } else if (typeId == Types.REF) { return new DatabaseFunction(stringVal); } else if (typeId == Types.ROWID) { return new DatabaseFunction(stringVal); } else if ((liquibaseDataType instanceof SmallIntType || typeId == Types.SMALLINT)) { if (scanner.hasNextInt()) { return scanner.nextInt(); } else { return new DatabaseFunction(stringVal); } } else if (typeId == Types.SQLXML) { return new DatabaseFunction(stringVal); } else if (typeId == Types.STRUCT) { return new DatabaseFunction(stringVal); } else if (liquibaseDataType instanceof TimeType || typeId == Types.TIME) { return DataTypeFactory.getInstance() .fromDescription("time", database) .sqlToObject(stringVal, database); } else if (liquibaseDataType instanceof DateTimeType || liquibaseDataType instanceof TimestampType || typeId == Types.TIMESTAMP) { return DataTypeFactory.getInstance() .fromDescription("datetime", database) .sqlToObject(stringVal, database); } else if ((liquibaseDataType instanceof TinyIntType || typeId == Types.TINYINT)) { if (scanner.hasNextInt()) { return scanner.nextInt(); } else { return new DatabaseFunction(stringVal); } } else if (typeId == Types.VARBINARY) { return new DatabaseFunction(stringVal); } else if (liquibaseDataType instanceof VarcharType || typeId == Types.VARCHAR) { return stringVal; } else if (database instanceof MySQLDatabase && typeName.toLowerCase().startsWith("enum")) { return stringVal; } else { LogFactory.getLogger() .info( "Unknown default value: value '" + stringVal + "' type " + typeName + " (" + type + "), assuming it is a function"); return new DatabaseFunction(stringVal); } }
protected DataType readDataType( CachedRow columnMetadataResultSet, Column column, Database database) throws SQLException { if (database instanceof OracleDatabase) { String dataType = columnMetadataResultSet.getString("DATA_TYPE"); dataType = dataType.replace("VARCHAR2", "VARCHAR"); dataType = dataType.replace("NVARCHAR2", "NVARCHAR"); DataType type = new DataType(dataType); // type.setDataTypeId(dataType); if (dataType.equalsIgnoreCase("NUMBER")) { type.setColumnSize(columnMetadataResultSet.getInt("DATA_PRECISION")); // if (type.getColumnSize() == null) { // type.setColumnSize(38); // } type.setDecimalDigits(columnMetadataResultSet.getInt("DATA_SCALE")); // if (type.getDecimalDigits() == null) { // type.setDecimalDigits(0); // } // type.setRadix(10); } else { type.setColumnSize(columnMetadataResultSet.getInt("DATA_LENGTH")); if (dataType.equalsIgnoreCase("NCLOB") || dataType.equalsIgnoreCase("BLOB") || dataType.equalsIgnoreCase("CLOB")) { type.setColumnSize(null); } else if (dataType.equalsIgnoreCase("NVARCHAR") || dataType.equalsIgnoreCase("NCHAR")) { type.setColumnSize(columnMetadataResultSet.getInt("CHAR_LENGTH")); type.setColumnSizeUnit(DataType.ColumnSizeUnit.CHAR); } else { String charUsed = columnMetadataResultSet.getString("CHAR_USED"); DataType.ColumnSizeUnit unit = null; if ("C".equals(charUsed)) { unit = DataType.ColumnSizeUnit.CHAR; type.setColumnSize(columnMetadataResultSet.getInt("CHAR_LENGTH")); } type.setColumnSizeUnit(unit); } } return type; } String columnTypeName = (String) columnMetadataResultSet.get("TYPE_NAME"); if (database instanceof FirebirdDatabase) { if (columnTypeName.equals("BLOB SUB_TYPE 0")) { columnTypeName = "BLOB"; } if (columnTypeName.equals("BLOB SUB_TYPE 1")) { columnTypeName = "CLOB"; } } if (database instanceof MySQLDatabase && (columnTypeName.equalsIgnoreCase("ENUM") || columnTypeName.equalsIgnoreCase("SET"))) { try { String boilerLength; if (columnTypeName.equalsIgnoreCase("ENUM")) boilerLength = "7"; else // SET boilerLength = "6"; List<String> enumValues = ExecutorService.getInstance() .getExecutor(database) .queryForList( new RawSqlStatement( "SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(COLUMN_TYPE, " + boilerLength + ", LENGTH(COLUMN_TYPE) - " + boilerLength + " - 1 ), \"','\", 1 + units.i + tens.i * 10) , \"','\", -1)\n" + "FROM INFORMATION_SCHEMA.COLUMNS\n" + "CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units\n" + "CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens\n" + "WHERE TABLE_NAME = '" + column.getRelation().getName() + "' \n" + "AND COLUMN_NAME = '" + column.getName() + "'"), String.class); String enumClause = ""; for (String enumValue : enumValues) { enumClause += "'" + enumValue + "', "; } enumClause = enumClause.replaceFirst(", $", ""); return new DataType(columnTypeName + "(" + enumClause + ")"); } catch (DatabaseException e) { LogFactory.getLogger().warning("Error fetching enum values", e); } } DataType.ColumnSizeUnit columnSizeUnit = DataType.ColumnSizeUnit.BYTE; int dataType = columnMetadataResultSet.getInt("DATA_TYPE"); Integer columnSize = null; Integer decimalDigits = null; if (!database.dataTypeIsNotModifiable( columnTypeName)) { // don't set size for types like int4, int8 etc columnSize = columnMetadataResultSet.getInt("COLUMN_SIZE"); decimalDigits = columnMetadataResultSet.getInt("DECIMAL_DIGITS"); if (decimalDigits != null && decimalDigits.equals(0)) { decimalDigits = null; } } Integer radix = columnMetadataResultSet.getInt("NUM_PREC_RADIX"); Integer characterOctetLength = columnMetadataResultSet.getInt("CHAR_OCTET_LENGTH"); if (database instanceof DB2Database) { String typeName = columnMetadataResultSet.getString("TYPE_NAME"); if (typeName.equalsIgnoreCase("DBCLOB") || typeName.equalsIgnoreCase("GRAPHIC") || typeName.equalsIgnoreCase("VARGRAPHIC")) { if (columnSize != null) { columnSize = columnSize / 2; // Stored as double length chars } } } DataType type = new DataType(columnTypeName); type.setDataTypeId(dataType); type.setColumnSize(columnSize); type.setDecimalDigits(decimalDigits); type.setRadix(radix); type.setCharacterOctetLength(characterOctetLength); type.setColumnSizeUnit(columnSizeUnit); return type; }
public LiquibaseDataType from(DataType type, Database database) { if (type == null) { return null; } return fromDescription(type.toString(), database); }