package edu.stanford.sulair.dlss.dor.dao;
import java.sql.SQLException;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import edu.stanford.sulair.dlss.dor.admin.Process;
public class HibernateProcessDao implements ProcessDao {
private Logger logger = Logger.getLogger(HibernateProcessDao.class);
private HibernateTemplate hibernateTemplate;
private static final String WAITING_PROCESSES_QUERY = "from Process process where process.repository=? and process.datastream=? and process.name=? and process.status!=? and process.status!=?";
private static final String WAITING_DRUIDS_BY_DATASTREAM_AND_COMPLETED_QUERY = "from Process process where process.repository=:repository and process.datastream=:ds and process.name=:waiting and process.status!=:errorStatus and process.status!=:completedStatus and process.status!=:queuedStatus and process.druid in (" +
"select p.druid from Process p where p.repository=:repository and p.datastream=:ds and p.name=:completed and p.status=:completedStatus ) ";
private static final String WAITING_DRUIDS_WITH_TWO_COMPLETED_QUERY = "from Process process where process.repository=:repository and process.datastream=:ds and process.name=:waiting and process.status!=:errorStatus and process.status!=:completedStatus and process.status!=:queuedStatus and process.druid in (" +
"select p1.druid from Process p1 where p1.repository=:repository and p1.datastream=:ds and p1.name=:c1 and p1.status=:completedStatus and p1.druid in (" +
"select p2.druid from Process p2 where p2.repository=:repository and p2.datastream=:ds and p2.name=:c2 and p2.status=:completedStatus)) ";
private static final String SIMPLE_PROCESS_BY_STATUS_QUERY = "from Process process where process.repository=? and process.datastream=? and process.name=? and process.status=?";
@Autowired
public void setSessionFactory(SessionFactory sf) {
hibernateTemplate = new HibernateTemplate(sf);
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Process> findProcessesByDruidAndDatastream(String repository, String druid, String datastream) {
String[] parms = {repository, druid, datastream};
return hibernateTemplate.find("from Process process where process.repository=? and process.druid=? and process.datastream=?", parms);
}
@Transactional(propagation = Propagation.NESTED )
public void persistProcess(Process p) {
this.hibernateTemplate.merge(p);
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public Process findProcess(String repository, String druid, String datastream, String name) {
String[] parms = {repository, druid, datastream, name};
List<Process> list = hibernateTemplate.find("from Process process where process.repository=? and process.druid=? and process.datastream=? and process.name=?", parms);
if(list.size() == 0){
return null;
}
//TODO: what to do if there are more than 1 items. Throw exception? Log warning?
return list.get(0);
}
@Transactional(propagation = Propagation.NESTED )
public void deleteProcessesByRepoDruidAndWorkflowName(final String repository, final String druid, final String workflowName) {
this.hibernateTemplate.execute( new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
String hql = "delete from Process where repository = :repository and druid = :druid and datastream = :workflowName";
Query query = session.createQuery(hql);
query.setString("repository", repository);
query.setString("druid", druid);
query.setString("workflowName", workflowName);
return query.executeUpdate();
}
}
);
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<String> findWaitingDruids(String repository, String datastream,
String waitingProcessName) {
String[] parms = {repository, datastream, waitingProcessName, Process.STATUS_COMPLETED, Process.STATUS_ERROR};
List<String> druids = hibernateTemplate.find("select process.druid " + WAITING_PROCESSES_QUERY, parms );
return druids;
}
@Transactional(readOnly = true)
public int countWaitingDruids(String repository, String datastream, String waitingProcessName) {
String[] parms = {repository, datastream, waitingProcessName, Process.STATUS_COMPLETED, Process.STATUS_ERROR};
return DataAccessUtils.intResult(hibernateTemplate.find("select count(*) " + WAITING_PROCESSES_QUERY, parms)) ;
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<String> findWaitingDruidsByDatastreamNameAndCompleted(
String repository, String datastream, String waitingProcessName, String completedProcessName) {
logger.debug("In findWaitingDruidsByDatastreamNameAndCompleted ....");
String[] names = {"repository", "ds", "waiting", "errorStatus", "completed", "completedStatus", "queuedStatus"};
String[] values = { repository, datastream, waitingProcessName, Process.STATUS_ERROR, completedProcessName, Process.STATUS_COMPLETED, Process.STATUS_QUEUED};
List<String> druids = hibernateTemplate.findByNamedParam("select distinct process.druid " + WAITING_DRUIDS_BY_DATASTREAM_AND_COMPLETED_QUERY, names, values );
return druids;
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public int countWaitingDruidsByDatastreamNameAndCompleted(String repository, String datastream, String waitingProcessName, String completedProcessName) {
String[] names = {"repository", "ds", "waiting", "errorStatus", "completed", "completedStatus", "queuedStatus"};
String[] values = { repository, datastream, waitingProcessName, Process.STATUS_ERROR, completedProcessName, Process.STATUS_COMPLETED, Process.STATUS_QUEUED};
return DataAccessUtils.intResult(hibernateTemplate.findByNamedParam("select distinct count(*) " + WAITING_DRUIDS_BY_DATASTREAM_AND_COMPLETED_QUERY, names, values)) ;
}
@Transactional(readOnly = true)
public List<String> findCompletedDruids(String repository, String datastream,
String completedProcessName) {
String[] parms = {repository, datastream, completedProcessName, Process.STATUS_COMPLETED};
List<String> druids = hibernateTemplate.find("select process.druid " + SIMPLE_PROCESS_BY_STATUS_QUERY, parms );
return druids;
}
@Transactional(readOnly = true)
public int countCompletedDruids(String repository, String datastream, String completedProcessName) {
String[] parms = {repository, datastream, completedProcessName, Process.STATUS_COMPLETED};
return DataAccessUtils.intResult(hibernateTemplate.find("select count(*) " + SIMPLE_PROCESS_BY_STATUS_QUERY, parms ));
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Process> findErrorProcessesByDatastreamAndName(
String repository, String datastream, String errorProcessName) {
String[] parms = {repository, datastream, errorProcessName, Process.STATUS_ERROR};
return hibernateTemplate.find(SIMPLE_PROCESS_BY_STATUS_QUERY, parms);
}
@Transactional(readOnly = true)
public int countErrorProcessesByDatastreamAndName(String repository, String datastream, String errorProcessName) {
String[] parms = {repository, datastream, errorProcessName, Process.STATUS_ERROR};
return DataAccessUtils.intResult(hibernateTemplate.find("select count(*) " + SIMPLE_PROCESS_BY_STATUS_QUERY, parms ));
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<String> findWaitingDruidsWithTwoCompletedProcesses(
String repository, String datastream, String waitingProcessName, String completed1,
String completed2) {
logger.debug("In findWaitingDruidsWithTwoCompletedProcesses");
String[] names = {"repository", "ds", "waiting", "errorStatus", "c1", "c2", "completedStatus", "queuedStatus"};
String[] values = { repository, datastream, waitingProcessName, Process.STATUS_ERROR, completed1, completed2, Process.STATUS_COMPLETED, Process.STATUS_QUEUED};
List<String> druids = hibernateTemplate.findByNamedParam("select distinct process.druid " + WAITING_DRUIDS_WITH_TWO_COMPLETED_QUERY, names, values );
return druids;
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public int countWaitingDruidsWithTwoCompletedProcesses(String repository, String datastream, String waitingProcessName, String completed1, String completed2) {
String[] names = {"repository", "ds", "waiting", "errorStatus", "c1", "c2", "completedStatus", "queuedStatus"};
String[] values = { repository, datastream, waitingProcessName, Process.STATUS_ERROR, completed1, completed2, Process.STATUS_COMPLETED, Process.STATUS_QUEUED};
return DataAccessUtils.intResult(hibernateTemplate.findByNamedParam("select distinct count(*) " + WAITING_DRUIDS_WITH_TWO_COMPLETED_QUERY, names, values));
}
public List<Process> findLifecycleCompletedProcesses(String repository, String druid) {
String[] parms = {repository, druid, Process.STATUS_COMPLETED};
return hibernateTemplate.find("from Process process " +
"where process.repository=? and " +
"process.druid=? and " +
"process.lifecycle is not null and " +
"process.status=? " +
"order by process.datetime", parms);
}
@Transactional(readOnly = true)
public List<String> findQueuedDruids(String repository, String datastream, String queuedProcessName) {
String[] parms = {repository, datastream, queuedProcessName, Process.STATUS_QUEUED};
List<String> druids = hibernateTemplate.find("select process.druid " + SIMPLE_PROCESS_BY_STATUS_QUERY, parms );
return druids;
}
@Transactional(readOnly = true)
public int countQueuedDruids(String repository, String datastream, String queuedProcessName) {
String[] parms = {repository, datastream, queuedProcessName, Process.STATUS_QUEUED};
return DataAccessUtils.intResult(hibernateTemplate.find("select count(*) " + SIMPLE_PROCESS_BY_STATUS_QUERY, parms ));
}
}