| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.ignite.internal.runner.app.jdbc; |
| |
| import java.sql.Connection; |
| import java.sql.DatabaseMetaData; |
| import java.sql.DriverManager; |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.sql.SQLClientInfoException; |
| import java.sql.SQLException; |
| import java.sql.SQLFeatureNotSupportedException; |
| import java.sql.SQLWarning; |
| import java.sql.Savepoint; |
| import java.sql.Statement; |
| import java.util.HashMap; |
| import java.util.Properties; |
| import java.util.concurrent.Executor; |
| import java.util.concurrent.Executors; |
| import org.junit.jupiter.api.Disabled; |
| import org.junit.jupiter.api.Test; |
| |
| import static java.sql.Connection.TRANSACTION_NONE; |
| import static java.sql.Connection.TRANSACTION_READ_COMMITTED; |
| import static java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; |
| import static java.sql.Connection.TRANSACTION_REPEATABLE_READ; |
| import static java.sql.Connection.TRANSACTION_SERIALIZABLE; |
| import static java.sql.ResultSet.CLOSE_CURSORS_AT_COMMIT; |
| import static java.sql.ResultSet.CONCUR_READ_ONLY; |
| import static java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT; |
| import static java.sql.ResultSet.TYPE_FORWARD_ONLY; |
| import static java.sql.Statement.NO_GENERATED_KEYS; |
| import static java.sql.Statement.RETURN_GENERATED_KEYS; |
| import static org.apache.ignite.client.proto.query.SqlStateCode.TRANSACTION_STATE_EXCEPTION; |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertThrows; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| import static org.junit.jupiter.api.Assertions.fail; |
| |
| /** |
| * Connection test. |
| */ |
| @SuppressWarnings("ThrowableNotThrown") |
| public class ITJdbcConnectionSelfTest extends AbstractJdbcSelfTest { |
| /** |
| * @throws Exception If failed. |
| */ |
| @SuppressWarnings({"EmptyTryBlock", "unused"}) |
| @Test |
| public void testDefaults() throws Exception { |
| var url = "jdbc:ignite:thin://127.0.1.1:10800"; |
| |
| try (Connection conn = DriverManager.getConnection(url)) { |
| // No-op. |
| } |
| |
| try (Connection conn = DriverManager.getConnection(url + "/")) { |
| // No-op. |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @SuppressWarnings({"EmptyTryBlock", "unused"}) |
| @Test |
| @Disabled("ITDS-1887") |
| public void testDefaultsIPv6() throws Exception { |
| var url = "jdbc:ignite:thin://[::1]:10800"; |
| |
| try (Connection conn = DriverManager.getConnection(url)) { |
| // No-op. |
| } |
| |
| try (Connection conn = DriverManager.getConnection(url + "/")) { |
| // No-op. |
| } |
| } |
| |
| /** |
| * Test invalid endpoint. |
| */ |
| @Test |
| public void testInvalidEndpoint() { |
| assertInvalid("jdbc:ignite:thin://", "Address is empty"); |
| assertInvalid("jdbc:ignite:thin://:10000", "Host name is empty"); |
| assertInvalid("jdbc:ignite:thin:// :10000", "Host name is empty"); |
| |
| assertInvalid("jdbc:ignite:thin://127.0.0.1:-1", "port range contains invalid port -1"); |
| assertInvalid("jdbc:ignite:thin://127.0.0.1:0", "port range contains invalid port 0"); |
| assertInvalid("jdbc:ignite:thin://127.0.0.1:100000", |
| "port range contains invalid port 100000"); |
| |
| assertInvalid("jdbc:ignite:thin://[::1]:-1", "port range contains invalid port -1"); |
| assertInvalid("jdbc:ignite:thin://[::1]:0", "port range contains invalid port 0"); |
| assertInvalid("jdbc:ignite:thin://[::1]:100000", |
| "port range contains invalid port 100000"); |
| } |
| |
| /** |
| * Test schema property in URL. |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testSchema() throws Exception { |
| assertInvalid(URL + "/qwe/qwe", |
| "Invalid URL format (only schema name is allowed in URL path parameter 'host:port[/schemaName]')" ); |
| |
| try (Connection conn = DriverManager.getConnection(URL + "/public")) { |
| assertEquals( "PUBLIC", conn.getSchema(), "Invalid schema"); |
| } |
| |
| String dfltSchema = "DEFAULT"; |
| |
| try (Connection conn = DriverManager.getConnection(URL + "/\"" + dfltSchema + '"')) { |
| assertEquals(dfltSchema, conn.getSchema(), "Invalid schema"); |
| } |
| |
| try (Connection conn = DriverManager.getConnection(URL + "/_not_exist_schema_")) { |
| assertEquals("_NOT_EXIST_SCHEMA_", conn.getSchema(), "Invalid schema"); |
| } |
| } |
| |
| /** |
| * Test schema property in URL with semicolon. |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testSchemaSemicolon() throws Exception { |
| String dfltSchema = "DEFAULT"; |
| |
| try (Connection conn = DriverManager.getConnection(URL + ";schema=public")) { |
| assertEquals("PUBLIC", conn.getSchema(), "Invalid schema"); |
| } |
| |
| try (Connection conn = |
| DriverManager.getConnection(URL + ";schema=\"" + dfltSchema + '"')) { |
| assertEquals( dfltSchema, conn.getSchema(), "Invalid schema"); |
| } |
| |
| try (Connection conn = DriverManager.getConnection(URL + ";schema=_not_exist_schema_")) { |
| assertEquals("_NOT_EXIST_SCHEMA_", conn.getSchema(), "Invalid schema"); |
| } |
| } |
| |
| /** |
| * Assert that provided URL is invalid. |
| * |
| * @param url URL. |
| * @param errMsg Error message. |
| */ |
| private void assertInvalid(final String url, String errMsg) { |
| assertThrows(SQLException.class, () -> DriverManager.getConnection(url), errMsg); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testClose() throws Exception { |
| final Connection conn; |
| |
| try (Connection conn0 = DriverManager.getConnection(URL)) { |
| conn = conn0; |
| |
| assertNotNull(conn); |
| assertFalse(conn.isClosed()); |
| } |
| |
| assertTrue(conn.isClosed()); |
| |
| assertFalse(conn.isValid(2), "Connection must be closed"); |
| |
| assertThrows(SQLException.class, () -> conn.isValid(-2), "Invalid timeout"); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateStatement() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| try (Statement stmt = conn.createStatement()) { |
| assertNotNull(stmt); |
| |
| stmt.close(); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.createStatement()); |
| } |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testCreateStatement2() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| int[] rsTypes = new int[] |
| {TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE}; |
| |
| int[] rsConcurs = new int[] |
| {CONCUR_READ_ONLY, ResultSet.CONCUR_UPDATABLE}; |
| |
| DatabaseMetaData meta = conn.getMetaData(); |
| |
| for (final int type : rsTypes) { |
| for (final int concur : rsConcurs) { |
| if (meta.supportsResultSetConcurrency(type, concur)) { |
| assertEquals(TYPE_FORWARD_ONLY, type); |
| assertEquals(CONCUR_READ_ONLY, concur); |
| |
| try (Statement stmt = conn.createStatement(type, concur)) { |
| assertNotNull(stmt); |
| |
| assertEquals(type, stmt.getResultSetType()); |
| assertEquals(concur, stmt.getResultSetConcurrency()); |
| } |
| |
| continue; |
| } |
| |
| assertThrows(SQLFeatureNotSupportedException.class, () -> conn.createStatement(type, concur)); |
| } |
| } |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.createStatement(TYPE_FORWARD_ONLY, CONCUR_READ_ONLY)); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testCreateStatement3() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| int[] rsTypes = new int[] |
| {TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE}; |
| |
| int[] rsConcurs = new int[] |
| {CONCUR_READ_ONLY, ResultSet.CONCUR_UPDATABLE}; |
| |
| int[] rsHoldabilities = new int[] |
| {HOLD_CURSORS_OVER_COMMIT, CLOSE_CURSORS_AT_COMMIT}; |
| |
| DatabaseMetaData meta = conn.getMetaData(); |
| |
| for (final int type : rsTypes) { |
| for (final int concur : rsConcurs) { |
| for (final int holdabililty : rsHoldabilities) { |
| if (meta.supportsResultSetConcurrency(type, concur)) { |
| assertEquals(TYPE_FORWARD_ONLY, type); |
| assertEquals(CONCUR_READ_ONLY, concur); |
| |
| try (Statement stmt = conn.createStatement(type, concur, holdabililty)) { |
| assertNotNull(stmt); |
| |
| assertEquals(type, stmt.getResultSetType()); |
| assertEquals(concur, stmt.getResultSetConcurrency()); |
| assertEquals(holdabililty, stmt.getResultSetHoldability()); |
| } |
| |
| continue; |
| } |
| |
| assertThrows(SQLFeatureNotSupportedException.class, |
| () -> conn.createStatement(type, concur, holdabililty)); |
| } |
| } |
| } |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.createStatement(TYPE_FORWARD_ONLY, CONCUR_READ_ONLY, HOLD_CURSORS_OVER_COMMIT)); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testPrepareStatement() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // null query text |
| assertThrows( |
| NullPointerException.class, |
| () -> conn.prepareStatement(null) |
| ); |
| |
| final String sqlText = "select * from test where param = ?"; |
| |
| try (PreparedStatement prepared = conn.prepareStatement(sqlText)) { |
| assertNotNull(prepared); |
| } |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.prepareStatement(sqlText)); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testPrepareStatement3() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String sqlText = "select * from test where param = ?"; |
| |
| int[] rsTypes = new int[] |
| {TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE}; |
| |
| int[] rsConcurs = new int[] |
| {CONCUR_READ_ONLY, ResultSet.CONCUR_UPDATABLE}; |
| |
| DatabaseMetaData meta = conn.getMetaData(); |
| |
| for (final int type : rsTypes) { |
| for (final int concur : rsConcurs) { |
| if (meta.supportsResultSetConcurrency(type, concur)) { |
| assertEquals(TYPE_FORWARD_ONLY, type); |
| assertEquals(CONCUR_READ_ONLY, concur); |
| |
| // null query text |
| assertThrows( |
| SQLException.class, |
| () -> conn.prepareStatement(null, type, concur), |
| "SQL string cannot be null" |
| ); |
| |
| continue; |
| } |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareStatement(sqlText, type, concur) |
| ); |
| } |
| } |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.prepareStatement(sqlText, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY)); |
| |
| conn.close(); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testPrepareStatement4() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String sqlText = "select * from test where param = ?"; |
| |
| int[] rsTypes = new int[] |
| {TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE}; |
| |
| int[] rsConcurs = new int[] |
| {CONCUR_READ_ONLY, ResultSet.CONCUR_UPDATABLE}; |
| |
| int[] rsHoldabilities = new int[] |
| {HOLD_CURSORS_OVER_COMMIT, CLOSE_CURSORS_AT_COMMIT}; |
| |
| DatabaseMetaData meta = conn.getMetaData(); |
| |
| for (final int type : rsTypes) { |
| for (final int concur : rsConcurs) { |
| for (final int holdabililty : rsHoldabilities) { |
| if (meta.supportsResultSetConcurrency(type, concur)) { |
| assertEquals(TYPE_FORWARD_ONLY, type); |
| assertEquals(CONCUR_READ_ONLY, concur); |
| |
| // null query text |
| assertThrows( |
| SQLException.class, |
| () -> conn.prepareStatement(null, type, concur, holdabililty), |
| "SQL string cannot be null" |
| ); |
| |
| continue; |
| } |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareStatement(sqlText, type, concur, holdabililty) |
| ); |
| } |
| } |
| } |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed( |
| () -> conn.prepareStatement(sqlText, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY, HOLD_CURSORS_OVER_COMMIT) |
| ); |
| |
| conn.close(); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testPrepareStatementAutoGeneratedKeysUnsupported() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String sqlText = "insert into test (val) values (?)"; |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareStatement(sqlText, RETURN_GENERATED_KEYS), |
| "Auto generated keys are not supported." |
| ); |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareStatement(sqlText, NO_GENERATED_KEYS), |
| "Auto generated keys are not supported." |
| ); |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareStatement(sqlText, new int[] {1}), |
| "Auto generated keys are not supported." |
| ); |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareStatement(sqlText, new String[] {"ID"}), |
| "Auto generated keys are not supported." |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testPrepareCallUnsupported() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String sqlText = "exec test()"; |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareCall(sqlText), |
| "Callable functions are not supported." |
| ); |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareCall(sqlText, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY), |
| "Callable functions are not supported." |
| ); |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.prepareCall(sqlText, TYPE_FORWARD_ONLY, CONCUR_READ_ONLY, HOLD_CURSORS_OVER_COMMIT), |
| "Callable functions are not supported." |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testNativeSql() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // null query text |
| assertThrows( |
| NullPointerException.class, |
| () -> conn.nativeSQL(null) |
| ); |
| |
| final String sqlText = "select * from test"; |
| |
| assertEquals(sqlText, conn.nativeSQL(sqlText)); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.nativeSQL(sqlText)); |
| } |
| } |
| |
| /** |
| * TODO Enable when transactions are ready. |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testGetSetAutoCommit() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| boolean ac0 = conn.getAutoCommit(); |
| |
| conn.setAutoCommit(!ac0); |
| // assert no exception |
| |
| conn.setAutoCommit(ac0); |
| // assert no exception |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.setAutoCommit(ac0)); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCommit() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Should not be called in auto-commit mode |
| assertThrows( |
| SQLException.class, |
| () -> conn.commit(), |
| "Transaction cannot be committed explicitly in auto-commit mode" |
| ); |
| |
| assertTrue(conn.getAutoCommit()); |
| |
| // Should not be called in auto-commit mode |
| assertThrows( |
| SQLException.class, |
| () -> conn.commit(), |
| "Transaction cannot be committed explicitly in auto-commit mode." |
| ); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.commit()); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testRollback() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Should not be called in auto-commit mode |
| assertThrows( |
| SQLException.class, |
| () -> conn.rollback(), |
| "Transaction cannot be rolled back explicitly in auto-commit mode." |
| ); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.rollback()); |
| } |
| } |
| |
| /** |
| * Enable when transactions are ready. |
| * |
| * @throws Exception if failed. |
| */ |
| @Test |
| @Disabled |
| public void testBeginFailsWhenMvccIsDisabled() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| conn.createStatement().execute("BEGIN"); |
| |
| fail("Exception is expected"); |
| } |
| catch (SQLException e) { |
| assertEquals(TRANSACTION_STATE_EXCEPTION, e.getSQLState()); |
| } |
| } |
| |
| /** |
| * Enable when transactions are ready. |
| * |
| * @throws Exception if failed. |
| */ |
| @Test |
| @Disabled |
| public void testCommitIgnoredWhenMvccIsDisabled() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| conn.setAutoCommit(false); |
| conn.createStatement().execute("COMMIT"); |
| |
| conn.commit(); |
| } |
| // assert no exception |
| } |
| |
| /** |
| * Enable when transactions are ready. |
| * |
| * @throws Exception if failed. |
| */ |
| @Test |
| @Disabled |
| public void testRollbackIgnoredWhenMvccIsDisabled() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| conn.setAutoCommit(false); |
| |
| conn.createStatement().execute("ROLLBACK"); |
| |
| conn.rollback(); |
| } |
| // assert no exception |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testGetMetaData() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| DatabaseMetaData meta = conn.getMetaData(); |
| |
| assertNotNull(meta); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.getMetaData()); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetReadOnly() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.setReadOnly(true)); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.isReadOnly()); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testGetSetCatalog() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertFalse(conn.getMetaData().supportsCatalogsInDataManipulation()); |
| |
| assertNull(conn.getCatalog()); |
| |
| conn.setCatalog("catalog"); |
| |
| assertNull(conn.getCatalog()); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.setCatalog("")); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.getCatalog()); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetTransactionIsolation() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Invalid parameter value |
| assertThrows( |
| SQLException.class, |
| () -> conn.setTransactionIsolation(-1), |
| "Invalid transaction isolation level" |
| ); |
| |
| // default level |
| assertEquals(TRANSACTION_NONE, conn.getTransactionIsolation()); |
| |
| int[] levels = { |
| TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED, |
| TRANSACTION_REPEATABLE_READ, TRANSACTION_SERIALIZABLE}; |
| |
| for (int level : levels) { |
| conn.setTransactionIsolation(level); |
| assertEquals(level, conn.getTransactionIsolation()); |
| } |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| |
| checkConnectionClosed(() -> conn.getTransactionIsolation()); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.setTransactionIsolation(TRANSACTION_SERIALIZABLE)); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testClearGetWarnings() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| SQLWarning warn = conn.getWarnings(); |
| |
| assertNull(warn); |
| |
| conn.clearWarnings(); |
| |
| warn = conn.getWarnings(); |
| |
| assertNull(warn); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.getWarnings()); |
| |
| // Exception when called on closed connection |
| checkConnectionClosed(() -> conn.clearWarnings()); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetTypeMap() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.getTypeMap(), |
| "Types mapping is not supported" |
| ); |
| |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.setTypeMap(new HashMap<String, Class<?>>()), |
| "Types mapping is not supported" |
| ); |
| |
| conn.close(); |
| |
| // Exception when called on closed connection |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.getTypeMap(), |
| "Connection is closed" |
| ); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.setTypeMap(new HashMap<String, Class<?>>()), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testGetSetHoldability() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // default value |
| assertEquals(conn.getMetaData().getResultSetHoldability(), conn.getHoldability()); |
| |
| assertEquals(HOLD_CURSORS_OVER_COMMIT, conn.getHoldability()); |
| |
| conn.setHoldability(CLOSE_CURSORS_AT_COMMIT); |
| |
| assertEquals(CLOSE_CURSORS_AT_COMMIT, conn.getHoldability()); |
| |
| // Invalid constant |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.setHoldability(-1), |
| "Invalid result set holdability value" |
| ); |
| |
| conn.close(); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.getHoldability(), |
| "Connection is closed" |
| ); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.setHoldability(HOLD_CURSORS_OVER_COMMIT), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testSetSavepoint() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertFalse(conn.getMetaData().supportsSavepoints()); |
| |
| // Disallowed in auto-commit mode |
| assertThrows( |
| SQLException.class, |
| () -> conn.setSavepoint(), |
| "Savepoint cannot be set in auto-commit mode" |
| ); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.setSavepoint()); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testSetSavepointName() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertFalse(conn.getMetaData().supportsSavepoints()); |
| |
| // Invalid arg |
| assertThrows( |
| SQLException.class, |
| () -> conn.setSavepoint(null), |
| "Savepoint name cannot be null" |
| ); |
| |
| final String name = "savepoint"; |
| |
| // Disallowed in auto-commit mode |
| assertThrows( |
| SQLException.class, |
| () -> conn.setSavepoint(name), |
| "Savepoint cannot be set in auto-commit mode" |
| ); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.setSavepoint(name)); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testRollbackSavePoint() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertFalse(conn.getMetaData().supportsSavepoints()); |
| |
| // Invalid arg |
| assertThrows( |
| SQLException.class, |
| () -> conn.rollback(null), |
| "Invalid savepoint" |
| ); |
| |
| final Savepoint savepoint = getFakeSavepoint(); |
| |
| // Disallowed in auto-commit mode |
| assertThrows( |
| SQLException.class, |
| () -> conn.rollback(savepoint), |
| "Auto-commit mode" |
| ); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.rollback(savepoint)); |
| } |
| } |
| |
| /** |
| * TODO IGNITE-15188 |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| @Disabled |
| public void testReleaseSavepoint() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertFalse(conn.getMetaData().supportsSavepoints()); |
| |
| // Invalid arg |
| assertThrows( |
| SQLException.class, |
| () -> conn.releaseSavepoint(null), |
| "Savepoint cannot be null" |
| ); |
| |
| final Savepoint savepoint = getFakeSavepoint(); |
| |
| checkNotSupported(() -> conn.releaseSavepoint(savepoint)); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.releaseSavepoint(savepoint)); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateClob() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Unsupported |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.createClob(), |
| "SQL-specific types are not supported" |
| ); |
| |
| conn.close(); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.createClob(), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateBlob() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Unsupported |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.createBlob(), |
| "SQL-specific types are not supported" |
| ); |
| |
| conn.close(); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.createBlob(), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateNClob() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Unsupported |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.createNClob(), |
| "SQL-specific types are not supported" |
| ); |
| |
| conn.close(); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.createNClob(), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateSQLXML() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Unsupported |
| assertThrows( |
| SQLFeatureNotSupportedException.class, |
| () -> conn.createSQLXML(), |
| "SQL-specific types are not supported" |
| ); |
| |
| conn.close(); |
| |
| assertThrows( |
| SQLException.class, |
| () -> conn.createSQLXML(), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetClientInfoPair() throws Exception { |
| // fail("https://issues.apache.org/jira/browse/IGNITE-5425"); |
| |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String name = "ApplicationName"; |
| final String val = "SelfTest"; |
| |
| assertNull(conn.getWarnings()); |
| |
| conn.setClientInfo(name, val); |
| |
| assertNull(conn.getClientInfo(val)); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.getClientInfo(name)); |
| |
| assertThrows( |
| SQLClientInfoException.class, |
| () -> conn.setClientInfo(name, val), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetClientInfoProperties() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String name = "ApplicationName"; |
| final String val = "SelfTest"; |
| |
| final Properties props = new Properties(); |
| props.setProperty(name, val); |
| |
| conn.setClientInfo(props); |
| |
| Properties propsResult = conn.getClientInfo(); |
| |
| assertNotNull(propsResult); |
| |
| assertTrue(propsResult.isEmpty()); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.getClientInfo()); |
| |
| assertThrows( |
| SQLClientInfoException.class, |
| () -> conn.setClientInfo(props), |
| "Connection is closed" |
| ); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateArrayOf() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| final String typeName = "varchar"; |
| |
| final String[] elements = new String[] {"apple", "pear"}; |
| |
| // Invalid typename |
| assertThrows( |
| SQLException.class, |
| () -> conn.createArrayOf(null, null), |
| "Type name cannot be null" |
| ); |
| |
| // Unsupported |
| |
| checkNotSupported(() -> conn.createArrayOf(typeName, elements)); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.createArrayOf(typeName, elements)); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateStruct() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // Invalid typename |
| assertThrows( |
| SQLException.class, |
| () -> conn.createStruct(null, null), |
| "Type name cannot be null" |
| ); |
| |
| final String typeName = "employee"; |
| |
| final Object[] attrs = new Object[] {100, "Tom"}; |
| |
| checkNotSupported(() -> conn.createStruct(typeName, attrs)); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.createStruct(typeName, attrs)); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetSchema() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| assertEquals("PUBLIC", conn.getSchema()); |
| |
| final String schema = "test"; |
| |
| conn.setSchema(schema); |
| |
| assertEquals(schema.toUpperCase(), conn.getSchema()); |
| |
| conn.setSchema('"' + schema + '"'); |
| |
| assertEquals(schema, conn.getSchema()); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.setSchema(schema)); |
| |
| checkConnectionClosed(() -> conn.getSchema()); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testAbort() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| //Invalid executor |
| assertThrows( |
| SQLException.class, |
| () -> conn.abort(null), |
| "Executor cannot be null" |
| ); |
| |
| final Executor executor = Executors.newFixedThreadPool(1); |
| |
| conn.abort(executor); |
| |
| assertTrue(conn.isClosed()); |
| } |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testGetSetNetworkTimeout() throws Exception { |
| try (Connection conn = DriverManager.getConnection(URL)) { |
| // default |
| assertEquals(0, conn.getNetworkTimeout()); |
| |
| final Executor executor = Executors.newFixedThreadPool(1); |
| |
| final int timeout = 1000; |
| |
| //Invalid timeout |
| assertThrows( |
| SQLException.class, |
| () -> conn.setNetworkTimeout(executor, -1), |
| "Network timeout cannot be negative" |
| ); |
| |
| conn.setNetworkTimeout(executor, timeout); |
| |
| assertEquals(timeout, conn.getNetworkTimeout()); |
| |
| conn.close(); |
| |
| checkConnectionClosed(() -> conn.getNetworkTimeout()); |
| |
| checkConnectionClosed(() -> conn.setNetworkTimeout(executor, timeout)); |
| } |
| } |
| |
| /** |
| * @return Savepoint. |
| */ |
| private Savepoint getFakeSavepoint() { |
| return new Savepoint() { |
| @Override public int getSavepointId() throws SQLException { |
| return 100; |
| } |
| |
| @Override public String getSavepointName() { |
| return "savepoint"; |
| } |
| }; |
| } |
| } |