Skip to content

Commit

Permalink
[jdbc-driver] Fix generated keys on update result.
Browse files Browse the repository at this point in the history
  • Loading branch information
cchantep committed May 1, 2014
1 parent 5ced4dc commit 99ac2f1
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 30 deletions.
16 changes: 8 additions & 8 deletions jdbc-driver/src/main/java/acolyte/AbstractStatement.java
Expand Up @@ -31,10 +31,9 @@ abstract class AbstractStatement implements java.sql.Statement {
Collections.unmodifiableList(new ArrayList<Parameter>());

/**
* No generated key
* Empty generated keys
*/
protected static final ResultSet NO_GENERATED_KEY =
RowLists.stringList().resultSet();
protected static final RowList<Row1<String>>.RowResultSet<Row1<String>> EMPTY_GENERATED_KEYS = RowLists.stringList().resultSet();

// --- Properties ---

Expand Down Expand Up @@ -80,9 +79,10 @@ abstract class AbstractStatement implements java.sql.Statement {

/**
* Last generated keys
* see #NO_GENERATED_KEY
* see #EMPTY_GENERATED_KEYS
*/
protected ResultSet generatedKeys = NO_GENERATED_KEY;
protected ResultSet generatedKeys =
EMPTY_GENERATED_KEYS.withStatement(this);

/**
* Max rows
Expand Down Expand Up @@ -156,7 +156,7 @@ public ResultSet executeQuery(final String sql) throws SQLException {
checkClosed();

this.updateCount = -1;
this.generatedKeys = NO_GENERATED_KEY;
this.generatedKeys = EMPTY_GENERATED_KEYS.withStatement(this);

try {
final QueryResult res = this.handler.whenSQLQuery(sql, NO_PARAMS);
Expand Down Expand Up @@ -496,8 +496,8 @@ private ImmutableTriple<Integer,ResultSet,SQLWarning> update(final String sql, f
final SQLWarning w = res.getWarning();
final ResultSet k = (res.generatedKeys == null
|| autoGeneratedKeys == NO_GENERATED_KEYS)
? RowLists.stringList().resultSet()/* empty ResultSet */
: res.generatedKeys.resultSet();
? EMPTY_GENERATED_KEYS.withStatement(this)
: res.generatedKeys.resultSet().withStatement(this);

return ImmutableTriple.of(res.getUpdateCount(), k, w);
} catch (SQLException se) {
Expand Down
4 changes: 3 additions & 1 deletion jdbc-driver/src/main/java/acolyte/CallableStatement.java
Expand Up @@ -57,13 +57,15 @@ public final class CallableStatement
*
* @param connection Owner connection
* @param sql SQL statement
* @param generatedKeys Generated keys flag
* @param handler Statement handler (not null)
*/
protected CallableStatement(final acolyte.Connection connection,
final String sql,
final int generatedKeys,
final StatementHandler handler) {

super(connection, sql, handler);
super(connection, sql, generatedKeys, handler);
} // end of <init>

// ---
Expand Down
16 changes: 8 additions & 8 deletions jdbc-driver/src/main/java/acolyte/Connection.java
Expand Up @@ -147,15 +147,15 @@ public Statement createStatement() throws SQLException {

/**
* {@inheritDoc}
* @see #prepareStatement(String, int)
* @see java.sql.Statement#RETURN_GENERATED_KEYS
*/
public PreparedStatement prepareStatement(final String sql)
throws SQLException {

checkClosed();

return new acolyte.
PreparedStatement(this, sql, this.handler.getStatementHandler());

return prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
} // end of prepareStatement

/**
Expand All @@ -165,7 +165,8 @@ public CallableStatement prepareCall(String sql) throws SQLException {
checkClosed();

return new acolyte.
CallableStatement(this, sql, this.handler.getStatementHandler());
CallableStatement(this, sql, Statement.RETURN_GENERATED_KEYS,
this.handler.getStatementHandler());

} // end of prepareCall

Expand Down Expand Up @@ -535,11 +536,10 @@ public PreparedStatement prepareStatement(final String sql,

checkClosed();

if (autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS) {
throw new SQLFeatureNotSupportedException();
} // end of if
return new acolyte.
PreparedStatement(this, sql, autoGeneratedKeys,
this.handler.getStatementHandler());

return prepareStatement(sql);
} // end of prepareStatement

/**
Expand Down
14 changes: 11 additions & 3 deletions jdbc-driver/src/main/java/acolyte/PreparedStatement.java
Expand Up @@ -103,6 +103,11 @@ public class PreparedStatement
*/
private final boolean query;

/**
* Generated key flag
*/
private final int generatedKeysFlag;

/**
* Parameters
*/
Expand All @@ -121,10 +126,12 @@ public class PreparedStatement
*
* @param connection Owner connection
* @param sql SQL statement
* @param generatedKeys Generated keys flag
* @param handler Statement handler (not null)
*/
protected PreparedStatement(final acolyte.Connection connection,
final String sql,
final int generatedKeys,
final StatementHandler handler) {

super(connection, handler);
Expand All @@ -135,6 +142,7 @@ protected PreparedStatement(final acolyte.Connection connection,

this.sql = sql;
this.query = handler.isQuery(sql);
this.generatedKeysFlag = generatedKeys;
this.batch = new ArrayList<ImmutablePair<String,TreeMap<Integer,Parameter>>>();
} // end of <init>

Expand Down Expand Up @@ -168,7 +176,7 @@ public ResultSet executeQuery() throws SQLException {

this.updateCount = -1;
this.warning = res.getWarning();
this.generatedKeys = NO_GENERATED_KEY;
this.generatedKeys = EMPTY_GENERATED_KEYS.withStatement(this);

return (this.result =
res.getRowList().resultSet().withStatement(this));
Expand Down Expand Up @@ -225,8 +233,8 @@ private ImmutableTriple<Integer,ResultSet,SQLWarning> update(final TreeMap<Integ
final UpdateResult res = this.handler.whenSQLUpdate(sql, params);
final SQLWarning w = res.getWarning();
final ResultSet k = (res.generatedKeys == null)
? RowLists.stringList().resultSet()/* empty ResultSet */
: res.generatedKeys.resultSet();
? EMPTY_GENERATED_KEYS.withStatement(this)
: res.generatedKeys.resultSet().withStatement(this);

return ImmutableTriple.of(res.getUpdateCount(), k, w);
} catch (SQLException se) {
Expand Down
1 change: 1 addition & 0 deletions jdbc-driver/src/main/java/acolyte/RowList.java
Expand Up @@ -263,6 +263,7 @@ private RowResultSet(final List<R> rows,
this.columnClasses = getColumnClasses();
this.columnLabels = getColumnLabels();
this.rows = Collections.unmodifiableList(rows);

this.statement = statement;
this.last = null;
super.fetchSize = rows.size();
Expand Down
Expand Up @@ -309,6 +309,6 @@ object CallableStatementSpec
}
}

override def statement(c: Connection = defaultCon, s: String = "TEST", h: StatementHandler = defaultHandler.getStatementHandler) = new CallableStatement(c, s, h)
override def statement(c: Connection = defaultCon, s: String = "TEST", h: StatementHandler = defaultHandler.getStatementHandler) = new CallableStatement(c, s, java.sql.Statement.NO_GENERATED_KEYS, h)

}
4 changes: 4 additions & 0 deletions jdbc-driver/src/test/scala/acolyte/ConnectionSpec.scala
Expand Up @@ -613,6 +613,8 @@ object ConnectionSpec extends Specification with ConnectionFixtures {
aka("statement connection") mustEqual c).
and(c.prepareStatement("TEST", Statement.NO_GENERATED_KEYS).
getConnection aka "statement connection" mustEqual c).
and(c.prepareStatement("TEST", Statement.RETURN_GENERATED_KEYS).
getConnection aka "statement connection" mustEqual c).
and(c.prepareStatement("TEST", TYPE_FORWARD_ONLY, CONCUR_READ_ONLY).
getConnection aka "statement connection" mustEqual c).
and(c.prepareStatement("TEST",
Expand All @@ -629,6 +631,8 @@ object ConnectionSpec extends Specification with ConnectionFixtures {
message = "Connection is closed")).
and(c.prepareStatement("TEST", Statement.NO_GENERATED_KEYS).
aka("creation") must throwA[SQLException]("Connection is closed")).
and(c.prepareStatement("TEST", Statement.RETURN_GENERATED_KEYS).
aka("creation") must throwA[SQLException]("Connection is closed")).
and(c.prepareStatement("TEST", TYPE_FORWARD_ONLY, CONCUR_READ_ONLY).
aka("creation") must throwA[SQLException]("Connection is closed")).
and(c.prepareStatement("TEST",
Expand Down
23 changes: 14 additions & 9 deletions jdbc-driver/src/test/scala/acolyte/PreparedStatementSpec.scala
Expand Up @@ -16,11 +16,11 @@ import acolyte.StatementHandler.Parameter
import acolyte.test.{ EmptyConnectionHandler, Params }

object PreparedStatementSpec
extends Specification with StatementSpecification[PreparedStatement] {
extends Specification with StatementSpecification[PreparedStatement] {

"Prepared statement specification" title

def statement(c: Connection = defaultCon, s: String = "TEST", h: StatementHandler = defaultHandler.getStatementHandler) = new PreparedStatement(c, s, h)
def statement(c: Connection = defaultCon, s: String = "TEST", h: StatementHandler = defaultHandler.getStatementHandler) = new PreparedStatement(c, s, java.sql.Statement.RETURN_GENERATED_KEYS, h)

}

Expand Down Expand Up @@ -145,7 +145,7 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

s.executeBatch() aka "batch execution" mustEqual Array[Int](1, 2) and (
h.exed aka "executed" must beLike {
case ("TEST", x) :: ("TEST", y) :: Nil =>
case ("TEST", x) :: ("TEST", y) :: Nil
(x aka "x" must_== a) and (y aka "y" must_== b)
})
}
Expand All @@ -161,7 +161,7 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

s.executeBatch() aka "batch execution" must throwA[BatchUpdateException].
like {
case ex: BatchUpdateException =>
case ex: BatchUpdateException
(ex.getUpdateCounts aka "update count" must_== Array[Int](
EXECUTE_FAILED, EXECUTE_FAILED)).
and(ex.getCause.getMessage aka "cause" mustEqual "Batch error")
Expand All @@ -187,7 +187,7 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

s.executeBatch() aka "batch execution" must throwA[BatchUpdateException].
like {
case ex: BatchUpdateException =>
case ex: BatchUpdateException
(ex.getUpdateCounts aka "update count" must_== Array[Int](
EXECUTE_FAILED, 2)).
and(ex.getCause.getMessage aka "cause" mustEqual "Batch error: 1")
Expand All @@ -209,7 +209,7 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

s.executeBatch() aka "batch execution" must throwA[BatchUpdateException].
like {
case ex: BatchUpdateException =>
case ex: BatchUpdateException
(ex.getUpdateCounts aka "update count" must_== Array[Int](
1, EXECUTE_FAILED)).
and(ex.getCause.getMessage aka "cause" mustEqual "Batch error: 2")
Expand All @@ -235,7 +235,7 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

s.executeBatch() aka "batch execution" must throwA[BatchUpdateException].
like {
case ex: BatchUpdateException =>
case ex: BatchUpdateException
(ex.getUpdateCounts aka "update count" must_== Array[Int](
1, EXECUTE_FAILED)).
and(ex.getCause.getMessage aka "cause" mustEqual "Batch error: 2")
Expand Down Expand Up @@ -1283,7 +1283,11 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

(query aka "execution" must not(throwA[SQLException])).
and(query aka "resultset" must not beNull).
and(s.getGeneratedKeys.next aka "has generated keys" must beFalse)
and(s.getGeneratedKeys aka "generated keys" must beLike {
case genKeys
(genKeys.getStatement aka "keys statement" mustEqual s).
and(genKeys.next aka "has keys" must beFalse)
})
}

"fail with update statement" in {
Expand Down Expand Up @@ -1325,7 +1329,8 @@ trait StatementSpecification[S <: PreparedStatement] extends Setters {

(s.executeUpdate aka "update count" must_== 1).
and(s.getGeneratedKeys aka "generated keys" must beLike {
case ks => (ks.next aka "has first key" must beTrue).
case ks (ks.getStatement aka "keys statement" mustEqual s).
and(ks.next aka "has first key" must beTrue).
and(ks.getInt(1) aka "first key" must_== 200).
and(ks.next aka "has second key" must beFalse)
})
Expand Down

0 comments on commit 99ac2f1

Please sign in to comment.