use of org.hibernate.procedure.spi.ParameterRegistrationImplementor in project hibernate-orm by hibernate.
the class ProcedureCallImpl method buildOutputs.
private ProcedureOutputsImpl buildOutputs() {
// todo : going to need a very specialized Loader for this.
// or, might be a good time to look at splitting Loader up into:
// 1) building statement objects
// 2) executing statement objects
// 3) processing result sets
// for now assume there are no resultClasses nor mappings defined..
// TOTAL PROOF-OF-CONCEPT!!!!!!
// todo : how to identify calls which should be in the form `{? = call procName...}` ??? (note leading param marker)
// more than likely this will need to be a method on the native API. I can see this as a trigger to
// both: (1) add the `? = ` part and also (2) register a REFCURSOR parameter for DBs (Oracle, PGSQL) that
// need it.
final String call = getProducer().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().renderCallableStatement(procedureName, getParameterMetadata(), paramBindings, getProducer());
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 ParameterRegistrationImplementor registration = (ParameterRegistrationImplementor) queryParameter;
registration.prepare(statement, i);
if (registration.getMode() == ParameterMode.REF_CURSOR) {
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);
}
use of org.hibernate.procedure.spi.ParameterRegistrationImplementor in project hibernate-orm by hibernate.
the class PostgresCallableStatementSupport method renderCallableStatement.
@Override
public String renderCallableStatement(String procedureName, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SharedSessionContractImplementor session) {
// 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();
}
use of org.hibernate.procedure.spi.ParameterRegistrationImplementor in project hibernate-orm by hibernate.
the class PostgresCallableStatementSupport method registerParameters.
@Override
public void registerParameters(String procedureName, CallableStatement statement, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SharedSessionContractImplementor session) {
// prepare parameters
int i = 1;
try {
for (ParameterRegistrationImplementor parameter : parameterRegistrations) {
if (parameter.getMode() == ParameterMode.REF_CURSOR) {
statement.registerOutParameter(i, Types.OTHER);
i++;
} else {
parameter.prepare(statement, i);
i += parameter.getSqlTypes().length;
}
}
} catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(e, "Error registering CallableStatement parameters", procedureName);
}
}
use of org.hibernate.procedure.spi.ParameterRegistrationImplementor in project hibernate-orm by hibernate.
the class StandardCallableStatementSupport method renderCallableStatement.
@Override
public String renderCallableStatement(String procedureName, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SharedSessionContractImplementor session) {
final StringBuilder buffer = new StringBuilder().append("{call ").append(procedureName).append("(");
String sep = "";
for (ParameterRegistrationImplementor parameter : parameterRegistrations) {
if (parameter == null) {
throw new QueryException("Parameter registrations had gaps");
}
if (parameter.getMode() == ParameterMode.REF_CURSOR) {
verifyRefCursorSupport(session.getJdbcServices().getJdbcEnvironment().getDialect());
buffer.append(sep).append("?");
sep = ",";
} else {
for (int i = 0; i < parameter.getSqlTypes().length; i++) {
buffer.append(sep).append("?");
sep = ",";
}
}
}
return buffer.append(")}").toString();
}
use of org.hibernate.procedure.spi.ParameterRegistrationImplementor in project hibernate-orm by hibernate.
the class ProcedureCallImpl method toParameterMementos.
private static List<ProcedureCallMementoImpl.ParameterMemento> toParameterMementos(ProcedureParameterMetadata parameterMetadata) {
if (parameterMetadata.getParameterStrategy() == ParameterStrategy.UNKNOWN) {
// none...
return Collections.emptyList();
}
final List<ProcedureCallMementoImpl.ParameterMemento> copy = new ArrayList<>();
parameterMetadata.visitRegistrations(queryParameter -> {
final ParameterRegistrationImplementor registration = (ParameterRegistrationImplementor) queryParameter;
copy.add(ProcedureCallMementoImpl.ParameterMemento.fromRegistration(registration));
});
return copy;
}
Aggregations