View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.jdbc.sqlstrategy;
8   
9   import org.mule.DefaultMuleMessage;
10  import org.mule.api.MuleEvent;
11  import org.mule.api.MuleMessage;
12  import org.mule.api.endpoint.ImmutableEndpoint;
13  import org.mule.api.transaction.Transaction;
14  import org.mule.transaction.TransactionCoordination;
15  import org.mule.transport.jdbc.JdbcConnector;
16  import org.mule.transport.jdbc.JdbcUtils;
17  import org.mule.util.ArrayUtils;
18  
19  import java.sql.Connection;
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import org.apache.log4j.Logger;
24  /**
25   * Implements strategy for handling individual insert, update, and delete statements
26   *
27   */
28  public  class SimpleUpdateSqlStatementStrategy implements SqlStatementStrategy
29  {
30      protected transient Logger logger = Logger.getLogger(getClass());
31      
32      public MuleMessage executeStatement(JdbcConnector connector,
33              ImmutableEndpoint endpoint, MuleEvent event,long timeout) throws Exception
34      {
35          //Unparsed SQL statement (with #[foo] format parameters)
36          String statement = connector.getStatement(endpoint);
37  
38          //Storage for parameters
39          List paramNames = new ArrayList();
40          
41          //Parsed SQL statement (with ? placeholders instead of #[foo] params)
42          String sql = connector.parseStatement(statement, paramNames);
43          
44          //Optionally escape or further manipulate SQL statement.  Used in subclasses.
45          sql = escapeStatement(sql);
46          
47          //Get parameter values from message
48          MuleMessage message = event.getMessage();
49          Object[] paramValues = connector.getParams(endpoint, paramNames, new DefaultMuleMessage(
50              event.getMessage().getPayload(), message, event.getMuleContext()), endpoint.getEndpointURI().getAddress());
51  
52          Transaction tx = TransactionCoordination.getInstance().getTransaction();
53          Connection con = null;
54              
55          try
56          {
57              con = connector.getConnection();
58              
59              
60              if (logger.isDebugEnabled())
61              {
62                  logger.debug("SQL UPDATE: " + sql + ", params = " + ArrayUtils.toString(paramValues));
63              }
64              
65              int nbRows = connector.getQueryRunnerFor(endpoint).update(con, sql, paramValues);
66              if (logger.isInfoEnabled())
67              {
68                  logger.info("Executing SQL statement: " + nbRows + " row(s) updated");
69              }
70              
71              // TODO Why should it always be 1?  Can't we update more than one row at a time with
72              // an update statement?  Or no rows depending on the contents of the table and/or 
73              // parameters?
74              //if (nbRows != 1)
75              //{
76              //    logger.warn("Row count for write should be 1 and not " + nbRows);
77              //}
78              if (tx == null)
79              {
80                  JdbcUtils.commitAndClose(con);
81              }
82              logger.debug("MuleEvent dispatched succesfuly");
83          }
84          catch (Exception e)
85          {
86              logger.debug("Error dispatching event: " + e.getMessage(), e);
87              if (tx == null)
88              {
89                  JdbcUtils.rollbackAndClose(con);
90              }
91              throw e;
92          }
93          
94          return event.getMessage();
95      }
96      
97      protected String escapeStatement(String statement)
98      {
99          //no escaping needed for normal SQL statement
100         return statement;
101     }
102 }