1
1
package org .tarantool .jdbc ;
2
2
3
+ import org .tarantool .SqlProtoUtils ;
4
+ import org .tarantool .jdbc .type .TarantoolSqlType ;
3
5
import org .tarantool .util .JdbcConstants ;
4
6
import org .tarantool .util .SQLStates ;
5
7
13
15
import java .sql .SQLWarning ;
14
16
import java .sql .Statement ;
15
17
import java .util .ArrayList ;
18
+ import java .util .Collections ;
16
19
import java .util .List ;
17
20
import java .util .concurrent .TimeUnit ;
18
21
import java .util .concurrent .atomic .AtomicBoolean ;
27
30
*/
28
31
public class SQLStatement implements TarantoolStatement {
29
32
30
- protected final SQLConnection connection ;
33
+ private static final String GENERATED_KEY_COLUMN_NAME = "GENERATED_KEY" ;
34
+
35
+ protected final TarantoolConnection connection ;
36
+ private final SQLResultSet emptyGeneratedKeys ;
31
37
32
38
/**
33
39
* Current result set / update count associated to this statement.
34
40
*/
35
41
protected SQLResultSet resultSet ;
36
42
protected int updateCount ;
43
+ protected SQLResultSet generatedKeys ;
37
44
38
45
private List <String > batchQueries = new ArrayList <>();
39
46
@@ -61,10 +68,12 @@ public class SQLStatement implements TarantoolStatement {
61
68
private final AtomicBoolean isClosed = new AtomicBoolean (false );
62
69
63
70
protected SQLStatement (SQLConnection sqlConnection ) throws SQLException {
64
- this .connection = sqlConnection ;
65
- this .resultSetType = ResultSet .TYPE_FORWARD_ONLY ;
66
- this .resultSetConcurrency = ResultSet .CONCUR_READ_ONLY ;
67
- this .resultSetHoldability = sqlConnection .getHoldability ();
71
+ this (
72
+ sqlConnection ,
73
+ ResultSet .TYPE_FORWARD_ONLY ,
74
+ ResultSet .CONCUR_READ_ONLY ,
75
+ sqlConnection .getHoldability ()
76
+ );
68
77
}
69
78
70
79
protected SQLStatement (SQLConnection sqlConnection ,
@@ -75,37 +84,34 @@ protected SQLStatement(SQLConnection sqlConnection,
75
84
this .resultSetType = resultSetType ;
76
85
this .resultSetConcurrency = resultSetConcurrency ;
77
86
this .resultSetHoldability = resultSetHoldability ;
87
+ this .emptyGeneratedKeys = this .generatedKeys = executeGeneratedKeys (Collections .emptyList ());
78
88
}
79
89
80
90
@ Override
81
91
public ResultSet executeQuery (String sql ) throws SQLException {
82
92
checkNotClosed ();
83
- if (!executeInternal (sql )) {
93
+ if (!executeInternal (NO_GENERATED_KEYS , sql )) {
84
94
throw new SQLException ("No results were returned" , SQLStates .NO_DATA .getSqlState ());
85
95
}
86
96
return resultSet ;
87
97
}
88
98
89
99
@ Override
90
100
public int executeUpdate (String sql ) throws SQLException {
91
- checkNotClosed ();
92
- if (executeInternal (sql )) {
93
- throw new SQLException (
94
- "Result was returned but nothing was expected" ,
95
- SQLStates .TOO_MANY_RESULTS .getSqlState ()
96
- );
97
- }
98
- return updateCount ;
101
+ return executeUpdate (sql , NO_GENERATED_KEYS );
99
102
}
100
103
101
104
@ Override
102
105
public int executeUpdate (String sql , int autoGeneratedKeys ) throws SQLException {
103
106
checkNotClosed ();
104
107
JdbcConstants .checkGeneratedKeysConstant (autoGeneratedKeys );
105
- if (autoGeneratedKeys != Statement .NO_GENERATED_KEYS ) {
106
- throw new SQLFeatureNotSupportedException ();
108
+ if (executeInternal (autoGeneratedKeys , sql )) {
109
+ throw new SQLException (
110
+ "Result was returned but nothing was expected" ,
111
+ SQLStates .TOO_MANY_RESULTS .getSqlState ()
112
+ );
107
113
}
108
- return executeUpdate ( sql ) ;
114
+ return updateCount ;
109
115
}
110
116
111
117
@ Override
@@ -195,17 +201,14 @@ public void setCursorName(String name) throws SQLException {
195
201
@ Override
196
202
public boolean execute (String sql ) throws SQLException {
197
203
checkNotClosed ();
198
- return executeInternal (sql );
204
+ return executeInternal (NO_GENERATED_KEYS , sql );
199
205
}
200
206
201
207
@ Override
202
208
public boolean execute (String sql , int autoGeneratedKeys ) throws SQLException {
203
209
checkNotClosed ();
204
210
JdbcConstants .checkGeneratedKeysConstant (autoGeneratedKeys );
205
- if (autoGeneratedKeys != Statement .NO_GENERATED_KEYS ) {
206
- throw new SQLFeatureNotSupportedException ();
207
- }
208
- return execute (sql );
211
+ return executeInternal (autoGeneratedKeys , sql );
209
212
}
210
213
211
214
@ Override
@@ -321,7 +324,7 @@ public Connection getConnection() throws SQLException {
321
324
@ Override
322
325
public ResultSet getGeneratedKeys () throws SQLException {
323
326
checkNotClosed ();
324
- return new SQLResultSet ( SQLResultHolder . ofEmptyQuery (), this ) ;
327
+ return generatedKeys ;
325
328
}
326
329
327
330
@ Override
@@ -401,6 +404,7 @@ protected void discardLastResults() throws SQLException {
401
404
clearWarnings ();
402
405
updateCount = -1 ;
403
406
resultSet = null ;
407
+ generatedKeys = emptyGeneratedKeys ;
404
408
405
409
if (lastResultSet != null ) {
406
410
try {
@@ -419,7 +423,7 @@ protected void discardLastResults() throws SQLException {
419
423
*
420
424
* @return {@code true}, if the result is a ResultSet object;
421
425
*/
422
- protected boolean executeInternal (String sql , Object ... params ) throws SQLException {
426
+ protected boolean executeInternal (int autoGeneratedKeys , String sql , Object ... params ) throws SQLException {
423
427
discardLastResults ();
424
428
SQLResultHolder holder ;
425
429
try {
@@ -433,6 +437,9 @@ protected boolean executeInternal(String sql, Object... params) throws SQLExcept
433
437
resultSet = new SQLResultSet (holder , this );
434
438
}
435
439
updateCount = holder .getUpdateCount ();
440
+ if (autoGeneratedKeys == Statement .RETURN_GENERATED_KEYS ) {
441
+ generatedKeys = executeGeneratedKeys (holder .getGeneratedIds ());
442
+ }
436
443
return holder .isQueryResult ();
437
444
}
438
445
@@ -474,4 +481,13 @@ protected void checkNotClosed() throws SQLException {
474
481
}
475
482
}
476
483
484
+ protected SQLResultSet executeGeneratedKeys (List <Integer > generatedKeys ) throws SQLException {
485
+ SqlProtoUtils .SQLMetaData sqlMetaData =
486
+ new SqlProtoUtils .SQLMetaData (GENERATED_KEY_COLUMN_NAME , TarantoolSqlType .INTEGER );
487
+ List <List <Object >> rows = generatedKeys .stream ()
488
+ .map (Collections ::<Object >singletonList )
489
+ .collect (Collectors .toList ());
490
+ return createResultSet (SQLResultHolder .ofQuery (Collections .singletonList (sqlMetaData ), rows ));
491
+ }
492
+
477
493
}
0 commit comments