You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/05/30 01:07:11 UTC
svn commit: r1487668 - in /jena/Experimental/jena-jdbc/jena-jdbc-core/src:
main/java/org/apache/jena/jdbc/results/
test/java/org/apache/jena/jdbc/results/
Author: rvesse
Date: Wed May 29 23:07:11 2013
New Revision: 1487668
URL: http://svn.apache.org/r1487668
Log:
Expand test coverage for scrollable result sets, fix various implementation bugs
Modified:
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedResults.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedSelectResults.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/results/AbstractResultSetTests.java
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedResults.java?rev=1487668&r1=1487667&r2=1487668&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedResults.java Wed May 29 23:07:11 2013
@@ -26,8 +26,8 @@ import org.apache.jena.jdbc.statements.J
import com.hp.hpl.jena.query.QueryExecution;
/**
- * Represents a set of streamed results backed by some {@link QueryExecution},
- * streamed results are considered to be forward only
+ * Represents a set of materialized results backed by some {@link QueryExecution},
+ * materialized results permit scrolling but are not sensitive to changes in the underlying data
*
* @param <T>
* Type of the underlying result rows
@@ -125,13 +125,13 @@ public abstract class MaterializedResult
// Try and move to before first row
this.beforeFirst();
return false;
- } else if (row >= this.getTotalRows()) {
+ } else if (row > this.getTotalRows()) {
// Try and move to after last row
this.afterLast();
return false;
} else if (row <= 0) {
// Move to a row relative to the end of the result set
- int destRow = this.getTotalRows() + row;
+ int destRow = this.getTotalRows() + 1 + row;
if (destRow < 1) {
// Move to before first
this.beforeFirst();
@@ -182,6 +182,10 @@ public abstract class MaterializedResult
public final void beforeFirst() throws SQLException {
if (this.isClosed())
throw new SQLException("Result Set is closed");
+
+ // Are we after the last row? If so reset current row or movePrevious() may break
+ if (this.isAfterLast())
+ this.currRow = this.getTotalRows();
// Move to start of results if necessary
while (this.hasPrevious()) {
@@ -212,13 +216,29 @@ public abstract class MaterializedResult
// Are we already at the first row?
if (this.currRow == 1)
return true;
-
- // Otherwise move backwards to it
- while (this.hasPrevious()) {
- this.currItem = this.movePrevious();
- this.currRow--;
+
+ // Are we after the last row? If so reset current row or movePrevious() may break
+ if (this.isAfterLast())
+ this.currRow = this.getTotalRows();
+
+ // Before first row?
+ if (this.isBeforeFirst()) {
+ // Need to move forwards to first row
+ if (this.hasNext()) {
+ this.currItem = this.moveNext();
+ this.currRow = 1;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // Otherwise move backwards to it
+ while (this.hasPrevious()) {
+ this.currItem = this.movePrevious();
+ this.currRow--;
+ }
+ return true;
}
- return true;
}
@Override
@@ -274,22 +294,36 @@ public abstract class MaterializedResult
@Override
public final boolean last() throws SQLException {
if (this.isClosed())
- throw new SQLException("Jena JDBC Result Sets are forward-only");
+ throw new SQLException("Result Set is closed");
// If no rows this should always return false
if (this.getTotalRows() == 0)
return false;
-
+
// Are we already at the last row?
if (this.currRow == this.getTotalRows())
return true;
- // Otherwise move forwards to the last row
- while (this.hasNext()) {
- this.currItem = this.moveNext();
- this.currRow++;
+ // Are we after the last row?
+ if (this.isAfterLast()) {
+ this.currRow = this.getTotalRows();
+
+ // Move backwards to last row
+ if (this.hasPrevious()) {
+ this.currItem = this.movePrevious();
+ this.currRow = this.getTotalRows();
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // Otherwise move forwards to the last row
+ while (this.hasNext()) {
+ this.currItem = this.moveNext();
+ this.currRow++;
+ }
+ return true;
}
- return true;
}
@@ -309,7 +343,7 @@ public abstract class MaterializedResult
}
}
}
-
+
@Override
public final boolean previous() throws SQLException {
if (this.isClosed()) {
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedSelectResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedSelectResults.java?rev=1487668&r1=1487667&r2=1487668&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedSelectResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/MaterializedSelectResults.java Wed May 29 23:07:11 2013
@@ -42,6 +42,7 @@ public class MaterializedSelectResults e
private ResultSetRewindable innerResults;
private Stack<Binding> previousResults = new Stack<Binding>();
+ private Stack<Binding> nextResults = new Stack<Binding>();
private List<String> columns;
private SelectResultsMetadata metadata;
@@ -126,7 +127,7 @@ public class MaterializedSelectResults e
protected boolean hasNext() throws SQLException {
// No null check here because superclass will not call us after we are
// closed and set to null
- return this.innerResults.hasNext();
+ return !this.nextResults.isEmpty() || this.innerResults.hasNext();
}
/**
@@ -136,7 +137,14 @@ public class MaterializedSelectResults e
protected Binding moveNext() throws SQLException {
// No null check here because superclass will not call us after we are
// closed and set to null
- this.previousResults.push(this.innerResults.nextBinding());
+
+ if (this.nextResults.isEmpty()) {
+ // Need to go to underlying result set
+ this.previousResults.push(this.innerResults.nextBinding());
+ } else {
+ // Continue through results we've previously seen and moved backwards from
+ this.previousResults.push(this.nextResults.pop());
+ }
return this.previousResults.peek();
}
@@ -147,9 +155,10 @@ public class MaterializedSelectResults e
@Override
protected Binding movePrevious() throws SQLException {
- return this.previousResults.pop();
+ this.nextResults.push(this.previousResults.pop());
+ return this.nextResults.peek();
}
-
+
@Override
protected int getTotalRows() {
return this.innerResults.size();
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/results/AbstractResultSetTests.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/results/AbstractResultSetTests.java?rev=1487668&r1=1487667&r2=1487668&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/results/AbstractResultSetTests.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/test/java/org/apache/jena/jdbc/results/AbstractResultSetTests.java Wed May 29 23:07:11 2013
@@ -982,4 +982,323 @@ public abstract class AbstractResultSetT
rset.close();
Assert.assertTrue(rset.isClosed());
}
+
+ /**
+ * Tests movement through SELECT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_select_movement_07() throws SQLException {
+ ResultSet rset = this.createResults(ds, "SELECT * { ?s ?p ?o . } LIMIT 5", ResultSet.TYPE_SCROLL_INSENSITIVE);
+ Assert.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move to various absolute rows
+ Assert.assertTrue(rset.absolute(1));
+ Assert.assertTrue(rset.absolute(1));
+ Assert.assertTrue(rset.absolute(3));
+ Assert.assertTrue(rset.absolute(2));
+ Assert.assertTrue(rset.absolute(4));
+ Assert.assertTrue(rset.absolute(5));
+ Assert.assertTrue(rset.absolute(-1));
+ Assert.assertTrue(rset.absolute(-2));
+ Assert.assertTrue(rset.absolute(-3));
+ Assert.assertTrue(rset.absolute(-4));
+ Assert.assertTrue(rset.absolute(-5));
+
+ // 0 is treated as moving to before first
+ Assert.assertFalse(rset.absolute(0));
+ Assert.assertTrue(rset.isBeforeFirst());
+
+ // 1 is treated as moving to first row
+ Assert.assertTrue(rset.absolute(1));
+ Assert.assertTrue(rset.isFirst());
+
+ // -1 is treated as moving to last row
+ Assert.assertTrue(rset.absolute(-1));
+ Assert.assertTrue(rset.isLast());
+
+ // Moving to a row beyond end positions us after last and returns false
+ Assert.assertFalse(rset.absolute(6));
+ Assert.assertTrue(rset.isAfterLast());
+
+ // Moving to a row before start positions us before first and returns false
+ Assert.assertFalse(rset.absolute(-6));
+ Assert.assertTrue(rset.isBeforeFirst());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through SELECT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_select_movement_08() throws SQLException {
+ ResultSet rset = this.createResults(ds, "SELECT * { ?s ?p ?o . } LIMIT 2", ResultSet.TYPE_SCROLL_INSENSITIVE);
+ Assert.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move forwards to after last row
+ rset.afterLast();
+ Assert.assertTrue(rset.isAfterLast());
+
+ // Can move backwards to last row
+ Assert.assertTrue(rset.last());
+ Assert.assertTrue(rset.isLast());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_01() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 1", ResultSet.TYPE_FORWARD_ONLY);
+ Assert.assertEquals(ResultSet.TYPE_FORWARD_ONLY, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Expect exactly one row we can move to
+ Assert.assertTrue(rset.next());
+ Assert.assertFalse(rset.isAfterLast());
+ Assert.assertTrue(rset.isLast());
+ Assert.assertFalse(rset.next());
+
+ Assert.assertTrue(rset.isAfterLast());
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_02() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 1", ResultSet.TYPE_FORWARD_ONLY);
+ Assert.assertEquals(ResultSet.TYPE_FORWARD_ONLY, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Expect exactly one row we can move to
+ Assert.assertTrue(rset.next());
+ Assert.assertFalse(rset.isAfterLast());
+ Assert.assertTrue(rset.isLast());
+ Assert.assertFalse(rset.next());
+
+ // Attempting to move backwards in a forwards only result set should result in an error
+ try {
+ rset.beforeFirst();
+ Assert.fail("Should not be permitted to move backwards in a FORWARD_ONLY result set");
+ } catch (SQLException e) {
+ // Expected
+ } finally {
+
+ Assert.assertTrue(rset.isAfterLast());
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_03() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 1", ResultSet.TYPE_FORWARD_ONLY);
+ Assert.assertEquals(ResultSet.TYPE_FORWARD_ONLY, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move forwards to last row
+ Assert.assertTrue(rset.last());
+ Assert.assertFalse(rset.isAfterLast());
+ Assert.assertTrue(rset.isLast());
+ Assert.assertFalse(rset.next());
+
+ Assert.assertTrue(rset.isAfterLast());
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_04() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 1", ResultSet.TYPE_FORWARD_ONLY);
+ Assert.assertEquals(ResultSet.TYPE_FORWARD_ONLY, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move forwards to after last row
+ rset.afterLast();
+ Assert.assertTrue(rset.isAfterLast());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_05() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 1", ResultSet.TYPE_SCROLL_INSENSITIVE);
+ Assert.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Expect exactly one row we can move to
+ Assert.assertTrue(rset.next());
+ Assert.assertFalse(rset.isAfterLast());
+ Assert.assertTrue(rset.isLast());
+ Assert.assertFalse(rset.next());
+
+ // Attempting to move backwards in a scrollable result set should result set should be fine
+ rset.beforeFirst();
+ Assert.assertTrue(rset.isBeforeFirst());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_06() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 2", ResultSet.TYPE_SCROLL_INSENSITIVE);
+ Assert.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move forwards to first row
+ Assert.assertTrue(rset.next());
+ Assert.assertTrue(rset.isFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Then can move forwards to second row
+ Assert.assertTrue(rset.next());
+ Assert.assertTrue(rset.isLast());
+
+ // Can move backwards to previous row
+ Assert.assertTrue(rset.previous());
+ Assert.assertTrue(rset.isFirst());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_07() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 5", ResultSet.TYPE_SCROLL_INSENSITIVE);
+ Assert.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move to various absolute rows
+ Assert.assertTrue(rset.absolute(1));
+ Assert.assertTrue(rset.absolute(1));
+ Assert.assertTrue(rset.absolute(3));
+ Assert.assertTrue(rset.absolute(2));
+ Assert.assertTrue(rset.absolute(4));
+ Assert.assertTrue(rset.absolute(5));
+ Assert.assertTrue(rset.absolute(-1));
+ Assert.assertTrue(rset.absolute(-2));
+ Assert.assertTrue(rset.absolute(-3));
+ Assert.assertTrue(rset.absolute(-4));
+ Assert.assertTrue(rset.absolute(-5));
+
+ // 0 is treated as moving to before first
+ Assert.assertFalse(rset.absolute(0));
+ Assert.assertTrue(rset.isBeforeFirst());
+
+ // 1 is treated as moving to first row
+ Assert.assertTrue(rset.absolute(1));
+ Assert.assertTrue(rset.isFirst());
+
+ // -1 is treated as moving to last row
+ Assert.assertTrue(rset.absolute(-1));
+ Assert.assertTrue(rset.isLast());
+
+ // Moving to a row beyond end positions us after last and returns false
+ Assert.assertFalse(rset.absolute(6));
+ Assert.assertTrue(rset.isAfterLast());
+
+ // Moving to a row before start positions us before first and returns false
+ Assert.assertFalse(rset.absolute(-6));
+ Assert.assertTrue(rset.isBeforeFirst());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
+
+ /**
+ * Tests movement through CONSTRUCT results
+ *
+ * @throws SQLException
+ */
+ @Test
+ public void test_results_construct_movement_08() throws SQLException {
+ ResultSet rset = this.createResults(ds, "CONSTRUCT WHERE { ?s ?p ?o . } LIMIT 2", ResultSet.TYPE_SCROLL_INSENSITIVE);
+ Assert.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rset.getType());
+ Assert.assertNotNull(rset);
+ Assert.assertFalse(rset.isClosed());
+ Assert.assertTrue(rset.isBeforeFirst());
+ Assert.assertFalse(rset.isLast());
+
+ // Can move forwards to after last row
+ rset.afterLast();
+ Assert.assertTrue(rset.isAfterLast());
+
+ // Can move backwards to last row
+ Assert.assertTrue(rset.last());
+ Assert.assertTrue(rset.isLast());
+
+ rset.close();
+ Assert.assertTrue(rset.isClosed());
+ }
}