// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.apidb.v0_6.impl; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainerFactory; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainerFactory; import org.openstreetmap.osmosis.core.database.DbFeatureHistory; import org.openstreetmap.osmosis.core.database.DbFeatureHistoryRowMapper; import org.openstreetmap.osmosis.core.database.DbFeatureRowMapper; import org.openstreetmap.osmosis.core.database.DbOrderedFeature; import org.openstreetmap.osmosis.core.database.DbOrderedFeatureHistoryComparator; import org.openstreetmap.osmosis.core.database.DbOrderedFeatureRowMapper; import org.openstreetmap.osmosis.core.database.RelationMemberCollectionLoader; import org.openstreetmap.osmosis.core.database.RowMapperListener; import org.openstreetmap.osmosis.core.database.SortingStoreRowMapperListener; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator; import org.openstreetmap.osmosis.core.sort.common.FileBasedSort; import org.openstreetmap.osmosis.core.store.SingleClassObjectSerializationFactory; import org.openstreetmap.osmosis.core.store.StoreReleasingIterator; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * Provides access to relations in the database. */ public class RelationDao extends EntityDao<Relation> { private static final Logger LOG = Logger.getLogger(RelationDao.class.getName()); private static final String[] TYPE_SPECIFIC_FIELD_NAMES = new String[] {}; /** * Creates a new instance. * * @param jdbcTemplate * Used to access the database. */ public RelationDao(JdbcTemplate jdbcTemplate) { super(jdbcTemplate, "relation"); } /** * {@inheritDoc} */ @Override protected RowMapperListener<CommonEntityData> getEntityRowMapper(RowMapperListener<Relation> entityListener) { return new RelationRowMapper(entityListener); } /** * {@inheritDoc} */ @Override protected String[] getTypeSpecificFieldNames() { return TYPE_SPECIFIC_FIELD_NAMES; } /** * {@inheritDoc} */ @Override protected EntityContainerFactory<Relation> getContainerFactory() { return new RelationContainerFactory(); } private ReleasableIterator<DbFeatureHistory<DbOrderedFeature<RelationMember>>> getRelationMemberHistory( String selectedEntityStatement, SqlParameterSource parameterSource) { FileBasedSort<DbFeatureHistory<DbOrderedFeature<RelationMember>>> sortingStore = new FileBasedSort<DbFeatureHistory<DbOrderedFeature<RelationMember>>>( new SingleClassObjectSerializationFactory(DbFeatureHistory.class), new DbOrderedFeatureHistoryComparator<RelationMember>(), true); try { String sql; SortingStoreRowMapperListener<DbFeatureHistory<DbOrderedFeature<RelationMember>>> storeListener; DbFeatureHistoryRowMapper<DbOrderedFeature<RelationMember>> dbFeatureHistoryRowMapper; DbFeatureRowMapper<RelationMember> dbFeatureRowMapper; DbOrderedFeatureRowMapper<RelationMember> dbOrderedFeatureRowMapper; RelationMemberRowMapper relationNodeRowMapper; ReleasableIterator<DbFeatureHistory<DbOrderedFeature<RelationMember>>> resultIterator; sql = "SELECT rm.relation_id AS id, rm.member_id, rm.member_role, rm.member_type, rm.version, rm.sequence_id" + " FROM " + "relation_members rm" + " INNER JOIN " + selectedEntityStatement + " t ON rm.relation_id = t.relation_id AND rm.version = t.version"; LOG.log(Level.FINER, "Relation member history query: " + sql); // Sends all received data into the object store. storeListener = new SortingStoreRowMapperListener<DbFeatureHistory<DbOrderedFeature<RelationMember>>>(sortingStore); // Retrieves the version information associated with the feature. dbFeatureHistoryRowMapper = new DbFeatureHistoryRowMapper<DbOrderedFeature<RelationMember>>(storeListener); // Retrieves the sequence number associated with the feature. dbOrderedFeatureRowMapper = new DbOrderedFeatureRowMapper<RelationMember>(dbFeatureHistoryRowMapper); // Retrieves the entity information associated with the feature. dbFeatureRowMapper = new DbFeatureRowMapper<RelationMember>(dbOrderedFeatureRowMapper); // Retrieves the basic feature information. relationNodeRowMapper = new RelationMemberRowMapper(dbFeatureRowMapper); // Perform the query passing the row mapper chain to process rows in a streamy fashion. getNamedParamJdbcTemplate().query(sql, parameterSource, relationNodeRowMapper); // Open a iterator on the store that will release the store upon completion. resultIterator = new StoreReleasingIterator<DbFeatureHistory<DbOrderedFeature<RelationMember>>>( sortingStore.iterate(), sortingStore); // The store itself shouldn't be released now that it has been attached to the iterator. sortingStore = null; return resultIterator; } finally { if (sortingStore != null) { sortingStore.close(); } } } /** * {@inheritDoc} */ @Override protected List<FeatureHistoryPopulator<Relation, ?, ?>> getFeatureHistoryPopulators( String selectedEntityTableName, MapSqlParameterSource parameterSource) { ReleasableIterator<DbFeatureHistory<DbOrderedFeature<RelationMember>>> relationNodeIterator; List<FeatureHistoryPopulator<Relation, ?, ?>> featurePopulators; featurePopulators = new ArrayList<FeatureHistoryPopulator<Relation, ?, ?>>(); // Get the relation nodes for the selected entities. relationNodeIterator = getRelationMemberHistory(selectedEntityTableName, parameterSource); // Wrap the relation node source into a feature history populator that can attach them to their // owning relations. featurePopulators.add( new FeatureHistoryPopulator<Relation, RelationMember, DbOrderedFeature<RelationMember>>( relationNodeIterator, new RelationMemberCollectionLoader())); return featurePopulators; } }