/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
package org.postgresql.test.jdbc3;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.postgresql.test.TestUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
public class Jdbc3SavepointTest {
private Connection _conn;
@Before
public void setUp() throws Exception {
_conn = TestUtil.openDB();
TestUtil.createTable(_conn, "savepointtable", "id int primary key");
_conn.setAutoCommit(false);
}
@After
public void tearDown() throws SQLException {
_conn.setAutoCommit(true);
TestUtil.dropTable(_conn, "savepointtable");
TestUtil.closeDB(_conn);
}
private boolean hasSavepoints() throws SQLException {
return true;
}
private void addRow(int id) throws SQLException {
PreparedStatement pstmt = _conn.prepareStatement("INSERT INTO savepointtable VALUES (?)");
pstmt.setInt(1, id);
pstmt.executeUpdate();
pstmt.close();
}
private int countRows() throws SQLException {
Statement stmt = _conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM savepointtable");
rs.next();
int count = rs.getInt(1);
rs.close();
return count;
}
@Test
public void testAutoCommitFails() throws SQLException {
if (!hasSavepoints()) {
return;
}
_conn.setAutoCommit(true);
try {
_conn.setSavepoint();
fail("Can't create a savepoint with autocommit.");
} catch (SQLException sqle) {
}
try {
_conn.setSavepoint("spname");
fail("Can't create a savepoint with autocommit.");
} catch (SQLException sqle) {
}
}
@Test
public void testCantMixSavepointTypes() throws SQLException {
if (!hasSavepoints()) {
return;
}
Savepoint namedSavepoint = _conn.setSavepoint("named");
Savepoint unNamedSavepoint = _conn.setSavepoint();
try {
namedSavepoint.getSavepointId();
fail("Can't get id from named savepoint.");
} catch (SQLException sqle) {
}
try {
unNamedSavepoint.getSavepointName();
fail("Can't get name from unnamed savepoint.");
} catch (SQLException sqle) {
}
}
@Test
public void testRollingBackToSavepoints() throws SQLException {
if (!hasSavepoints()) {
return;
}
Savepoint empty = _conn.setSavepoint();
addRow(1);
Savepoint onerow = _conn.setSavepoint("onerow");
addRow(2);
assertEquals(2, countRows());
_conn.rollback(onerow);
assertEquals(1, countRows());
_conn.rollback(empty);
assertEquals(0, countRows());
}
@Test
public void testGlobalRollbackWorks() throws SQLException {
if (!hasSavepoints()) {
return;
}
_conn.setSavepoint();
addRow(1);
_conn.setSavepoint("onerow");
addRow(2);
assertEquals(2, countRows());
_conn.rollback();
assertEquals(0, countRows());
}
@Test
public void testContinueAfterError() throws SQLException {
if (!hasSavepoints()) {
return;
}
addRow(1);
Savepoint savepoint = _conn.setSavepoint();
try {
addRow(1);
fail("Should have thrown duplicate key exception");
} catch (SQLException sqle) {
_conn.rollback(savepoint);
}
assertEquals(1, countRows());
addRow(2);
assertEquals(2, countRows());
}
@Test
public void testReleaseSavepoint() throws SQLException {
if (!hasSavepoints()) {
return;
}
Savepoint savepoint = _conn.setSavepoint("mysavepoint");
_conn.releaseSavepoint(savepoint);
try {
savepoint.getSavepointName();
fail("Can't use savepoint after release.");
} catch (SQLException sqle) {
}
savepoint = _conn.setSavepoint();
_conn.releaseSavepoint(savepoint);
try {
savepoint.getSavepointId();
fail("Can't use savepoint after release.");
} catch (SQLException sqle) {
}
}
@Test
public void testComplicatedSavepointName() throws SQLException {
if (!hasSavepoints()) {
return;
}
Savepoint savepoint = _conn.setSavepoint("name with spaces + \"quotes\"");
_conn.rollback(savepoint);
_conn.releaseSavepoint(savepoint);
}
@Test
public void testRollingBackToInvalidSavepointFails() throws SQLException {
if (!hasSavepoints()) {
return;
}
Savepoint sp1 = _conn.setSavepoint();
Savepoint sp2 = _conn.setSavepoint();
_conn.rollback(sp1);
try {
_conn.rollback(sp2);
fail("Can't rollback to a savepoint that's invalid.");
} catch (SQLException sqle) {
}
}
@Test
public void testRollbackMultipleTimes() throws SQLException {
if (!hasSavepoints()) {
return;
}
addRow(1);
Savepoint savepoint = _conn.setSavepoint();
addRow(2);
_conn.rollback(savepoint);
assertEquals(1, countRows());
_conn.rollback(savepoint);
assertEquals(1, countRows());
addRow(2);
_conn.rollback(savepoint);
assertEquals(1, countRows());
_conn.releaseSavepoint(savepoint);
assertEquals(1, countRows());
}
}