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