/
PostgresCallableStatementSupport.java
110 lines (95 loc) · 3.45 KB
/
PostgresCallableStatementSupport.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.procedure.internal;
import java.sql.CallableStatement;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.procedure.spi.ParameterStrategy;
import org.hibernate.query.spi.ParameterMetadataImplementor;
import org.hibernate.sql.exec.spi.JdbcCall;
/**
* @author Steve Ebersole
*/
public class PostgresCallableStatementSupport implements CallableStatementSupport {
/**
* Singleton access
*/
public static final PostgresCallableStatementSupport INSTANCE = new PostgresCallableStatementSupport();
@Override
public JdbcCall interpretCall(
String procedureName,
FunctionReturnImpl functionReturn,
ParameterMetadataImplementor parameterMetadata,
ProcedureParamBindings paramBindings,
SharedSessionContractImplementor session) {
// 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
public void registerParameters(
String procedureName,
CallableStatement statement,
ParameterStrategy parameterStrategy,
ParameterMetadataImplementor parameterMetadata,
SharedSessionContractImplementor session) {
throw new NotYetImplementedFor6Exception( getClass() );
// // 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
// );
// }
}
}