Exemple #1
0
  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);
 }