package nl.ipo.cds.etl.process;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.sql.DataSource;
import nl.idgis.commons.jobexecutor.Job;
import nl.idgis.commons.jobexecutor.JobLogger;
import nl.idgis.commons.jobexecutor.Process;
import nl.ipo.cds.domain.TagJob;
import nl.ipo.cds.etl.db.annotation.Table;
import nl.ipo.cds.etl.theme.ThemeDiscoverer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.base.Joiner;
@Transactional
public class TagProcess implements Process<TagJob> {
private static final Log log = LogFactory.getLog(TagProcess.class);
private final DataSource dataSource;
private ThemeDiscoverer themeDiscoverer;
public TagProcess(final DataSource dataSource, final ThemeDiscoverer themeDiscoverer) {
this.dataSource = dataSource;
this.themeDiscoverer = themeDiscoverer;
}
@Override
public boolean process(TagJob job, JobLogger logger) {
log.debug("tagging dataset started");
final Table table = themeDiscoverer.getThemeConfiguration(job.getThema()).getFeatureTypeClass().getAnnotation(Table.class);
log.debug("bronhouder: " + job.getBronhouder());
log.debug("datasetType: " + job.getDatasetType());
log.debug("uuid: " + job.getUuid());
log.debug("schema name: " + table.schema());
log.debug("tag: " + job.getTag());
log.debug("table: " + table.name());
// Now return all columns for the features in the table.
Set<String> columnNames = retrieveColumns(table);
// Actually copy the data.
copyData(job, table, columnNames);
log.debug("tagging dataset finished");
return false;
}
private void copyData(TagJob job, Table table, Set<String> columnNames) {
String colStr = Joiner.on(',').join(columnNames);
String srcTable = String.format("%s.%s", table.schema(), table.name());
String destTable = String.format("%s_tagged", srcTable);
NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(dataSource);
MapSqlParameterSource namedParams = new MapSqlParameterSource();
namedParams.addValue("tag", job.getTag());
int numRecords = jdbc.queryForObject(String.format("select count(*) from %s", srcTable), new MapSqlParameterSource(), Integer.class);
int numCopied = jdbc.update(String.format("insert into %s (tag, %s) select :tag, %s from %s", destTable, colStr, colStr, srcTable), namedParams);
if (numCopied != numRecords) {
throw new RuntimeException(String.format("Not all records where correctly copied to the _tagged table. Expected number of records: %d, actual: %d.", numRecords, numCopied));
}
}
/**
* Retrieve a set of columns for a table in a certain schema.
*/
private Set<String> retrieveColumns(Table table) {
NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(dataSource);
Map<String, String> params = new HashMap<String, String>();
params.put("schema_name", table.schema());
params.put("table_name", table.name());
SqlRowSet columnResultSet = jdbc.queryForRowSet("select column_name from information_schema.columns where table_schema=:schema_name and table_name=:table_name", params);
SortedSet<String> columnNames = new TreeSet<String>();
while (columnResultSet.next()) {
String columnName = columnResultSet.getString("column_name");
if (!columnName.equals("id")) {
columnNames.add(columnName);
}
}
return columnNames;
}
@Override
public Class<? extends Job> getJobType() {
return TagJob.class;
}
}