package org.hivedb.meta.directory;
import org.hivedb.meta.Resource;
import org.hivedb.meta.SecondaryIndex;
import org.hivedb.util.database.Statements;
import org.hivedb.util.functional.Transform;
import org.hivedb.util.functional.Unary;
import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
/**
* A class for transactionally performing batches of directory operations. This class is a close collaborator with DbDirectory.
* It is probably more appropriately and inner class of DbDirectory. It is only extracted for readability.
*
* @author bcrawford
*/
public class BatchIndexWriter extends SimpleJdbcDaoSupport {
private DbDirectory directory;
private IndexSqlFormatter sql;
public BatchIndexWriter(DbDirectory directory) {
this.directory = directory;
this.sql = new IndexSqlFormatter();
this.setDataSource(directory.getDataSource());
}
public Integer insertSecondaryIndexKeys(final Map<SecondaryIndex, Collection<Object>> secondaryIndexValueMap, final Object resourceId) {
return (Integer) directory.newTransaction().execute(new TransactionCallback() {
public Integer doInTransaction(TransactionStatus status) {
return Transform.flatMap(new Unary<Map.Entry<SecondaryIndex, Collection<Object>>, Collection<Object>>() {
public Collection<Object> f(final Entry<SecondaryIndex, Collection<Object>> secondaryIndexKeysEntry) {
return Transform.map(new Unary<Object, Object>() {
public Object f(Object secondaryIndexKey) {
return directory.insertSecondaryIndexKeyNoTransaction(secondaryIndexKeysEntry.getKey(), secondaryIndexKey, resourceId);
}
}, secondaryIndexKeysEntry.getValue());
}
},
secondaryIndexValueMap.entrySet()).size();
}
});
}
public Integer deleteSecondaryIndexKeys(final Map<SecondaryIndex, Collection<Object>> secondaryIndexValueMap, final Object resourceId) {
return (Integer) directory.newTransaction().execute(new TransactionCallback() {
public Integer doInTransaction(TransactionStatus status) {
return Transform.flatMap(new Unary<Map.Entry<SecondaryIndex, Collection<Object>>, Collection<Object>>() {
public Collection<Object> f(final Entry<SecondaryIndex, Collection<Object>> secondaryIndexKeysEntry) {
return Transform.map(new Unary<Object, Object>() {
public Object f(Object secondaryIndexKey) {
return directory.deleteSecondaryIndexKeyNoTransaction(secondaryIndexKeysEntry.getKey(), secondaryIndexKey, resourceId);
}
}, secondaryIndexKeysEntry.getValue());
}
},
secondaryIndexValueMap.entrySet()).size();
}
});
}
public Integer deleteAllSecondaryIndexKeysOfResourceId(final Resource resource, Object id) {
final Object[] parameters = new Object[]{id};
return (Integer) directory.newTransaction().execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus arg0) {
Integer rowsAffected = 0;
for (SecondaryIndex secondaryIndex : resource.getSecondaryIndexes()) {
PreparedStatementCreatorFactory deleteIndexFactory =
Statements.newStmtCreatorFactory(sql.deleteAllSecondaryIndexKeysForResourceId(secondaryIndex), resource.getColumnType());
rowsAffected += getJdbcTemplate().update(deleteIndexFactory.newPreparedStatementCreator(parameters));
}
return rowsAffected;
}
});
}
}