Search in sources :

Example 1 with SqlOutParameter

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;
}
Also used : SqlParameter(org.springframework.jdbc.core.SqlParameter) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) SqlOutParameter(org.springframework.jdbc.core.SqlOutParameter) LinkedHashMap(java.util.LinkedHashMap) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException)

Example 2 with SqlOutParameter

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());
}
Also used : SqlParameter(org.springframework.jdbc.core.SqlParameter) MapSqlParameterSource(org.springframework.jdbc.core.namedparam.MapSqlParameterSource) ArrayList(java.util.ArrayList) SqlOutParameter(org.springframework.jdbc.core.SqlOutParameter) SqlInOutParameter(org.springframework.jdbc.core.SqlInOutParameter) Test(org.junit.Test)

Example 3 with SqlOutParameter

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" });
}
Also used : DriverManagerDataSource(org.springframework.jdbc.datasource.DriverManagerDataSource) SqlOutParameter(org.springframework.jdbc.core.SqlOutParameter) SqlInOutParameter(org.springframework.jdbc.core.SqlInOutParameter) Test(org.junit.Test)

Example 4 with SqlOutParameter

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();
}
Also used : SqlParameter(org.springframework.jdbc.core.SqlParameter) SqlOutParameter(org.springframework.jdbc.core.SqlOutParameter) Test(org.junit.Test)

Example 5 with SqlOutParameter

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();
}
Also used : SqlParameter(org.springframework.jdbc.core.SqlParameter) MapSqlParameterSource(org.springframework.jdbc.core.namedparam.MapSqlParameterSource) SqlOutParameter(org.springframework.jdbc.core.SqlOutParameter) Test(org.junit.Test)

Aggregations

SqlOutParameter (org.springframework.jdbc.core.SqlOutParameter)7 Test (org.junit.Test)6 SqlParameter (org.springframework.jdbc.core.SqlParameter)6 MapSqlParameterSource (org.springframework.jdbc.core.namedparam.MapSqlParameterSource)3 ArrayList (java.util.ArrayList)2 SqlInOutParameter (org.springframework.jdbc.core.SqlInOutParameter)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 InvalidDataAccessApiUsageException (org.springframework.dao.InvalidDataAccessApiUsageException)1 DriverManagerDataSource (org.springframework.jdbc.datasource.DriverManagerDataSource)1