package liquibase.database.typeconversion.core; import liquibase.database.Database; import liquibase.database.core.PostgresDatabase; import liquibase.database.structure.type.*; import java.text.ParseException; import java.sql.Types; public class PostgresTypeConverter extends AbstractTypeConverter { public int getPriority() { return PRIORITY_DATABASE; } public boolean supports(Database database) { return database instanceof PostgresDatabase; } @Override public Object convertDatabaseValueToObject(Object defaultValue, int dataType, int columnSize, int decimalDigits, Database database) throws ParseException { if (defaultValue != null) { if (defaultValue instanceof String) { defaultValue = ((String) defaultValue).replaceAll("'::[\\w\\s]+$", "'"); if (dataType == Types.DATE || dataType == Types.TIME || dataType == Types.TIMESTAMP) { //remove trailing time zone info defaultValue = ((String) defaultValue).replaceFirst("-\\d+$", ""); } } } return super.convertDatabaseValueToObject(defaultValue, dataType, columnSize, decimalDigits, database); } @Override public DataType getDataType(String columnTypeString, Boolean autoIncrement) { DataType type = super.getDataType(columnTypeString, autoIncrement); if (type.getDataTypeName().toLowerCase().contains("text")) { type = getClobType(); } else if (type.getDataTypeName().toLowerCase().contains("blob")) { type = getBlobType(); } else if (type.getDataTypeName().toLowerCase().startsWith("float8")) { type.setDataTypeName("FLOAT8"); } else if (type.getDataTypeName().toLowerCase().startsWith("float4")) { type.setDataTypeName("FLOAT4"); } if (autoIncrement != null && autoIncrement) { if ("integer".equals(type.getDataTypeName().toLowerCase())) { type.setDataTypeName("serial"); } else if ("bigint".equals(type.getDataTypeName().toLowerCase()) || "bigserial".equals(type.getDataTypeName().toLowerCase())) { type.setDataTypeName("bigserial"); } else { // Unknown integer type, default to "serial" type.setDataTypeName("serial"); } } return type; } @Override protected Object convertToCorrectObjectType(String value, int dataType, int columnSize, int decimalDigits, Database database) throws ParseException { Object returnValue = super.convertToCorrectObjectType(value, dataType, columnSize, decimalDigits, database); if (returnValue != null && returnValue instanceof String) { if (((String) returnValue).startsWith("NULL::")) { return null; } } return returnValue; } @Override public ClobType getClobType() { return new ClobType("TEXT"); } @Override public BlobType getBlobType() { return new BlobType("BYTEA"); } @Override public DateTimeType getDateTimeType() { return new DateTimeType("TIMESTAMP WITH TIME ZONE"); } @Override public NumberType getNumberType() { return new NumberType("NUMERIC"); } @Override public TinyIntType getTinyIntType() { return new TinyIntType("SMALLINT"); } @Override public DoubleType getDoubleType() { return new DoubleType("DOUBLE PRECISION"); } }