package org.jdbi.v3.core.statement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import org.jdbi.v3.core.internal.UtilityClassException;
class ArgumentBinder {
private ArgumentBinder() {
throw new UtilityClassException();
}
static void bind(ParsedParameters parameters, Binding binding, PreparedStatement statement, StatementContext context) {
if (parameters.isPositional()) {
bindPositional(parameters, binding, statement, context);
} else {
bindNamed(parameters, binding, statement, context);
}
}
private static void bindPositional(ParsedParameters params, Binding binding, PreparedStatement statement, StatementContext context) {
boolean moreArgumentsProvidedThanDeclared = binding.findForPosition(params.getParameterCount()).isPresent();
if (moreArgumentsProvidedThanDeclared && !context.getConfig(SqlStatements.class).isUnusedBindingAllowed()) {
throw new UnableToCreateStatementException("Superfluous positional param at (0 based) position " + params.getParameterCount(), context);
}
for (int i = 0; i < params.getParameterCount(); i++) {
final int index = i;
try {
binding.findForPosition(i)
.orElseThrow(() -> new UnableToCreateStatementException("Missing positional param at (0 based) position " + index, context))
.apply(i + 1, statement, context);
} catch (SQLException e) {
throw new UnableToCreateStatementException("Exception while binding positional param at (0 based) position " + i, e, context);
}
}
}
private static void bindNamed(ParsedParameters params, Binding binding, PreparedStatement statement, StatementContext context) {
List<String> paramNames = params.getParameterNames();
boolean argumentsProvidedButNoneDeclared = paramNames.isEmpty() && !binding.isEmpty();
if (argumentsProvidedButNoneDeclared && !context.getConfig(SqlStatements.class).isUnusedBindingAllowed()) {
throw new UnableToCreateStatementException(String.format(
"Superfluous named parameters provided while the query "
+ "declares none: '%s'. This check may be disabled by calling "
+ "getConfig(SqlStatements.class).setUnusedBindingAllowed(true) "
+ "or using @AllowUnusedBindings in SQL object.", binding), context);
}
for (int i = 0; i < paramNames.size(); i++) {
final String name = paramNames.get(i);
try {
binding.findForName(name, context)
.orElseThrow(() -> new UnableToCreateStatementException(String.format("Missing named parameter '%s'.", name), context))
.apply(i + 1, statement, context);
} catch (SQLException e) {
throw new UnableToCreateStatementException(String.format("Exception while binding named parameter '%s'", name), e, context);
}
}
}
}