Permalink
Browse files

[jdbc-driver] Fix generated keys on update result.

  • Loading branch information...
cchantep
cchantep committed May 1, 2014
1 parent 5ced4dc commit 99ac2f1d01681b01f2c236268061d498ba1217c1
@@ -31,10 +31,9 @@
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 ---
@@ -80,9 +79,10 @@
/**
* 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
@@ -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);
@@ -496,8 +496,8 @@ public int executeUpdate(final String sql, final int autoGeneratedKeys)
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) {
@@ -57,13 +57,15 @@
*
* @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>
// ---
@@ -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
/**
@@ -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
@@ -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
/**
@@ -103,6 +103,11 @@
*/
private final boolean query;
/**
* Generated key flag
*/
private final int generatedKeysFlag;
/**
* Parameters
*/
@@ -121,10 +126,12 @@
*
* @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);
@@ -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>
@@ -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));
@@ -225,8 +233,8 @@ public int executeUpdate() throws SQLException {
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) {
@@ -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();
@@ -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)
}
@@ -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",
@@ -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",
@@ -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)
}
@@ -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)
})
}
@@ -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")
@@ -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")
@@ -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")
@@ -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")
@@ -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 {
@@ -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)
})

0 comments on commit 99ac2f1

Please sign in to comment.