/*
 * 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.builder.endpoint.dsl;

import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Generated;
import org.apache.camel.ExchangePattern;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
import org.apache.camel.spi.ExceptionHandler;
import org.apache.camel.spi.PollingConsumerPollStrategy;

/**
 * The sql component allows you to work with databases using JDBC SQL queries.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface SqlEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the SQL component.
     */
    public interface SqlEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedSqlEndpointConsumerBuilder advanced() {
            return (AdvancedSqlEndpointConsumerBuilder) this;
        }
        /**
         * Whether to allow using named parameters in the queries.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder allowNamedParameters(
                boolean allowNamedParameters) {
            doSetProperty("allowNamedParameters", allowNamedParameters);
            return this;
        }
        /**
         * Whether to allow using named parameters in the queries.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder allowNamedParameters(
                String allowNamedParameters) {
            doSetProperty("allowNamedParameters", allowNamedParameters);
            return this;
        }
        /**
         * Sets the DataSource to use to communicate with the database.
         * 
         * The option is a: <code>javax.sql.DataSource</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder dataSource(Object dataSource) {
            doSetProperty("dataSource", dataSource);
            return this;
        }
        /**
         * Sets the DataSource to use to communicate with the database.
         * 
         * The option will be converted to a <code>javax.sql.DataSource</code>
         * type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder dataSource(String dataSource) {
            doSetProperty("dataSource", dataSource);
            return this;
        }
        /**
         * Sets the reference to a DataSource to lookup from the registry, to
         * use for communicating with the database.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        @Deprecated
        default SqlEndpointConsumerBuilder dataSourceRef(String dataSourceRef) {
            doSetProperty("dataSourceRef", dataSourceRef);
            return this;
        }
        /**
         * Specify the full package and class name to use as conversion when
         * outputType=SelectOne.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder outputClass(String outputClass) {
            doSetProperty("outputClass", outputClass);
            return this;
        }
        /**
         * Store the query result in a header instead of the message body. By
         * default, outputHeader == null and the query result is stored in the
         * message body, any existing content in the message body is discarded.
         * If outputHeader is set, the value is used as the name of the header
         * to store the query result and the original message body is preserved.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder outputHeader(String outputHeader) {
            doSetProperty("outputHeader", outputHeader);
            return this;
        }
        /**
         * Make the output of consumer or producer to SelectList as List of Map,
         * or SelectOne as single Java object in the following way: a) If the
         * query has only single column, then that JDBC Column object is
         * returned. (such as SELECT COUNT( ) FROM PROJECT will return a Long
         * object. b) If the query has more than one column, then it will return
         * a Map of that result. c) If the outputClass is set, then it will
         * convert the query result into an Java bean object by calling all the
         * setters that match the column names. It will assume your class has a
         * default constructor to create instance with. d) If the query resulted
         * in more than one rows, it throws an non-unique result exception.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder outputType(SqlOutputType outputType) {
            doSetProperty("outputType", outputType);
            return this;
        }
        /**
         * Make the output of consumer or producer to SelectList as List of Map,
         * or SelectOne as single Java object in the following way: a) If the
         * query has only single column, then that JDBC Column object is
         * returned. (such as SELECT COUNT( ) FROM PROJECT will return a Long
         * object. b) If the query has more than one column, then it will return
         * a Map of that result. c) If the outputClass is set, then it will
         * convert the query result into an Java bean object by calling all the
         * setters that match the column names. It will assume your class has a
         * default constructor to create instance with. d) If the query resulted
         * in more than one rows, it throws an non-unique result exception.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder outputType(String outputType) {
            doSetProperty("outputType", outputType);
            return this;
        }
        /**
         * The separator to use when parameter values is taken from message body
         * (if the body is a String type), to be inserted at # placeholders.
         * Notice if you use named parameters, then a Map type is used instead.
         * The default value is comma.
         * 
         * The option is a: <code>char</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder separator(char separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * The separator to use when parameter values is taken from message body
         * (if the body is a String type), to be inserted at # placeholders.
         * Notice if you use named parameters, then a Map type is used instead.
         * The default value is comma.
         * 
         * The option will be converted to a <code>char</code> type.
         * 
         * Group: common
         */
        default SqlEndpointConsumerBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Sets whether to break batch if onConsume failed.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder breakBatchOnConsumeFail(
                boolean breakBatchOnConsumeFail) {
            doSetProperty("breakBatchOnConsumeFail", breakBatchOnConsumeFail);
            return this;
        }
        /**
         * Sets whether to break batch if onConsume failed.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder breakBatchOnConsumeFail(
                String breakBatchOnConsumeFail) {
            doSetProperty("breakBatchOnConsumeFail", breakBatchOnConsumeFail);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder bridgeErrorHandler(
                boolean bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Sets an expected update count to validate when using onConsume.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder expectedUpdateCount(
                int expectedUpdateCount) {
            doSetProperty("expectedUpdateCount", expectedUpdateCount);
            return this;
        }
        /**
         * Sets an expected update count to validate when using onConsume.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder expectedUpdateCount(
                String expectedUpdateCount) {
            doSetProperty("expectedUpdateCount", expectedUpdateCount);
            return this;
        }
        /**
         * Sets the maximum number of messages to poll.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder maxMessagesPerPoll(
                int maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * Sets the maximum number of messages to poll.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder maxMessagesPerPoll(
                String maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * After processing each row then this query can be executed, if the
         * Exchange was processed successfully, for example to mark the row as
         * processed. The query can have parameter.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder onConsume(String onConsume) {
            doSetProperty("onConsume", onConsume);
            return this;
        }
        /**
         * After processing the entire batch, this query can be executed to bulk
         * update rows etc. The query cannot have parameters.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder onConsumeBatchComplete(
                String onConsumeBatchComplete) {
            doSetProperty("onConsumeBatchComplete", onConsumeBatchComplete);
            return this;
        }
        /**
         * After processing each row then this query can be executed, if the
         * Exchange failed, for example to mark the row as failed. The query can
         * have parameter.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder onConsumeFailed(
                String onConsumeFailed) {
            doSetProperty("onConsumeFailed", onConsumeFailed);
            return this;
        }
        /**
         * Sets whether empty resultset should be allowed to be sent to the next
         * hop. Defaults to false. So the empty resultset will be filtered out.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder routeEmptyResultSet(
                boolean routeEmptyResultSet) {
            doSetProperty("routeEmptyResultSet", routeEmptyResultSet);
            return this;
        }
        /**
         * Sets whether empty resultset should be allowed to be sent to the next
         * hop. Defaults to false. So the empty resultset will be filtered out.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder routeEmptyResultSet(
                String routeEmptyResultSet) {
            doSetProperty("routeEmptyResultSet", routeEmptyResultSet);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                boolean sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * Enables or disables transaction. If enabled then if processing an
         * exchange failed then the consumer break out processing any further
         * exchanges to cause a rollback eager.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder transacted(boolean transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
        /**
         * Enables or disables transaction. If enabled then if processing an
         * exchange failed then the consumer break out processing any further
         * exchanges to cause a rollback eager.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
        /**
         * Sets how resultset should be delivered to route. Indicates delivery
         * as either a list or individual object. defaults to true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder useIterator(boolean useIterator) {
            doSetProperty("useIterator", useIterator);
            return this;
        }
        /**
         * Sets how resultset should be delivered to route. Indicates delivery
         * as either a list or individual object. defaults to true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SqlEndpointConsumerBuilder useIterator(String useIterator) {
            doSetProperty("useIterator", useIterator);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder backoffErrorThreshold(
                int backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder backoffErrorThreshold(
                String backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder backoffIdleThreshold(
                int backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder backoffIdleThreshold(
                String backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder backoffMultiplier(
                int backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder backoffMultiplier(
                String backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * Milliseconds before the next poll. You can also specify time values
         * using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder delay(long delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * Milliseconds before the next poll. You can also specify time values
         * using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder delay(String delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder greedy(boolean greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder greedy(String greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * Milliseconds before the first poll starts. You can also specify time
         * values using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder initialDelay(long initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Milliseconds before the first poll starts. You can also specify time
         * values using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder initialDelay(String initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder repeatCount(long repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder repeatCount(String repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder runLoggingLevel(
                LoggingLevel runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder runLoggingLevel(
                String runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option is a:
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder scheduledExecutorService(
                ScheduledExecutorService scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder scheduledExecutorService(
                String scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * To use a cron scheduler from either camel-spring or camel-quartz
         * component.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder scheduler(String scheduler) {
            doSetProperty("scheduler", scheduler);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder schedulerProperties(
                Map<String, Object> schedulerProperties) {
            doSetProperty("schedulerProperties", schedulerProperties);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder schedulerProperties(
                String schedulerProperties) {
            doSetProperty("schedulerProperties", schedulerProperties);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder startScheduler(boolean startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder startScheduler(String startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option is a: <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder timeUnit(TimeUnit timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder timeUnit(String timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder useFixedDelay(boolean useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SqlEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the SQL component.
     */
    public interface AdvancedSqlEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default SqlEndpointConsumerBuilder basic() {
            return (SqlEndpointConsumerBuilder) this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder exceptionHandler(
                ExceptionHandler exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.ExceptionHandler</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder exceptionHandler(
                String exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option is a: <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder exchangePattern(
                ExchangePattern exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder pollStrategy(
                PollingConsumerPollStrategy pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlProcessingStrategy to execute
         * queries when the consumer has processed the rows/batch.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlProcessingStrategy</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder processingStrategy(
                Object processingStrategy) {
            doSetProperty("processingStrategy", processingStrategy);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlProcessingStrategy to execute
         * queries when the consumer has processed the rows/batch.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlProcessingStrategy</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSqlEndpointConsumerBuilder processingStrategy(
                String processingStrategy) {
            doSetProperty("processingStrategy", processingStrategy);
            return this;
        }
        /**
         * If enabled then the populateStatement method from
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy is always
         * invoked, also if there is no expected parameters to be prepared. When
         * this is false then the populateStatement is only invoked if there is
         * 1 or more expected parameters to be set; for example this avoids
         * reading the message body/headers for SQL queries with no parameters.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder alwaysPopulateStatement(
                boolean alwaysPopulateStatement) {
            doSetProperty("alwaysPopulateStatement", alwaysPopulateStatement);
            return this;
        }
        /**
         * If enabled then the populateStatement method from
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy is always
         * invoked, also if there is no expected parameters to be prepared. When
         * this is false then the populateStatement is only invoked if there is
         * 1 or more expected parameters to be set; for example this avoids
         * reading the message body/headers for SQL queries with no parameters.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder alwaysPopulateStatement(
                String alwaysPopulateStatement) {
            doSetProperty("alwaysPopulateStatement", alwaysPopulateStatement);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * 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.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder parametersCount(
                int parametersCount) {
            doSetProperty("parametersCount", parametersCount);
            return this;
        }
        /**
         * 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.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder parametersCount(
                String parametersCount) {
            doSetProperty("parametersCount", parametersCount);
            return this;
        }
        /**
         * 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).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder placeholder(
                String placeholder) {
            doSetProperty("placeholder", placeholder);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy to control
         * preparation of the query and prepared statement.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlPrepareStatementStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder prepareStatementStrategy(
                Object prepareStatementStrategy) {
            doSetProperty("prepareStatementStrategy", prepareStatementStrategy);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy to control
         * preparation of the query and prepared statement.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlPrepareStatementStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder prepareStatementStrategy(
                String prepareStatementStrategy) {
            doSetProperty("prepareStatementStrategy", prepareStatementStrategy);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Configures the Spring JdbcTemplate with the key/values from the Map.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder templateOptions(
                Map<String, Object> templateOptions) {
            doSetProperty("templateOptions", templateOptions);
            return this;
        }
        /**
         * Configures the Spring JdbcTemplate with the key/values from the Map.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder templateOptions(
                String templateOptions) {
            doSetProperty("templateOptions", templateOptions);
            return this;
        }
        /**
         * Sets whether to use placeholder and replace all placeholder
         * characters with sign in the SQL queries. This option is default true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder usePlaceholder(
                boolean usePlaceholder) {
            doSetProperty("usePlaceholder", usePlaceholder);
            return this;
        }
        /**
         * Sets whether to use placeholder and replace all placeholder
         * characters with sign in the SQL queries. This option is default true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointConsumerBuilder usePlaceholder(
                String usePlaceholder) {
            doSetProperty("usePlaceholder", usePlaceholder);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the SQL component.
     */
    public interface SqlEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedSqlEndpointProducerBuilder advanced() {
            return (AdvancedSqlEndpointProducerBuilder) this;
        }
        /**
         * Whether to allow using named parameters in the queries.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder allowNamedParameters(
                boolean allowNamedParameters) {
            doSetProperty("allowNamedParameters", allowNamedParameters);
            return this;
        }
        /**
         * Whether to allow using named parameters in the queries.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder allowNamedParameters(
                String allowNamedParameters) {
            doSetProperty("allowNamedParameters", allowNamedParameters);
            return this;
        }
        /**
         * Sets the DataSource to use to communicate with the database.
         * 
         * The option is a: <code>javax.sql.DataSource</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder dataSource(Object dataSource) {
            doSetProperty("dataSource", dataSource);
            return this;
        }
        /**
         * Sets the DataSource to use to communicate with the database.
         * 
         * The option will be converted to a <code>javax.sql.DataSource</code>
         * type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder dataSource(String dataSource) {
            doSetProperty("dataSource", dataSource);
            return this;
        }
        /**
         * Sets the reference to a DataSource to lookup from the registry, to
         * use for communicating with the database.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        @Deprecated
        default SqlEndpointProducerBuilder dataSourceRef(String dataSourceRef) {
            doSetProperty("dataSourceRef", dataSourceRef);
            return this;
        }
        /**
         * Specify the full package and class name to use as conversion when
         * outputType=SelectOne.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder outputClass(String outputClass) {
            doSetProperty("outputClass", outputClass);
            return this;
        }
        /**
         * Store the query result in a header instead of the message body. By
         * default, outputHeader == null and the query result is stored in the
         * message body, any existing content in the message body is discarded.
         * If outputHeader is set, the value is used as the name of the header
         * to store the query result and the original message body is preserved.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder outputHeader(String outputHeader) {
            doSetProperty("outputHeader", outputHeader);
            return this;
        }
        /**
         * Make the output of consumer or producer to SelectList as List of Map,
         * or SelectOne as single Java object in the following way: a) If the
         * query has only single column, then that JDBC Column object is
         * returned. (such as SELECT COUNT( ) FROM PROJECT will return a Long
         * object. b) If the query has more than one column, then it will return
         * a Map of that result. c) If the outputClass is set, then it will
         * convert the query result into an Java bean object by calling all the
         * setters that match the column names. It will assume your class has a
         * default constructor to create instance with. d) If the query resulted
         * in more than one rows, it throws an non-unique result exception.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder outputType(SqlOutputType outputType) {
            doSetProperty("outputType", outputType);
            return this;
        }
        /**
         * Make the output of consumer or producer to SelectList as List of Map,
         * or SelectOne as single Java object in the following way: a) If the
         * query has only single column, then that JDBC Column object is
         * returned. (such as SELECT COUNT( ) FROM PROJECT will return a Long
         * object. b) If the query has more than one column, then it will return
         * a Map of that result. c) If the outputClass is set, then it will
         * convert the query result into an Java bean object by calling all the
         * setters that match the column names. It will assume your class has a
         * default constructor to create instance with. d) If the query resulted
         * in more than one rows, it throws an non-unique result exception.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder outputType(String outputType) {
            doSetProperty("outputType", outputType);
            return this;
        }
        /**
         * The separator to use when parameter values is taken from message body
         * (if the body is a String type), to be inserted at # placeholders.
         * Notice if you use named parameters, then a Map type is used instead.
         * The default value is comma.
         * 
         * The option is a: <code>char</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder separator(char separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * The separator to use when parameter values is taken from message body
         * (if the body is a String type), to be inserted at # placeholders.
         * Notice if you use named parameters, then a Map type is used instead.
         * The default value is comma.
         * 
         * The option will be converted to a <code>char</code> type.
         * 
         * Group: common
         */
        default SqlEndpointProducerBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Enables or disables batch mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder batch(boolean batch) {
            doSetProperty("batch", batch);
            return this;
        }
        /**
         * Enables or disables batch mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder batch(String batch) {
            doSetProperty("batch", batch);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder lazyStartProducer(
                boolean lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * If set, will ignore the results of the SQL query and use the existing
         * IN message as the OUT message for the continuation of processing.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder noop(boolean noop) {
            doSetProperty("noop", noop);
            return this;
        }
        /**
         * If set, will ignore the results of the SQL query and use the existing
         * IN message as the OUT message for the continuation of processing.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder noop(String noop) {
            doSetProperty("noop", noop);
            return this;
        }
        /**
         * Whether to use the message body as the SQL and then headers for
         * parameters. If this option is enabled then the SQL in the uri is not
         * used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder useMessageBodyForSql(
                boolean useMessageBodyForSql) {
            doSetProperty("useMessageBodyForSql", useMessageBodyForSql);
            return this;
        }
        /**
         * Whether to use the message body as the SQL and then headers for
         * parameters. If this option is enabled then the SQL in the uri is not
         * used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SqlEndpointProducerBuilder useMessageBodyForSql(
                String useMessageBodyForSql) {
            doSetProperty("useMessageBodyForSql", useMessageBodyForSql);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the SQL component.
     */
    public interface AdvancedSqlEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default SqlEndpointProducerBuilder basic() {
            return (SqlEndpointProducerBuilder) this;
        }
        /**
         * If enabled then the populateStatement method from
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy is always
         * invoked, also if there is no expected parameters to be prepared. When
         * this is false then the populateStatement is only invoked if there is
         * 1 or more expected parameters to be set; for example this avoids
         * reading the message body/headers for SQL queries with no parameters.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder alwaysPopulateStatement(
                boolean alwaysPopulateStatement) {
            doSetProperty("alwaysPopulateStatement", alwaysPopulateStatement);
            return this;
        }
        /**
         * If enabled then the populateStatement method from
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy is always
         * invoked, also if there is no expected parameters to be prepared. When
         * this is false then the populateStatement is only invoked if there is
         * 1 or more expected parameters to be set; for example this avoids
         * reading the message body/headers for SQL queries with no parameters.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder alwaysPopulateStatement(
                String alwaysPopulateStatement) {
            doSetProperty("alwaysPopulateStatement", alwaysPopulateStatement);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * 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.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder parametersCount(
                int parametersCount) {
            doSetProperty("parametersCount", parametersCount);
            return this;
        }
        /**
         * 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.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder parametersCount(
                String parametersCount) {
            doSetProperty("parametersCount", parametersCount);
            return this;
        }
        /**
         * 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).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder placeholder(
                String placeholder) {
            doSetProperty("placeholder", placeholder);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy to control
         * preparation of the query and prepared statement.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlPrepareStatementStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder prepareStatementStrategy(
                Object prepareStatementStrategy) {
            doSetProperty("prepareStatementStrategy", prepareStatementStrategy);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy to control
         * preparation of the query and prepared statement.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlPrepareStatementStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder prepareStatementStrategy(
                String prepareStatementStrategy) {
            doSetProperty("prepareStatementStrategy", prepareStatementStrategy);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Configures the Spring JdbcTemplate with the key/values from the Map.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder templateOptions(
                Map<String, Object> templateOptions) {
            doSetProperty("templateOptions", templateOptions);
            return this;
        }
        /**
         * Configures the Spring JdbcTemplate with the key/values from the Map.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder templateOptions(
                String templateOptions) {
            doSetProperty("templateOptions", templateOptions);
            return this;
        }
        /**
         * Sets whether to use placeholder and replace all placeholder
         * characters with sign in the SQL queries. This option is default true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder usePlaceholder(
                boolean usePlaceholder) {
            doSetProperty("usePlaceholder", usePlaceholder);
            return this;
        }
        /**
         * Sets whether to use placeholder and replace all placeholder
         * characters with sign in the SQL queries. This option is default true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointProducerBuilder usePlaceholder(
                String usePlaceholder) {
            doSetProperty("usePlaceholder", usePlaceholder);
            return this;
        }
    }

    /**
     * Builder for endpoint for the SQL component.
     */
    public interface SqlEndpointBuilder
            extends
                SqlEndpointConsumerBuilder, SqlEndpointProducerBuilder {
        default AdvancedSqlEndpointBuilder advanced() {
            return (AdvancedSqlEndpointBuilder) this;
        }
        /**
         * Whether to allow using named parameters in the queries.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder allowNamedParameters(
                boolean allowNamedParameters) {
            doSetProperty("allowNamedParameters", allowNamedParameters);
            return this;
        }
        /**
         * Whether to allow using named parameters in the queries.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder allowNamedParameters(
                String allowNamedParameters) {
            doSetProperty("allowNamedParameters", allowNamedParameters);
            return this;
        }
        /**
         * Sets the DataSource to use to communicate with the database.
         * 
         * The option is a: <code>javax.sql.DataSource</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder dataSource(Object dataSource) {
            doSetProperty("dataSource", dataSource);
            return this;
        }
        /**
         * Sets the DataSource to use to communicate with the database.
         * 
         * The option will be converted to a <code>javax.sql.DataSource</code>
         * type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder dataSource(String dataSource) {
            doSetProperty("dataSource", dataSource);
            return this;
        }
        /**
         * Sets the reference to a DataSource to lookup from the registry, to
         * use for communicating with the database.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        @Deprecated
        default SqlEndpointBuilder dataSourceRef(String dataSourceRef) {
            doSetProperty("dataSourceRef", dataSourceRef);
            return this;
        }
        /**
         * Specify the full package and class name to use as conversion when
         * outputType=SelectOne.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder outputClass(String outputClass) {
            doSetProperty("outputClass", outputClass);
            return this;
        }
        /**
         * Store the query result in a header instead of the message body. By
         * default, outputHeader == null and the query result is stored in the
         * message body, any existing content in the message body is discarded.
         * If outputHeader is set, the value is used as the name of the header
         * to store the query result and the original message body is preserved.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder outputHeader(String outputHeader) {
            doSetProperty("outputHeader", outputHeader);
            return this;
        }
        /**
         * Make the output of consumer or producer to SelectList as List of Map,
         * or SelectOne as single Java object in the following way: a) If the
         * query has only single column, then that JDBC Column object is
         * returned. (such as SELECT COUNT( ) FROM PROJECT will return a Long
         * object. b) If the query has more than one column, then it will return
         * a Map of that result. c) If the outputClass is set, then it will
         * convert the query result into an Java bean object by calling all the
         * setters that match the column names. It will assume your class has a
         * default constructor to create instance with. d) If the query resulted
         * in more than one rows, it throws an non-unique result exception.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder outputType(SqlOutputType outputType) {
            doSetProperty("outputType", outputType);
            return this;
        }
        /**
         * Make the output of consumer or producer to SelectList as List of Map,
         * or SelectOne as single Java object in the following way: a) If the
         * query has only single column, then that JDBC Column object is
         * returned. (such as SELECT COUNT( ) FROM PROJECT will return a Long
         * object. b) If the query has more than one column, then it will return
         * a Map of that result. c) If the outputClass is set, then it will
         * convert the query result into an Java bean object by calling all the
         * setters that match the column names. It will assume your class has a
         * default constructor to create instance with. d) If the query resulted
         * in more than one rows, it throws an non-unique result exception.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder outputType(String outputType) {
            doSetProperty("outputType", outputType);
            return this;
        }
        /**
         * The separator to use when parameter values is taken from message body
         * (if the body is a String type), to be inserted at # placeholders.
         * Notice if you use named parameters, then a Map type is used instead.
         * The default value is comma.
         * 
         * The option is a: <code>char</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder separator(char separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * The separator to use when parameter values is taken from message body
         * (if the body is a String type), to be inserted at # placeholders.
         * Notice if you use named parameters, then a Map type is used instead.
         * The default value is comma.
         * 
         * The option will be converted to a <code>char</code> type.
         * 
         * Group: common
         */
        default SqlEndpointBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the SQL component.
     */
    public interface AdvancedSqlEndpointBuilder
            extends
                AdvancedSqlEndpointConsumerBuilder, AdvancedSqlEndpointProducerBuilder {
        default SqlEndpointBuilder basic() {
            return (SqlEndpointBuilder) this;
        }
        /**
         * If enabled then the populateStatement method from
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy is always
         * invoked, also if there is no expected parameters to be prepared. When
         * this is false then the populateStatement is only invoked if there is
         * 1 or more expected parameters to be set; for example this avoids
         * reading the message body/headers for SQL queries with no parameters.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder alwaysPopulateStatement(
                boolean alwaysPopulateStatement) {
            doSetProperty("alwaysPopulateStatement", alwaysPopulateStatement);
            return this;
        }
        /**
         * If enabled then the populateStatement method from
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy is always
         * invoked, also if there is no expected parameters to be prepared. When
         * this is false then the populateStatement is only invoked if there is
         * 1 or more expected parameters to be set; for example this avoids
         * reading the message body/headers for SQL queries with no parameters.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder alwaysPopulateStatement(
                String alwaysPopulateStatement) {
            doSetProperty("alwaysPopulateStatement", alwaysPopulateStatement);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * 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.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder parametersCount(int parametersCount) {
            doSetProperty("parametersCount", parametersCount);
            return this;
        }
        /**
         * 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.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder parametersCount(
                String parametersCount) {
            doSetProperty("parametersCount", parametersCount);
            return this;
        }
        /**
         * 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).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder placeholder(String placeholder) {
            doSetProperty("placeholder", placeholder);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy to control
         * preparation of the query and prepared statement.
         * 
         * The option is a:
         * <code>org.apache.camel.component.sql.SqlPrepareStatementStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder prepareStatementStrategy(
                Object prepareStatementStrategy) {
            doSetProperty("prepareStatementStrategy", prepareStatementStrategy);
            return this;
        }
        /**
         * Allows to plugin to use a custom
         * org.apache.camel.component.sql.SqlPrepareStatementStrategy to control
         * preparation of the query and prepared statement.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.sql.SqlPrepareStatementStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder prepareStatementStrategy(
                String prepareStatementStrategy) {
            doSetProperty("prepareStatementStrategy", prepareStatementStrategy);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder synchronous(boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Configures the Spring JdbcTemplate with the key/values from the Map.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder templateOptions(
                Map<String, Object> templateOptions) {
            doSetProperty("templateOptions", templateOptions);
            return this;
        }
        /**
         * Configures the Spring JdbcTemplate with the key/values from the Map.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder templateOptions(
                String templateOptions) {
            doSetProperty("templateOptions", templateOptions);
            return this;
        }
        /**
         * Sets whether to use placeholder and replace all placeholder
         * characters with sign in the SQL queries. This option is default true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder usePlaceholder(boolean usePlaceholder) {
            doSetProperty("usePlaceholder", usePlaceholder);
            return this;
        }
        /**
         * Sets whether to use placeholder and replace all placeholder
         * characters with sign in the SQL queries. This option is default true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSqlEndpointBuilder usePlaceholder(String usePlaceholder) {
            doSetProperty("usePlaceholder", usePlaceholder);
            return this;
        }
    }

    /**
     * Proxy enum for <code>org.apache.camel.component.sql.SqlOutputType</code>
     * enum.
     */
    enum SqlOutputType {
        SelectOne,
        SelectList,
        StreamList;
    }
    /**
     * SQL (camel-sql)
     * The sql component allows you to work with databases using JDBC SQL
     * queries.
     * 
     * Category: database,sql
     * Since: 1.4
     * Maven coordinates: org.apache.camel:camel-sql
     * 
     * Syntax: <code>sql:query</code>
     * 
     * Path parameter: query (required)
     * Sets the SQL query to perform. You can externalize the query by using
     * file: or classpath: as prefix and specify the location of the file.
     */
    default SqlEndpointBuilder sql(String path) {
        class SqlEndpointBuilderImpl extends AbstractEndpointBuilder implements SqlEndpointBuilder, AdvancedSqlEndpointBuilder {
            public SqlEndpointBuilderImpl(String path) {
                super("sql", path);
            }
        }
        return new SqlEndpointBuilderImpl(path);
    }
}