Search in sources :

Example 6 with AbstractDb2Database

use of liquibase.database.core.AbstractDb2Database in project liquibase by liquibase.

the class SqlUtil method parseValue.

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();
    }
    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 if (!stringVal.matches("\\d+\\.?\\d*")) {
            // not just a number
            return new DatabaseFunction(stringVal);
        }
        if (maybeDate != null) {
            if (maybeDate instanceof java.util.Date) {
                return maybeDate;
            } else {
                return new DatabaseFunction(stringVal);
            }
        }
    }
    boolean strippedSingleQuotes = false;
    if (stringVal.startsWith("'") && stringVal.endsWith("'")) {
        stringVal = stringVal.substring(1, stringVal.length() - 1);
        strippedSingleQuotes = true;
    } 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));
    }
    String typeName = type.getTypeName();
    try (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'") || stringVal.startsWith("B'")) {
                // mysql returns boolean values as b'0' and b'1'
                stringVal = stringVal.replaceFirst("b'", "").replaceFirst("B'", "").replaceFirst("'$", "");
            }
            // postgres defaults for bit columns look like: B'0'::"bit"
            if (stringVal.endsWith("'::\"bit\"")) {
                stringVal = stringVal.replaceFirst("'::\"bit\"", "");
            }
            stringVal = stringVal.trim();
            if (database instanceof MySQLDatabase) {
                return "1".equals(stringVal) || "true".equalsIgnoreCase(stringVal);
            }
            Object value = stringVal;
            if (scanner.hasNextBoolean()) {
                value = scanner.nextBoolean();
            } else if (scanner.hasNextInt()) {
                value = Integer.valueOf(stringVal);
            }
            // Make sure we handle BooleanType values which are not Boolean
            if (database instanceof MSSQLDatabase) {
                if (value instanceof Boolean) {
                    if ((Boolean) value) {
                        return new DatabaseFunction("'true'");
                    } else {
                        return new DatabaseFunction("'false'");
                    }
                } else if (value instanceof Integer) {
                    if (((Integer) value) != 0) {
                        return new DatabaseFunction("'true'");
                    } else {
                        return new DatabaseFunction("'false'");
                    }
                } else {
                    // you can declare in MsSQL: `col_name bit default 'nonsense'`
                    return new DatabaseFunction(String.format("'%s'", value));
                }
            }
            return value;
        } else if (liquibaseDataType instanceof BlobType || typeId == Types.BLOB) {
            if (strippedSingleQuotes) {
                return stringVal;
            } else {
                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 || liquibaseDataType.getName().equalsIgnoreCase("NCLOB")) {
            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()) {
                if (database instanceof MSSQLDatabase && stringVal.endsWith(".0") || stringVal.endsWith(".00") || stringVal.endsWith(".000")) {
                    // MSSQL can store the value with the decimal digits. return it directly to avoid unexpected differences
                    return new DatabaseFunction(stringVal);
                }
                return scanner.nextBigDecimal();
            } else {
                if (stringVal.equals("")) {
                    // can have numeric default '' on sql server
                    return new DatabaseFunction("''");
                }
                return new DatabaseFunction(stringVal);
            }
        } else if (liquibaseDataType instanceof NVarcharType || typeId == Types.NVARCHAR) {
            return stringVal;
        } else if (typeId == Types.OTHER) {
            if (database instanceof AbstractDb2Database && 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 if ((database instanceof MSSQLDatabase) && typeName.toLowerCase().startsWith("datetimeoffset")) {
            return stringVal;
        } else {
            if (stringVal.equals("")) {
                return stringVal;
            }
            Scope.getCurrentScope().getLog(SqlUtil.class).info("Unknown default value: value '" + stringVal + "' type " + typeName + " (" + type + "). Calling it a function so it's not additionally quoted");
            if (strippedSingleQuotes) {
                // put quotes back
                return new DatabaseFunction("'" + stringVal + "'");
            }
            return new DatabaseFunction(stringVal);
        }
    }
}
Also used : Scanner(java.util.Scanner) DatabaseFunction(liquibase.statement.DatabaseFunction) AbstractDb2Database(liquibase.database.core.AbstractDb2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) LiquibaseDataType(liquibase.datatype.LiquibaseDataType) MySQLDatabase(liquibase.database.core.MySQLDatabase) BigDecimal(java.math.BigDecimal) OracleDatabase(liquibase.database.core.OracleDatabase)

Example 7 with AbstractDb2Database

use of liquibase.database.core.AbstractDb2Database in project liquibase by liquibase.

the class CreateTableGeneratorTest method testAutoIncrementStartWithIncrementByDB2Database.

@Test
public void testAutoIncrementStartWithIncrementByDB2Database() throws Exception {
    for (Database database : TestContext.getInstance().getAllDatabases()) {
        if (database instanceof AbstractDb2Database) {
            CreateTableStatement statement = new CreateTableStatement(CATALOG_NAME, SCHEMA_NAME, TABLE_NAME);
            statement.addColumn(COLUMN_NAME1, DataTypeFactory.getInstance().fromDescription("BIGINT{autoIncrement:true}", database), new AutoIncrementConstraint(COLUMN_NAME1, BigInteger.ZERO, BigInteger.TEN));
            Sql[] generatedSql = this.generatorUnderTest.generateSql(statement, database, null);
            assertEquals("CREATE TABLE \"CATALOG_NAME\".TABLE_NAME (COLUMN1_NAME BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 0, INCREMENT BY 10))", generatedSql[0].toSql());
        }
    }
}
Also used : AbstractDb2Database(liquibase.database.core.AbstractDb2Database) CreateTableStatement(liquibase.statement.core.CreateTableStatement) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DerbyDatabase(liquibase.database.core.DerbyDatabase) H2Database(liquibase.database.core.H2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) MySQLDatabase(liquibase.database.core.MySQLDatabase) PostgresDatabase(liquibase.database.core.PostgresDatabase) OracleDatabase(liquibase.database.core.OracleDatabase) SybaseDatabase(liquibase.database.core.SybaseDatabase) SybaseASADatabase(liquibase.database.core.SybaseASADatabase) Database(liquibase.database.Database) AbstractDb2Database(liquibase.database.core.AbstractDb2Database) HsqlDatabase(liquibase.database.core.HsqlDatabase) Sql(liquibase.sql.Sql) AbstractSqlGeneratorTest(liquibase.sqlgenerator.AbstractSqlGeneratorTest) Test(org.junit.Test)

Example 8 with AbstractDb2Database

use of liquibase.database.core.AbstractDb2Database in project liquibase by liquibase.

the class CreateTableGeneratorTest method testAutoIncrementStartWithDB2Database.

@Test
public void testAutoIncrementStartWithDB2Database() throws Exception {
    for (Database database : TestContext.getInstance().getAllDatabases()) {
        if (database instanceof AbstractDb2Database) {
            CreateTableStatement statement = new CreateTableStatement(CATALOG_NAME, SCHEMA_NAME, TABLE_NAME);
            statement.addColumn(COLUMN_NAME1, DataTypeFactory.getInstance().fromDescription("BIGINT{autoIncrement:true}", database), new AutoIncrementConstraint(COLUMN_NAME1, BigInteger.ZERO, null));
            Sql[] generatedSql = this.generatorUnderTest.generateSql(statement, database, null);
            assertEquals("CREATE TABLE \"CATALOG_NAME\".TABLE_NAME (COLUMN1_NAME BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 0))", generatedSql[0].toSql());
        }
    }
}
Also used : AbstractDb2Database(liquibase.database.core.AbstractDb2Database) CreateTableStatement(liquibase.statement.core.CreateTableStatement) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DerbyDatabase(liquibase.database.core.DerbyDatabase) H2Database(liquibase.database.core.H2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) MySQLDatabase(liquibase.database.core.MySQLDatabase) PostgresDatabase(liquibase.database.core.PostgresDatabase) OracleDatabase(liquibase.database.core.OracleDatabase) SybaseDatabase(liquibase.database.core.SybaseDatabase) SybaseASADatabase(liquibase.database.core.SybaseASADatabase) Database(liquibase.database.Database) AbstractDb2Database(liquibase.database.core.AbstractDb2Database) HsqlDatabase(liquibase.database.core.HsqlDatabase) Sql(liquibase.sql.Sql) AbstractSqlGeneratorTest(liquibase.sqlgenerator.AbstractSqlGeneratorTest) Test(org.junit.Test)

Aggregations

AbstractDb2Database (liquibase.database.core.AbstractDb2Database)8 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)8 OracleDatabase (liquibase.database.core.OracleDatabase)8 MySQLDatabase (liquibase.database.core.MySQLDatabase)7 Sql (liquibase.sql.Sql)7 PostgresDatabase (liquibase.database.core.PostgresDatabase)6 SybaseASADatabase (liquibase.database.core.SybaseASADatabase)6 SQLiteDatabase (liquibase.database.core.SQLiteDatabase)5 SybaseDatabase (liquibase.database.core.SybaseDatabase)5 Database (liquibase.database.Database)4 DerbyDatabase (liquibase.database.core.DerbyDatabase)4 H2Database (liquibase.database.core.H2Database)4 HsqlDatabase (liquibase.database.core.HsqlDatabase)4 AbstractSqlGeneratorTest (liquibase.sqlgenerator.AbstractSqlGeneratorTest)4 CreateTableStatement (liquibase.statement.core.CreateTableStatement)4 Test (org.junit.Test)4 UnparsedSql (liquibase.sql.UnparsedSql)3 InformixDatabase (liquibase.database.core.InformixDatabase)2 DatabaseFunction (liquibase.statement.DatabaseFunction)2 BigDecimal (java.math.BigDecimal)1