package eu.kielczewski.akanke.common.repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Component
class DocumentRepositoryImpl implements DocumentRepositoryCustom {
private static final Logger LOGGER = LoggerFactory.getLogger(DocumentRepositoryImpl.class);
@PersistenceContext
private EntityManager em;
@Override
public Map<String, Map<String, Long>> getCountInYearMonth() {
LOGGER.debug("Getting document count in year, month");
List<Object[]> rows = getCountInYearMonthQueryResult();
Map<String, Map<String, Long>> counts = new LinkedHashMap<>();
for (Object[] row : rows) {
String year = String.valueOf(row[0]);
String month = String.format("%02d", (Integer) row[1]);
Long count = (Long) row[2];
Map<String, Long> countInMonth = counts.get(year);
if (countInMonth != null) {
countInMonth.put(month, count);
} else {
countInMonth = new LinkedHashMap<>();
countInMonth.put(month, count);
counts.put(year, countInMonth);
}
}
LOGGER.trace("Returning {}", counts);
return counts;
}
private List<Object[]> getCountInYearMonthQueryResult() {
Query query = em.createQuery("SELECT YEAR(d.datePublished) AS year, MONTH(d.datePublished) as month, COUNT(*) "
+ "FROM Document d GROUP BY YEAR(d.datePublished), MONTH(d.datePublished) ORDER "
+ "BY YEAR(d.datePublished) DESC, MONTH(d.datePublished) ASC");
//noinspection unchecked
return query.getResultList();
}
@Override
public Map<String, Long> getCountInMonthByYear(int year) {
LOGGER.debug("Getting document count in month by year={}", year);
List<Object[]> rows = getCountInMonthByYearQueryResult(year);
Map<String, Long> count = new LinkedHashMap<>();
for (Object[] row : rows) {
count.put(String.valueOf(String.format("%02d", (Integer) row[0])), (Long) row[1]);
}
LOGGER.trace("Returning {}", count);
return count;
}
private List<Object[]> getCountInMonthByYearQueryResult(int year) {
Query query = em.createQuery("SELECT MONTH(d.datePublished) as month, COUNT(*) FROM Document d "
+ "WHERE YEAR(d.datePublished) = ?1 GROUP BY MONTH(d.datePublished) ORDER BY month ASC");
query.setParameter(1, year);
//noinspection unchecked
return query.getResultList();
}
@Override
public long getCountByYearMonth(int year, int month) {
LOGGER.debug("Getting document count in year={}, month={}", year, month);
long count = getCountByYearMonthQueryResult(year, month);
LOGGER.trace("Returning {}", count);
return count;
}
private long getCountByYearMonthQueryResult(int year, int month) {
Query query = em.createQuery("SELECT COUNT(*) FROM Document d "
+ "WHERE YEAR(d.datePublished) = ?1 AND MONTH(d.datePublished) = ?2");
query.setParameter(1, year);
query.setParameter(2, month);
return (long) query.getSingleResult();
}
@Override
public Map<String, Long> getTagCounts() {
LOGGER.debug("Getting document tag counts");
List<Object[]> rows = getTagCountsQueryResult();
Map<String, Long> count = new HashMap<>();
for (Object[] row : rows) {
count.put((String) row[0], ((BigInteger) row[1]).longValue());
}
LOGGER.trace("Returning {}", count);
return count;
}
private List<Object[]> getTagCountsQueryResult() {
Query query = em.createNativeQuery("SELECT dt.tag, COUNT(*) as count_ FROM document_tags dt "
+ "GROUP BY dt.tag ORDER BY count_ DESC");
//noinspection unchecked
return query.getResultList();
}
}