package org.ovirt.engine.core.dao;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.ovirt.engine.core.common.businessentities.BusinessEntity;
import org.ovirt.engine.core.common.businessentities.comparators.BusinessEntityComparator;
import org.ovirt.engine.core.dal.dbbroker.MapSqlParameterMapper;
/**
* Implementation for the {@link MassOperationsDao} which provides a default
* N{@link MassOperationsDao#updateAll(Collection)} method that uses the {@link DefaultGenericDao#update} method
* in a more smart way, reusing the {@link org.springframework.jdbc.core.simple.SimpleJdbcCallOperations}.
*
* @param <T>
* The type of entity.
* @param <ID>
* The type of the entity's id.
*/
public abstract class MassOperationsGenericDao<T extends BusinessEntity<ID>, ID extends Serializable & Comparable<ID>>
extends DefaultGenericDao<T, ID> implements MassOperationsDao<T, ID> {
public MassOperationsGenericDao(String entityStoredProcedureName) {
super(entityStoredProcedureName);
}
@Override
public void updateAll(Collection<T> entities) {
updateAll(getProcedureNameForUpdate(), entities);
}
/**
* Enables to send update procedure name as a parameter that overrides the default
* one. In case this parameter is null the default procedure is used.
*/
@Override
public void updateAll(String procedureName, Collection<T> entities) {
if (procedureName == null) {
procedureName = getProcedureNameForUpdate();
}
for (T entity : entities) {
update(entity, procedureName);
}
}
/**
* Enables to send update procedure name as a parameter that overrides the default one. In case this parameter is
* null the default procedure is used.
*/
protected void updateAllInBatch(String procedureName,
Collection<T> paramValues,
MapSqlParameterMapper<T> mapper) {
// To overcome possible deadlocks, we need to sort the collection
List<T> sortedParamValues = new ArrayList<>(paramValues);
Collections.sort(sortedParamValues, BusinessEntityComparator.newInstance());
getCallsHandler().executeStoredProcAsBatch(procedureName == null ? getProcedureNameForUpdate() : procedureName,
sortedParamValues, mapper);
}
@Override
public void removeAll(Collection<ID> ids) {
ids.forEach(this::remove);
}
/**
* Enables to send remove procedure name as a parameter that overrides the default one. In case this parameter is
* null, default procedure is used.
*/
protected void removeAllInBatch(String procedureName, Collection<T> paramValues, MapSqlParameterMapper<T> mapper) {
getCallsHandler().executeStoredProcAsBatch(procedureName == null ? getProcedureNameForRemove() : procedureName,
paramValues,
mapper);
}
@Override
public void removeAllInBatch(Collection<T> entities) {
if (entities.isEmpty()) {
return;
}
// TODO: batch remove all should probably use only IDs (and id parameter source) as its non-batch counterpart
removeAllInBatch(getProcedureNameForRemove(), entities, getBatchMapper());
}
@Override
public void saveAll(Collection<T> entities) {
entities.forEach(this::save);
}
@Override
public void saveAllInBatch(Collection<T> entities) {
if (entities.isEmpty()) {
return;
}
getCallsHandler().executeStoredProcAsBatch(getProcedureNameForSave(), entities, getBatchMapper());
}
@Override
public void updateAllInBatch(Collection<T> entities) {
if (entities.isEmpty()) {
return;
}
updateAllInBatch(getProcedureNameForUpdate(), entities, getBatchMapper());
}
public MapSqlParameterMapper<T> getBatchMapper() {
return this::createFullParametersMapper;
}
}