001: /*
002: * $Id: BatchSqlHandler.java,v 1.7 2004/09/28 19:15:45 spal Exp $
003: * $Source: /cvsroot/sqlunit/sqlunit/src/net/sourceforge/sqlunit/handlers/BatchSqlHandler.java,v $
004: * SQLUnit - a test harness for unit testing database stored procedures.
005: * Copyright (C) 2003 The SQLUnit Team
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021: package net.sourceforge.sqlunit.handlers;
022:
023: import net.sourceforge.sqlunit.ConnectionRegistry;
024: import net.sourceforge.sqlunit.IErrorCodes;
025: import net.sourceforge.sqlunit.IHandler;
026: import net.sourceforge.sqlunit.SQLUnitException;
027: import net.sourceforge.sqlunit.beans.BatchDatabaseResult;
028: import net.sourceforge.sqlunit.utils.XMLUtils;
029:
030: import org.apache.log4j.Logger;
031: import org.jdom.Element;
032:
033: import java.sql.BatchUpdateException;
034: import java.sql.Connection;
035: import java.sql.Statement;
036: import java.util.List;
037:
038: /**
039: * The BatchSqlHandler class processes the contents of a batchsql tag in the
040: * input XML file.
041: * @author Sujit Pal (spal@users.sourceforge.net)
042: * @version $Revision: 1.7 $
043: * @sqlunit.parent name="batchtest" ref="batchtest"
044: * @sqlunit.element name="batchsql"
045: * description="The batchsql tag allows the client to specify a set of
046: * non-parameterized SQL statements which need to run in a batch. SQLUnit
047: * uses the JDBC batching mechanism to run the set of SQL statements."
048: * syntax="((stmt)+)"
049: * @sqlunit.attrib name="connection-id"
050: * description="When multiple Connections are defined in a SQLUnit test,
051: * this attribute provides a mechanism for choosing one of the defined
052: * Connections to use for running this batch. If a connection-id is not
053: * specified, SQLUnit will try to look up a Connection which has no
054: * connection-id."
055: * required="No"
056: * @sqlunit.child name="stmt"
057: * description="Contains the SQL statement or stored procedure call in
058: * the body of the element"
059: * required="One or more stmt elements need to be specified"
060: * ref="none"
061: * @sqlunit.example name="A typical batchsql call"
062: * description="
063: * <batchsql>{\n}
064: * {\t}<stmt>delete from customer where custId=1</stmt>{\n}
065: * {\t}<stmt>insert into customer values(1,'Some One','secret',{\n}
066: * {\t}{\t}'en_US',null,0,now())</stmt>{\n}
067: * {\t}<stmt>insert into customer values(1,'Someone Else','secret',{\n}
068: * {\t}{\t}'en_US',null,0,now())</stmt>{\n}
069: * {\t}<stmt>delete from customer where 1=1</stmt>{\n}
070: * </batchsql>
071: * "
072: */
073: public class BatchSqlHandler implements IHandler {
074:
075: private static final Logger LOG = Logger
076: .getLogger(BatchSqlHandler.class.getName());
077:
078: /**
079: * Runs the batch of SQL statements supplied as a batch and returns
080: * a BatchDatabaseResult object.
081: * @param elBatchSql the JDOM Element representing the batchsql tag.
082: * @return the DatabaseResult returned from executing the SQL.
083: * @exception Exception if there was a problem running the SQL.
084: */
085: public final Object process(final Element elBatchSql)
086: throws Exception {
087: LOG.debug(">> process()");
088: if (elBatchSql == null) {
089: throw new SQLUnitException(IErrorCodes.ELEMENT_IS_NULL,
090: new String[] { "batchsql" });
091: }
092: String connectionId = XMLUtils.getAttributeValue(elBatchSql,
093: "connection-id");
094: Connection conn = ConnectionRegistry
095: .getConnection(connectionId);
096: if (conn == null) {
097: throw new SQLUnitException(IErrorCodes.CONNECTION_IS_NULL,
098: new String[] { (connectionId == null ? "DEFAULT"
099: : connectionId) });
100: }
101: int numStmts = -1;
102: BatchDatabaseResult result = new BatchDatabaseResult();
103: try {
104: // Create a batch
105: Statement batchStmt = conn.createStatement();
106: // Parse the element to get individual stmt elements, and
107: // add them to the batch
108: List elStmtList = elBatchSql.getChildren("stmt");
109: numStmts = elStmtList.size();
110: for (int i = 0; i < numStmts; i++) {
111: Element elStmt = (Element) elStmtList.get(i);
112: String sql = XMLUtils.getText(elStmt);
113: batchStmt.addBatch(sql);
114: }
115: // execute the batch
116: int[] updateCounts = batchStmt.executeBatch();
117: // parse the results into a BatchDatabaseResult object
118: for (int i = 0; i < updateCounts.length; i++) {
119: result.addUpdateCount(updateCounts[i]);
120: }
121: // and return it
122: return result;
123: } catch (BatchUpdateException e) {
124: int[] updateCounts = e.getUpdateCounts();
125: result.resetUpdateCounts();
126: for (int i = 0; i < updateCounts.length; i++) {
127: result.addUpdateCount(updateCounts[i]);
128: }
129: BatchDatabaseResult.setException(e);
130: ConnectionRegistry.invalidate(connectionId);
131: return result;
132: } catch (Exception e) {
133: ConnectionRegistry.invalidate(connectionId);
134: throw new SQLUnitException(IErrorCodes.GENERIC_ERROR,
135: new String[] { "System", e.getClass().getName(),
136: e.getMessage() }, e);
137: }
138: }
139: }
|