// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.pgsimple.v0_6.impl;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openstreetmap.osmosis.core.OsmosisRuntimeException;
import org.openstreetmap.osmosis.core.database.DbFeature;
import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator;
import org.openstreetmap.osmosis.core.store.Storeable;
import org.openstreetmap.osmosis.pgsimple.common.BaseDao;
import org.openstreetmap.osmosis.pgsimple.common.DatabaseContext;
/**
* Provides functionality common to all entity feature daos.
*
* @author Brett Henderson
* @param <Tef>
* The entity feature type to be supported.
* @param <Tdb>
* The entity feature database wrapper type to be used.
*/
public class EntityFeatureDao<Tef extends Storeable, Tdb extends DbFeature<Tef>> extends BaseDao {
private static final Logger LOG = Logger.getLogger(EntityFeatureDao.class.getName());
/**
* Provides jdbc mapping functionality for this entity feature type.
*/
protected EntityFeatureMapper<Tdb> entityFeatureBuilder;
private PreparedStatement getStatement;
private PreparedStatement insertStatement;
private PreparedStatement deleteStatement;
/**
* Creates a new instance.
*
* @param dbCtx
* The database context to use for accessing the database.
* @param entityFeatureBuilder
* Provides entity type specific JDBC support.
*/
protected EntityFeatureDao(DatabaseContext dbCtx, EntityFeatureMapper<Tdb> entityFeatureBuilder) {
super(dbCtx);
this.entityFeatureBuilder = entityFeatureBuilder;
}
/**
* Loads all instances of this feature for the specified entity from the database.
*
* @param entityId
* The unique identifier of the entity.
* @return All instances of this feature type for the entity.
*/
public Collection<Tdb> getAll(long entityId) {
ResultSet resultSet = null;
if (getStatement == null) {
getStatement = prepareStatement(entityFeatureBuilder.getSqlSelect(true, true));
}
try {
List<Tdb> resultList;
getStatement.setLong(1, entityId);
resultSet = getStatement.executeQuery();
resultList = new ArrayList<Tdb>();
while (resultSet.next()) {
resultList.add(entityFeatureBuilder.buildEntity(resultSet));
}
resultSet.close();
resultSet = null;
return resultList;
} catch (SQLException e) {
throw new OsmosisRuntimeException("Query failed for "
+ entityFeatureBuilder.getEntityName() + " " + entityId + ".", e);
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
// We are already in an error condition so log and continue.
LOG.log(Level.WARNING, "Unable to close result set.", e);
}
}
}
}
/**
* Loads all instances of this feature for the specified entity from the database.
*
* @param entityId
* The unique identifier of the entity.
* @return All instances of this feature type for the entity.
*/
public Collection<Tef> getAllRaw(long entityId) {
Collection<Tdb> dbFeatures;
Collection<Tef> rawFeatures;
dbFeatures = getAll(entityId);
rawFeatures = new ArrayList<Tef>(dbFeatures.size());
for (Tdb dbFeature : dbFeatures) {
rawFeatures.add(dbFeature.getFeature());
}
return rawFeatures;
}
/**
* Adds the specified features to the database.
*
* @param features
* The features to add.
*/
public void addAll(Collection<Tdb> features) {
if (insertStatement == null) {
insertStatement = prepareStatement(entityFeatureBuilder.getSqlInsert(1));
}
for (Tdb feature : features) {
try {
entityFeatureBuilder.populateEntityParameters(insertStatement, 1, feature);
insertStatement.executeUpdate();
} catch (SQLException e) {
throw new OsmosisRuntimeException(
"Insert failed for "
+ entityFeatureBuilder.getEntityName() + " " + feature.getEntityId()
+ "."
);
}
}
}
/**
* Removes the specified feature list from the database.
*
* @param entityId
* The id of the entity to remove.
*/
public void removeList(long entityId) {
int prmIndex;
if (deleteStatement == null) {
deleteStatement = prepareStatement(entityFeatureBuilder.getSqlDelete(true));
}
try {
prmIndex = 1;
deleteStatement.setLong(prmIndex++, entityId);
deleteStatement.executeUpdate();
} catch (SQLException e) {
throw new OsmosisRuntimeException(
"Delete failed for "
+ entityFeatureBuilder.getEntityName() + " "
+ entityId + "."
);
}
}
/**
* Returns an iterator providing access to all entity features of this type
* in the database.
*
* @return The entity feature iterator.
*/
public ReleasableIterator<Tdb> iterate() {
return new EntityFeatureTableReader<Tef, Tdb>(getDatabaseContext(), entityFeatureBuilder);
}
}