Search in sources :

Example 1 with LoadDataChange

use of liquibase.change.core.LoadDataChange in project liquibase by liquibase.

the class MissingDataExternalFileChangeGenerator method fixMissing.

@Override
public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outputControl, Database referenceDatabase, Database comparisionDatabase, ChangeGeneratorChain chain) {
    ResultSet rs = null;
    try (Statement stmt = ((JdbcConnection) referenceDatabase.getConnection()).createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
        Data data = (Data) missingObject;
        Table table = data.getTable();
        if (referenceDatabase.isLiquibaseObject(table)) {
            return null;
        }
        String sql = "SELECT * FROM " + referenceDatabase.escapeTableName(table.getSchema().getCatalogName(), table.getSchema().getName(), table.getName());
        stmt.setFetchSize(100);
        rs = stmt.executeQuery(sql);
        if (rs.isBeforeFirst()) {
            List<String> columnNames = new ArrayList<>();
            for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
                columnNames.add(rs.getMetaData().getColumnName(i + 1));
            }
            String fileName = table.getName().toLowerCase() + ".csv";
            if (dataDir != null) {
                fileName = dataDir + "/" + fileName;
                File parentDir = new File(dataDir);
                if (!parentDir.exists()) {
                    parentDir.mkdirs();
                }
                if (!parentDir.isDirectory()) {
                    throw new IOException(parentDir.getAbsolutePath() + " is not a valid directory");
                }
            }
            String[] dataTypes = new String[0];
            try (FileOutputStream fileOutputStream = new FileOutputStream(fileName);
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue());
                CSVWriter outputFile = new CSVWriter(new BufferedWriter(outputStreamWriter))) {
                dataTypes = new String[columnNames.size()];
                String[] line = new String[columnNames.size()];
                for (int i = 0; i < columnNames.size(); i++) {
                    line[i] = columnNames.get(i);
                }
                outputFile.writeNext(line);
                int rowNum = 0;
                while (rs.next()) {
                    line = new String[columnNames.size()];
                    for (int i = 0; i < columnNames.size(); i++) {
                        Object value = JdbcUtil.getResultSetValue(rs, i + 1);
                        if ((dataTypes[i] == null) && (value != null)) {
                            if (value instanceof Number) {
                                dataTypes[i] = "NUMERIC";
                            } else if (value instanceof Boolean) {
                                dataTypes[i] = "BOOLEAN";
                            } else if (value instanceof Date) {
                                dataTypes[i] = "DATE";
                            } else if (value instanceof byte[]) {
                                dataTypes[i] = "BLOB";
                            } else {
                                dataTypes[i] = "STRING";
                            }
                        }
                        if (value == null) {
                            line[i] = "NULL";
                        } else {
                            if (value instanceof Date) {
                                line[i] = new ISODateFormat().format(((Date) value));
                            } else if (value instanceof byte[]) {
                                // extract the value as a Base64 string, to safely store the
                                // binary data
                                line[i] = Base64.getEncoder().encodeToString((byte[]) value);
                            } else {
                                line[i] = value.toString();
                            }
                        }
                    }
                    outputFile.writeNext(line);
                    rowNum++;
                    if ((rowNum % 5000) == 0) {
                        outputFile.flush();
                    }
                }
            }
            LoadDataChange change = new LoadDataChange();
            change.setFile(fileName);
            change.setEncoding(GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue());
            if (outputControl.getIncludeCatalog()) {
                change.setCatalogName(table.getSchema().getCatalogName());
            }
            if (outputControl.getIncludeSchema()) {
                change.setSchemaName(table.getSchema().getName());
            }
            change.setTableName(table.getName());
            for (int i = 0; i < columnNames.size(); i++) {
                String colName = columnNames.get(i);
                LoadDataColumnConfig columnConfig = new LoadDataColumnConfig();
                columnConfig.setHeader(colName);
                columnConfig.setName(colName);
                columnConfig.setType(dataTypes[i] != null ? dataTypes[i] : "skip");
                change.addColumn(columnConfig);
            }
            return new Change[] { change };
        }
        return new Change[] {};
    } catch (Exception e) {
        throw new UnexpectedLiquibaseException(e);
    } finally {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException ignore) {
            // nothing can be done
            }
        // try...
        }
    // rs == null?
    }
// try... finally
}
Also used : SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) CSVWriter(liquibase.util.csv.CSVWriter) JdbcConnection(liquibase.database.jvm.JdbcConnection) ISODateFormat(liquibase.util.ISODateFormat) ResultSet(java.sql.ResultSet) LoadDataColumnConfig(liquibase.change.core.LoadDataColumnConfig) LoadDataChange(liquibase.change.core.LoadDataChange) Table(liquibase.structure.core.Table) Statement(java.sql.Statement) Data(liquibase.structure.core.Data) Change(liquibase.change.Change) LoadDataChange(liquibase.change.core.LoadDataChange) Date(java.util.Date) SQLException(java.sql.SQLException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseObject(liquibase.structure.DatabaseObject) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException)

Aggregations

ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 Statement (java.sql.Statement)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 Change (liquibase.change.Change)1 LoadDataChange (liquibase.change.core.LoadDataChange)1 LoadDataColumnConfig (liquibase.change.core.LoadDataColumnConfig)1 JdbcConnection (liquibase.database.jvm.JdbcConnection)1 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)1 DatabaseObject (liquibase.structure.DatabaseObject)1 Data (liquibase.structure.core.Data)1 Table (liquibase.structure.core.Table)1 ISODateFormat (liquibase.util.ISODateFormat)1 CSVWriter (liquibase.util.csv.CSVWriter)1