3636import java .sql .Blob ;
3737import java .sql .SQLException ;
3838import java .sql .Time ;
39+ import java .sql .Types ;
3940import java .util .ArrayList ;
4041import java .util .Arrays ;
4142import java .util .Calendar ;
4243import java .util .HashMap ;
4344import java .util .Map ;
45+ import java .util .Optional ;
4446import java .util .concurrent .ConcurrentHashMap ;
4547import java .util .concurrent .atomic .AtomicInteger ;
4648
@@ -75,7 +77,7 @@ final class ExternalEngine implements IExternalEngineIntf
7577{
7678 private static final IEncodingFactory encodingFactory = EncodingFactory .getPlatformDefault ();
7779 private static Map <String , SharedData > sharedDataMap = new ConcurrentHashMap <>();
78- private static Map <Integer , String > fbTypeNames ;
80+ private static Map <Integer , Pair < String , Integer > > fbTypeNames ;
7981 private static Map <Class <?>, DataType > dataTypesByClass ;
8082 private static Map <String , Class <?>> javaClassesByName ;
8183 private static Map <Integer , DataType > defaultDataTypes ;
@@ -137,22 +139,22 @@ private ExternalEngine(String securityDatabase)
137139 static
138140 {
139141 fbTypeNames = new HashMap <>();
140- fbTypeNames .put (ISCConstants .SQL_TEXT , "CHAR" );
141- fbTypeNames .put (ISCConstants .SQL_VARYING , "VARCHAR" );
142- fbTypeNames .put (ISCConstants .SQL_SHORT , "SMALLINT" );
143- fbTypeNames .put (ISCConstants .SQL_LONG , "INTEGER" );
144- fbTypeNames .put (ISCConstants .SQL_FLOAT , "FLOAT" );
145- fbTypeNames .put (ISCConstants .SQL_DOUBLE , "DOUBLE PRECISION" );
146- fbTypeNames .put (ISCConstants .SQL_D_FLOAT , "FLOAT" );
147- fbTypeNames .put (ISCConstants .SQL_TIMESTAMP , "TIMESTAMP" );
148- fbTypeNames .put (ISCConstants .SQL_BLOB , "BLOB" );
149- fbTypeNames .put (ISCConstants .SQL_ARRAY , "ARRAY" );
150- fbTypeNames .put (ISCConstants .SQL_QUAD , "QUAD" );
151- fbTypeNames .put (ISCConstants .SQL_TYPE_TIME , "TIME" );
152- fbTypeNames .put (ISCConstants .SQL_TYPE_DATE , "DATE" );
153- fbTypeNames .put (ISCConstants .SQL_INT64 , "BIGINT" );
154- fbTypeNames .put (ISCConstants .SQL_BOOLEAN , "BOOLEAN" );
155- fbTypeNames .put (ISCConstants .SQL_NULL , "NULL" );
142+ fbTypeNames .put (ISCConstants .SQL_TEXT , Pair . of ( "CHAR" , Types . CHAR ) );
143+ fbTypeNames .put (ISCConstants .SQL_VARYING , Pair . of ( "VARCHAR" , Types . VARCHAR ) );
144+ fbTypeNames .put (ISCConstants .SQL_SHORT , Pair . of ( "SMALLINT" , Types . SMALLINT ) );
145+ fbTypeNames .put (ISCConstants .SQL_LONG , Pair . of ( "INTEGER" , Types . INTEGER ) );
146+ fbTypeNames .put (ISCConstants .SQL_FLOAT , Pair . of ( "FLOAT" , Types . FLOAT ) );
147+ fbTypeNames .put (ISCConstants .SQL_DOUBLE , Pair . of ( "DOUBLE PRECISION" , Types . DOUBLE ) );
148+ fbTypeNames .put (ISCConstants .SQL_D_FLOAT , Pair . of ( "FLOAT" , Types . FLOAT ) );
149+ fbTypeNames .put (ISCConstants .SQL_TIMESTAMP , Pair . of ( "TIMESTAMP" , Types . TIMESTAMP ) );
150+ fbTypeNames .put (ISCConstants .SQL_BLOB , Pair . of ( "BLOB" , Types . BLOB ) );
151+ fbTypeNames .put (ISCConstants .SQL_ARRAY , Pair . of ( "ARRAY" , Types . ARRAY ) );
152+ fbTypeNames .put (ISCConstants .SQL_QUAD , Pair . of ( "QUAD" , - 1 ) );
153+ fbTypeNames .put (ISCConstants .SQL_TYPE_TIME , Pair . of ( "TIME" , Types . TIME ) );
154+ fbTypeNames .put (ISCConstants .SQL_TYPE_DATE , Pair . of ( "DATE" , Types . DATE ) );
155+ fbTypeNames .put (ISCConstants .SQL_INT64 , Pair . of ( "BIGINT" , Types . BIGINT ) );
156+ fbTypeNames .put (ISCConstants .SQL_BOOLEAN , Pair . of ( "BOOLEAN" , Types . BOOLEAN ) );
157+ fbTypeNames .put (ISCConstants .SQL_NULL , Pair . of ( "NULL" , Types . NULL ) );
156158
157159 dataTypesByClass = new HashMap <>();
158160 javaClassesByName = new HashMap <>();
@@ -228,9 +230,9 @@ void putInMessage(IExternalContext context, Pointer message, int nullOffset, int
228230
229231 default :
230232 {
231- String typeName = fbTypeNames .get (type );
232- if ( typeName == null )
233- typeName = String .valueOf (type );
233+ String typeName = Optional . of ( fbTypeNames .get (type ))
234+ . map ( Pair :: getFirst )
235+ . orElse ( String .valueOf (type ) );
234236
235237 throw new FbException (
236238 String .format ("Cannot use Java String type for the Firebird type '%s'." , typeName ));
@@ -297,9 +299,9 @@ Conversion setupConversion(IStatus status, Class<?> javaClass, IMessageMetadata
297299
298300 default :
299301 {
300- String typeName = fbTypeNames .get (type );
301- if ( typeName == null )
302- typeName = String .valueOf (type );
302+ String typeName = Optional . of ( fbTypeNames .get (type ))
303+ . map ( Pair :: getFirst )
304+ . orElse ( String .valueOf (type ) );
303305
304306 throw new FbException (
305307 String .format ("Cannot use Java byte[] type for the Firebird type '%s'." , typeName ));
@@ -419,9 +421,9 @@ Conversion setupConversion(IStatus status, Class<?> javaClass, IMessageMetadata
419421
420422 if (type != ISCConstants .SQL_BLOB )
421423 {
422- String typeName = fbTypeNames .get (type );
423- if ( typeName == null )
424- typeName = String .valueOf (type );
424+ String typeName = Optional . of ( fbTypeNames .get (type ))
425+ . map ( Pair :: getFirst )
426+ . orElse ( String .valueOf (type ) );
425427
426428 throw new FbException (
427429 String .format ("Cannot use Java java.sql.Blob type for the Firebird type '%s'." , typeName ));
@@ -938,9 +940,9 @@ Conversion setupConversion(IStatus status, Class<?> javaClass, IMessageMetadata
938940
939941 if (defaultType == null )
940942 {
941- String typeName = fbTypeNames .get (type );
942- if ( typeName == null )
943- typeName = String .valueOf (type );
943+ String typeName = Optional . of ( fbTypeNames .get (type ))
944+ . map ( Pair :: getFirst )
945+ . orElse ( String .valueOf (type ) );
944946
945947 throw new FbException (
946948 String .format ("Cannot use Java Object type for the Firebird type '%s'." , typeName ));
@@ -1185,10 +1187,24 @@ private Routine getRoutine(IStatus status, IExternalContext context, IRoutineMet
11851187 boolean isOutput = n > inCount && n <= inCount + outCount ;
11861188 Parameter parameter = getDataType (entryPoint , pos , isOutput );
11871189
1190+ IMessageMetadata inOutMetadata ;
1191+ int index ;
1192+
11881193 if (isOutput )
1194+ {
11891195 routine .outputParameters .add (parameter );
1196+ inOutMetadata = outMetadata ;
1197+ index = n - 1 - inCount ;
1198+ }
11901199 else
1200+ {
11911201 routine .inputParameters .add (parameter );
1202+ inOutMetadata = inMetadata ;
1203+ index = n - 1 ;
1204+ }
1205+
1206+ parameter .name = inOutMetadata .getField (status , index );
1207+ parameter .type = fbTypeNames .get (inOutMetadata .getType (status , index ));
11921208
11931209 paramTypes .add (parameter .javaClass );
11941210
@@ -1224,6 +1240,7 @@ else if (pos[0] != entryPoint.length())
12241240 switch (type )
12251241 {
12261242 case FUNCTION :
1243+ {
12271244 assert outCount == 1 ;
12281245
12291246 if (paramTypes .size () != inCount )
@@ -1243,8 +1260,12 @@ else if (pos[0] != entryPoint.length())
12431260 routine .method .getReturnType ().getName ()));
12441261 }
12451262
1246- routine .outputParameters .add (new Parameter (returnType , routine .method .getReturnType ()));
1263+ Parameter parameter = new Parameter (returnType , routine .method .getReturnType ());
1264+ parameter .type = fbTypeNames .get (outMetadata .getType (status , 0 ));
1265+
1266+ routine .outputParameters .add (parameter );
12471267 break ;
1268+ }
12481269
12491270 case PROCEDURE :
12501271 if (paramTypes .size () != inCount + outCount )
0 commit comments