Skip to content

Commit b27f5a0

Browse files
committed
Support Statement.NO_GENERATED_KEYS option
Add a proper behaviour when Connection.prepareStatement, Statement.execute, and Statement.executeUpdate are called with the Statement.NO_GENERATED_KEYS flag. Return an empty generated keys when the Statement.NO_GENERATED_KEYS is set as a special case of a generated keys absence. Fixes: #78
1 parent e81aaca commit b27f5a0

File tree

7 files changed

+157
-54
lines changed

7 files changed

+157
-54
lines changed

Diff for: src/main/java/org/tarantool/jdbc/SQLConnection.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,12 @@ public PreparedStatement prepareStatement(String sql,
197197

198198
@Override
199199
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
200-
throw new SQLFeatureNotSupportedException();
200+
checkNotClosed();
201+
JdbcConstants.checkGeneratedKeysConstant(autoGeneratedKeys);
202+
if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS) {
203+
throw new SQLFeatureNotSupportedException();
204+
}
205+
return prepareStatement(sql);
201206
}
202207

203208
@Override

Diff for: src/main/java/org/tarantool/jdbc/SQLStatement.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.tarantool.jdbc;
22

33
import org.tarantool.JDBCBridge;
4+
import org.tarantool.util.JdbcConstants;
45

56
import java.sql.Connection;
67
import java.sql.ResultSet;
@@ -10,7 +11,6 @@
1011
import java.sql.SQLWarning;
1112
import java.sql.Statement;
1213

13-
@SuppressWarnings("Since15")
1414
public class SQLStatement implements Statement {
1515

1616
protected final SQLConnection connection;
@@ -56,7 +56,12 @@ public int executeUpdate(String sql) throws SQLException {
5656

5757
@Override
5858
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
59-
throw new SQLFeatureNotSupportedException();
59+
checkNotClosed();
60+
JdbcConstants.checkGeneratedKeysConstant(autoGeneratedKeys);
61+
if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS) {
62+
throw new SQLFeatureNotSupportedException();
63+
}
64+
return executeUpdate(sql);
6065
}
6166

6267
@Override
@@ -146,7 +151,12 @@ public boolean execute(String sql) throws SQLException {
146151

147152
@Override
148153
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
149-
throw new SQLFeatureNotSupportedException();
154+
checkNotClosed();
155+
JdbcConstants.checkGeneratedKeysConstant(autoGeneratedKeys);
156+
if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS) {
157+
throw new SQLFeatureNotSupportedException();
158+
}
159+
return execute(sql);
150160
}
151161

152162
@Override
@@ -250,7 +260,8 @@ public Connection getConnection() throws SQLException {
250260

251261
@Override
252262
public ResultSet getGeneratedKeys() throws SQLException {
253-
throw new SQLFeatureNotSupportedException();
263+
checkNotClosed();
264+
return new SQLResultSet(JDBCBridge.EMPTY, this);
254265
}
255266

256267
@Override

Diff for: src/main/java/org/tarantool/util/JdbcConstants.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@
77

88
public class JdbcConstants {
99

10+
public static void checkGeneratedKeysConstant(int autoGeneratedKeys) throws SQLException {
11+
if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS &&
12+
autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS) {
13+
throw new SQLNonTransientException("", SQLStates.INVALID_PARAMETER_VALUE.getSqlState());
14+
}
15+
}
16+
1017
public static void checkHoldabilityConstant(int holdability) throws SQLException {
11-
if (holdability != ResultSet.CLOSE_CURSORS_AT_COMMIT
12-
&& holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
18+
if (holdability != ResultSet.CLOSE_CURSORS_AT_COMMIT &&
19+
holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
1320
throw new SQLNonTransientException("", SQLStates.INVALID_PARAMETER_VALUE.getSqlState());
1421
}
1522
}

Diff for: src/test/java/org/tarantool/jdbc/JdbcConnectionIT.java

+37-17
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,23 @@ public void testClosedConnection() throws SQLException {
8989
@Override
9090
public void execute() throws Throwable {
9191
switch (step) {
92-
case 0:
93-
conn.createStatement();
94-
break;
95-
case 1:
96-
conn.prepareStatement("TEST");
97-
break;
98-
case 2:
99-
conn.getMetaData();
100-
break;
101-
case 3:
102-
conn.getNetworkTimeout();
103-
break;
104-
case 4:
105-
conn.setNetworkTimeout(null, 1000);
106-
break;
107-
default:
108-
fail();
92+
case 0:
93+
conn.createStatement();
94+
break;
95+
case 1:
96+
conn.prepareStatement("TEST");
97+
break;
98+
case 2:
99+
conn.getMetaData();
100+
break;
101+
case 3:
102+
conn.getNetworkTimeout();
103+
break;
104+
case 4:
105+
conn.setNetworkTimeout(null, 1000);
106+
break;
107+
default:
108+
fail();
109109
}
110110
}
111111
});
@@ -230,4 +230,24 @@ public void testPrepareHoldableStatement() throws SQLException {
230230
});
231231
}
232232

233+
@Test
234+
public void testGeneratedKeys() throws SQLException {
235+
String sql = "SELECT * FROM test";
236+
PreparedStatement preparedStatement = conn.prepareStatement(sql, Statement.NO_GENERATED_KEYS);
237+
assertNotNull(preparedStatement);
238+
preparedStatement.close();
239+
240+
assertThrows(SQLFeatureNotSupportedException.class, () -> conn.prepareStatement(sql, new int[] { 1 }));
241+
assertThrows(SQLFeatureNotSupportedException.class, () -> conn.prepareStatement(sql, new String[] { "id" }));
242+
243+
assertThrows(SQLException.class, () -> conn.prepareStatement(sql, Integer.MAX_VALUE));
244+
assertThrows(SQLException.class, () -> conn.prepareStatement(sql, Integer.MIN_VALUE));
245+
assertThrows(SQLException.class, () -> conn.prepareStatement(sql, -76));
246+
assertThrows(
247+
SQLFeatureNotSupportedException.class,
248+
() -> conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
249+
);
250+
}
251+
233252
}
253+

Diff for: src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java

+5
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,9 @@ public void testIsWrapperFor() throws SQLException {
267267
assertFalse(meta.isWrapperFor(Integer.class));
268268
}
269269

270+
@Test
271+
public void testSupportGeneratedKeys() throws SQLException {
272+
assertFalse(meta.supportsGetGeneratedKeys());
273+
}
274+
270275
}

Diff for: src/test/java/org/tarantool/jdbc/JdbcPreparedStatementIT.java

+39-22
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
import java.sql.PreparedStatement;
1818
import java.sql.ResultSet;
1919
import java.sql.SQLException;
20+
import java.sql.Statement;
2021

2122
public class JdbcPreparedStatementIT extends JdbcTypesIT {
23+
2224
private PreparedStatement prep;
2325

2426
@AfterEach
@@ -105,6 +107,8 @@ public void testExecuteReturnsUpdateCount() throws Exception {
105107

106108
assertEquals("ten", getRow("test", 10).get(1));
107109
assertEquals("twenty", getRow("test", 20).get(1));
110+
111+
conn.createStatement().execute("DELETE FROM test WHERE id IN (10, 20)");
108112
}
109113

110114
@Test
@@ -118,17 +122,17 @@ void testForbiddenMethods() throws SQLException {
118122
@Override
119123
public void execute() throws Throwable {
120124
switch (step) {
121-
case 0:
122-
prep.executeQuery("TEST");
123-
break;
124-
case 1:
125-
prep.executeUpdate("TEST");
126-
break;
127-
case 2:
128-
prep.execute("TEST");
129-
break;
130-
default:
131-
fail();
125+
case 0:
126+
prep.executeQuery("TEST");
127+
break;
128+
case 1:
129+
prep.executeUpdate("TEST");
130+
break;
131+
case 2:
132+
prep.execute("TEST");
133+
break;
134+
default:
135+
fail();
132136
}
133137
}
134138
});
@@ -150,17 +154,17 @@ public void testClosedConnection() throws SQLException {
150154
@Override
151155
public void execute() throws Throwable {
152156
switch (step) {
153-
case 0:
154-
prep.executeQuery();
155-
break;
156-
case 1:
157-
prep.executeUpdate();
158-
break;
159-
case 2:
160-
prep.execute();
161-
break;
162-
default:
163-
fail();
157+
case 0:
158+
prep.executeQuery();
159+
break;
160+
case 1:
161+
prep.executeUpdate();
162+
break;
163+
case 2:
164+
prep.execute();
165+
break;
166+
default:
167+
fail();
164168
}
165169
}
166170
});
@@ -185,6 +189,18 @@ public void testIsWrapperFor() throws SQLException {
185189
assertFalse(prep.isWrapperFor(Integer.class));
186190
}
187191

192+
@Test
193+
public void testSupportGeneratedKeys() throws SQLException {
194+
prep = conn.prepareStatement("INSERT INTO test values (50, 'fifty')", Statement.NO_GENERATED_KEYS);
195+
assertFalse(prep.execute());
196+
assertEquals(1, prep.getUpdateCount());
197+
198+
ResultSet generatedKeys = prep.getGeneratedKeys();
199+
assertNotNull(generatedKeys);
200+
assertEquals(ResultSet.TYPE_FORWARD_ONLY, generatedKeys.getType());
201+
assertEquals(ResultSet.CONCUR_READ_ONLY, generatedKeys.getConcurrency());
202+
}
203+
188204
@Test
189205
public void testSetByte() throws SQLException {
190206
makeHelper(Byte.class)
@@ -256,4 +272,5 @@ public void testSetDate() throws SQLException {
256272
.setValues(DATE_VALS)
257273
.testSetParameter();
258274
}
275+
259276
}

Diff for: src/test/java/org/tarantool/jdbc/JdbcStatementIT.java

+46-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.sql.Statement;
1818

1919
public class JdbcStatementIT extends AbstractJdbcIT {
20+
2021
private Statement stmt;
2122

2223
@BeforeEach
@@ -79,14 +80,17 @@ public void testClosedConnection() throws Exception {
7980
@Override
8081
public void execute() throws Throwable {
8182
switch (step) {
82-
case 0: stmt.executeQuery("TEST");
83-
break;
84-
case 1: stmt.executeUpdate("TEST");
85-
break;
86-
case 2: stmt.execute("TEST");
87-
break;
88-
default:
89-
fail();
83+
case 0:
84+
stmt.executeQuery("TEST");
85+
break;
86+
case 1:
87+
stmt.executeUpdate("TEST");
88+
break;
89+
case 2:
90+
stmt.execute("TEST");
91+
break;
92+
default:
93+
fail();
9094
}
9195
}
9296
});
@@ -107,4 +111,38 @@ public void testIsWrapperFor() throws SQLException {
107111
assertFalse(stmt.isWrapperFor(Integer.class));
108112
}
109113

114+
@Test
115+
public void testSupportedGeneratedKeys() throws SQLException {
116+
int affectedRows = stmt.executeUpdate(
117+
"INSERT INTO test(id, val) VALUES (50, 'fifty')",
118+
Statement.NO_GENERATED_KEYS
119+
);
120+
assertEquals(1, affectedRows);
121+
ResultSet generatedKeys = stmt.getGeneratedKeys();
122+
assertNotNull(generatedKeys);
123+
assertEquals(ResultSet.TYPE_FORWARD_ONLY, generatedKeys.getType());
124+
assertEquals(ResultSet.CONCUR_READ_ONLY, generatedKeys.getConcurrency());
125+
}
126+
127+
@Test
128+
void testUnsupportedGeneratedKeys() {
129+
assertThrows(
130+
SQLException.class,
131+
() -> stmt.executeUpdate(
132+
"INSERT INTO test(id, val) VALUES (100, 'hundred'), (1000, 'thousand')",
133+
Statement.RETURN_GENERATED_KEYS
134+
)
135+
);
136+
137+
int[] wrongConstants = { Integer.MAX_VALUE, Integer.MIN_VALUE, -31, 344 };
138+
for (int wrongConstant : wrongConstants) {
139+
assertThrows(SQLException.class,
140+
() -> stmt.executeUpdate(
141+
"INSERT INTO test(id, val) VALUES (100, 'hundred'), (1000, 'thousand')",
142+
wrongConstant
143+
)
144+
);
145+
}
146+
}
147+
110148
}

0 commit comments

Comments
 (0)