// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6; import java.util.Collections; import java.util.Date; import org.openstreetmap.osmosis.core.OsmosisConstants; import org.openstreetmap.osmosis.apidb.common.DatabaseContext2; import org.openstreetmap.osmosis.apidb.v0_6.impl.AllEntityDao; import org.openstreetmap.osmosis.apidb.v0_6.impl.EntitySnapshotReader; import org.openstreetmap.osmosis.apidb.v0_6.impl.SchemaVersionValidator; import org.openstreetmap.osmosis.core.container.v0_6.BoundContainer; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials; import org.openstreetmap.osmosis.core.database.DatabasePreferences; import org.openstreetmap.osmosis.core.domain.v0_6.Bound; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; /** * An OSM data source reading from a database. The entire contents of the database are read. * * @author Brett Henderson */ public class ApidbReader implements RunnableSource { private Sink sink; private DatabaseLoginCredentials loginCredentials; private DatabasePreferences preferences; private Date snapshotInstant; /** * Creates a new instance. * * @param loginCredentials Contains all information required to connect to the database. * @param preferences Contains preferences configuring database behaviour. * @param snapshotInstant The state of the node table at this point in time will be dumped. This * ensures a consistent snapshot. */ public ApidbReader(DatabaseLoginCredentials loginCredentials, DatabasePreferences preferences, Date snapshotInstant) { this.loginCredentials = loginCredentials; this.preferences = preferences; this.snapshotInstant = snapshotInstant; } /** * {@inheritDoc} */ public void setSink(Sink sink) { this.sink = sink; } /** * Runs the task implementation. This is called by the run method within a transaction. * * @param dbCtx * Used to access the database. */ protected void runImpl(DatabaseContext2 dbCtx) { try { AllEntityDao entityDao; sink.initialize(Collections.<String, Object>emptyMap()); new SchemaVersionValidator(loginCredentials, preferences) .validateVersion(ApidbVersionConstants.SCHEMA_MIGRATIONS); entityDao = new AllEntityDao(dbCtx.getJdbcTemplate()); sink.process(new BoundContainer(new Bound("Osmosis " + OsmosisConstants.VERSION))); try (ReleasableIterator<EntityContainer> reader = new EntitySnapshotReader(entityDao.getHistory(), snapshotInstant)) { while (reader.hasNext()) { sink.process(reader.next()); } } sink.complete(); } finally { sink.close(); } } /** * Reads all data from the database and send it to the sink. */ public void run() { try (DatabaseContext2 dbCtx = new DatabaseContext2(loginCredentials)) { dbCtx.executeWithinTransaction(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { runImpl(dbCtx); } }); } } }