11package org .tarantool .jdbc ;
22
3+ import org .tarantool .SqlProtoUtils ;
4+ import org .tarantool .jdbc .type .TarantoolSqlType ;
35import org .tarantool .util .JdbcConstants ;
46import org .tarantool .util .SQLStates ;
57
1113import java .sql .SQLTimeoutException ;
1214import java .sql .SQLWarning ;
1315import java .sql .Statement ;
16+ import java .util .Collections ;
17+ import java .util .List ;
1418import java .util .concurrent .TimeUnit ;
1519import java .util .concurrent .atomic .AtomicBoolean ;
20+ import java .util .stream .Collectors ;
1621
1722/**
1823 * Tarantool {@link Statement} implementation.
2328 */
2429public class SQLStatement implements TarantoolStatement {
2530
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 ;
2735
2836 /**
2937 * Current result set / update count associated to this statement.
3038 */
3139 protected SQLResultSet resultSet ;
3240 protected int updateCount ;
41+ protected SQLResultSet generatedKeys ;
3342
3443 private boolean isCloseOnCompletion ;
3544
@@ -47,10 +56,12 @@ public class SQLStatement implements TarantoolStatement {
4756 private final AtomicBoolean isClosed = new AtomicBoolean (false );
4857
4958 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+ );
5465 }
5566
5667 protected SQLStatement (SQLConnection sqlConnection ,
@@ -61,37 +72,34 @@ protected SQLStatement(SQLConnection sqlConnection,
6172 this .resultSetType = resultSetType ;
6273 this .resultSetConcurrency = resultSetConcurrency ;
6374 this .resultSetHoldability = resultSetHoldability ;
75+ this .emptyGeneratedKeys = this .generatedKeys = executeGeneratedKeys (Collections .emptyList ());
6476 }
6577
6678 @ Override
6779 public ResultSet executeQuery (String sql ) throws SQLException {
6880 checkNotClosed ();
69- if (!executeInternal (sql )) {
81+ if (!executeInternal (NO_GENERATED_KEYS , sql )) {
7082 throw new SQLException ("No results were returned" , SQLStates .NO_DATA .getSqlState ());
7183 }
7284 return resultSet ;
7385 }
7486
7587 @ Override
7688 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 );
8590 }
8691
8792 @ Override
8893 public int executeUpdate (String sql , int autoGeneratedKeys ) throws SQLException {
8994 checkNotClosed ();
9095 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+ );
93101 }
94- return executeUpdate ( sql ) ;
102+ return updateCount ;
95103 }
96104
97105 @ Override
@@ -181,17 +189,14 @@ public void setCursorName(String name) throws SQLException {
181189 @ Override
182190 public boolean execute (String sql ) throws SQLException {
183191 checkNotClosed ();
184- return executeInternal (sql );
192+ return executeInternal (NO_GENERATED_KEYS , sql );
185193 }
186194
187195 @ Override
188196 public boolean execute (String sql , int autoGeneratedKeys ) throws SQLException {
189197 checkNotClosed ();
190198 JdbcConstants .checkGeneratedKeysConstant (autoGeneratedKeys );
191- if (autoGeneratedKeys != Statement .NO_GENERATED_KEYS ) {
192- throw new SQLFeatureNotSupportedException ();
193- }
194- return execute (sql );
199+ return executeInternal (autoGeneratedKeys , sql );
195200 }
196201
197202 @ Override
@@ -296,7 +301,7 @@ public Connection getConnection() throws SQLException {
296301 @ Override
297302 public ResultSet getGeneratedKeys () throws SQLException {
298303 checkNotClosed ();
299- return new SQLResultSet ( SQLResultHolder . ofEmptyQuery (), this ) ;
304+ return generatedKeys ;
300305 }
301306
302307 @ Override
@@ -374,6 +379,7 @@ protected void discardLastResults() throws SQLException {
374379 clearWarnings ();
375380 updateCount = -1 ;
376381 resultSet = null ;
382+ generatedKeys = emptyGeneratedKeys ;
377383
378384 if (lastResultSet != null ) {
379385 try {
@@ -392,7 +398,7 @@ protected void discardLastResults() throws SQLException {
392398 *
393399 * @return {@code true}, if the result is a ResultSet object;
394400 */
395- protected boolean executeInternal (String sql , Object ... params ) throws SQLException {
401+ protected boolean executeInternal (int autoGeneratedKeys , String sql , Object ... params ) throws SQLException {
396402 discardLastResults ();
397403 SQLResultHolder holder ;
398404 try {
@@ -406,6 +412,9 @@ protected boolean executeInternal(String sql, Object... params) throws SQLExcept
406412 resultSet = new SQLResultSet (holder , this );
407413 }
408414 updateCount = holder .getUpdateCount ();
415+ if (autoGeneratedKeys == Statement .RETURN_GENERATED_KEYS ) {
416+ generatedKeys = executeGeneratedKeys (holder .getGeneratedIds ());
417+ }
409418 return holder .isQueryResult ();
410419 }
411420
@@ -425,4 +434,13 @@ protected void checkNotClosed() throws SQLException {
425434 }
426435 }
427436
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+
428446}
0 commit comments