/*
   * (non-Javadoc)
   *
   * @see org.sakaiproject.search.dao.SearchIndexBuilderWorkerDao#createIndexTransaction(org.sakaiproject.search.api.SearchIndexBuilderWorker)
   */
  public void createIndexTransaction(SearchIndexBuilderWorker worker) {
    Connection connection = null;
    try {
      connection = dataSource.getConnection();
      long startTime = System.currentTimeMillis();
      int totalDocs = 0;

      log.debug("Preupdate Start");
      indexStorage.doPreIndexUpdate();
      log.debug("Preupdate End");

      createIndex(worker, connection);

      // get lock
      try {
        log.debug("Post update Start");
        indexStorage.doPostIndexUpdate();
        log.debug("Post update End");
      } catch (IOException e) {
        log.error("Failed to do Post Index Update", e); // $NON-NLS-1$
      }
      log.info("Created Index"); // $NON-NLS-1$
    } catch (Exception ex) {
      log.warn("Failed to create Index " + ex.getMessage()); // $NON-NLS-1$
      log.debug("Traceback is ", ex); // $NON-NLS-1$
    } finally {
      try {
        connection.close();
      } catch (Exception ex) {
        log.debug(ex);
      }
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see org.sakaiproject.search.component.dao.impl.SearchIndexBuilderWorkerDao#processToDoListTransaction()
   */
  public void processToDoListTransaction(SearchIndexBuilderWorker worker, int indexBatchSize) {
    Connection connection = null;
    try {
      connection = dataSource.getConnection();
      long startTime = System.currentTimeMillis();
      int totalDocs = 0;

      // Load the list

      List runtimeToDo = findPending(indexBatchSize, connection, worker);

      totalDocs = runtimeToDo.size();

      log.debug("Processing " + totalDocs + " documents"); // $NON-NLS-1$ //$NON-NLS-2$

      if (totalDocs > 0) {
        log.debug("Preupdate Start");
        indexStorage.doPreIndexUpdate();
        log.debug("Preupdate End");

        // get lock

        // this needs to be exclusive
        log.debug("Process Deletes Start");

        processDeletes(worker, connection, runtimeToDo);
        log.debug("Process Deletes End");

        // upate and release lock
        // after a process Deletes the index needs to updated

        // can be parallel
        log.debug("Process Add Start");

        processAdd(worker, connection, runtimeToDo);
        log.debug("Process Add End");
        log.debug("Complete Update Start");

        completeUpdate(worker, connection, runtimeToDo);
        log.debug("Complete Update End");

        // get lock
        try {
          log.debug("Post update Start");
          indexStorage.doPostIndexUpdate();
          log.debug("Post update End");
        } catch (IOException e) {
          log.error("Failed to do Post Index Update", e); // $NON-NLS-1$
        }
        // release lock

      }

      if (worker.isRunning()) {
        long endTime = System.currentTimeMillis();
        float totalTime = endTime - startTime;
        float ndocs = totalDocs;
        if (totalDocs > 0) {
          float docspersec = 1000 * ndocs / totalTime;
          log.info(
              "Completed Process List of "
                  + totalDocs
                  + " at " //$NON-NLS-1$ //$NON-NLS-2$
                  + docspersec
                  + " documents/per second "); //$NON-NLS-1$
        }
      }
    } catch (Exception ex) {
      log.warn("Failed to perform index cycle " + ex.getMessage(), ex); // $NON-NLS-1$
      // rollback any uncommitted transactions
      try {
        connection.rollback();
      } catch (SQLException e) {
        log.debug(e);
      }
    } finally {
      try {
        connection.close();
      } catch (Exception ex) {
        log.debug(ex);
      }
    }
  }