Search in sources :

Example 1 with CharType

use of liquibase.datatype.core.CharType in project liquibase by liquibase.

the class AddDefaultValueGenerator method validate.

@Override
public ValidationErrors validate(AddDefaultValueStatement addDefaultValueStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    Object defaultValue = addDefaultValueStatement.getDefaultValue();
    ValidationErrors validationErrors = new ValidationErrors();
    validationErrors.checkRequiredField("defaultValue", defaultValue);
    validationErrors.checkRequiredField("columnName", addDefaultValueStatement.getColumnName());
    validationErrors.checkRequiredField("tableName", addDefaultValueStatement.getTableName());
    if (!database.supportsSequences() && defaultValue instanceof SequenceNextValueFunction) {
        validationErrors.addError("Database " + database.getShortName() + " does not support sequences");
    }
    if (database instanceof HsqlDatabase) {
        if (defaultValue instanceof SequenceNextValueFunction) {
            validationErrors.addError("Database " + database.getShortName() + " does not support adding sequence-based default values");
        } else if (defaultValue instanceof DatabaseFunction && !HsqlDatabase.supportsDefaultValueComputed(addDefaultValueStatement.getColumnDataType(), defaultValue.toString())) {
            validationErrors.addError("Database " + database.getShortName() + " does not support adding function-based default values");
        }
    }
    String columnDataType = addDefaultValueStatement.getColumnDataType();
    if (columnDataType != null) {
        LiquibaseDataType dataType = DataTypeFactory.getInstance().fromDescription(columnDataType, database);
        boolean typeMismatch = false;
        if (dataType instanceof BooleanType) {
            if (!(defaultValue instanceof Boolean)) {
                typeMismatch = true;
            }
        } else if (dataType instanceof CharType) {
            if (!(defaultValue instanceof String) && !(defaultValue instanceof DatabaseFunction)) {
                typeMismatch = true;
            }
        }
        if (typeMismatch) {
            validationErrors.addError("Default value of " + defaultValue + " does not match defined type of " + columnDataType);
        }
    }
    return validationErrors;
}
Also used : HsqlDatabase(liquibase.database.core.HsqlDatabase) DatabaseFunction(liquibase.statement.DatabaseFunction) ValidationErrors(liquibase.exception.ValidationErrors) LiquibaseDataType(liquibase.datatype.LiquibaseDataType) BooleanType(liquibase.datatype.core.BooleanType) SequenceNextValueFunction(liquibase.statement.SequenceNextValueFunction) CharType(liquibase.datatype.core.CharType)

Example 2 with CharType

use of liquibase.datatype.core.CharType in project liquibase by liquibase.

the class DataTypeFactory method fromDescription.

//    public Map<String, SortedSet<Class<? extends LiquibaseDataType>>> getRegistry() {
//        return registry;
//    }
//    public LiquibaseDataType fromDescription(String dataTypeDefinition) {
//        return fromDescription(dataTypeDefinition, null);
//    }
public LiquibaseDataType fromDescription(String dataTypeDefinition, Database database) {
    String dataTypeName = dataTypeDefinition;
    if (dataTypeName.matches(".+\\(.*\\).*")) {
        dataTypeName = dataTypeName.replaceFirst("\\s*\\(.*\\)", "");
    }
    if (dataTypeName.matches(".+\\{.*")) {
        dataTypeName = dataTypeName.replaceFirst("\\s*\\{.*", "");
    }
    boolean autoIncrement = false;
    if (dataTypeName.endsWith(" identity")) {
        dataTypeName = dataTypeName.replaceFirst(" identity$", "");
        autoIncrement = true;
    }
    // unquote delimited identifiers
    final String[][] quotePairs = new String[][] { // double quotes
    { "\"", "\"" }, // square brackets (a la mssql)
    { "[", "]" }, // backticks (a la mysql)
    { "`", "`" }, // single quotes
    { "'", "'" } };
    for (String[] quotePair : quotePairs) {
        String openQuote = quotePair[0];
        String closeQuote = quotePair[1];
        if (dataTypeName.startsWith(openQuote)) {
            int indexOfCloseQuote = dataTypeName.indexOf(closeQuote, openQuote.length());
            if (indexOfCloseQuote != -1 && dataTypeName.indexOf(closeQuote, indexOfCloseQuote + closeQuote.length()) == -1) {
                dataTypeName = dataTypeName.substring(openQuote.length(), indexOfCloseQuote) + dataTypeName.substring(indexOfCloseQuote + closeQuote.length(), dataTypeName.length());
                break;
            }
        }
    }
    String additionalInfo = null;
    if (dataTypeName.toLowerCase().startsWith("bit varying") || dataTypeName.toLowerCase().startsWith("character varying")) {
    //not going to do anything. Special case for postgres in our tests, need to better support handling these types of differences
    } else {
        String[] splitTypeName = dataTypeName.split("\\s+", 2);
        dataTypeName = splitTypeName[0];
        if (splitTypeName.length > 1) {
            additionalInfo = splitTypeName[1];
        }
    }
    Collection<Class<? extends LiquibaseDataType>> classes = registry.get(dataTypeName.toLowerCase());
    LiquibaseDataType liquibaseDataType = null;
    if (classes == null) {
        if (dataTypeName.toUpperCase().startsWith("INTERVAL")) {
            liquibaseDataType = new UnknownType(dataTypeDefinition);
        } else {
            liquibaseDataType = new UnknownType(dataTypeName);
        }
    } else {
        Iterator<Class<? extends LiquibaseDataType>> iterator = classes.iterator();
        do {
            try {
                liquibaseDataType = iterator.next().newInstance();
            } catch (Exception e) {
                throw new UnexpectedLiquibaseException(e);
            }
        } while ((database != null) && !liquibaseDataType.supports(database) && iterator.hasNext());
    }
    if ((database != null) && !liquibaseDataType.supports(database)) {
        throw new UnexpectedLiquibaseException("Could not find type for " + liquibaseDataType.toString() + " for databaes " + database.getShortName());
    }
    if (liquibaseDataType == null) {
        liquibaseDataType = new UnknownType(dataTypeName);
    }
    liquibaseDataType.setAdditionalInformation(additionalInfo);
    if (dataTypeDefinition.matches(".+\\s*\\(.*")) {
        String paramStrings = dataTypeDefinition.replaceFirst(".*?\\(", "").replaceFirst("\\).*", "");
        String[] params = paramStrings.split(",");
        for (String param : params) {
            param = StringUtils.trimToNull(param);
            if (param != null) {
                if (liquibaseDataType instanceof CharType && !(database instanceof OracleDatabase)) {
                    //only use byte types on oracle, not sure what else supports it
                    param = param.replaceFirst(" BYTE", "");
                }
                liquibaseDataType.addParameter(param);
            }
        }
    }
    if (dataTypeDefinition.matches(".*\\{.*")) {
        String paramStrings = dataTypeDefinition.replaceFirst(".*?\\{", "").replaceFirst("\\}.*", "");
        String[] params = paramStrings.split(",");
        for (String param : params) {
            param = StringUtils.trimToNull(param);
            if (param != null) {
                String[] paramAndValue = param.split(":", 2);
                try {
                    ObjectUtil.setProperty(liquibaseDataType, paramAndValue[0], paramAndValue[1]);
                } catch (Exception e) {
                    throw new RuntimeException("Unknown property " + paramAndValue[0] + " for " + liquibaseDataType.getClass().getName() + " " + liquibaseDataType.toString());
                }
            }
        }
    }
    if (autoIncrement && liquibaseDataType instanceof IntType) {
        ((IntType) liquibaseDataType).setAutoIncrement(true);
    }
    if (autoIncrement && liquibaseDataType instanceof BigIntType) {
        ((BigIntType) liquibaseDataType).setAutoIncrement(true);
    }
    liquibaseDataType.finishInitialization(dataTypeDefinition);
    return liquibaseDataType;
}
Also used : BigIntType(liquibase.datatype.core.BigIntType) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) IntType(liquibase.datatype.core.IntType) BigIntType(liquibase.datatype.core.BigIntType) UnknownType(liquibase.datatype.core.UnknownType) OracleDatabase(liquibase.database.core.OracleDatabase) CharType(liquibase.datatype.core.CharType) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException)

Aggregations

CharType (liquibase.datatype.core.CharType)2 HsqlDatabase (liquibase.database.core.HsqlDatabase)1 OracleDatabase (liquibase.database.core.OracleDatabase)1 LiquibaseDataType (liquibase.datatype.LiquibaseDataType)1 BigIntType (liquibase.datatype.core.BigIntType)1 BooleanType (liquibase.datatype.core.BooleanType)1 IntType (liquibase.datatype.core.IntType)1 UnknownType (liquibase.datatype.core.UnknownType)1 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)1 ValidationErrors (liquibase.exception.ValidationErrors)1 DatabaseFunction (liquibase.statement.DatabaseFunction)1 SequenceNextValueFunction (liquibase.statement.SequenceNextValueFunction)1