This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 48cbba0a58a CAMEL-19211: camel-sql - Make it possible to configure
custom RowMapper
48cbba0a58a is described below
commit 48cbba0a58ab17394dd1b94b1283d35f84bc8afc
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Mar 28 07:12:47 2023 +0200
CAMEL-19211: camel-sql - Make it possible to configure custom RowMapper
---
.../org/apache/camel/catalog/components/sql.json | 1 +
.../camel/component/sql/SqlEndpointConfigurer.java | 6 ++
.../camel/component/sql/SqlEndpointUriFactory.java | 3 +-
.../org/apache/camel/component/sql/sql.json | 1 +
.../component/sql/DefaultRowMapperFactory.java | 37 +++++++++
.../camel/component/sql/DefaultSqlEndpoint.java | 29 +++++--
.../camel/component/sql/RowMapperFactory.java | 38 +++++++++
.../endpoint/dsl/SqlEndpointBuilderFactory.java | 96 ++++++++++++++++++++++
8 files changed, 202 insertions(+), 9 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
index a5cbbc08764..24c8d8e53e9 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
@@ -69,6 +69,7 @@
"parametersCount": { "kind": "parameter", "displayName": "Parameters
Count", "group": "advanced", "label": "advanced", "required": false, "type":
"integer", "javaType": "int", "deprecated": false, "autowired": false,
"secret": false, "description": "If set greater than zero, then Camel will use
this count value of parameters to replace instead of querying via JDBC metadata
API. This is useful if the JDBC vendor could not return correct parameters
count, then user may override instead." },
"placeholder": { "kind": "parameter", "displayName": "Placeholder",
"group": "advanced", "label": "advanced", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "#", "description": "Specifies a character
that will be replaced to in SQL query. Notice, that it is simple
String.replaceAll() operation and no SQL parsing is involved (quoted strings
will also change)." },
"prepareStatementStrategy": { "kind": "parameter", "displayName": "Prepare
Statement Strategy", "group": "advanced", "label": "advanced", "required":
false, "type": "object", "javaType":
"org.apache.camel.component.sql.SqlPrepareStatementStrategy", "deprecated":
false, "autowired": false, "secret": false, "description": "Allows to plugin to
use a custom org.apache.camel.component.sql.SqlPrepareStatementStrategy to
control preparation of the query and prepared statement." },
+ "rowMapperFactory": { "kind": "parameter", "displayName": "Row Mapper
Factory", "group": "advanced", "label": "advanced", "required": false, "type":
"object", "javaType": "org.apache.camel.component.sql.RowMapperFactory",
"deprecated": false, "autowired": false, "secret": false, "description":
"Factory for creating RowMapper" },
"templateOptions": { "kind": "parameter", "displayName": "Template
Options", "group": "advanced", "label": "advanced", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>",
"prefix": "template.", "multiValue": true, "deprecated": false, "autowired":
false, "secret": false, "description": "Configures the Spring JdbcTemplate with
the key\/values from the Map" },
"usePlaceholder": { "kind": "parameter", "displayName": "Use Placeholder",
"group": "advanced", "label": "advanced", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": true, "description": "Sets whether to use placeholder
and replace all placeholder characters with sign in the SQL queries." },
"backoffErrorThreshold": { "kind": "parameter", "displayName": "Backoff
Error Threshold", "group": "scheduler", "label": "consumer,scheduler",
"required": false, "type": "integer", "javaType": "int", "deprecated": false,
"autowired": false, "secret": false, "description": "The number of subsequent
error polls (failed due some error) that should happen before the
backoffMultipler should kick-in." },
diff --git
a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointConfigurer.java
b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointConfigurer.java
index cdee3121a92..823812b8fd6 100644
---
a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointConfigurer.java
+++
b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointConfigurer.java
@@ -78,6 +78,8 @@ public class SqlEndpointConfigurer extends
PropertyConfigurerSupport implements
case "repeatCount": target.setRepeatCount(property(camelContext,
long.class, value)); return true;
case "routeemptyresultset":
case "routeEmptyResultSet":
target.setRouteEmptyResultSet(property(camelContext, boolean.class, value));
return true;
+ case "rowmapperfactory":
+ case "rowMapperFactory":
target.setRowMapperFactory(property(camelContext,
org.apache.camel.component.sql.RowMapperFactory.class, value)); return true;
case "runlogginglevel":
case "runLoggingLevel":
target.setRunLoggingLevel(property(camelContext,
org.apache.camel.LoggingLevel.class, value)); return true;
case "scheduledexecutorservice":
@@ -172,6 +174,8 @@ public class SqlEndpointConfigurer extends
PropertyConfigurerSupport implements
case "repeatCount": return long.class;
case "routeemptyresultset":
case "routeEmptyResultSet": return boolean.class;
+ case "rowmapperfactory":
+ case "rowMapperFactory": return
org.apache.camel.component.sql.RowMapperFactory.class;
case "runlogginglevel":
case "runLoggingLevel": return org.apache.camel.LoggingLevel.class;
case "scheduledexecutorservice":
@@ -262,6 +266,8 @@ public class SqlEndpointConfigurer extends
PropertyConfigurerSupport implements
case "repeatCount": return target.getRepeatCount();
case "routeemptyresultset":
case "routeEmptyResultSet": return target.isRouteEmptyResultSet();
+ case "rowmapperfactory":
+ case "rowMapperFactory": return target.getRowMapperFactory();
case "runlogginglevel":
case "runLoggingLevel": return target.getRunLoggingLevel();
case "scheduledexecutorservice":
diff --git
a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointUriFactory.java
b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointUriFactory.java
index 1931acee130..32afd2d2a8d 100644
---
a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointUriFactory.java
+++
b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlEndpointUriFactory.java
@@ -21,7 +21,7 @@ public class SqlEndpointUriFactory extends
org.apache.camel.support.component.En
private static final Set<String> SECRET_PROPERTY_NAMES;
private static final Set<String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(46);
+ Set<String> props = new HashSet<>(47);
props.add("allowNamedParameters");
props.add("alwaysPopulateStatement");
props.add("backoffErrorThreshold");
@@ -54,6 +54,7 @@ public class SqlEndpointUriFactory extends
org.apache.camel.support.component.En
props.add("query");
props.add("repeatCount");
props.add("routeEmptyResultSet");
+ props.add("rowMapperFactory");
props.add("runLoggingLevel");
props.add("scheduledExecutorService");
props.add("scheduler");
diff --git
a/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/sql.json
b/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/sql.json
index a5cbbc08764..24c8d8e53e9 100644
---
a/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/sql.json
+++
b/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/sql.json
@@ -69,6 +69,7 @@
"parametersCount": { "kind": "parameter", "displayName": "Parameters
Count", "group": "advanced", "label": "advanced", "required": false, "type":
"integer", "javaType": "int", "deprecated": false, "autowired": false,
"secret": false, "description": "If set greater than zero, then Camel will use
this count value of parameters to replace instead of querying via JDBC metadata
API. This is useful if the JDBC vendor could not return correct parameters
count, then user may override instead." },
"placeholder": { "kind": "parameter", "displayName": "Placeholder",
"group": "advanced", "label": "advanced", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "#", "description": "Specifies a character
that will be replaced to in SQL query. Notice, that it is simple
String.replaceAll() operation and no SQL parsing is involved (quoted strings
will also change)." },
"prepareStatementStrategy": { "kind": "parameter", "displayName": "Prepare
Statement Strategy", "group": "advanced", "label": "advanced", "required":
false, "type": "object", "javaType":
"org.apache.camel.component.sql.SqlPrepareStatementStrategy", "deprecated":
false, "autowired": false, "secret": false, "description": "Allows to plugin to
use a custom org.apache.camel.component.sql.SqlPrepareStatementStrategy to
control preparation of the query and prepared statement." },
+ "rowMapperFactory": { "kind": "parameter", "displayName": "Row Mapper
Factory", "group": "advanced", "label": "advanced", "required": false, "type":
"object", "javaType": "org.apache.camel.component.sql.RowMapperFactory",
"deprecated": false, "autowired": false, "secret": false, "description":
"Factory for creating RowMapper" },
"templateOptions": { "kind": "parameter", "displayName": "Template
Options", "group": "advanced", "label": "advanced", "required": false, "type":
"object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>",
"prefix": "template.", "multiValue": true, "deprecated": false, "autowired":
false, "secret": false, "description": "Configures the Spring JdbcTemplate with
the key\/values from the Map" },
"usePlaceholder": { "kind": "parameter", "displayName": "Use Placeholder",
"group": "advanced", "label": "advanced", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": true, "description": "Sets whether to use placeholder
and replace all placeholder characters with sign in the SQL queries." },
"backoffErrorThreshold": { "kind": "parameter", "displayName": "Backoff
Error Threshold", "group": "scheduler", "label": "consumer,scheduler",
"required": false, "type": "integer", "javaType": "int", "deprecated": false,
"autowired": false, "secret": false, "description": "The number of subsequent
error polls (failed due some error) that should happen before the
backoffMultipler should kick-in." },
diff --git
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultRowMapperFactory.java
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultRowMapperFactory.java
new file mode 100644
index 00000000000..4adc16a4819
--- /dev/null
+++
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultRowMapperFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.ColumnMapRowMapper;
+import org.springframework.jdbc.core.RowMapper;
+
+/**
+ * Default {@link RowMapperFactory}.
+ */
+public class DefaultRowMapperFactory implements RowMapperFactory {
+
+ @Override
+ public RowMapper<?> newColumnRowMapper() {
+ return new ColumnMapRowMapper();
+ }
+
+ @Override
+ public RowMapper<?> newBeanRowMapper(Class<?> mappedClass) {
+ return new BeanPropertyRowMapper<>(mappedClass);
+ }
+}
diff --git
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
index a31f961ad71..b5d47c7770b 100644
---
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
+++
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
@@ -30,8 +30,6 @@ import org.apache.camel.Component;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriParam;
import org.apache.camel.support.DefaultPollingEndpoint;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;
@@ -128,6 +126,10 @@ public abstract class DefaultSqlEndpoint extends
DefaultPollingEndpoint {
description = "Configures the Spring JdbcTemplate with the
key/values from the Map")
private Map<String, Object> templateOptions;
+ @UriParam(label = "advanced",
+ description = "Factory for creating RowMapper")
+ private RowMapperFactory rowMapperFactory = new DefaultRowMapperFactory();
+
public DefaultSqlEndpoint() {
}
@@ -449,16 +451,27 @@ public abstract class DefaultSqlEndpoint extends
DefaultPollingEndpoint {
this.templateOptions = templateOptions;
}
+ public RowMapperFactory getRowMapperFactory() {
+ return rowMapperFactory;
+ }
+
+ /**
+ * Factory for creating RowMapper
+ */
+ public void setRowMapperFactory(RowMapperFactory rowMapperFactory) {
+ this.rowMapperFactory = rowMapperFactory;
+ }
+
@SuppressWarnings("unchecked")
public List<?> queryForList(ResultSet rs, boolean allowMapToClass) throws
SQLException {
if (allowMapToClass && outputClass != null) {
Class<?> outputClazz =
getCamelContext().getClassResolver().resolveClass(outputClass);
- RowMapper rowMapper = new BeanPropertyRowMapper(outputClazz);
+ RowMapper rowMapper =
rowMapperFactory.newBeanRowMapper(outputClazz);
RowMapperResultSetExtractor<?> mapper = new
RowMapperResultSetExtractor(rowMapper);
List<?> data = mapper.extractData(rs);
return data;
} else {
- ColumnMapRowMapper rowMapper = new ColumnMapRowMapper();
+ RowMapper rowMapper = rowMapperFactory.newColumnRowMapper();
RowMapperResultSetExtractor<Map<String, Object>> mapper = new
RowMapperResultSetExtractor<>(rowMapper);
List<Map<String, Object>> data = mapper.extractData(rs);
return data;
@@ -469,7 +482,7 @@ public abstract class DefaultSqlEndpoint extends
DefaultPollingEndpoint {
public Object queryForObject(ResultSet rs) throws SQLException {
Object result = null;
if (outputClass == null) {
- RowMapper rowMapper = new ColumnMapRowMapper();
+ RowMapper rowMapper = rowMapperFactory.newColumnRowMapper();
RowMapperResultSetExtractor<Map<String, Object>> mapper
= new RowMapperResultSetExtractor<Map<String,
Object>>(rowMapper);
List<Map<String, Object>> data = mapper.extractData(rs);
@@ -487,7 +500,7 @@ public abstract class DefaultSqlEndpoint extends
DefaultPollingEndpoint {
}
} else {
Class<?> outputClzz =
getCamelContext().getClassResolver().resolveClass(outputClass);
- RowMapper rowMapper = new BeanPropertyRowMapper(outputClzz);
+ RowMapper rowMapper =
rowMapperFactory.newBeanRowMapper(outputClzz);
RowMapperResultSetExtractor<?> mapper = new
RowMapperResultSetExtractor(rowMapper);
List<?> data = mapper.extractData(rs);
if (data.size() > 1) {
@@ -505,11 +518,11 @@ public abstract class DefaultSqlEndpoint extends
DefaultPollingEndpoint {
@SuppressWarnings("unchecked")
public ResultSetIterator queryForStreamList(Connection connection,
Statement statement, ResultSet rs) throws SQLException {
if (outputClass == null) {
- RowMapper rowMapper = new ColumnMapRowMapper();
+ RowMapper rowMapper = rowMapperFactory.newColumnRowMapper();
return new ResultSetIterator(connection, statement, rs, rowMapper);
} else {
Class<?> outputClzz =
getCamelContext().getClassResolver().resolveClass(outputClass);
- RowMapper rowMapper = new BeanPropertyRowMapper(outputClzz);
+ RowMapper rowMapper =
rowMapperFactory.newBeanRowMapper(outputClzz);
return new ResultSetIterator(connection, statement, rs, rowMapper);
}
}
diff --git
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/RowMapperFactory.java
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/RowMapperFactory.java
new file mode 100644
index 00000000000..d663c049097
--- /dev/null
+++
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/RowMapperFactory.java
@@ -0,0 +1,38 @@
+/*
+ * 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 org.springframework.jdbc.core.RowMapper;
+
+/**
+ * Factory for creating {@link RowMapper}.
+ */
+public interface RowMapperFactory {
+
+ /**
+ * Creates a new column based row mapper
+ */
+ RowMapper<?> newColumnRowMapper();
+
+ /**
+ * Creates a new bean based row mapper
+ *
+ * @param mappedClass the mapped class
+ */
+ RowMapper<?> newBeanRowMapper(Class<?> mappedClass);
+
+}
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
index 6b558f83aca..3365c077874 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
@@ -1325,6 +1325,38 @@ public interface SqlEndpointBuilderFactory {
doSetProperty("prepareStatementStrategy",
prepareStatementStrategy);
return this;
}
+ /**
+ * Factory for creating RowMapper.
+ *
+ * The option is a:
+ *
<code>org.apache.camel.component.sql.RowMapperFactory</code> type.
+ *
+ * Group: advanced
+ *
+ * @param rowMapperFactory the value to set
+ * @return the dsl builder
+ */
+ default AdvancedSqlEndpointConsumerBuilder rowMapperFactory(
+ org.apache.camel.component.sql.RowMapperFactory
rowMapperFactory) {
+ doSetProperty("rowMapperFactory", rowMapperFactory);
+ return this;
+ }
+ /**
+ * Factory for creating RowMapper.
+ *
+ * The option will be converted to a
+ *
<code>org.apache.camel.component.sql.RowMapperFactory</code> type.
+ *
+ * Group: advanced
+ *
+ * @param rowMapperFactory the value to set
+ * @return the dsl builder
+ */
+ default AdvancedSqlEndpointConsumerBuilder rowMapperFactory(
+ String rowMapperFactory) {
+ doSetProperty("rowMapperFactory", rowMapperFactory);
+ return this;
+ }
/**
* Configures the Spring JdbcTemplate with the key/values from the Map.
*
@@ -1899,6 +1931,38 @@ public interface SqlEndpointBuilderFactory {
doSetProperty("prepareStatementStrategy",
prepareStatementStrategy);
return this;
}
+ /**
+ * Factory for creating RowMapper.
+ *
+ * The option is a:
+ *
<code>org.apache.camel.component.sql.RowMapperFactory</code> type.
+ *
+ * Group: advanced
+ *
+ * @param rowMapperFactory the value to set
+ * @return the dsl builder
+ */
+ default AdvancedSqlEndpointProducerBuilder rowMapperFactory(
+ org.apache.camel.component.sql.RowMapperFactory
rowMapperFactory) {
+ doSetProperty("rowMapperFactory", rowMapperFactory);
+ return this;
+ }
+ /**
+ * Factory for creating RowMapper.
+ *
+ * The option will be converted to a
+ *
<code>org.apache.camel.component.sql.RowMapperFactory</code> type.
+ *
+ * Group: advanced
+ *
+ * @param rowMapperFactory the value to set
+ * @return the dsl builder
+ */
+ default AdvancedSqlEndpointProducerBuilder rowMapperFactory(
+ String rowMapperFactory) {
+ doSetProperty("rowMapperFactory", rowMapperFactory);
+ return this;
+ }
/**
* Configures the Spring JdbcTemplate with the key/values from the Map.
*
@@ -2320,6 +2384,38 @@ public interface SqlEndpointBuilderFactory {
doSetProperty("prepareStatementStrategy",
prepareStatementStrategy);
return this;
}
+ /**
+ * Factory for creating RowMapper.
+ *
+ * The option is a:
+ *
<code>org.apache.camel.component.sql.RowMapperFactory</code> type.
+ *
+ * Group: advanced
+ *
+ * @param rowMapperFactory the value to set
+ * @return the dsl builder
+ */
+ default AdvancedSqlEndpointBuilder rowMapperFactory(
+ org.apache.camel.component.sql.RowMapperFactory
rowMapperFactory) {
+ doSetProperty("rowMapperFactory", rowMapperFactory);
+ return this;
+ }
+ /**
+ * Factory for creating RowMapper.
+ *
+ * The option will be converted to a
+ *
<code>org.apache.camel.component.sql.RowMapperFactory</code> type.
+ *
+ * Group: advanced
+ *
+ * @param rowMapperFactory the value to set
+ * @return the dsl builder
+ */
+ default AdvancedSqlEndpointBuilder rowMapperFactory(
+ String rowMapperFactory) {
+ doSetProperty("rowMapperFactory", rowMapperFactory);
+ return this;
+ }
/**
* Configures the Spring JdbcTemplate with the key/values from the Map.
*