Skip to content

Commit

Permalink
Implementing ProcedureParamBindings
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 authored and beikov committed Oct 5, 2021
1 parent d4007c5 commit 6931635
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 97 deletions.
Expand Up @@ -31,48 +31,47 @@ public JdbcCall interpretCall(
ParameterMetadataImplementor parameterMetadata,
ProcedureParamBindings paramBindings,
SharedSessionContractImplementor session) {
throw new NotYetImplementedFor6Exception( getClass() );

// // if there are any parameters, see if the first is REF_CURSOR
// final boolean firstParamIsRefCursor = ! parameterRegistrations.isEmpty()
// && parameterRegistrations.get( 0 ).getMode() == ParameterMode.REF_CURSOR;
//
// if ( firstParamIsRefCursor ) {
// // validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional)
// if ( parameterStrategy == ParameterStrategy.NAMED ) {
// throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on PostgreSQL" );
// }
// }
//
// final StringBuilder buffer;
// if ( firstParamIsRefCursor ) {
// buffer = new StringBuilder().append( "{? = call " );
// }
// else {
// buffer = new StringBuilder().append( "{call " );
// }
//
// buffer.append( procedureName ).append( "(" );
//
// String sep = "";
//
// // skip the first registration if it was a REF_CURSOR
// final int startIndex = firstParamIsRefCursor ? 1 : 0;
// for ( int i = startIndex; i < parameterRegistrations.size(); i++ ) {
// final ParameterRegistrationImplementor parameter = parameterRegistrations.get( i );
//
// // any additional REF_CURSOR parameter registrations are an error
// if ( parameter.getMode() == ParameterMode.REF_CURSOR ) {
// throw new HibernateException( "PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered" );
// }
//
// for ( int ignored : parameter.getSqlTypes() ) {
// buffer.append( sep ).append( "?" );
// sep = ",";
// }
// }
//
// return buffer.append( ")}" ).toString();
// if there are any parameters, see if the first is REF_CURSOR
final boolean firstParamIsRefCursor = parameterMetadata.getParameterCount() != 0
&& paramBindings..getMode() == ParameterMode.REF_CURSOR;

if ( firstParamIsRefCursor ) {
// validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional)
if ( parameterStrategy == ParameterStrategy.NAMED ) {
throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on PostgreSQL" );
}
}

final StringBuilder buffer;
if ( firstParamIsRefCursor ) {
buffer = new StringBuilder().append( "{? = call " );
}
else {
buffer = new StringBuilder().append( "{call " );
}

buffer.append( procedureName ).append( "(" );

String sep = "";

// skip the first registration if it was a REF_CURSOR
final int startIndex = firstParamIsRefCursor ? 1 : 0;
for ( int i = startIndex; i < parameterRegistrations.size(); i++ ) {
final ParameterRegistrationImplementor parameter = parameterRegistrations.get( i );

// any additional REF_CURSOR parameter registrations are an error
if ( parameter.getMode() == ParameterMode.REF_CURSOR ) {
throw new HibernateException( "PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered" );
}

for ( int ignored : parameter.getSqlTypes() ) {
buffer.append( sep ).append( "?" );
sep = ",";
}
}

return buffer.append( ")}" ).toString();
}

@Override
Expand Down
Expand Up @@ -6,6 +6,8 @@
*/
package org.hibernate.procedure.internal;

import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
Expand All @@ -14,6 +16,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Stream;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType;
Expand All @@ -27,7 +30,6 @@

import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.ScrollMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
Expand Down Expand Up @@ -62,8 +64,11 @@
import org.hibernate.result.ResultSetOutput;
import org.hibernate.result.UpdateCountOutput;
import org.hibernate.result.spi.ResultContext;
import org.hibernate.sql.exec.spi.JdbcCall;
import org.hibernate.sql.results.NoMoreOutputsException;

import org.jboss.logging.Logger;

/**
* Standard implementation of {@link ProcedureCall}
*
Expand All @@ -72,6 +77,7 @@
public class ProcedureCallImpl<R>
extends AbstractQuery<R>
implements ProcedureCallImplementor<R>, ResultContext {
private static final Logger LOG = Logger.getLogger( ProcedureCallImpl.class );

private final String procedureName;

Expand Down Expand Up @@ -432,51 +438,51 @@ private ProcedureOutputsImpl buildOutputs() {
// both: (1) add the `? = ` part and also (2) register a REFCURSOR parameter for DBs (Oracle, PGSQL) that
// need it.

// final String call = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().renderCallableStatement(
// procedureName,
// getParameterMetadata(),
// paramBindings,
// getSession()
// );
//
// LOG.debugf( "Preparing procedure call : %s", call );
// final CallableStatement statement = (CallableStatement) getSession()
// .getJdbcCoordinator()
// .getStatementPreparer()
// .prepareStatement( call, true );
//
//
// // prepare parameters
//
// getParameterMetadata().visitRegistrations(
// new Consumer<QueryParameter<?>>() {
// int i = 1;
//
// @Override
// public void accept(QueryParameter queryParameter) {
// try {
// final ProcedureParameterImplementor registration = (ProcedureParameterImplementor) queryParameter;
// registration.prepare( statement, i, ProcedureCallImpl.this );
final JdbcCall call = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().interpretCall(
procedureName,
functionReturn,
getParameterMetadata(),
paramBindings,
getSession()
);

LOG.debugf( "Preparing procedure call : %s", call );
final CallableStatement statement = (CallableStatement) getSession()
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( call.getSql(), true );


// prepare parameters

getParameterMetadata().visitRegistrations(
new Consumer<QueryParameter<?>>() {
int i = 1;

@Override
public void accept(QueryParameter queryParameter) {
try {
final ProcedureParameterImplementor registration = (ProcedureParameterImplementor) queryParameter;
registration.prepare( statement, i, ProcedureCallImpl.this );
// if ( registration.getMode() == ParameterMode.REF_CURSOR ) {
// i++;
i++;
// }
// else {
// i += registration.getSqlTypes().length;
// }
// }
// catch (SQLException e) {
// throw getSession().getJdbcServices().getSqlExceptionHelper().convert(
// e,
// "Error preparing registered callable parameter",
// getProcedureName()
// );
// }
// }
// }
// );
//
// return new ProcedureOutputsImpl( this, statement );
throw new NotYetImplementedFor6Exception( getClass() );
}
catch (SQLException e) {
throw getSession().getJdbcServices().getSqlExceptionHelper().convert(
e,
"Error preparing registered callable parameter",
getProcedureName()
);
}
}
}
);

return new ProcedureOutputsImpl( this, statement );
}

@Override
Expand Down
Expand Up @@ -13,7 +13,6 @@
import org.hibernate.procedure.spi.ProcedureParameterBindingImplementor;
import org.hibernate.procedure.spi.ProcedureParameterImplementor;
import org.hibernate.query.procedure.ProcedureParameterBinding;
import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindingTypeResolver;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryParameterImplementor;
Expand Down Expand Up @@ -45,17 +44,16 @@ public boolean isBound(QueryParameterImplementor<?> parameter) {
}

@Override
public <P> QueryParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
// return getBinding( parameterMetadata.resolve( parameter ) );
throw new NotYetImplementedFor6Exception( getClass() );
public <P> ProcedureParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
return getQueryParamerBinding( (ProcedureParameterImplementor) parameter );
}

public ProcedureParameterBindingImplementor<?> getBinding(ProcedureParameterImplementor<?> parameter) {
public <P> ProcedureParameterBinding<P> getQueryParamerBinding(ProcedureParameterImplementor<P> parameter) {
final ProcedureParameterImplementor procParam = parameterMetadata.resolve( parameter );
ProcedureParameterBindingImplementor binding = bindingMap.get( procParam );

if ( binding == null ) {
if ( ! parameterMetadata.containsReference( parameter ) ) {
if ( !parameterMetadata.containsReference( parameter ) ) {
throw new IllegalArgumentException( "Passed parameter is not registered with this query" );
}

Expand All @@ -68,15 +66,23 @@ public ProcedureParameterBindingImplementor<?> getBinding(ProcedureParameterImpl
}

@Override
public ProcedureParameterBinding<?> getBinding(String name) {
// return (ProcedureParameterBinding<?>) getBinding( parameterMetadata.getQueryParameter( name ) );
throw new NotYetImplementedFor6Exception( getClass() );
public <P> ProcedureParameterBinding<P> getBinding(String name) {
final ProcedureParameterImplementor<P> parameter = (ProcedureParameterImplementor<P>) parameterMetadata
.getQueryParameter( name );
if ( parameter == null ) {
throw new IllegalArgumentException( "Parameter does not exist: " + name );
}
return getQueryParamerBinding( parameter );
}

@Override
public ProcedureParameterBinding getBinding(int position) {
// return getBinding( parameterMetadata.getQueryParameter( position ) );
throw new NotYetImplementedFor6Exception( getClass() );
public <P> ProcedureParameterBinding<P> getBinding(int position) {
final ProcedureParameterImplementor<P> parameter = (ProcedureParameterImplementor<P>) parameterMetadata
.getQueryParameter( position );
if ( parameter == null ) {
throw new IllegalArgumentException( "Parameter at position " + position + "does not exist" );
}
return getQueryParamerBinding( parameter );
}

@Override
Expand All @@ -101,5 +107,4 @@ public boolean hasAnyMultiValuedBindings() {
return false;
}


}
Expand Up @@ -63,7 +63,6 @@

import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.NotImplementedYet;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
Expand All @@ -74,7 +73,6 @@
/**
* @author Vlad Mihalcea
*/
@NotImplementedYet
@DomainModel
@SessionFactory
public class StoredProcedureParameterTypeTest {
Expand Down

0 comments on commit 6931635

Please sign in to comment.