package cc.nfscan.server.dao;
import cc.nfscan.server.domain.IDomain;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedScanList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Base Data Access Object
*
* @param <T> Class we want to provide DAO functionality
*
* @author Paulo Miguel Almeida <a href="http://github.com/PauloMigAlmeida">@PauloMigAlmeida</a>
*/
public abstract class AbstractDAO<T extends IDomain> {
/**
* AmazonDynamoDBClient reference to this object
*/
@Autowired
protected AmazonDynamoDBClient amazonDynamoDBClient;
/**
* DynamoDBMapper reference to this object
*/
@Autowired
protected DynamoDBMapper dynamoDBMapper;
/**
* Find all rows in table given the entity object
*
* @return a list of entities found
* @throws DataAccessException
*/
public List<T> findAll() throws DataAccessException {
DynamoDBScanExpression dynamoDBScanExpression = new DynamoDBScanExpression();
DynamoDBMapperConfig config = new DynamoDBMapperConfig(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING);
PaginatedScanList<T> paginatedScanList = dynamoDBMapper.scan(getType(), dynamoDBScanExpression, config);
paginatedScanList.loadAllResults();
List<T> list = new ArrayList<T>(paginatedScanList.size());
Iterator<T> iterator = paginatedScanList.iterator();
while (iterator.hasNext()) {
T element = iterator.next();
list.add(element);
}
return list;
}
/**
* Saves an entity to database
*
* @param entity entity object
* @throws DataAccessException
*/
public void save(T entity) throws DataAccessException {
dynamoDBMapper.save(entity);
}
/**
* Removes an entity to database
*
* @param entity entity object
* @throws DataAccessException
*/
public void remove(T entity) throws DataAccessException {
dynamoDBMapper.delete(entity);
}
/**
* Counts all rows in this specific table.
* Use it carefully since it loads all results from DynamoDB. To be honest there are only
* a few situations where this could be considered a wise solution.
*
* @return a amount of rows found
* @throws DataAccessException
*/
public int count() throws DataAccessException {
DynamoDBScanExpression dynamoDBScanExpression = new DynamoDBScanExpression();
DynamoDBMapperConfig config = new DynamoDBMapperConfig(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING);
PaginatedScanList<T> paginatedScanList = dynamoDBMapper.scan(getType(), dynamoDBScanExpression, config);
paginatedScanList.loadAllResults();
return paginatedScanList.size();
}
/**
* Specifies which Entity we are going to provide this functionality
*
* @return a class object
*/
public abstract Class<T> getType();
/**
* Find object by id
*
* @param entity object we want to find
* @return a entity object or null
* @throws DataAccessException
*/
public abstract T findById(T entity) throws DataAccessException;
}