77
88import java .lang .reflect .Array ;
99import java .sql .CallableStatement ;
10+ import java .sql .Date ;
1011import java .sql .PreparedStatement ;
1112import java .sql .ResultSet ;
1213import java .sql .SQLException ;
14+ import java .sql .Time ;
15+ import java .sql .Timestamp ;
1316import java .sql .Types ;
17+ import java .time .LocalDate ;
18+ import java .time .LocalDateTime ;
19+ import java .time .LocalTime ;
1420
15- import org .hibernate .HibernateException ;
21+ import org .hibernate .reactive .adaptor .impl .ArrayAdaptor ;
22+ import org .hibernate .reactive .adaptor .impl .ResultSetAdaptor ;
1623import org .hibernate .type .descriptor .ValueBinder ;
1724import org .hibernate .type .descriptor .ValueExtractor ;
1825import org .hibernate .type .descriptor .WrapperOptions ;
2431import org .hibernate .type .descriptor .jdbc .BasicExtractor ;
2532import org .hibernate .type .descriptor .jdbc .JdbcLiteralFormatter ;
2633import org .hibernate .type .descriptor .jdbc .JdbcType ;
27- import org .hibernate .type .descriptor .jdbc .ObjectJdbcType ;
2834import org .hibernate .type .descriptor .jdbc .internal .JdbcLiteralFormatterArray ;
2935import org .hibernate .type .spi .TypeConfiguration ;
3036
37+
38+
3139/**
3240 * {@link java.sql.Connection} has a method {@link java.sql.Connection#createArrayOf(String, Object[])}, but we don't have
3341 * it in Vert.x SQL Client.
42+ * <p>
43+ * Plus, the Vert.x SQL client accept arrays as parameters.
44+ * </p>
3445 *
3546 * @see org.hibernate.type.descriptor.jdbc.ArrayJdbcType
3647 */
37- public class ReactiveArrayJdbcType implements JdbcType {
38-
39- public static final ReactiveArrayJdbcType INSTANCE = new ReactiveArrayJdbcType ( ObjectJdbcType .INSTANCE );
48+ public class ReactiveArrayJdbcType implements JdbcType {
4049
4150 private final JdbcType elementJdbcType ;
4251
@@ -88,20 +97,64 @@ public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
8897 @ Override
8998 protected void doBind (PreparedStatement st , X value , int index , WrapperOptions options )
9099 throws SQLException {
91- st .setObject ( index , value );
100+
101+ ArrayAdaptor arrayObject = getArrayObject ( value , options );
102+ st .setArray ( index , arrayObject );
92103 }
93104
94105 @ Override
95- protected void doBind (CallableStatement st , X value , String name , WrapperOptions options ){
96- try {
97- st .setObject ( name , value );
106+ protected void doBind (CallableStatement st , X value , String name , WrapperOptions options ) {
107+ throw new UnsupportedOperationException ();
108+ }
109+
110+ private ArrayAdaptor getArrayObject (X value , WrapperOptions options ) {
111+ final TypeConfiguration typeConfiguration = options .getSessionFactory ().getTypeConfiguration ();
112+ ReactiveArrayJdbcType jdbcType = (ReactiveArrayJdbcType ) getJdbcType ();
113+ final JdbcType elementJdbcType = jdbcType .getElementJdbcType ();
114+ final JdbcType underlyingJdbcType = typeConfiguration .getJdbcTypeRegistry ()
115+ .getDescriptor ( elementJdbcType .getDefaultSqlTypeCode () );
116+ final Class <?> elementJdbcJavaTypeClass = elementJdbcJavaTypeClass (
117+ options ,
118+ elementJdbcType ,
119+ underlyingJdbcType ,
120+ typeConfiguration
121+ );
122+ //noinspection unchecked
123+ final Class <Object []> arrayClass = (Class <Object []>) Array .newInstance ( elementJdbcJavaTypeClass , 0 )
124+ .getClass ();
125+ final Object [] objects = getJavaType ().unwrap ( value , arrayClass , options );
126+ return new ArrayAdaptor ( elementJdbcType , objects );
127+ }
128+
129+ private Class <?> elementJdbcJavaTypeClass (
130+ WrapperOptions options ,
131+ JdbcType elementJdbcType ,
132+ JdbcType underlyingJdbcType ,
133+ TypeConfiguration typeConfiguration ) {
134+ final Class <?> preferredJavaTypeClass = elementJdbcType .getPreferredJavaTypeClass ( options );
135+ final Class <?> elementJdbcJavaTypeClass ;
136+ if ( preferredJavaTypeClass == null ) {
137+ elementJdbcJavaTypeClass = underlyingJdbcType
138+ .getJdbcRecommendedJavaTypeMapping ( null , null , typeConfiguration )
139+ .getJavaTypeClass ();
98140 }
99- catch (SQLException ex ) {
100- throw new HibernateException (
101- "JDBC driver does not support named parameters for setArray. Use positional." ,
102- ex
103- );
141+ else {
142+ elementJdbcJavaTypeClass = preferredJavaTypeClass ;
104143 }
144+ return convertTypes ( elementJdbcJavaTypeClass );
145+ }
146+
147+ private Class <?> convertTypes (Class <?> elementJdbcJavaTypeClass ) {
148+ if ( Timestamp .class .equals ( elementJdbcJavaTypeClass ) ) {
149+ return LocalDateTime .class ;
150+ }
151+ if ( Date .class .equals ( elementJdbcJavaTypeClass ) ) {
152+ return LocalDate .class ;
153+ }
154+ if ( Time .class .equals ( elementJdbcJavaTypeClass ) ) {
155+ return LocalTime .class ;
156+ }
157+ return elementJdbcJavaTypeClass ;
105158 }
106159 };
107160 }
@@ -110,13 +163,19 @@ protected void doBind(CallableStatement st, X value, String name, WrapperOptions
110163 public <X > ValueExtractor <X > getExtractor (final JavaType <X > javaTypeDescriptor ) {
111164 return new BasicExtractor <>( javaTypeDescriptor , this ) {
112165 @ Override
113- protected X doExtract (ResultSet rs , int paramIndex , WrapperOptions options ) throws SQLException {
114- return javaTypeDescriptor .wrap ( rs .getArray ( paramIndex ), options );
166+ protected X doExtract (ResultSet rs , int paramIndex , WrapperOptions options ) {
167+ return javaTypeDescriptor .wrap (
168+ ( (ResultSetAdaptor ) rs ).getArray ( paramIndex , elementJdbcType ),
169+ options
170+ );
115171 }
116172
117173 @ Override
118- protected X doExtract (CallableStatement statement , int index , WrapperOptions options ) throws SQLException {
119- return javaTypeDescriptor .wrap ( statement .getArray ( index ), options );
174+ protected X doExtract (CallableStatement statement , int index , WrapperOptions options ) {
175+ return javaTypeDescriptor .wrap (
176+ ( (ResultSetAdaptor ) statement ).getArray ( index , elementJdbcType ),
177+ options
178+ );
120179 }
121180
122181 @ Override
@@ -132,6 +191,10 @@ public String getFriendlyName() {
132191 return "ARRAY" ;
133192 }
134193
194+ public JdbcType getElementJdbcType () {
195+ return elementJdbcType ;
196+ }
197+
135198 @ Override
136199 public String toString () {
137200 return ReactiveArrayJdbcType .class .getSimpleName () + "(" + getFriendlyName () + ")" ;
0 commit comments