Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle XML data types for DB2 DAT-12878 #4827

Merged
merged 4 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import liquibase.change.core.LoadDataColumnConfig;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
import liquibase.database.core.DB2Database;
import liquibase.database.jvm.JdbcConnection;
import liquibase.diff.output.DiffOutputControl;
import liquibase.diff.output.changelog.ChangeGeneratorChain;
Expand Down Expand Up @@ -47,13 +48,22 @@ public int getPriority(Class<? extends DatabaseObject> objectType, Database data
return PRIORITY_NONE;
}

private Statement createStatement(Database database) throws Exception {
if (! (database instanceof DB2Database)) {
Statement stmt = ((JdbcConnection) database.getConnection()).createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
return stmt;
}
Statement stmt = ((JdbcConnection) database.getConnection()).createStatement();
return stmt;
}

@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)
Statement stmt = createStatement(referenceDatabase);
)
{
Data data = (Data) missingObject;
Expand All @@ -69,7 +79,7 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu
stmt.setFetchSize(100);
rs = stmt.executeQuery(sql);

if (rs.isBeforeFirst()) {
if (referenceDatabase instanceof DB2Database || rs.isBeforeFirst()) {
List<String> columnNames = new ArrayList<>();
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
columnNames.add(rs.getMetaData().getColumnName(i + 1));
Expand Down Expand Up @@ -99,43 +109,48 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu
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 (rs.next()) {
do {
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);
if (value == null) {
line[i] = "NULL";
} else {
line[i] = value.toString();
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();
}
outputFile.writeNext(line);
rowNum++;
if ((rowNum % 5000) == 0) {
outputFile.flush();
}
} while (rs.next());
}
if (rowNum == 0) {
return Change.EMPTY_CHANGE;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public static Object getResultSetValue(ResultSet rs, int index) throws SQLExcept
if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) {
obj = rs.getTimestamp(index);
}
} else if (obj instanceof SQLXML) {
obj = rs.getSQLXML(index).getString();
}
return obj;
}
Expand Down