blob: 3b1068b7f43abb10c280c7c61a444d3d5273626a [file] [log] [blame]
/*
*
* Derby - Class SURBaseTest
*
* 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.derbyTesting.functionTests.tests.jdbcapi;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.JDBC;
import junit.framework.*;
import java.sql.*;
/**
* Base class for testing Scrollable Updatable ResultSets.
* The setUp() provides a Connection to the database.
*
* Tests of this class needs to be decorated by a DBSetup
* and SURDataModelSetup.
*
*/
abstract public class SURBaseTest extends BaseJDBCTestCase {
/** Creates a new instance of SURBaseTest */
public SURBaseTest(String name) {
super(name);
recordCount = SURDataModelSetup.recordCount;
}
/** Creates a new instance of SURBaseTest*/
public SURBaseTest(String name, int records) {
super(name);
recordCount = records;
}
/**
* Override a connection's default state to ensure it
* is always in autocommit false and repeatable
* read as a starting point.
*/
protected void initializeConnection(Connection conn) throws SQLException {
conn.setAutoCommit(false);
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
}
/**
* Verify the data of a tuple in the ResultSet, based on the data
* that were inserted.
*/
protected void verifyTuple(ResultSet rs) throws SQLException {
int id = rs.getInt(1);
int a = rs.getInt(2);
int b = rs.getInt(3);
int sum = a + id + 17;
println("Reading tuple:(" + id + "," + a + "," + b + ",'" +
rs.getString(4) + "', '"+rs.getString(5)+"'");
assertEquals("Expecting b==id+a+17", sum, b);
}
/**
* Update the current tuple in the ResultSet using updateXXX() and
* updateRow()
*/
protected void updateTuple(ResultSet rs) throws SQLException {
int id = rs.getInt(1);
int a = rs.getInt(2);
int b = rs.getInt(3);
int newA = a*2 +id + 37;
int newB = newA + id + 17;
println("Updating record (" + id + "," + newA + "," + newB + ")");
rs.updateInt(2, newA);
rs.updateInt(3, newB);
rs.updateRow();
}
/**
* Update the current tuple in the ResultSet using positioned update
*/
protected void updateTuplePositioned(ResultSet rs) throws SQLException {
int id = rs.getInt(1);
int a = rs.getInt(2);
int b = rs.getInt(3);
int newA = a*2 +id + 37;
int newB = newA + id + 17;
PreparedStatement ps =
prepareStatement("update T1 set a=?,b=? where current of " +
rs.getCursorName());
ps.setInt(1, newA);
ps.setInt(2, newB);
assertEquals("Expected one tuple to be updated", 1, ps.executeUpdate());
ps.close();
}
/**
* Scroll forward to the end of the ResultSet, and verify tuples while
* scrolling.
*/
protected void scrollForward(ResultSet rs) throws SQLException
{
boolean ignoreCount = rs.getType()==ResultSet.TYPE_FORWARD_ONLY
|| !rs.isBeforeFirst();
int nRecords = 0;
while (rs.next()) {
nRecords++;
verifyTuple(rs);
}
if (!ignoreCount) {
assertEquals("Record Count", recordCount, nRecords);
}
}
/**
* Scroll backward to the beginning of the ResultSet, and verify tuples
* while scrolling.
*/
protected void scrollBackward(ResultSet rs) throws SQLException
{
boolean ignoreCount = rs.getType()==ResultSet.TYPE_FORWARD_ONLY
|| !rs.isAfterLast();
int nRecords = 0;
while (rs.previous()) {
nRecords++;
verifyTuple(rs);
}
if (!ignoreCount) {
assertEquals("Record Count", recordCount, nRecords);
}
}
/**
* Scroll forward and update the tuples using updateXXX() and updateRow()
*/
protected void scrollForwardAndUpdate(ResultSet rs) throws SQLException
{
int nRecords = 0;
boolean ignoreCount = rs.getType()==ResultSet.TYPE_FORWARD_ONLY
|| !rs.isBeforeFirst();
while (rs.next()) {
nRecords++;
verifyTuple(rs);
updateTuple(rs);
}
if (!ignoreCount) {
assertEquals("Record Count", recordCount, nRecords);
}
assertNotNull("rs.getCursorName()", rs.getCursorName());
}
/**
* Scroll forward and do positioned updates.
*/
protected void scrollForwardAndUpdatePositioned(ResultSet rs)
throws SQLException
{
int nRecords = 0;
boolean ignoreCount = rs.getType()==ResultSet.TYPE_FORWARD_ONLY
|| !rs.isBeforeFirst();
while (rs.next()) {
nRecords++;
verifyTuple(rs);
updateTuplePositioned(rs);
}
if (!ignoreCount) {
assertEquals("Record Count", recordCount, nRecords);
}
assertNotNull("rs.getCursorName()", rs.getCursorName());
}
/**
* Scroll backward and update the records using updateXXX() and updateRow()
*/
protected void scrollBackwardAndUpdate(ResultSet rs) throws SQLException
{
int nRecords = 0;
boolean ignoreCount = rs.getType()==ResultSet.TYPE_FORWARD_ONLY
|| !rs.isAfterLast();
while (rs.previous()) {
nRecords++;
verifyTuple(rs);
updateTuple(rs);
}
if (!ignoreCount) {
assertEquals("Record Count", recordCount, nRecords);
}
assertNotNull("rs.getCursorName()", rs.getCursorName());
}
/**
* Scroll backward and update the records using positioned updates.
*/
protected void scrollBackwardAndUpdatePositioned(ResultSet rs)
throws SQLException
{
int nRecords = 0;
boolean ignoreCount = rs.getType()==ResultSet.TYPE_FORWARD_ONLY
|| !rs.isAfterLast();
while (rs.previous()) {
nRecords++;
verifyTuple(rs);
updateTuplePositioned(rs);
}
if (!ignoreCount) {
assertEquals("Record Count", recordCount, nRecords);
}
assertNotNull("rs.getCursorName()", rs.getCursorName());
}
/**
* Assert that update of ResultSet fails with a SQLException
* due to read-only ResultSet.
*/
protected void assertFailOnUpdate(ResultSet rs)
throws SQLException
{
boolean failedCorrect = false;
try {
updateTuple(rs);
} catch (SQLException e) {
failedCorrect = true;
assertEquals("Unexpected SQL state",
RESULTSET_NOT_UPDATABLE_SQL_STATE,
e.getSQLState());
}
assertTrue("Expected cursor to fail on update, since it is read only",
failedCorrect);
}
/**
* Assert that a warning was received
*/
protected void assertWarning(SQLWarning warn, String sqlState)
throws SQLException
{
if (warn!=null || usingEmbedded()) {
assertEquals("Unexpected SQL state",
sqlState,
warn.getSQLState());
} else {
println("Expected warning with SQLState = '" + sqlState +
"', however warning not propagated to client driver");
}
}
final int recordCount;
/**
* Error codes and SQL state
*/
final static String FOR_UPDATE_NOT_PERMITTED_SQL_STATE = "42Y90";
final static String CURSOR_NOT_UPDATABLE_SQL_STATE = "42X23";
final static String RESULTSET_NOT_UPDATABLE_SQL_STATE = "XJ083";
final static String LOCK_TIMEOUT_SQL_STATE = "40XL1";
final static String LOCK_TIMEOUT_EXPRESSION_SQL_STATE = "38000";
final static String INVALID_CURSOR_STATE_NO_CURRENT_ROW = "24000";
final static String CURSOR_OPERATION_CONFLICT = "01001";
final static String QUERY_NOT_QUALIFIED_FOR_UPDATABLE_RESULTSET = "01J06";
final static String CURSOR_NOT_POSITIONED_ON_INSERT_ROW = "XJ086";
}