// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.pgsnapshot.v0_6;
import java.util.HashMap;
import java.util.Map;
import org.openstreetmap.osmosis.core.OsmosisRuntimeException;
import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer;
import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials;
import org.openstreetmap.osmosis.core.database.DatabasePreferences;
import org.openstreetmap.osmosis.core.task.common.ChangeAction;
import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink;
import org.openstreetmap.osmosis.pgsnapshot.common.DatabaseContext;
import org.openstreetmap.osmosis.pgsnapshot.common.SchemaVersionValidator;
import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.ActionChangeWriter;
import org.openstreetmap.osmosis.pgsnapshot.v0_6.impl.ChangeWriter;
/**
* A change sink writing to database tables. This aims to be suitable for
* running at regular intervals with database overhead proportional to changeset
* size.
*
* @author Brett Henderson
*/
public class PostgreSqlChangeWriter implements ChangeSink {
private ChangeWriter changeWriter;
private Map<ChangeAction, ActionChangeWriter> actionWriterMap;
private DatabaseContext dbCtx;
private SchemaVersionValidator schemaVersionValidator;
private boolean initialized;
/**
* Creates a new instance.
*
* @param loginCredentials
* Contains all information required to connect to the database.
* @param preferences
* Contains preferences configuring database behaviour.
* @param keepInvalidWays
* If true, zero and single node ways are kept. Otherwise they are
* silently dropped to avoid putting invalid geometries into the
* database which can cause problems with postgis functions.
*/
public PostgreSqlChangeWriter(DatabaseLoginCredentials loginCredentials,
DatabasePreferences preferences, boolean keepInvalidWays) {
dbCtx = new DatabaseContext(loginCredentials);
changeWriter = new ChangeWriter(dbCtx);
actionWriterMap = new HashMap<ChangeAction, ActionChangeWriter>();
actionWriterMap.put(ChangeAction.Create,
new ActionChangeWriter(changeWriter, ChangeAction.Create, keepInvalidWays));
actionWriterMap.put(ChangeAction.Modify,
new ActionChangeWriter(changeWriter, ChangeAction.Modify, keepInvalidWays));
actionWriterMap.put(ChangeAction.Delete,
new ActionChangeWriter(changeWriter, ChangeAction.Delete, keepInvalidWays));
schemaVersionValidator = new SchemaVersionValidator(dbCtx.getJdbcTemplate(), preferences);
initialized = false;
}
private void initialize() {
if (!initialized) {
dbCtx.beginTransaction();
initialized = true;
}
}
/**
* {@inheritDoc}
*/
public void initialize(Map<String, Object> metaData) {
// Do nothing.
}
/**
* {@inheritDoc}
*/
public void process(ChangeContainer change) {
ChangeAction action;
initialize();
// Verify that the schema version is supported.
schemaVersionValidator.validateVersion(PostgreSqlVersionConstants.SCHEMA_VERSION);
action = change.getAction();
if (!actionWriterMap.containsKey(action)) {
throw new OsmosisRuntimeException("The action " + action + " is unrecognized.");
}
// Process the entity using the action writer appropriate for the change
// action.
change.getEntityContainer().process(actionWriterMap.get(action));
}
/**
* {@inheritDoc}
*/
public void complete() {
initialize();
changeWriter.complete();
dbCtx.commitTransaction();
}
/**
* {@inheritDoc}
*/
public void release() {
changeWriter.release();
dbCtx.release();
}
}