/** @param sqe */
 private void endException(int batchSize) {
   // Rollback if dbContext.getAutoCommit() is false
   try {
     dbContext.getDataConnection().rollback();
   } catch (SQLException sqe) {
     logger.error(
         Messages.getFormattedString(
             "DatabaseDAO.sqlExceptionRollback",
             new String[] {
               String.valueOf(currentRowNumber + 1 - batchSize),
               String.valueOf(currentRowNumber + 1),
               dbContext.getDbConfigName(),
               sqe.getMessage()
             }),
         sqe);
   }
 }
 /*
  * (non-Javadoc)
  * @see com.salesforce.dataloader.dao.DataAccessObject#checkConnection()
  */
 @Override
 public void checkConnection() throws DataAccessObjectInitializationException {
   dbContext.checkConnection(dataSource);
 }
  /*
   * (non-Javadoc)
   * @see com.salesforce.dataloader.dao.DataWriter#writeRowList(java.util.List)
   */
  @Override
  public boolean writeRowList(List<Row> inputRowList) throws DataAccessObjectException {

    // make sure that the update is setup and ready to go, otherwise stop
    if (!dbContext.isOpen()) {
      throw new DataAccessObjectInitializationException(
          Messages.getString("DatabaseDAO.errorUpdateNotOpen"));
    }

    boolean success = true;
    int startingRowNumber = currentRowNumber;

    try {
      // for batchsize = 1, don't do batching, this provides much better error output
      if (inputRowList.size() == 1) {
        dbContext.setSqlParamValues(sqlConfig, config, inputRowList.get(0));
        currentRowNumber++;
      } else {
        // for each row set the Sql params in the prepared statement
        dbContext.getDataStatement().clearBatch();
        for (Row inputRow : inputRowList) {
          dbContext.setSqlParamValues(sqlConfig, config, inputRow);
          dbContext.getDataStatement().addBatch();
          currentRowNumber++;
        }
      }
    } catch (ParameterLoadException e) {
      throw new DataAccessObjectException(e.getMessage(), e);
    } catch (SQLException sqe) {
      String errMsg =
          Messages.getFormattedString(
              "DatabaseDAO.sqlExceptionPrepareRow",
              new String[] {
                String.valueOf(currentRowNumber + 1), String.valueOf(startingRowNumber + 1),
                String.valueOf(startingRowNumber + inputRowList.size() + 1),
                    dbContext.getDbConfigName(),
                sqe.getMessage()
              });
      logger.error(errMsg, sqe);
      // batch failed: set current row number to the end of the batch
      currentRowNumber = startingRowNumber + inputRowList.size();
      throw new DataAccessObjectException(errMsg, sqe);
    } catch (Exception e) {
      String errMsg =
          Messages.getFormattedString(
              "DatabaseDAO.exceptionPrepareRow",
              new String[] {
                String.valueOf(currentRowNumber + 1), String.valueOf(startingRowNumber + 1),
                String.valueOf(startingRowNumber + inputRowList.size() + 1),
                    dbContext.getDbConfigName(),
                e.getMessage()
              });
      logger.error(errMsg, e);
      // batch failed: set current row number to the end of the batch
      currentRowNumber = startingRowNumber + inputRowList.size();
      throw new DataAccessObjectException(errMsg, e);
    }

    try {
      // for batchsize = 1, don't do batching, this provides much better error output
      int totalSuccessRows = 0;
      if (inputRowList.size() == 1) {
        // non-batch update returns exception, so it's always success unless exception is returned
        dbContext.getDataStatement().executeUpdate();
        success = true;
        totalSuccessRows = 1;
      } else {
        // execute the update SQL in batch
        int[] rowsUpdatedArray = dbContext.getDataStatement().executeBatch();
        for (int rowsUpdated : rowsUpdatedArray) {
          if (rowsUpdated == PreparedStatement.SUCCESS_NO_INFO) {
            totalSuccessRows = rowsUpdatedArray.length;
            success = true;
            break;
          }
        }
      }
      logger.debug(
          Messages.getFormattedString(
              "DatabaseDAO.updatedStatus",
              new String[] {String.valueOf(totalSuccessRows), String.valueOf(currentRowNumber)}));

      // commit the change
      dbContext.getDataConnection().commit();

    } catch (SQLException sqe) {
      if (sqe instanceof BatchUpdateException) {
        int[] updateCountArray = ((BatchUpdateException) sqe).getUpdateCounts();
        for (int i = 0; i < updateCountArray.length; i++) {
          if (updateCountArray[i] == PreparedStatement.EXECUTE_FAILED) {
            // FIXME all results are the same, return
            success = false;
            break;
          }
        }
      }
      String errMsg =
          Messages.getFormattedString(
              "DatabaseDAO.sqlExceptionWriteRow",
              new String[] {
                String.valueOf(currentRowNumber + 1 - inputRowList.size()),
                    String.valueOf(currentRowNumber + 1),
                dbContext.getDbConfigName(), sqe.getMessage()
              });
      logger.error(errMsg, sqe);

      endException(inputRowList.size());
      throw new DataAccessObjectException(errMsg, sqe);
    } catch (Exception e) {
      String errMsg =
          Messages.getFormattedString(
              "DatabaseDAO.exceptionWriteRow",
              new String[] {
                String.valueOf(currentRowNumber + 1 - inputRowList.size()),
                    String.valueOf(currentRowNumber + 1),
                dbContext.getDbConfigName(), e.getMessage()
              });
      logger.error(errMsg, e);

      endException(inputRowList.size());
      throw new DataAccessObjectException(errMsg, e);
    }

    return success;
  }
 private void setupUpdate() throws DataAccessObjectInitializationException {
   dbContext.initConnection(dataSource);
   dbContext.replaceSqlParams(sqlConfig.getSqlString());
   dbContext.prepareStatement();
 }
 /*
  * (non-Javadoc)
  * @see com.salesforce.dataloader.dao.DataAccessObject#close()
  */
 @Override
 public void close() {
   dbContext.close();
 }
 /*
  * (non-Javadoc)
  * @see com.salesforce.dataloader.dao.DataWriter#open(java.util.List)
  */
 @Override
 public void open() throws DataAccessObjectInitializationException {
   setupUpdate(); // setup for writing
   dbContext.setOpen(true);
 }