package liquibase.datatype.core; import liquibase.database.Database; import liquibase.database.core.*; import liquibase.datatype.DataTypeInfo; import liquibase.datatype.DatabaseDataType; import liquibase.datatype.LiquibaseDataType; import liquibase.util.StringUtils; import java.math.BigInteger; import java.util.Arrays; @DataTypeInfo(name = "blob", aliases = {"longblob", "longvarbinary", "java.sql.Types.BLOB", "java.sql.Types.LONGBLOB", "java.sql.Types.LONGVARBINARY", "java.sql.Types.VARBINARY", "java.sql.Types.BINARY", "varbinary", "binary", "image", "tinyblob", "mediumblob"}, minParameters = 0, maxParameters = 1, priority = LiquibaseDataType.PRIORITY_DEFAULT) public class BlobType extends LiquibaseDataType { @Override public DatabaseDataType toDatabaseDataType(Database database) { String originalDefinition = StringUtils.trimToEmpty(getRawDefinition()); if (database instanceof H2Database || database instanceof HsqlDatabase) { if (originalDefinition.toLowerCase().startsWith("varbinary") || originalDefinition.startsWith("java.sql.Types.VARBINARY")) { return new DatabaseDataType("VARBINARY", getParameters()); } else if (originalDefinition.toLowerCase().startsWith("longvarbinary") || originalDefinition.startsWith("java.sql.Types.LONGVARBINARY")) { return new DatabaseDataType("LONGVARBINARY", getParameters()); } else if (originalDefinition.toLowerCase().startsWith("binary")) { return new DatabaseDataType("BINARY", getParameters()); } else { return new DatabaseDataType("BLOB"); } } if (database instanceof MSSQLDatabase) { Object[] parameters = getParameters(); if (originalDefinition.equalsIgnoreCase("varbinary") || originalDefinition.equals("[varbinary]") || originalDefinition.matches("(?i)varbinary\\s*\\(.+") || originalDefinition.matches("\\[varbinary\\]\\s*\\(.+")) { return new DatabaseDataType(database.escapeDataTypeName("varbinary"), maybeMaxParam(parameters, database)); } else if (originalDefinition.equalsIgnoreCase("binary") || originalDefinition.equals("[binary]") || originalDefinition.matches("(?i)binary\\s*\\(.+") || originalDefinition.matches("\\[binary\\]\\s*\\(.+")) { if (parameters.length < 1) { parameters = new Object[]{1}; } else if (parameters.length > 1) { parameters = Arrays.copyOfRange(parameters, 0, 1); } return new DatabaseDataType(database.escapeDataTypeName("binary"), parameters); } if (originalDefinition.equalsIgnoreCase("image") || originalDefinition.equals("[image]") || originalDefinition.matches("(?i)image\\s*\\(.+") || originalDefinition.matches("\\[image\\]\\s*\\(.+")) { return new DatabaseDataType(database.escapeDataTypeName("image")); } if (parameters.length == 0) { return new DatabaseDataType(database.escapeDataTypeName("varbinary"), "MAX"); } else { return new DatabaseDataType(database.escapeDataTypeName("varbinary"), maybeMaxParam(parameters, database)); } } if (database instanceof MySQLDatabase) { if (originalDefinition.toLowerCase().startsWith("blob") || originalDefinition.equals("java.sql.Types.BLOB")) { return new DatabaseDataType("BLOB"); } else if (originalDefinition.toLowerCase().startsWith("varbinary") || originalDefinition.equals("java.sql.Types.VARBINARY")) { return new DatabaseDataType("VARBINARY", getParameters()); } else if (originalDefinition.toLowerCase().startsWith("tinyblob")) { return new DatabaseDataType("TINYBLOB"); } else if (originalDefinition.toLowerCase().startsWith("mediumblob")) { return new DatabaseDataType("MEDIUMBLOB"); } else if (originalDefinition.toLowerCase().startsWith("binary")) { return new DatabaseDataType("BINARY", getParameters()); } else { return new DatabaseDataType("LONGBLOB"); } } if (database instanceof PostgresDatabase) { if (originalDefinition.toLowerCase().startsWith("blob") || originalDefinition.equals("java.sql.Types.BLOB")) { return new DatabaseDataType("OID"); } return new DatabaseDataType("BYTEA"); } if (database instanceof SybaseASADatabase) { return new DatabaseDataType("LONG BINARY"); } if (database instanceof SybaseDatabase) { return new DatabaseDataType("IMAGE"); } if (database instanceof OracleDatabase) { if (getRawDefinition().toLowerCase().startsWith("bfile")) { return new DatabaseDataType("BFILE"); } if (originalDefinition.toLowerCase().startsWith("raw") || originalDefinition.toLowerCase().startsWith("binary") || originalDefinition.toLowerCase().startsWith("varbinary")) { return new DatabaseDataType("RAW", getParameters()); } return new DatabaseDataType("BLOB"); } if (database instanceof FirebirdDatabase) { return new DatabaseDataType("BLOB"); } return super.toDatabaseDataType(database); } private Object[] maybeMaxParam(Object[] parameters, Database database) { if (parameters.length < 1) { parameters = new Object[]{1}; } else if (parameters.length > 1) { parameters = Arrays.copyOfRange(parameters, 0, 1); } boolean max = true; if (parameters.length > 0) { String param1 = parameters[0].toString(); max = !param1.matches("\\d+") || new BigInteger(param1).compareTo(BigInteger.valueOf(8000L)) > 0; } if (max) { return new Object[]{"MAX"}; } if (parameters.length > 1) { parameters = Arrays.copyOfRange(parameters, 0, 1); } return parameters; } @Override public String objectToSql(Object value, Database database) { if (value == null) { return null; } else if (value instanceof String) { return "'" + value + "'"; } else { return value.toString(); } } //sqlite // } else if (columnTypeString.toLowerCase(Locale.ENGLISH).contains("blob") || // columnTypeString.toLowerCase(Locale.ENGLISH).contains("binary")) { // type = new BlobType("BLOB"); }