use of org.springframework.jdbc.core.SqlOutParameter in project spring-framework by spring-projects.
the class CallMetaDataContext method reconcileParameters.
/**
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
*/
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
final List<SqlParameter> declaredReturnParams = new ArrayList<>();
final Map<String, SqlParameter> declaredParams = new LinkedHashMap<>();
boolean returnDeclared = false;
List<String> outParamNames = new ArrayList<>();
List<String> metaDataParamNames = new ArrayList<>();
// Get the names of the meta data parameters
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
metaDataParamNames.add(meta.getParameterName().toLowerCase());
}
}
// Separate implicit return parameters from explicit parameters...
for (SqlParameter param : parameters) {
if (param.isResultsParameter()) {
declaredReturnParams.add(param);
} else {
String paramName = param.getName();
if (paramName == null) {
throw new IllegalArgumentException("Anonymous parameters not supported for calls - " + "please specify a name for the parameter of SQL type " + param.getSqlType());
}
String paramNameToMatch = this.metaDataProvider.parameterNameToUse(paramName).toLowerCase();
declaredParams.put(paramNameToMatch, param);
if (param instanceof SqlOutParameter) {
outParamNames.add(paramName);
if (isFunction() && !metaDataParamNames.contains(paramNameToMatch)) {
if (!returnDeclared) {
if (logger.isDebugEnabled()) {
logger.debug("Using declared out parameter '" + paramName + "' for function return value");
}
setFunctionReturnName(paramName);
returnDeclared = true;
}
}
}
}
}
setOutParameterNames(outParamNames);
List<SqlParameter> workParams = new ArrayList<>();
workParams.addAll(declaredReturnParams);
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
workParams.addAll(declaredParams.values());
return workParams;
}
Map<String, String> limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size());
for (String limitedParamName : this.limitedInParameterNames) {
limitedInParamNamesMap.put(this.metaDataProvider.parameterNameToUse(limitedParamName).toLowerCase(), limitedParamName);
}
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
String paramNameToCheck = null;
if (meta.getParameterName() != null) {
paramNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase();
}
String paramNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName());
if (declaredParams.containsKey(paramNameToCheck) || (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
SqlParameter param;
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
param = declaredParams.get(getFunctionReturnName());
if (param == null && getOutParameterNames().size() > 0) {
param = declaredParams.get(getOutParameterNames().get(0).toLowerCase());
}
if (param == null) {
throw new InvalidDataAccessApiUsageException("Unable to locate declared parameter for function return value - " + " add a SqlOutParameter with name '" + getFunctionReturnName() + "'");
} else {
setFunctionReturnName(param.getName());
}
} else {
param = declaredParams.get(paramNameToCheck);
}
if (param != null) {
workParams.add(param);
if (logger.isDebugEnabled()) {
logger.debug("Using declared parameter for '" + (paramNameToUse != null ? paramNameToUse : getFunctionReturnName()) + "'");
}
}
} else {
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
if (!isFunction() && !isReturnValueRequired() && this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) {
if (logger.isDebugEnabled()) {
logger.debug("Bypassing metadata return parameter for '" + meta.getParameterName() + "'");
}
} else {
String returnNameToUse = (StringUtils.hasLength(meta.getParameterName()) ? paramNameToUse : getFunctionReturnName());
workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta));
if (isFunction()) {
setFunctionReturnName(returnNameToUse);
outParamNames.add(returnNameToUse);
}
if (logger.isDebugEnabled()) {
logger.debug("Added metadata return parameter for '" + returnNameToUse + "'");
}
}
} else {
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta));
outParamNames.add(paramNameToUse);
if (logger.isDebugEnabled()) {
logger.debug("Added metadata out parameter for '" + paramNameToUse + "'");
}
} else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta));
outParamNames.add(paramNameToUse);
if (logger.isDebugEnabled()) {
logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'");
}
} else {
if (this.limitedInParameterNames.isEmpty() || limitedInParamNamesMap.containsKey(paramNameToUse.toLowerCase())) {
workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta));
if (logger.isDebugEnabled()) {
logger.debug("Added metadata in parameter for '" + paramNameToUse + "'");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Limited set of parameters " + limitedInParamNamesMap.keySet() + " skipped parameter for '" + paramNameToUse + "'");
}
}
}
}
}
}
return workParams;
}
use of org.springframework.jdbc.core.SqlOutParameter in project spring-framework by spring-projects.
the class CallMetaDataContextTests method testMatchParameterValuesAndSqlInOutParameters.
@Test
public void testMatchParameterValuesAndSqlInOutParameters() throws Exception {
final String TABLE = "customers";
final String USER = "me";
given(databaseMetaData.getDatabaseProductName()).willReturn("MyDB");
given(databaseMetaData.getUserName()).willReturn(USER);
given(databaseMetaData.storesLowerCaseIdentifiers()).willReturn(true);
List<SqlParameter> parameters = new ArrayList<>();
parameters.add(new SqlParameter("id", Types.NUMERIC));
parameters.add(new SqlInOutParameter("name", Types.NUMERIC));
parameters.add(new SqlOutParameter("customer_no", Types.NUMERIC));
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
parameterSource.addValue("id", 1);
parameterSource.addValue("name", "Sven");
parameterSource.addValue("customer_no", "12345XYZ");
context.setProcedureName(TABLE);
context.initializeMetaData(dataSource);
context.processParameters(parameters);
Map<String, Object> inParameters = context.matchInParameterValuesWithCallParameters(parameterSource);
assertEquals("Wrong number of matched in parameter values", 2, inParameters.size());
assertTrue("in parameter value missing", inParameters.containsKey("id"));
assertTrue("in out parameter value missing", inParameters.containsKey("name"));
assertTrue("out parameter value matched", !inParameters.containsKey("customer_no"));
List<String> names = context.getOutParameterNames();
assertEquals("Wrong number of out parameters", 2, names.size());
List<SqlParameter> callParameters = context.getCallParameters();
assertEquals("Wrong number of call parameters", 3, callParameters.size());
}
use of org.springframework.jdbc.core.SqlOutParameter in project spring-framework by spring-projects.
the class RdbmsOperationTests method validateInOutParameter.
@Test
public void validateInOutParameter() {
operation.setDataSource(new DriverManagerDataSource());
operation.setSql("DUMMY_PROC");
operation.declareParameter(new SqlOutParameter("DUMMY_OUT_PARAM", Types.VARCHAR));
operation.declareParameter(new SqlInOutParameter("DUMMY_IN_OUT_PARAM", Types.VARCHAR));
operation.validateParameters(new Object[] { "DUMMY_VALUE1", "DUMMY_VALUE2" });
}
use of org.springframework.jdbc.core.SqlOutParameter in project spring-framework by spring-projects.
the class SimpleJdbcCallTests method testAddInvoiceFuncWithoutMetaDataUsingArrayParams.
@Test
public void testAddInvoiceFuncWithoutMetaDataUsingArrayParams() throws Exception {
initializeAddInvoiceWithoutMetaData(true);
SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice");
adder.declareParameters(new SqlOutParameter("return", Types.INTEGER), new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER));
Number newId = adder.executeFunction(Number.class, 1103, 3);
assertEquals(4, newId.intValue());
verifyAddInvoiceWithoutMetaData(true);
verify(connection, atLeastOnce()).close();
}
use of org.springframework.jdbc.core.SqlOutParameter in project spring-framework by spring-projects.
the class SimpleJdbcCallTests method testAddInvoiceProcWithoutMetaDataUsingMapParamSource.
@Test
public void testAddInvoiceProcWithoutMetaDataUsingMapParamSource() throws Exception {
initializeAddInvoiceWithoutMetaData(false);
SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withProcedureName("add_invoice");
adder.declareParameters(new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), new SqlOutParameter("newid", Types.INTEGER));
Number newId = adder.executeObject(Number.class, new MapSqlParameterSource().addValue("amount", 1103).addValue("custid", 3));
assertEquals(4, newId.intValue());
verifyAddInvoiceWithoutMetaData(false);
verify(connection, atLeastOnce()).close();
}
Aggregations