public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet)
     throws PreconditionFailedException, PreconditionErrorException {
   try {
     boolean checkPassed;
     if (getForeignKeyTableName() == null) {
       checkPassed =
           DatabaseSnapshotGeneratorFactory.getInstance()
                   .createSnapshot(database, getSchemaName(), null)
                   .getForeignKey(getForeignKeyName())
               != null;
     } else { // much faster if we can limit to correct table
       checkPassed =
           DatabaseSnapshotGeneratorFactory.getInstance()
                   .getGenerator(database)
                   .getForeignKeyByForeignKeyTable(
                       getSchemaName(), getForeignKeyTableName(), getForeignKeyName(), database)
               != null;
     }
     if (!checkPassed) {
       String message = "Foreign Key " + database.escapeStringForDatabase(getForeignKeyName());
       if (getForeignKeyTableName() != null) {
         message += " on table " + getForeignKeyTableName();
       }
       message += " does not exist";
       throw new PreconditionFailedException(message, changeLog, this);
     }
   } catch (DatabaseException e) {
     throw new PreconditionErrorException(e, changeLog, this);
   }
 }
Example #2
0
  @Override
  public String objectToSql(Object value, Database database) {
    if (value == null || value.toString().equalsIgnoreCase("null")) {
      return null;
    }

    if (value instanceof DatabaseFunction) {
      return value.toString();
    }

    String val = String.valueOf(value);
    // postgres type character varying gets identified as a char type
    // simple sanity check to avoid double quoting a value
    if (database instanceof PostgresDatabase && val.startsWith("'") && val.endsWith("'")) {
      return val;
    } else {
      if (database instanceof MSSQLDatabase && !StringUtils.isAscii(val)) {
        return "N'" + database.escapeStringForDatabase(val) + "'";
      }

      return "'" + database.escapeStringForDatabase(val) + "'";
    }
  }
  protected String getWhereClause(
      InsertOrUpdateStatement insertOrUpdateStatement, Database database) {
    StringBuffer where = new StringBuffer();

    String[] pkColumns = insertOrUpdateStatement.getPrimaryKey().split(",");

    for (String thisPkColumn : pkColumns) {
      where
          .append(
              database.escapeColumnName(
                  insertOrUpdateStatement.getSchemaName(),
                  insertOrUpdateStatement.getTableName(),
                  thisPkColumn))
          .append(" = ");
      Object newValue = insertOrUpdateStatement.getColumnValues().get(thisPkColumn);
      if (newValue == null || newValue.toString().equals("NULL")) {
        where.append("NULL");
      } else if (newValue instanceof String && database.shouldQuoteValue(((String) newValue))) {
        where.append("'").append(database.escapeStringForDatabase((String) newValue)).append("'");
      } else if (newValue instanceof Date) {
        where.append(database.getDateLiteral(((Date) newValue)));
      } else if (newValue instanceof Boolean) {
        if (((Boolean) newValue)) {
          where.append(
              TypeConverterFactory.getInstance()
                  .findTypeConverter(database)
                  .getBooleanType()
                  .getTrueBooleanValue());
        } else {
          where.append(
              TypeConverterFactory.getInstance()
                  .findTypeConverter(database)
                  .getBooleanType()
                  .getFalseBooleanValue());
        }
      } else {
        where.append(newValue);
      }

      where.append(" AND ");
    }

    where.delete(where.lastIndexOf(" AND "), where.lastIndexOf(" AND ") + " AND ".length());
    return where.toString();
  }
 // Copied from liquibase.sqlgenerator.core.InsertOrUpdateGeneratorMySQL
 private String convertToString(Object newValue, Database database) {
   String sqlString;
   if (newValue == null
       || newValue.toString().equals("")
       || newValue.toString().equalsIgnoreCase("NULL")) {
     sqlString = "NULL";
   } else if (newValue instanceof String
       && !looksLikeFunctionCall(((String) newValue), database)) {
     sqlString = "'" + database.escapeStringForDatabase(newValue.toString()) + "'";
   } else if (newValue instanceof Date) {
     sqlString = database.getDateLiteral(((Date) newValue));
   } else if (newValue instanceof Boolean) {
     if (((Boolean) newValue)) {
       sqlString = DataTypeFactory.getInstance().getTrueBooleanValue(database);
     } else {
       sqlString = DataTypeFactory.getInstance().getFalseBooleanValue(database);
     }
   } else {
     sqlString = newValue.toString();
   }
   return sqlString;
 }
  @Override
  public Sql[] generateSql(
      MarkChangeSetRanStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    String dateValue = database.getCurrentDateTimeFunction();

    ChangeSet changeSet = statement.getChangeSet();

    SqlStatement runStatement;
    try {
      if (statement.getExecType().equals(ChangeSet.ExecType.FAILED)
          || statement.getExecType().equals(ChangeSet.ExecType.SKIPPED)) {
        return new Sql[0]; // don't mark
      } else if (statement.getExecType().ranBefore) {
        runStatement =
            new UpdateStatement(
                    database.getLiquibaseCatalogName(),
                    database.getLiquibaseSchemaName(),
                    database.getDatabaseChangeLogTableName())
                .addNewColumnValue("DATEEXECUTED", new DatabaseFunction(dateValue))
                .addNewColumnValue("MD5SUM", changeSet.generateCheckSum().toString())
                .addNewColumnValue("EXECTYPE", statement.getExecType().value)
                .setWhereClause("ID=? AND AUTHOR=? AND FILENAME=?")
                .addWhereParameters(
                    changeSet.getId(), changeSet.getAuthor(), changeSet.getFilePath());
      } else {
        runStatement =
            new InsertStatement(
                    database.getLiquibaseCatalogName(),
                    database.getLiquibaseSchemaName(),
                    database.getDatabaseChangeLogTableName())
                .addColumnValue("ID", changeSet.getId())
                .addColumnValue("AUTHOR", changeSet.getAuthor())
                .addColumnValue("FILENAME", changeSet.getFilePath())
                .addColumnValue("DATEEXECUTED", new DatabaseFunction(dateValue))
                .addColumnValue(
                    "ORDEREXECUTED",
                    ChangeLogHistoryServiceFactory.getInstance()
                        .getChangeLogService(database)
                        .getNextSequenceValue())
                .addColumnValue("MD5SUM", changeSet.generateCheckSum().toString())
                .addColumnValue("DESCRIPTION", limitSize(changeSet.getDescription()))
                .addColumnValue(
                    "COMMENTS",
                    limitSize(
                        database.escapeStringForDatabase(
                            StringUtils.trimToEmpty(changeSet.getComments()))))
                .addColumnValue("EXECTYPE", statement.getExecType().value)
                .addColumnValue(
                    "LIQUIBASE", LiquibaseUtil.getBuildVersion().replaceAll("SNAPSHOT", "SNP"));

        String tag = null;
        List<Change> changes = changeSet.getChanges();
        if (changes != null && changes.size() == 1) {
          Change change = changes.get(0);
          if (change instanceof TagDatabaseChange) {
            TagDatabaseChange tagChange = (TagDatabaseChange) change;
            tag = tagChange.getTag();
          }
        }
        if (tag != null) {
          ((InsertStatement) runStatement).addColumnValue("TAG", tag);
        }
      }
    } catch (LiquibaseException e) {
      throw new UnexpectedLiquibaseException(e);
    }

    return SqlGeneratorFactory.getInstance().generateSql(runStatement, database);
  }
  @Override
  protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot)
      throws DatabaseException, InvalidExampleException {
    Database database = snapshot.getDatabase();
    Relation relation = ((Column) example).getRelation();
    if (((Column) example).getComputed() != null && ((Column) example).getComputed()) {
      return example;
    }
    Schema schema = relation.getSchema();

    List<CachedRow> columnMetadataRs = null;
    try {

      JdbcDatabaseSnapshot.CachingDatabaseMetaData databaseMetaData =
          ((JdbcDatabaseSnapshot) snapshot).getMetaData();

      columnMetadataRs =
          databaseMetaData.getColumns(
              ((AbstractJdbcDatabase) database).getJdbcCatalogName(schema),
              ((AbstractJdbcDatabase) database).getJdbcSchemaName(schema),
              relation.getName(),
              example.getName());

      if (columnMetadataRs.size() > 0) {
        CachedRow data = columnMetadataRs.get(0);
        Column column = readColumn(data, relation, database);

        if (column != null
            && database instanceof MSSQLDatabase
            && database.getDatabaseMajorVersion() >= 8) {
          String sql;
          if (database.getDatabaseMajorVersion() >= 9) {
            // SQL Server 2005 or later
            // https://technet.microsoft.com/en-us/library/ms177541.aspx
            sql =
                "SELECT CAST([ep].[value] AS [nvarchar](MAX)) AS [REMARKS] "
                    + "FROM [sys].[extended_properties] AS [ep] "
                    + "WHERE [ep].[class] = 1 "
                    + "AND [ep].[major_id] = OBJECT_ID(N'"
                    + database.escapeStringForDatabase(
                        database.escapeTableName(
                            schema.getCatalogName(), schema.getName(), relation.getName()))
                    + "') "
                    + "AND [ep].[minor_id] = COLUMNPROPERTY([ep].[major_id], N'"
                    + database.escapeStringForDatabase(column.getName())
                    + "', 'ColumnId') "
                    + "AND [ep].[name] = 'MS_Description'";
          } else {
            // SQL Server 2000
            // https://technet.microsoft.com/en-us/library/aa224810%28v=sql.80%29.aspx
            sql =
                "SELECT CAST([p].[value] AS [ntext]) AS [REMARKS] "
                    + "FROM [dbo].[sysproperties] AS [p] "
                    + "WHERE [p].[id] = OBJECT_ID(N'"
                    + database.escapeStringForDatabase(
                        database.escapeTableName(
                            schema.getCatalogName(), schema.getName(), relation.getName()))
                    + "') "
                    + "AND [p].[smallid] = COLUMNPROPERTY([p].[id], N'"
                    + database.escapeStringForDatabase(column.getName())
                    + "', 'ColumnId') "
                    + "AND [p].[type] = 4 "
                    + "AND [p].[name] = 'MS_Description'";
          }

          List<String> remarks =
              ExecutorService.getInstance()
                  .getExecutor(snapshot.getDatabase())
                  .queryForList(new RawSqlStatement(sql), String.class);
          if (remarks != null && remarks.size() > 0) {
            column.setRemarks(StringUtils.trimToNull(remarks.iterator().next()));
          }
        }

        return column;
      } else {
        return null;
      }
    } catch (Exception e) {
      throw new DatabaseException(e);
    }
  }