/*
* 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.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.jdbi.v3.core.Handle;
import org.jdbi.v3.core.argument.Argument;
Used for invoking stored procedures.
/**
* Used for invoking stored procedures.
*/
public class Call extends SqlStatement<Call> {
private final List<OutParamArgument> params = new ArrayList<>();
public Call(Handle handle, String sql) {
super(handle, sql);
}
Register a positional output parameter
Params: - position – the parameter position (zero-based)
- sqlType – an SQL type constant as defined by
Types
or by the JDBC vendor.
Returns: self
/**
* Register a positional output parameter
* @param position the parameter position (zero-based)
* @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor.
* @return self
*/
public Call registerOutParameter(int position, int sqlType) {
return registerOutParameter(position, sqlType, null);
}
Register a positional output parameter
Params: - position – the parameter position (zero-based)
- sqlType – an SQL type constant as defined by
Types
or by the JDBC vendor. - mapper – a mapper which converts the
CallableStatement
to a desired output type.
Returns: self
/**
* Register a positional output parameter
* @param position the parameter position (zero-based)
* @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor.
* @param mapper a mapper which converts the {@link CallableStatement} to a desired output type.
* @return self
*/
public Call registerOutParameter(int position, int sqlType, CallableStatementMapper mapper) {
getBinding().addPositional(position, new OutParamArgument(sqlType, mapper, null));
return this;
}
Register a named output parameter
Params: - name – the parameter name
- sqlType – an SQL type constant as defined by
Types
or by the JDBC vendor.
Returns: self
/**
* Register a named output parameter
* @param name the parameter name
* @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor.
* @return self
*/
public Call registerOutParameter(String name, int sqlType) {
return registerOutParameter(name, sqlType, null);
}
Register a named output parameter
Params: - name – the parameter name
- sqlType – an SQL type constant as defined by
Types
or by the JDBC vendor. - mapper – a mapper which converts the
CallableStatement
to a desired output type.
Returns: self
/**
* Register a named output parameter
* @param name the parameter name
* @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor.
* @param mapper a mapper which converts the {@link CallableStatement} to a desired output type.
* @return self
*/
public Call registerOutParameter(String name, int sqlType, CallableStatementMapper mapper) {
getBinding().addNamed(name, new OutParamArgument(sqlType, mapper, name));
return this;
}
Invoke the callable statement
Returns: the output parameters resulting from the invocation.
/**
* Invoke the callable statement
* @return the output parameters resulting from the invocation.
*/
public OutParameters invoke() {
try {
final PreparedStatement stmt = this.internalExecute();
OutParameters out = new OutParameters();
for (OutParamArgument param : params) {
Object obj = param.map((CallableStatement) stmt);
// convert from JDBC 1-based position to Jdbi's 0-based
int index = param.position - 1;
out.getMap().put(index, obj);
if (param.name != null) {
out.getMap().put(param.name, obj);
}
}
return out;
} finally {
close();
}
}
// TODO tostring?
private class OutParamArgument implements Argument {
private final int sqlType;
private final CallableStatementMapper mapper;
private final String name;
private int position;
OutParamArgument(int sqlType, CallableStatementMapper mapper, String name) {
this.sqlType = sqlType;
this.mapper = mapper;
this.name = name;
params.add(this);
}
@Override
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
((CallableStatement) statement).registerOutParameter(position, sqlType);
this.position = position;
}
public Object map(CallableStatement stmt) {
try {
if (mapper != null) {
return mapper.map(position, stmt);
}
switch (sqlType) {
case Types.CLOB:
case Types.VARCHAR:
case Types.LONGNVARCHAR:
case Types.LONGVARCHAR:
case Types.NCLOB:
case Types.NVARCHAR:
return stmt.getString(position);
case Types.BLOB:
case Types.VARBINARY:
return stmt.getBytes(position);
case Types.SMALLINT:
return stmt.getShort(position);
case Types.INTEGER:
return stmt.getInt(position);
case Types.BIGINT:
return stmt.getLong(position);
case Types.TIMESTAMP:
case Types.TIME:
return stmt.getTimestamp(position);
case Types.DATE:
return stmt.getDate(position);
case Types.FLOAT:
return stmt.getFloat(position);
case Types.DECIMAL:
case Types.DOUBLE:
return stmt.getDouble(position);
default:
return stmt.getObject(position);
}
} catch (SQLException e) {
throw new UnableToExecuteStatementException("Could not get OUT parameter from statement", e, getContext());
}
}
}
}