/*
 * Licensed 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.jdbi.v3.core.statement;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.jdbi.v3.core.Handle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents a group of non-prepared statements to be sent to the RDMBS in one "request".
 */
public class Batch extends BaseStatement<Batch> {
    private static final Logger LOG = LoggerFactory.getLogger(Batch.class);

    private final List<String> parts = new ArrayList<>();

    public Batch(Handle handle) {
        super(handle);
    }

    /**
     * Add a statement to the batch
     *
     * @param sql SQL to be added to the batch, possibly a named statement
     * @return the same Batch statement
     */
    public Batch add(String sql) {
        parts.add(sql);
        return this;
    }

    /**
     * Execute the batch and return the number of rows affected for each batch part.
     * Note that some database drivers might return special values like {@link Statement#SUCCESS_NO_INFO}
     * or {@link Statement#EXECUTE_FAILED}.
     *
     * @return the number of rows affected per batch part
     * @see Statement#executeBatch()
     */
    public int[] execute() {
        // short circuit empty batch
        if (parts.isEmpty()) {
            return new int[] {};
        }

        @SuppressWarnings("PMD.CloseResource")
        Statement stmt;
        try {
            try {
                stmt = getHandle().getStatementBuilder().create(getHandle().getConnection(), getContext());

                getContext().addCleanable(stmt::close);
                getConfig(SqlStatements.class).customize(stmt);
            } catch (SQLException e) {
                throw new UnableToCreateStatementException(e, getContext());
            }

            LOG.trace("Execute batch [");

            try {
                for (String part : parts) {
                    final String sql = getConfig(SqlStatements.class).getTemplateEngine().render(part, getContext());
                    LOG.trace(" {}", sql);
                    stmt.addBatch(sql);
                }
            } catch (SQLException e) {
                throw new UnableToExecuteStatementException("Unable to configure JDBC statement", e, getContext());
            }

            try {
                return SqlLoggerUtil.wrap(stmt::executeBatch, getContext(), getConfig(SqlStatements.class).getSqlLogger());
            } catch (SQLException e) {
                throw new UnableToExecuteStatementException(mungeBatchException(e), getContext());
            }
        } finally {
            close();
        }
    }

    /**
     * SQLExceptions thrown from batch executions have errors
     * in a {@link SQLException#getNextException()} chain, which
     * doesn't print out when you log them.  Convert them to be
     * {@link Throwable#addSuppressed(Throwable)} exceptions,
     * which do print out with common logging frameworks.
     *
     * @param e the exception
     * @return the 'suppressed' munged exception change
     */
    static SQLException mungeBatchException(SQLException e) {
        for (SQLException next = e.getNextException(); next != null; next = next.getNextException()) {
            e.addSuppressed(next);
        }
        return e;
    }
}

@@ -2102,17 +2102,16 @@
 ext());%0A
-%0A
         
@@ -2148,19 +2148,99 @@
 ble(
-stmt::close
+() -%3E getHandle().getStatementBuilder().close(getHandle().getConnection(), %22%3Cbatch%3E%22, stmt)
 );%0A 

Use statement builder for cleanup