From 7e95c309538720c5fe9e81532b790268b18d408c Mon Sep 17 00:00:00 2001 From: Kris Jurka Date: Wed, 16 Jun 2004 05:12:13 +0000 Subject: [PATCH] When deleteRow() is called on an updateable ResultSet the ResultSet should be positioned on the previous row. Reported by Bob Messenger and Chris Pesarchick. --- .../jdbc2/AbstractJdbc2ResultSet.java | 120 +++++------ .../test/jdbc2/UpdateableResultTest.java | 197 ++++++++++-------- 2 files changed, 162 insertions(+), 155 deletions(-) diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java index ac55120aa37..6a479e7cd01 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java @@ -9,7 +9,7 @@ * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.25.2.5 2004/04/24 01:54:45 jurka Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.25.2.6 2004/06/16 05:11:44 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -584,6 +584,8 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra deleteStatement.executeUpdate(); rows.removeElementAt(current_row); + current_row--; + moveToCurrentRow(); } @@ -738,22 +740,19 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra public boolean rowDeleted() throws SQLException { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); + return false; } public boolean rowInserted() throws SQLException { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); + return false; } public boolean rowUpdated() throws SQLException { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); + return false; } @@ -938,73 +937,68 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra { throw new PSQLException( "postgresql.updateable.notupdateable" ); } + if (onInsertRow) + throw new PSQLException("postgresql.res.oninsertrow"); - try + if (isBeforeFirst() || isAfterLast()) + return; + + StringBuffer selectSQL = new StringBuffer( "select "); + + final int numColumns = java.lang.reflect.Array.getLength(fields); + + for (int i = 0; i < numColumns; i++ ) { - StringBuffer selectSQL = new StringBuffer( "select "); - final int numColumns = java.lang.reflect.Array.getLength(fields); + selectSQL.append( fields[i].getName() ); - for (int i = 0; i < numColumns; i++ ) + if ( i < numColumns - 1 ) { - selectSQL.append( fields[i].getName() ); - - if ( i < numColumns - 1 ) - { - - selectSQL.append(", "); - } - + selectSQL.append(", "); } - selectSQL.append(" from " ).append(tableName).append(" where "); - - int numKeys = primaryKeys.size(); - - for ( int i = 0; i < numKeys; i++ ) - { - - PrimaryKey primaryKey = ((PrimaryKey) primaryKeys.get(i)); - selectSQL.append(primaryKey.name).append("= ?"); - - if ( i < numKeys - 1 ) - { - selectSQL.append(" and "); - } - } - if ( Driver.logDebug ) - Driver.debug("selecting " + selectSQL.toString()); - selectStatement = ((java.sql.Connection) connection).prepareStatement(selectSQL.toString()); - - - for ( int j = 0, i = 1; j < numKeys; j++, i++) - { - selectStatement.setObject( i, ((PrimaryKey) primaryKeys.get(j)).getValue() ); - } - - AbstractJdbc2ResultSet rs = (AbstractJdbc2ResultSet) selectStatement.executeQuery(); - - if ( rs.first() ) - { - rowBuffer = rs.rowBuffer; - } - - rows.setElementAt( rowBuffer, current_row ); - this_row = rowBuffer; - if ( Driver.logDebug ) - Driver.debug("done updates"); - - rs.close(); - selectStatement.close(); - selectStatement = null; } - catch (Exception e) + selectSQL.append(" from " ).append(tableName).append(" where "); + + int numKeys = primaryKeys.size(); + + for ( int i = 0; i < numKeys; i++ ) { - if ( Driver.logDebug ) - Driver.debug(e.getClass().getName() + e); - throw new SQLException( e.getMessage() ); + + PrimaryKey primaryKey = ((PrimaryKey) primaryKeys.get(i)); + selectSQL.append(primaryKey.name).append("= ?"); + + if ( i < numKeys - 1 ) + { + selectSQL.append(" and "); + } } + if ( Driver.logDebug ) + Driver.debug("selecting " + selectSQL.toString()); + selectStatement = ((java.sql.Connection) connection).prepareStatement(selectSQL.toString()); + + + for ( int j = 0, i = 1; j < numKeys; j++, i++) + { + selectStatement.setObject( i, ((PrimaryKey) primaryKeys.get(j)).getValue() ); + } + + AbstractJdbc2ResultSet rs = (AbstractJdbc2ResultSet) selectStatement.executeQuery(); + + if ( rs.first() ) + { + rowBuffer = rs.rowBuffer; + } + + rows.setElementAt( rowBuffer, current_row ); + this_row = rowBuffer; + if ( Driver.logDebug ) + Driver.debug("done updates"); + + rs.close(); + selectStatement.close(); + selectStatement = null; } diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java index 362f3ace63b..e3a932136a1 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java @@ -42,6 +42,34 @@ public class UpdateableResultTest extends TestCase TestUtil.closeDB(con); } + public void testDeleteRows() throws SQLException + { + Statement st = con.createStatement(); + st.executeUpdate("INSERT INTO second values (2,'two')"); + st.executeUpdate("INSERT INTO second values (3,'three')"); + st.executeUpdate("INSERT INTO second values (4,'four')"); + st.close(); + + st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); + ResultSet rs = st.executeQuery( "select id1,name1 from second order by id1"); + + assertTrue(rs.next()); + assertEquals(1, rs.getInt("id1")); + rs.deleteRow(); + assertTrue(rs.isBeforeFirst()); + + assertTrue(rs.next()); + assertTrue(rs.next()); + assertEquals(3, rs.getInt("id1")); + rs.deleteRow(); + assertEquals(2, rs.getInt("id1")); + + rs.close(); + st.close(); + } + + + public void testCancelRowUpdates() throws Exception { Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); @@ -84,106 +112,91 @@ public class UpdateableResultTest extends TestCase - public void testUpdateable() + public void testUpdateable() throws SQLException { + Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); + ResultSet rs = st.executeQuery( "select * from updateable"); + assertNotNull( rs ); + rs.moveToInsertRow(); + rs.updateInt( 1, 1 ); + rs.updateString( 2, "jake" ); + rs.updateString( 3, "avalue" ); + rs.insertRow(); + rs.first(); + + rs.updateInt( "id", 2 ); + rs.updateString( "name", "dave" ); + rs.updateRow(); + + assertEquals(2, rs.getInt("id")); + assertEquals("dave", rs.getString("name")); + assertEquals("avalue", rs.getString("notselected")); + + rs.deleteRow(); + rs.moveToInsertRow(); + rs.updateInt("id", 3); + rs.updateString("name", "paul"); + + rs.insertRow(); + + try { + rs.refreshRow(); + fail("Can't refresh when on the insert row."); + } catch (SQLException sqle) { } + + assertEquals(3, rs.getInt("id")); + assertEquals("paul", rs.getString("name")); + assertNull(rs.getString("notselected")); + + rs.close(); + + rs = st.executeQuery("select id1, id, name, name1 from updateable, second" ); try { - Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); - ResultSet rs = st.executeQuery( "select * from updateable"); - assertNotNull( rs ); - rs.moveToInsertRow(); - rs.updateInt( 1, 1 ); - rs.updateString( 2, "jake" ); - rs.updateString( 3, "avalue" ); - rs.insertRow(); - rs.first(); - - rs.updateInt( "id", 2 ); - rs.updateString( "name", "dave" ); - rs.updateRow(); - - assertTrue( rs.getInt("id") == 2 ); - assertTrue( rs.getString("name").equals("dave")); - assertTrue( rs.getString("notselected").equals("avalue") ); - - rs.deleteRow(); - rs.moveToInsertRow(); - rs.updateInt("id", 3); - rs.updateString("name", "paul"); - - rs.insertRow(); - rs.refreshRow(); - assertTrue( rs.getInt("id") == 3 ); - assertTrue( rs.getString("name").equals("paul")); - assertTrue( rs.getString("notselected") == null ); - - - rs.close(); - - rs = st.executeQuery("select id1, id, name, name1 from updateable, second" ); - try + while ( rs.next() ) { - while ( rs.next() ) - { - rs.updateInt( "id", 2 ); - rs.updateString( "name", "dave" ); - rs.updateRow(); - } - - - assertTrue( "should not get here, update should fail", false ); - } - catch (SQLException ex) - {} - - try - { - rs = st.executeQuery("select oid,* from updateable"); - if ( rs.first() ) - { - rs.updateInt( "id", 3 ); - rs.updateString( "name", "dave3"); - rs.updateRow(); - assertTrue(rs.getInt("id") == 3 ); - assertTrue(rs.getString("name").equals("dave3")); - - rs.moveToInsertRow(); - rs.updateInt( "id", 4 ); - rs.updateString( "name", "dave4" ); - - rs.insertRow(); - rs.updateInt("id", 5 ); - rs.updateString( "name", "dave5" ); - rs.insertRow(); - - rs.moveToCurrentRow(); - assertTrue(rs.getInt("id") == 3 ); - assertTrue(rs.getString("name").equals("dave3")); - - assertTrue( rs.next() ); - assertTrue(rs.getInt("id") == 4 ); - assertTrue(rs.getString("name").equals("dave4")); - - assertTrue( rs.next() ); - assertTrue(rs.getInt("id") == 5 ); - assertTrue(rs.getString("name").equals("dave5")); - - } - } - catch (SQLException ex) - { - fail(ex.getMessage()); + rs.updateInt( "id", 2 ); + rs.updateString( "name", "dave" ); + rs.updateRow(); } - st.close(); + fail("should not get here, update should fail"); } - catch (Exception ex) - { - ex.printStackTrace(); - fail(ex.getMessage()); - } + catch (SQLException ex) + {} + + rs = st.executeQuery("select oid,* from updateable"); + assertTrue(rs.first()); + rs.updateInt( "id", 3 ); + rs.updateString( "name", "dave3"); + rs.updateRow(); + assertEquals(3, rs.getInt("id")); + assertEquals("dave3", rs.getString("name")); + + rs.moveToInsertRow(); + rs.updateInt( "id", 4 ); + rs.updateString( "name", "dave4" ); + + rs.insertRow(); + rs.updateInt("id", 5 ); + rs.updateString( "name", "dave5" ); + rs.insertRow(); + + rs.moveToCurrentRow(); + assertEquals(3, rs.getInt("id")); + assertEquals("dave3", rs.getString("name")); + + assertTrue( rs.next() ); + assertEquals(4, rs.getInt("id")); + assertEquals("dave4", rs.getString("name")); + + assertTrue( rs.next() ); + assertEquals(5, rs.getInt("id")); + assertEquals("dave5", rs.getString("name")); + + rs.close(); + st.close(); } - }