Permalink
Browse files

[jdbc-driver] Add connection property `acolyte.resultSet.initOnFirstR…

…ow` to make Acolyte ResultSet iterates rows as degraded Oracle one.
  • Loading branch information...
cchantep
cchantep committed Jan 9, 2015
1 parent 9499203 commit 42a9ddfdccc65c175edf7d22cd677592843af0bf
@@ -9,7 +9,6 @@
import java.sql.BatchUpdateException;
import java.sql.SQLException;
import java.sql.SQLWarning;
-import java.sql.Connection;
import java.sql.ResultSet;
import org.apache.commons.lang3.tuple.ImmutableTriple;
@@ -112,7 +111,7 @@
/**
* Owner connection
*/
- protected final acolyte.jdbc.Connection connection;
+ final acolyte.jdbc.Connection connection;
// --- Constructors ---
@@ -16,7 +16,6 @@
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
-import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Array;
import java.sql.Date;
@@ -236,7 +235,7 @@ public NilRowList withNullable(final int columnIndex,
final List<Class<?>> columnClasses;
final Map<String,Integer> columnLabels;
final List<R> rows;
- final Statement statement;
+ final AbstractStatement statement;
final SQLWarning warning;
private Object last;
@@ -254,7 +253,7 @@ protected RowResultSet(final List<R> rows) {
this.columnClasses = getColumnClasses();
this.columnLabels = getColumnLabels();
this.rows = Collections.unmodifiableList(rows);
- this.statement = null; // dettached
+ this.statement = null; // detached
this.warning = null;
this.last = null;
super.fetchSize = rows.size();
@@ -265,7 +264,7 @@ protected RowResultSet(final List<R> rows) {
*/
private RowResultSet(final List<R> rows,
final Object last,
- final Statement statement,
+ final AbstractStatement statement,
final SQLWarning warning) {
if (rows == null) {
@@ -281,14 +280,21 @@ private RowResultSet(final List<R> rows,
this.warning = warning;
this.last = null;
super.fetchSize = rows.size();
+
+ if (this.statement != null && super.fetchSize > 0 &&
+ "true".equals(this.statement.connection.getProperties().
+ get("acolyte.resultSet.initOnFirstRow"))) {
+ // Initially move to first row, contrary to JDBC specs
+ this.row = 1;
+ }
} // end of <init>
// ---
/**
* Returns updated resultset, attached with given |statement|.
*/
- public RowResultSet<R> withStatement(final Statement statement) {
+ public RowResultSet<R> withStatement(final AbstractStatement statement) {
return new RowResultSet<R>(this.rows, this.last,
statement, this.warning);
@@ -350,7 +356,7 @@ public int hashCode() {
/**
* {@inheritDoc}
*/
- public Statement getStatement() {
+ public AbstractStatement getStatement() {
return this.statement;
} // end of getStatement
@@ -21,6 +21,7 @@ import org.apache.commons.io.IOUtils.contentEquals
import acolyte.jdbc.Rows.{ row1, row2 }
import acolyte.jdbc.RowList.{ Column Col }
+import acolyte.jdbc.test.Params
object RowListSpec extends Specification with RowListTest {
"Row list" title
@@ -732,6 +733,33 @@ object RowListSpec extends Specification with RowListTest {
}
+ "be read on first row without `next()` call if option 'acolyte.resultSet.initOnFirstRow' is used" in {
+ val url = "jdbc:acolyte:test"
+ lazy val sh = new StatementHandler {
+ def isQuery(s: String) = true
+ def whenSQLUpdate(s: String, p: Params) = UpdateResult.Nothing
+ def whenSQLQuery(s: String, p: Params) = {
+ RowLists.rowList1(classOf[String]).
+ append("Foo").append("Bar").asResult
+ }
+ }
+ val ch = new ConnectionHandler.Default(sh)
+ val props = new java.util.Properties()
+ props.put("acolyte.resultSet.initOnFirstRow", "true")
+ lazy val con = new acolyte.jdbc.Connection(url, props, ch)
+ lazy val st = con.prepareStatement("SELECT * FROM Test")
+ lazy val rs = {
+ st.execute()
+ st.getResultSet
+ }
+
+ rs.getFetchSize aka "fetch size" must_== 2 and (
+ rs.getObject(1) aka "first row" must_== "Foo") and (
+ rs.next aka "has second row" must beTrue) and (
+ rs.getObject(1) aka "second row" must_== "Bar") and (
+ rs.next aka "has third row" must beFalse)
+ }
+
"be expected one" in {
lazy val rs = (new RowList1.Impl(classOf[Long]).
append(row1(123.toLong))).resultSet
@@ -835,6 +863,33 @@ object RowListSpec extends Specification with RowListTest {
}
+ "be read on first row without `next()` call if option 'acolyte.resultSet.initOnFirstRow' is used" in {
+ val url = "jdbc:acolyte:test"
+ lazy val sh = new StatementHandler {
+ def isQuery(s: String) = true
+ def whenSQLUpdate(s: String, p: Params) = UpdateResult.Nothing
+ def whenSQLQuery(s: String, p: Params) = {
+ RowLists.rowList1(Col(classOf[String], "colStr")).
+ append("Foo").append("Bar").asResult
+ }
+ }
+ val ch = new ConnectionHandler.Default(sh)
+ val props = new java.util.Properties()
+ props.put("acolyte.resultSet.initOnFirstRow", "true")
+ lazy val con = new acolyte.jdbc.Connection(url, props, ch)
+ lazy val st = con.prepareStatement("SELECT * FROM Test")
+ lazy val rs = {
+ st.execute()
+ st.getResultSet
+ }
+
+ rs.getFetchSize aka "fetch size" must_== 2 and (
+ rs.getObject("colStr") aka "first row" must_== "Foo") and (
+ rs.next aka "has second row" must beTrue) and (
+ rs.getObject("colStr") aka "second row" must_== "Bar") and (
+ rs.next aka "has third row" must beFalse)
+ }
+
"be expected one" in {
lazy val rs = (new RowList1.Impl(classOf[Long]).
withLabel(1, "l").append(row1(123.toLong))).resultSet
@@ -117,6 +117,7 @@ Acolyte specific properties are:
- `acolyte.parameter.untypedNull`: If `"true"`, Acolyte fallbacks untyped null from `statement.setObject(p, null)` to null string (default: false).
- `acolyte.batch.continueOnError`: If `"true"`, Acolyte doesn't stop executing batch on statement, but continue processing and finally throw `BatchUpdateException` with update counts of successfully executed elements (see [java.sql.Statement#executeBatch](http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeBatch%28%29)).
+- `acolyte.resultSet.initOnFirstRow`: If `"true"`, Acolyte will degrade JDBC compliance by positioning cursor of result sets initially on the first row, rather than before (as specified by [JDBC ResultSet class](https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#next%28%29). It makes Acolyte behaves has Oracle JDBC driver.
## Query result creation

0 comments on commit 42a9ddf

Please sign in to comment.