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
11
13
import java .sql .SQLTimeoutException ;
12
14
import java .sql .SQLWarning ;
13
15
import java .sql .Statement ;
16
+ import java .util .Collections ;
17
+ import java .util .List ;
14
18
import java .util .concurrent .TimeUnit ;
15
19
import java .util .concurrent .atomic .AtomicBoolean ;
20
+ import java .util .stream .Collectors ;
16
21
17
22
/**
18
23
* Tarantool {@link Statement} implementation.
23
28
*/
24
29
public class SQLStatement implements TarantoolStatement {
25
30
26
- protected final SQLConnection connection ;
31
+ private static final String GENERATED_KEY_COLUMN_NAME = "GENERATED_KEY" ;
32
+
33
+ protected final TarantoolConnection connection ;
34
+ private final SQLResultSet emptyGeneratedKeys ;
27
35
28
36
/**
29
37
* Current result set / update count associated to this statement.
30
38
*/
31
39
protected SQLResultSet resultSet ;
32
40
protected int updateCount ;
41
+ protected SQLResultSet generatedKeys ;
33
42
34
43
private boolean isCloseOnCompletion ;
35
44
@@ -47,10 +56,12 @@ public class SQLStatement implements TarantoolStatement {
47
56
private final AtomicBoolean isClosed = new AtomicBoolean (false );
48
57
49
58
protected SQLStatement (SQLConnection sqlConnection ) throws SQLException {
50
- this .connection = sqlConnection ;
51
- this .resultSetType = ResultSet .TYPE_FORWARD_ONLY ;
52
- this .resultSetConcurrency = ResultSet .CONCUR_READ_ONLY ;
53
- this .resultSetHoldability = sqlConnection .getHoldability ();
59
+ this (
60
+ sqlConnection ,
61
+ ResultSet .TYPE_FORWARD_ONLY ,
62
+ ResultSet .CONCUR_READ_ONLY ,
63
+ sqlConnection .getHoldability ()
64
+ );
54
65
}
55
66
56
67
protected SQLStatement (SQLConnection sqlConnection ,
@@ -61,37 +72,34 @@ protected SQLStatement(SQLConnection sqlConnection,
61
72
this .resultSetType = resultSetType ;
62
73
this .resultSetConcurrency = resultSetConcurrency ;
63
74
this .resultSetHoldability = resultSetHoldability ;
75
+ this .emptyGeneratedKeys = this .generatedKeys = executeGeneratedKeys (Collections .emptyList ());
64
76
}
65
77
66
78
@ Override
67
79
public ResultSet executeQuery (String sql ) throws SQLException {
68
80
checkNotClosed ();
69
- if (!executeInternal (sql )) {
81
+ if (!executeInternal (NO_GENERATED_KEYS , sql )) {
70
82
throw new SQLException ("No results were returned" , SQLStates .NO_DATA .getSqlState ());
71
83
}
72
84
return resultSet ;
73
85
}
74
86
75
87
@ Override
76
88
public int executeUpdate (String sql ) throws SQLException {
77
- checkNotClosed ();
78
- if (executeInternal (sql )) {
79
- throw new SQLException (
80
- "Result was returned but nothing was expected" ,
81
- SQLStates .TOO_MANY_RESULTS .getSqlState ()
82
- );
83
- }
84
- return updateCount ;
89
+ return executeUpdate (sql , NO_GENERATED_KEYS );
85
90
}
86
91
87
92
@ Override
88
93
public int executeUpdate (String sql , int autoGeneratedKeys ) throws SQLException {
89
94
checkNotClosed ();
90
95
JdbcConstants .checkGeneratedKeysConstant (autoGeneratedKeys );
91
- if (autoGeneratedKeys != Statement .NO_GENERATED_KEYS ) {
92
- throw new SQLFeatureNotSupportedException ();
96
+ if (executeInternal (autoGeneratedKeys , sql )) {
97
+ throw new SQLException (
98
+ "Result was returned but nothing was expected" ,
99
+ SQLStates .TOO_MANY_RESULTS .getSqlState ()
100
+ );
93
101
}
94
- return executeUpdate ( sql ) ;
102
+ return updateCount ;
95
103
}
96
104
97
105
@ Override
@@ -181,17 +189,14 @@ public void setCursorName(String name) throws SQLException {
181
189
@ Override
182
190
public boolean execute (String sql ) throws SQLException {
183
191
checkNotClosed ();
184
- return executeInternal (sql );
192
+ return executeInternal (NO_GENERATED_KEYS , sql );
185
193
}
186
194
187
195
@ Override
188
196
public boolean execute (String sql , int autoGeneratedKeys ) throws SQLException {
189
197
checkNotClosed ();
190
198
JdbcConstants .checkGeneratedKeysConstant (autoGeneratedKeys );
191
- if (autoGeneratedKeys != Statement .NO_GENERATED_KEYS ) {
192
- throw new SQLFeatureNotSupportedException ();
193
- }
194
- return execute (sql );
199
+ return executeInternal (autoGeneratedKeys , sql );
195
200
}
196
201
197
202
@ Override
@@ -296,7 +301,7 @@ public Connection getConnection() throws SQLException {
296
301
@ Override
297
302
public ResultSet getGeneratedKeys () throws SQLException {
298
303
checkNotClosed ();
299
- return new SQLResultSet ( SQLResultHolder . ofEmptyQuery (), this ) ;
304
+ return generatedKeys ;
300
305
}
301
306
302
307
@ Override
@@ -374,6 +379,7 @@ protected void discardLastResults() throws SQLException {
374
379
clearWarnings ();
375
380
updateCount = -1 ;
376
381
resultSet = null ;
382
+ generatedKeys = emptyGeneratedKeys ;
377
383
378
384
if (lastResultSet != null ) {
379
385
try {
@@ -392,7 +398,7 @@ protected void discardLastResults() throws SQLException {
392
398
*
393
399
* @return {@code true}, if the result is a ResultSet object;
394
400
*/
395
- protected boolean executeInternal (String sql , Object ... params ) throws SQLException {
401
+ protected boolean executeInternal (int autoGeneratedKeys , String sql , Object ... params ) throws SQLException {
396
402
discardLastResults ();
397
403
SQLResultHolder holder ;
398
404
try {
@@ -406,6 +412,9 @@ protected boolean executeInternal(String sql, Object... params) throws SQLExcept
406
412
resultSet = new SQLResultSet (holder , this );
407
413
}
408
414
updateCount = holder .getUpdateCount ();
415
+ if (autoGeneratedKeys == Statement .RETURN_GENERATED_KEYS ) {
416
+ generatedKeys = executeGeneratedKeys (holder .getGeneratedIds ());
417
+ }
409
418
return holder .isQueryResult ();
410
419
}
411
420
@@ -425,4 +434,13 @@ protected void checkNotClosed() throws SQLException {
425
434
}
426
435
}
427
436
437
+ protected SQLResultSet executeGeneratedKeys (List <Integer > generatedKeys ) throws SQLException {
438
+ SqlProtoUtils .SQLMetaData sqlMetaData =
439
+ new SqlProtoUtils .SQLMetaData (GENERATED_KEY_COLUMN_NAME , TarantoolSqlType .INTEGER );
440
+ List <List <Object >> rows = generatedKeys .stream ()
441
+ .map (Collections ::<Object >singletonList )
442
+ .collect (Collectors .toList ());
443
+ return createResultSet (SQLResultHolder .ofQuery (Collections .singletonList (sqlMetaData ), rows ));
444
+ }
445
+
428
446
}
0 commit comments