Author: davsclaus
Date: Thu Jan 17 11:19:49 2013
New Revision: 1434618

URL: http://svn.apache.org/viewvc?rev=1434618&view=rev
Log:
CAMEL-5977: camel-sql added support for named parameters. Work in progress.

Added:
    
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
   (with props)
    
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java
   (with props)
    
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParameterTest.java
      - copied, changed from r1434567, 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlRouteTest.java
    
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
   (with props)
Modified:
    
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
    
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
    
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
    camel/trunk/components/camel-sql/src/test/resources/log4j.properties

Added: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java?rev=1434618&view=auto
==============================================================================
--- 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
 (added)
+++ 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
 Thu Jan 17 11:19:49 2013
@@ -0,0 +1,155 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.sql;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeExchangeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default {@link SqlPrepareStatementStrategy} that supports named query 
parameters as well index based.
+ */
+public class DefaultSqlPrepareStatementStrategy implements 
SqlPrepareStatementStrategy {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(DefaultSqlPrepareStatementStrategy.class);
+
+    @Override
+    public String prepareQuery(String query, boolean allowNamedParameters) 
throws SQLException {
+        String answer;
+        if (allowNamedParameters && hasNamedParameters(query)) {
+            // replace all :?word with just ?
+            answer = query.replaceAll("\\:\\?\\w+", "\\?");
+        } else {
+            answer = query;
+        }
+
+        LOG.trace("Prepared query: {}", answer);
+        return answer;
+    }
+
+    @Override
+    public Iterator<?> createPopulateIterator(final String query, final String 
preparedQuery, final int expectedParams,
+                                              final Exchange exchange, final 
Object value) throws SQLException {
+        if (hasNamedParameters(query)) {
+            // create an iterator that returns the value in the named order
+            // the body must be a map type when using named parameters
+            try {
+                final Map map = 
exchange.getContext().getTypeConverter().mandatoryConvertTo(Map.class, value);
+
+                return new Iterator() {
+                    private NamedQueryParser parser = new 
NamedQueryParser(query);
+                    private Object next;
+                    private boolean done;
+
+                    @Override
+                    public boolean hasNext() {
+                        if (done) {
+                            return false;
+                        }
+                        if (next == null) {
+                            next = next();
+                        }
+                        return next != null;
+                    }
+
+                    @Override
+                    public Object next() {
+                        if (next == null) {
+                            String key = parser.next();
+                            if (key == null) {
+                                done = true;
+                                return null;
+                            }
+                            // the key is expected to exist, if not report so 
end user can see this
+                            if (!map.containsKey(key)) {
+                                throw new RuntimeExchangeException("Cannot 
find key [" + key + "] in message body to use when setting named parameter in 
query [" + query + "]", exchange);
+                            }
+                            next = map.get(key);
+                        }
+                        Object answer = next;
+                        next = null;
+                        return answer;
+                    }
+
+                    @Override
+                    public void remove() {
+                        // noop
+                    }
+                };
+            } catch (Exception e) {
+                throw new SQLException("The message body must be a 
java.util.Map type when using named parameters in the query: " + query, e);
+            }
+
+
+        } else {
+            // just use a regular iterator
+            return 
exchange.getContext().getTypeConverter().convertTo(Iterator.class, value);
+        }
+    }
+
+    @Override
+    public void populateStatement(PreparedStatement ps, Iterator<?> iterator, 
int expectedParams) throws SQLException {
+        int argNumber = 1;
+        if (expectedParams > 0) {
+            while (iterator != null && iterator.hasNext()) {
+                Object value = iterator.next();
+                LOG.trace("Setting parameter #{} with value: {}", argNumber, 
value);
+                ps.setObject(argNumber, value);
+                argNumber++;
+            }
+        }
+
+        if (argNumber - 1 != expectedParams) {
+            throw new SQLException("Number of parameters mismatch. Expected: " 
+ expectedParams + ", was:" + (argNumber - 1));
+        }
+    }
+
+    protected boolean hasNamedParameters(String query) {
+        NamedQueryParser parser = new NamedQueryParser(query);
+        return parser.next() != null;
+    }
+
+    private static final class NamedQueryParser {
+
+        private static final Pattern PATTERN = Pattern.compile("\\:\\?(\\w+)");
+        private final Matcher matcher;
+
+        private NamedQueryParser(String query) {
+            this.matcher = PATTERN.matcher(query);
+        }
+
+        public String next() {
+            if (!matcher.find()) {
+                return null;
+            }
+
+            return matcher.group(1);
+        }
+
+        public String replaceAll(String replacement) {
+            return matcher.replaceAll(replacement);
+        }
+    }
+}

Propchange: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlPrepareStatementStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java?rev=1434618&r1=1434617&r2=1434618&view=diff
==============================================================================
--- 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
 (original)
+++ 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
 Thu Jan 17 11:19:49 2013
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Queue;
 
-import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.Message;
@@ -69,19 +68,26 @@ public class SqlConsumer extends Schedul
         }
     }
 
-    public SqlConsumer(Endpoint endpoint, Processor processor, JdbcTemplate 
jdbcTemplate, String query) {
+    public SqlConsumer(SqlEndpoint endpoint, Processor processor, JdbcTemplate 
jdbcTemplate, String query) {
         super(endpoint, processor);
         this.jdbcTemplate = jdbcTemplate;
         this.query = query;
     }
 
     @Override
+    public SqlEndpoint getEndpoint() {
+        return (SqlEndpoint) super.getEndpoint();
+    }
+
+    @Override
     protected int poll() throws Exception {
         // must reset for each poll
         shutdownRunningTask = null;
         pendingExchanges = 0;
 
-        Integer messagePolled = jdbcTemplate.execute(query, new 
PreparedStatementCallback<Integer>() {
+        final String preparedQuery = 
getEndpoint().getPrepareStatementStrategy().prepareQuery(query, 
getEndpoint().isAllowNamedParameters());
+
+        Integer messagePolled = jdbcTemplate.execute(preparedQuery, new 
PreparedStatementCallback<Integer>() {
             @Override
             public Integer doInPreparedStatement(PreparedStatement 
preparedStatement) throws SQLException, DataAccessException {
                 Queue<DataHolder> answer = new LinkedList<DataHolder>();

Modified: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java?rev=1434618&r1=1434617&r2=1434618&view=diff
==============================================================================
--- 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
 (original)
+++ 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
 Thu Jan 17 11:19:49 2013
@@ -35,7 +35,9 @@ public class SqlEndpoint extends Default
     private boolean batch;
     private int maxMessagesPerPoll;
     private SqlProcessingStrategy processingStrategy = new 
DefaultSqlProcessingStrategy();
+    private SqlPrepareStatementStrategy prepareStatementStrategy = new 
DefaultSqlPrepareStatementStrategy();
     private String onConsume;
+    private boolean allowNamedParameters = true;
 
     // TODO: onConsumeBatchDone to execute a query when batch done
 
@@ -104,6 +106,14 @@ public class SqlEndpoint extends Default
         this.processingStrategy = processingStrategy;
     }
 
+    public SqlPrepareStatementStrategy getPrepareStatementStrategy() {
+        return prepareStatementStrategy;
+    }
+
+    public void setPrepareStatementStrategy(SqlPrepareStatementStrategy 
prepareStatementStrategy) {
+        this.prepareStatementStrategy = prepareStatementStrategy;
+    }
+
     public String getOnConsume() {
         return onConsume;
     }
@@ -112,6 +122,14 @@ public class SqlEndpoint extends Default
         this.onConsume = onConsume;
     }
 
+    public boolean isAllowNamedParameters() {
+        return allowNamedParameters;
+    }
+
+    public void setAllowNamedParameters(boolean allowNamedParameters) {
+        this.allowNamedParameters = allowNamedParameters;
+    }
+
     @Override
     protected String createEndpointUri() {
         // Make sure it's properly encoded

Added: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java?rev=1434618&view=auto
==============================================================================
--- 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java
 (added)
+++ 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java
 Thu Jan 17 11:19:49 2013
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.sql;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+
+import org.apache.camel.Exchange;
+
+/**
+ * Strategy for preparing statements when executing SQL queries.
+ */
+public interface SqlPrepareStatementStrategy {
+
+    /**
+     * Prepares the query to be executed.
+     *
+     * @param query                 the query which may contain named query 
parameters
+     * @param allowNamedParameters  whether named parameters is allowed
+     * @return the query to actually use, which must be accepted by the JDBC 
driver.
+     */
+    String prepareQuery(String query, boolean allowNamedParameters) throws 
SQLException;
+
+    /**
+     * Creates the iterator to use when setting query parameters on the 
prepared statement.
+     *
+     * @param query            the original query which may contain named 
parameters
+     * @param preparedQuery    the query to actually use, which must be 
accepted by the JDBC driver.
+     * @param expectedParams   number of expected parameters
+     * @param exchange         the current exchange
+     * @param value            the message body that contains the data for the 
query parameters
+     * @return  the iterator
+     * @throws SQLException is thrown if error creating the iterator
+     */
+    Iterator<?> createPopulateIterator(String query, String preparedQuery, int 
expectedParams, Exchange exchange, Object value) throws SQLException;
+
+    /**
+     * Populates the query parameters on the prepared statement
+     *
+     * @param ps               the prepared statement
+     * @param iterator         the iterator to use for getting the parameter 
data
+     * @param expectedParams   number of expected parameters
+     * @throws SQLException is thrown if error populating parameters
+     */
+    void populateStatement(PreparedStatement ps, Iterator<?> iterator, int 
expectedParams) throws SQLException;
+
+}

Propchange: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlPrepareStatementStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java?rev=1434618&r1=1434617&r2=1434618&view=diff
==============================================================================
--- 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
 (original)
+++ 
camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlProducer.java
 Thu Jan 17 11:19:49 2013
@@ -41,27 +41,34 @@ public class SqlProducer extends Default
         this.batch = batch;
     }
 
+    @Override
+    public SqlEndpoint getEndpoint() {
+        return (SqlEndpoint) super.getEndpoint();
+    }
+
     public void process(final Exchange exchange) throws Exception {
         String queryHeader = 
exchange.getIn().getHeader(SqlConstants.SQL_QUERY, String.class);
-        String sql = queryHeader != null ? queryHeader : query;
 
-        jdbcTemplate.execute(sql, new PreparedStatementCallback<Map<?, ?>>() {
+        final String sql = queryHeader != null ? queryHeader : query;
+        final String preparedQuery = 
getEndpoint().getPrepareStatementStrategy().prepareQuery(sql, 
getEndpoint().isAllowNamedParameters());
+
+        jdbcTemplate.execute(preparedQuery, new 
PreparedStatementCallback<Map<?, ?>>() {
             public Map<?, ?> doInPreparedStatement(PreparedStatement ps) 
throws SQLException {
                 int expected = ps.getParameterMetaData().getParameterCount();
 
                 // transfer incoming message body data to prepared statement 
parameters, if necessary
                 if (exchange.getIn().getBody() != null) {
-                    Iterator<?> iterator = 
exchange.getIn().getBody(Iterator.class);
-                    
                     if (batch) {
+                        Iterator<?> iterator = 
exchange.getIn().getBody(Iterator.class);
                         while (iterator != null && iterator.hasNext()) {
                             Object value = iterator.next();
-                            Iterator<?> i = 
exchange.getContext().getTypeConverter().convertTo(Iterator.class, value);
-                            populateStatement(ps, i, expected);
+                            Iterator<?> i = 
getEndpoint().getPrepareStatementStrategy().createPopulateIterator(sql, 
preparedQuery, expected, exchange, value);
+                            
getEndpoint().getPrepareStatementStrategy().populateStatement(ps, i, expected);
                             ps.addBatch();
                         }
                     } else {
-                        populateStatement(ps, iterator, expected);
+                        Iterator<?> i = 
getEndpoint().getPrepareStatementStrategy().createPopulateIterator(sql, 
preparedQuery, expected, exchange, exchange.getIn().getBody());
+                        
getEndpoint().getPrepareStatementStrategy().populateStatement(ps, i, expected);
                     }
                 }
 
@@ -93,19 +100,4 @@ public class SqlProducer extends Default
         });
     }
 
-    private void populateStatement(PreparedStatement ps, Iterator<?> iterator, 
int expectedParams) throws SQLException {
-        int argNumber = 1;
-        if (expectedParams > 0) {
-            while (iterator != null && iterator.hasNext()) {
-                Object value = iterator.next();
-                log.trace("Setting parameter #{} with value: {}", argNumber, 
value);
-                ps.setObject(argNumber, value);
-                argNumber++;
-            }
-        }
-        
-        if (argNumber - 1 != expectedParams) {
-            throw new SQLException("Number of parameters mismatch. Expected: " 
+ expectedParams + ", was:" + (argNumber - 1));
-        }
-    }
 }

Copied: 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParameterTest.java
 (from r1434567, 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlRouteTest.java)
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParameterTest.java?p2=camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParameterTest.java&p1=camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlRouteTest.java&r1=1434567&r2=1434618&rev=1434618&view=diff
==============================================================================
--- 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlRouteTest.java
 (original)
+++ 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParameterTest.java
 Thu Jan 17 11:19:49 2013
@@ -16,24 +16,16 @@
  */
 package org.apache.camel.component.sql;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.UncategorizedSQLException;
-import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@@ -41,231 +33,44 @@ import org.springframework.jdbc.datasour
 /**
  * @version 
  */
-public class SqlRouteTest extends CamelTestSupport {
+public class SqlProducerNamedParameterTest extends CamelTestSupport {
 
     private EmbeddedDatabase db;
-    private JdbcTemplate jdbcTemplate;
 
-    @Test
-    public void testSimpleBody() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        template.sendBody("direct:simple", "XXX");
-        mock.assertIsSatisfied();
-        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals("Linux", row.get("PROJECT"));
-    }
-
-    @Test
-    public void testQueryAsHeader() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-
-        template.sendBodyAndHeader("direct:simple", "Camel", 
SqlConstants.SQL_QUERY, "select * from projects where project = ? order by id");
-        mock.assertIsSatisfied();
-        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals(1, row.get("id"));
-        assertEquals("ASF", row.get("license"));
-        mock.reset();
-
-        mock.expectedMessageCount(1);
-        template.sendBodyAndHeader("direct:simple", 3, SqlConstants.SQL_QUERY, 
"select * from projects where id = ? order by id");
-        mock.assertIsSatisfied();
-        received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        row = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals("Linux", row.get("PROJECT"));
-        assertEquals("XXX", row.get("license"));
-    }
-
-    @Test
-    public void testListBody() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        List<Object> body = new ArrayList<Object>();
-        body.add("ASF");
-        body.add("Camel");
-        template.sendBody("direct:list", body);
-        mock.assertIsSatisfied();
-        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        Map<?, ?> firstRow = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals(1, firstRow.get("ID"));
+    @Before
+    public void setUp() throws Exception {
+        db = new EmbeddedDatabaseBuilder()
+            
.setType(EmbeddedDatabaseType.DERBY).addScript("sql/createAndPopulateDatabase.sql").build();
         
-        // unlikely to have accidental ordering with 3 rows x 3 columns
-        for (Object obj : received) {
-            Map<?, ?> row = assertIsInstanceOf(Map.class, obj);
-            assertTrue("not preserving key ordering for a given row keys: " + 
row.keySet(), isOrdered(row.keySet()));
-        }
-    }
-
-    @Test
-    public void testLowNumberOfParameter() throws Exception {
-        try {
-            template.sendBody("direct:list", "ASF");
-            fail();
-        } catch (RuntimeCamelException e) {
-            // should have DataAccessException thrown
-            assertTrue("Exception thrown is wrong", e.getCause() instanceof 
DataAccessException);
-        }
+        super.setUp();
     }
 
-    @Test
-    public void testHighNumberOfParameter() throws Exception {
-        try {
-            template.sendBody("direct:simple", new Object[] {"ASF", "Foo"});
-            fail();
-        } catch (RuntimeCamelException e) {
-            // should have DataAccessException thrown
-            assertTrue("Exception thrown is wrong", e.getCause() instanceof 
DataAccessException);
-        }
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+        
+        db.shutdown();
     }
 
     @Test
-    public void testListResult() throws Exception {
+    public void testNamedParameter() throws Exception {
         MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedHeaderReceived(SqlConstants.SQL_ROW_COUNT, "2");
         mock.expectedMessageCount(1);
-        List<Object> body = new ArrayList<Object>();
-        body.add("ASF");
-        template.sendBody("direct:simple", body);
-        mock.assertIsSatisfied();
-        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        assertEquals(2, received.size());
-        Map<?, ?> row1 = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals("Camel", row1.get("PROJECT"));
-        Map<?, ?> row2 = assertIsInstanceOf(Map.class, received.get(1));
-        assertEquals("AMQ", row2.get("PROJECT"));
-    }
 
-    @Test
-    public void testListLimitedResult() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        List<Object> body = new ArrayList<Object>();
-        body.add("ASF");
-        template.sendBody("direct:simpleLimited", body);
-        mock.assertIsSatisfied();
-        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        assertEquals(1, received.size());
-        Map<?, ?> row1 = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals("Camel", row1.get("PROJECT"));
-    }
+        Map map = new HashMap();
+        map.put("lic", "ASF");
 
-    @Test
-    public void testInsert() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
+        template.sendBody("direct:start", map);
 
-        template.sendBody("direct:insert", new Object[] {10, "test", "test"});
         mock.assertIsSatisfied();
-        try {
-            String projectName = jdbcTemplate.queryForObject("select project 
from projects where id = 10", String.class);
-            assertEquals("test", projectName);
-        } catch (EmptyResultDataAccessException e) {
-            fail("no row inserted");
-        }
 
-        Integer actualUpdateCount = 
mock.getExchanges().get(0).getIn().getHeader(SqlConstants.SQL_UPDATE_COUNT, 
Integer.class);
-        assertEquals((Integer) 1, actualUpdateCount);
-    }
-
-    @Test
-    public void testNoBody() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        template.sendBody("direct:no-param", null);
-        mock.assertIsSatisfied();
-        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
-        Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
-        assertEquals("Camel", row.get("PROJECT"));
-    }
-    
-    @Test
-    public void testHashesInQuery() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        template.sendBody("direct:no-param-insert", "XGPL");
-        mock.assertIsSatisfied();
-        Number received = assertIsInstanceOf(Number.class, 
mock.getReceivedExchanges().get(0).getIn().getHeader(SqlConstants.SQL_UPDATE_COUNT));
-        assertEquals(1, received.intValue());
-        Map<?, ?> projectNameInserted = jdbcTemplate.queryForMap("select 
project, license from projects where id = 5");
-        assertEquals("#", projectNameInserted.get("PROJECT"));
-        assertEquals("XGPL", projectNameInserted.get("LICENSE"));
-    }
-    
-    @Test
-    public void testBodyButNoParams() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        template.sendBody("direct:no-param", "Mock body");
-        mock.assertIsSatisfied();
         List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
+        assertEquals(2, received.size());
         Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
         assertEquals("Camel", row.get("PROJECT"));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testBatch() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedMessageCount(1);
-        List<?> data = Arrays.asList(Arrays.asList(6, "abc", "def"), 
Arrays.asList(7, "ghi", "jkl"), Arrays.asList(8, "mno", "pqr"));
-        template.sendBody("direct:batch", data);
-        mock.assertIsSatisfied();
-        Number received = assertIsInstanceOf(Number.class, 
mock.getReceivedExchanges().get(0).getIn().getHeader(SqlConstants.SQL_UPDATE_COUNT));
-        assertEquals(3, received.intValue());
-        assertEquals("abc", jdbcTemplate.queryForObject("select project from 
projects where id = 6", String.class));
-        assertEquals("def", jdbcTemplate.queryForObject("select license from 
projects where id = 6", String.class));
-        assertEquals("ghi", jdbcTemplate.queryForObject("select project from 
projects where id = 7", String.class));
-        assertEquals("jkl", jdbcTemplate.queryForObject("select license from 
projects where id = 7", String.class));
-        assertEquals("mno", jdbcTemplate.queryForObject("select project from 
projects where id = 8", String.class));
-        assertEquals("pqr", jdbcTemplate.queryForObject("select license from 
projects where id = 8", String.class));
-    }
-    
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testBatchMissingParamAtEnd() throws Exception {
-        try {
-            List<?> data = Arrays.asList(Arrays.asList(9, "stu", "vwx"), 
Arrays.asList(10, "yza"));
-            template.sendBody("direct:batch", data);
-            fail();
-        } catch (RuntimeCamelException e) {
-            assertTrue(e.getCause() instanceof UncategorizedSQLException);
-        }
-        assertEquals(0, jdbcTemplate.queryForInt("select count(*) from 
projects where id = 9"));
-        assertEquals(0, jdbcTemplate.queryForInt("select count(*) from 
projects where id = 10"));
-    }
-    
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testBatchMissingParamAtBeginning() throws Exception {
-        try {
-            List<?> data = Arrays.asList(Arrays.asList(9, "stu"), 
Arrays.asList(10, "vwx", "yza"));
-            template.sendBody("direct:batch", data);
-            fail();
-        } catch (RuntimeCamelException e) {
-            assertTrue(e.getCause() instanceof UncategorizedSQLException);
-        }
-        assertEquals(0, jdbcTemplate.queryForInt("select count(*) from 
projects where id = 9"));
-        assertEquals(0, jdbcTemplate.queryForInt("select count(*) from 
projects where id = 10"));
-    }
-    
-    @Before
-    public void setUp() throws Exception {
-        db = new EmbeddedDatabaseBuilder()
-            
.setType(EmbeddedDatabaseType.DERBY).addScript("sql/createAndPopulateDatabase.sql").build();
-        
-        jdbcTemplate = new JdbcTemplate(db);
-        
-        super.setUp();
-    }
 
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-        
-        db.shutdown();
+        row = assertIsInstanceOf(Map.class, received.get(1));
+        assertEquals("AMQ", row.get("PROJECT"));
     }
 
     @Override
@@ -274,42 +79,10 @@ public class SqlRouteTest extends CamelT
             public void configure() {
                 getContext().getComponent("sql", 
SqlComponent.class).setDataSource(db);
 
-                errorHandler(noErrorHandler());
-                
-                from("direct:simple").to("sql:select * from projects where 
license = # order by id")
-                    .to("mock:result");
-
-                from("direct:list")
-                    .to("sql:select * from projects where license = # and 
project = # order by id")
-                    .to("mock:result");
-
-                from("direct:simpleLimited")
-                    .to("sql:select * from projects where license = # order by 
id?template.maxRows=1")
-                    .to("mock:result");
-
-                from("direct:insert").to("sql:insert into projects values (#, 
#, #)").to("mock:result");
-                
-                from("direct:no-param").to("sql:select * from projects order 
by id").to("mock:result");
-                
-                from("direct:no-param-insert").to("sql:insert into projects 
values (5, '#', param)?placeholder=param").to("mock:result");
-                
-                from("direct:batch")
-                    .to("sql:insert into projects values (#, #, #)?batch=true")
+                from("direct:start")
+                    .to("sql:select * from projects where license = :#lic 
order by id")
                     .to("mock:result");
             }
         };
     }
-    
-    private boolean isOrdered(Set<?> keySet) {
-        assertTrue("isOrdered() requires the following keys: id, project, 
license", keySet.contains("id"));
-        assertTrue("isOrdered() requires the following keys: id, project, 
license", keySet.contains("project"));
-        assertTrue("isOrdered() requires the following keys: id, project, 
license", keySet.contains("license"));
-        
-        // the implementation uses a case insensitive Map
-        final Iterator<?> it = keySet.iterator();
-        return "id".equalsIgnoreCase(assertIsInstanceOf(String.class, 
it.next()))
-            && "project".equalsIgnoreCase(assertIsInstanceOf(String.class, 
it.next()))
-            && "license".equalsIgnoreCase(assertIsInstanceOf(String.class, 
it.next()));
-    }
-
 }

Added: 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java?rev=1434618&view=auto
==============================================================================
--- 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
 (added)
+++ 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
 Thu Jan 17 11:19:49 2013
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.sql;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+
+/**
+ * @version 
+ */
+public class SqlProducerNamedParametersTest extends CamelTestSupport {
+
+    private EmbeddedDatabase db;
+
+    @Before
+    public void setUp() throws Exception {
+        db = new EmbeddedDatabaseBuilder()
+            
.setType(EmbeddedDatabaseType.DERBY).addScript("sql/createAndPopulateDatabase.sql").build();
+
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+        
+        db.shutdown();
+    }
+
+    @Test
+    public void testNamedParameters() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        Map map = new HashMap();
+        map.put("lic", "ASF");
+        map.put("min", 1);
+
+        template.sendBody("direct:start", map);
+
+        mock.assertIsSatisfied();
+
+        List<?> received = assertIsInstanceOf(List.class, 
mock.getReceivedExchanges().get(0).getIn().getBody());
+        assertEquals(1, received.size());
+        Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0));
+        assertEquals("AMQ", row.get("PROJECT"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                getContext().getComponent("sql", 
SqlComponent.class).setDataSource(db);
+
+                from("direct:start")
+                    .to("sql:select * from projects where license = :#lic and 
id > :#min order by id")
+                    .to("mock:result");
+            }
+        };
+    }
+}

Propchange: 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: 
camel/trunk/components/camel-sql/src/test/java/org/apache/camel/component/sql/SqlProducerNamedParametersTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/components/camel-sql/src/test/resources/log4j.properties
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/test/resources/log4j.properties?rev=1434618&r1=1434617&r2=1434618&view=diff
==============================================================================
--- camel/trunk/components/camel-sql/src/test/resources/log4j.properties 
(original)
+++ camel/trunk/components/camel-sql/src/test/resources/log4j.properties Thu 
Jan 17 11:19:49 2013
@@ -21,6 +21,7 @@
 log4j.rootLogger=INFO, file
 
 #log4j.logger.org.apache.camel.component.sql=DEBUG
+#log4j.logger.org.apache.camel.component.sql=TRACE
 #log4j.logger.org.apache.camel.processor.aggregate.sql=DEBUG
 #log4j.logger.org.apache.camel.processor.idempotent.sql=DEBUG
 


Reply via email to