io.nflow.engine.internal.dao.TableMetadataChecker Maven / Gradle / Ivy
package io.nflow.engine.internal.dao;
import static java.lang.String.format;
import static java.util.Collections.singletonMap;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.inject.Named;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.nflow.engine.config.NFlow;
import io.nflow.engine.model.ModelObject;
@Named
public class TableMetadataChecker {
private final JdbcTemplate jdbc;
public TableMetadataChecker(@NFlow JdbcTemplate jdbcTemplate) {
this.jdbc = jdbcTemplate;
}
public void ensureCopyingPossible(String sourceTable, String destinationTable) {
Map sourceMetadataMap = getMetadata(sourceTable);
Map destMetadataMap = getMetadata(destinationTable);
if (destMetadataMap.size() < sourceMetadataMap.size()) {
throw new IllegalArgumentException(format("Source table %s has more columns than destination table %s", sourceTable,
destinationTable));
}
Set sourceKeySet = sourceMetadataMap.keySet();
Set destKeySet = destMetadataMap.keySet();
if (!destKeySet.containsAll(sourceKeySet)) {
Set missingColumns = new LinkedHashSet<>(sourceKeySet);
missingColumns.removeAll(destKeySet);
throw new IllegalArgumentException(format("Destination table %s is missing columns %s that are present in source table %s",
destinationTable, missingColumns, sourceTable));
}
for (Entry entry : sourceMetadataMap.entrySet()) {
ColumnMetadata sourceMetadata = entry.getValue();
ColumnMetadata destMetadata = destMetadataMap.get(entry.getKey());
if (!sourceMetadata.typeName.equals(destMetadata.typeName)) {
throw new IllegalArgumentException(format(
"Source column %s.%s has type %s and destination column %s.%s has mismatching type %s", sourceTable,
sourceMetadata.columnName, sourceMetadata.typeName, destinationTable, destMetadata.columnName, destMetadata.typeName));
}
if (sourceMetadata.size > destMetadata.size) {
throw new IllegalArgumentException(format("Source column %s.%s has size %s and destination column %s.%s smaller size %s",
sourceTable, sourceMetadata.columnName, sourceMetadata.size, destinationTable, destMetadata.columnName,
destMetadata.size));
}
}
}
@SuppressFBWarnings(value = "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", justification = "jdbc is injected")
private Map getMetadata(String tableName) {
return jdbc.query("select * from " + tableName + " where 1 = 0", new MetadataExtractor());
}
static class MetadataExtractor implements ResultSetExtractor