Skip to content

Commit e53235c

Browse files
authored
Prepared statement created by SqlConnection#prepare should not be cached (#578)
* non one-shot preparedQuery should not be cached Signed-off-by: Billy Yuan <billy112487983@gmail.com> * update documentation and examples Signed-off-by: Billy Yuan <billy112487983@gmail.com> * update the db2 examples as well Signed-off-by: Billy Yuan <billy112487983@gmail.com> * rename auto to cacheable Signed-off-by: Billy Yuan <billy112487983@gmail.com> * add a test for postgres statement close Signed-off-by: Billy Yuan <billy112487983@gmail.com>
1 parent 1be779b commit e53235c

File tree

23 files changed

+327
-65
lines changed

23 files changed

+327
-65
lines changed

vertx-db2-client/src/main/java/examples/SqlClientExamples.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,41 @@ public void queries08(SqlClient client) {
131131
});
132132
}
133133

134-
public void queries09(Vertx vertx, SqlConnectOptions connectOptions, PoolOptions poolOptions) {
134+
public void queries09(SqlClient client, SqlConnectOptions connectOptions) {
135135

136136
// Enable prepare statements caching
137137
connectOptions.setCachePreparedStatements(true);
138+
client
139+
.preparedQuery("SELECT * FROM users WHERE id = ?")
140+
.execute(Tuple.of("julien"), ar -> {
141+
if (ar.succeeded()) {
142+
RowSet<Row> rows = ar.result();
143+
System.out.println("Got " + rows.size() + " rows ");
144+
} else {
145+
System.out.println("Failure: " + ar.cause().getMessage());
146+
}
147+
});
148+
}
149+
150+
public void queries10(SqlConnection sqlConnection) {
151+
sqlConnection
152+
.prepare("SELECT * FROM users WHERE id= ?", ar -> {
153+
if (ar.succeeded()) {
154+
PreparedStatement preparedStatement = ar.result();
155+
preparedStatement.query()
156+
.execute(Tuple.of("julien"), ar2 -> {
157+
if (ar2.succeeded()) {
158+
RowSet<Row> rows = ar2.result();
159+
System.out.println("Got " + rows.size() + " rows ");
160+
preparedStatement.close();
161+
} else {
162+
System.out.println("Failure: " + ar2.cause().getMessage());
163+
}
164+
});
165+
} else {
166+
System.out.println("Failure: " + ar.cause().getMessage());
167+
}
168+
});
138169
}
139170

140171
public void usingConnections01(Vertx vertx, Pool pool) {

vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2PreparedStatement.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class DB2PreparedStatement implements PreparedStatement {
3636
final DB2ParamDesc paramDesc;
3737
final DB2RowDesc rowDesc;
3838
final Section section;
39+
final boolean cacheable;
3940

4041
private final Map<String, QueryInstance> activeQueries = new HashMap<>(4);
4142

@@ -51,11 +52,12 @@ public static class QueryInstance {
5152
}
5253
}
5354

54-
DB2PreparedStatement(String sql, DB2ParamDesc paramDesc, DB2RowDesc rowDesc, Section section) {
55+
DB2PreparedStatement(String sql, DB2ParamDesc paramDesc, DB2RowDesc rowDesc, Section section, boolean cacheable) {
5556
this.paramDesc = paramDesc;
5657
this.rowDesc = rowDesc;
5758
this.sql = sql;
5859
this.section = section;
60+
this.cacheable = cacheable;
5961
}
6062

6163
@Override
@@ -78,6 +80,11 @@ public String prepare(TupleInternal values) {
7880
return paramDesc.prepare(values);
7981
}
8082

83+
@Override
84+
public boolean cacheable() {
85+
return cacheable;
86+
}
87+
8188
QueryInstance getQueryInstance(String cursorId) {
8289
cursorId = cursorId == null ? UUID.randomUUID().toString() : cursorId;
8390
return activeQueries.computeIfAbsent(cursorId, c -> {

vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PrepareStatementCodec.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
import io.vertx.sqlclient.impl.command.PrepareStatementCommand;
2828

2929
class PrepareStatementCodec extends CommandCodec<PreparedStatement, PrepareStatementCommand> {
30-
30+
3131
private static final Logger LOG = LoggerFactory.getLogger(PrepareStatementCodec.class);
3232

3333
private static enum CommandHandlerState {
34-
INIT,
35-
HANDLING_PARAM_COLUMN_DEFINITION,
36-
PARAM_DEFINITIONS_DECODING_COMPLETED,
37-
HANDLING_COLUMN_COLUMN_DEFINITION,
34+
INIT,
35+
HANDLING_PARAM_COLUMN_DEFINITION,
36+
PARAM_DEFINITIONS_DECODING_COMPLETED,
37+
HANDLING_COLUMN_COLUMN_DEFINITION,
3838
COLUMN_DEFINITIONS_DECODING_COMPLETED
3939
}
4040

@@ -90,7 +90,7 @@ void decodePayload(ByteBuf payload, int payloadLength) {
9090

9191
private void handleReadyForQuery() {
9292
completionHandler.handle(CommandResponse.success(new DB2PreparedStatement(cmd.sql(),
93-
new DB2ParamDesc(paramDesc), new DB2RowDesc(rowDesc), section)));
93+
new DB2ParamDesc(paramDesc), new DB2RowDesc(rowDesc), section, cmd.cacheable())));
9494
}
9595

9696
private void resetIntermediaryResult() {
@@ -104,7 +104,7 @@ private void handleColumnDefinitionsDecodingCompleted() {
104104
handleReadyForQuery();
105105
resetIntermediaryResult();
106106
}
107-
107+
108108
@Override
109109
public String toString() {
110110
return new StringBuilder(getClass().getSimpleName())

vertx-mssql-client/src/main/java/examples/SqlClientExamples.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,41 @@ public void queries08(SqlClient client) {
120120
});
121121
}
122122

123-
public void queries09(Vertx vertx, SqlConnectOptions connectOptions, PoolOptions poolOptions) {
123+
public void queries09(SqlClient client, SqlConnectOptions connectOptions) {
124124

125125
// Enable prepare statements caching
126126
connectOptions.setCachePreparedStatements(true);
127+
client
128+
.preparedQuery("SELECT * FROM users WHERE id = @p1")
129+
.execute(Tuple.of("julien"), ar -> {
130+
if (ar.succeeded()) {
131+
RowSet<Row> rows = ar.result();
132+
System.out.println("Got " + rows.size() + " rows ");
133+
} else {
134+
System.out.println("Failure: " + ar.cause().getMessage());
135+
}
136+
});
137+
}
138+
139+
public void queries10(SqlConnection sqlConnection) {
140+
sqlConnection
141+
.prepare("SELECT * FROM users WHERE id = @p1", ar -> {
142+
if (ar.succeeded()) {
143+
PreparedStatement preparedStatement = ar.result();
144+
preparedStatement.query()
145+
.execute(Tuple.of("julien"), ar2 -> {
146+
if (ar2.succeeded()) {
147+
RowSet<Row> rows = ar2.result();
148+
System.out.println("Got " + rows.size() + " rows ");
149+
preparedStatement.close();
150+
} else {
151+
System.out.println("Failure: " + ar2.cause().getMessage());
152+
}
153+
});
154+
} else {
155+
System.out.println("Failure: " + ar.cause().getMessage());
156+
}
157+
});
127158
}
128159

129160
public void usingConnections01(Vertx vertx, Pool pool) {

vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLPreparedStatement.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
public class MSSQLPreparedStatement implements PreparedStatement {
2020
final String sql;
2121
final MSSQLParamDesc paramDesc;
22+
final boolean cacheable;
2223

23-
public MSSQLPreparedStatement(String sql, MSSQLParamDesc paramDesc) {
24+
public MSSQLPreparedStatement(String sql, MSSQLParamDesc paramDesc, boolean cacheable) {
2425
this.sql = sql;
2526
this.paramDesc = paramDesc;
27+
this.cacheable = cacheable;
2628
}
2729

2830
@Override
@@ -45,4 +47,9 @@ public String prepare(TupleInternal values) {
4547
// return paramDesc.prepare(values);
4648
return null;
4749
}
50+
51+
@Override
52+
public boolean cacheable() {
53+
return cacheable;
54+
}
4855
}

vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/PrepareStatementCodec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class PrepareStatementCodec extends MSSQLCommandCodec<PreparedStatement, Prepare
2525
void encode(TdsMessageEncoder encoder) {
2626
super.encode(encoder);
2727
// we use sp_prepexec instead of sp_prepare + sp_exec
28-
PreparedStatement preparedStatement = new MSSQLPreparedStatement(cmd.sql(), null);
28+
PreparedStatement preparedStatement = new MSSQLPreparedStatement(cmd.sql(), null, cmd.cacheable());
2929
completionHandler.handle(CommandResponse.success(preparedStatement));
3030

3131
}

vertx-mysql-client/src/main/java/examples/SqlClientExamples.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,41 @@ public void queries08(SqlClient client) {
131131
});
132132
}
133133

134-
public void queries09(Vertx vertx, SqlConnectOptions connectOptions, PoolOptions poolOptions) {
134+
public void queries09(SqlClient client, SqlConnectOptions connectOptions) {
135135

136136
// Enable prepare statements caching
137137
connectOptions.setCachePreparedStatements(true);
138+
client
139+
.preparedQuery("SELECT * FROM users WHERE id = ?")
140+
.execute(Tuple.of("julien"), ar -> {
141+
if (ar.succeeded()) {
142+
RowSet<Row> rows = ar.result();
143+
System.out.println("Got " + rows.size() + " rows ");
144+
} else {
145+
System.out.println("Failure: " + ar.cause().getMessage());
146+
}
147+
});
148+
}
149+
150+
public void queries10(SqlConnection sqlConnection) {
151+
sqlConnection
152+
.prepare("SELECT * FROM users WHERE id = ?", ar -> {
153+
if (ar.succeeded()) {
154+
PreparedStatement preparedStatement = ar.result();
155+
preparedStatement.query()
156+
.execute(Tuple.of("julien"), ar2 -> {
157+
if (ar2.succeeded()) {
158+
RowSet<Row> rows = ar2.result();
159+
System.out.println("Got " + rows.size() + " rows ");
160+
preparedStatement.close();
161+
} else {
162+
System.out.println("Failure: " + ar2.cause().getMessage());
163+
}
164+
});
165+
} else {
166+
System.out.println("Failure: " + ar.cause().getMessage());
167+
}
168+
});
138169
}
139170

140171
public void usingConnections01(Vertx vertx, Pool pool) {

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLPreparedStatement.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ class MySQLPreparedStatement implements PreparedStatement {
3030
final String sql;
3131
final MySQLParamDesc paramDesc;
3232
final MySQLRowDesc rowDesc;
33+
final boolean cacheable;
3334

3435
boolean isCursorOpen;
3536

36-
MySQLPreparedStatement(String sql, long statementId, MySQLParamDesc paramDesc, MySQLRowDesc rowDesc) {
37+
MySQLPreparedStatement(String sql, long statementId, MySQLParamDesc paramDesc, MySQLRowDesc rowDesc, boolean cacheable) {
3738
this.statementId = statementId;
3839
this.paramDesc = paramDesc;
3940
this.rowDesc = rowDesc;
4041
this.sql = sql;
42+
this.cacheable = cacheable;
4143
}
4244

4345
@Override
@@ -59,4 +61,9 @@ public String sql() {
5961
public String prepare(TupleInternal values) {
6062
return paramDesc.prepare(values);
6163
}
64+
65+
@Override
66+
public boolean cacheable() {
67+
return cacheable;
68+
}
6269
}

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PrepareStatementCodec.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ private void handleReadyForQuery() {
135135
cmd.sql(),
136136
this.statementId,
137137
new MySQLParamDesc(paramDescs),
138-
new MySQLRowDesc(columnDescs, DataFormat.BINARY))));
138+
new MySQLRowDesc(columnDescs, DataFormat.BINARY),
139+
cmd.cacheable())));
139140
}
140141

141142
private void resetIntermediaryResult() {

vertx-pg-client/src/main/java/examples/SqlClientExamples.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,41 @@ public void queries08(SqlClient client) {
131131
});
132132
}
133133

134-
public void queries09(Vertx vertx, SqlConnectOptions connectOptions, PoolOptions poolOptions) {
134+
public void queries09(SqlClient client, SqlConnectOptions connectOptions) {
135135

136136
// Enable prepare statements caching
137137
connectOptions.setCachePreparedStatements(true);
138+
client
139+
.preparedQuery("SELECT * FROM users WHERE id = $1")
140+
.execute(Tuple.of("julien"), ar -> {
141+
if (ar.succeeded()) {
142+
RowSet<Row> rows = ar.result();
143+
System.out.println("Got " + rows.size() + " rows ");
144+
} else {
145+
System.out.println("Failure: " + ar.cause().getMessage());
146+
}
147+
});
148+
}
149+
150+
public void queries10(SqlConnection sqlConnection) {
151+
sqlConnection
152+
.prepare("SELECT * FROM users WHERE id = $1", ar -> {
153+
if (ar.succeeded()) {
154+
PreparedStatement preparedStatement = ar.result();
155+
preparedStatement.query()
156+
.execute(Tuple.of("julien"), ar2 -> {
157+
if (ar2.succeeded()) {
158+
RowSet<Row> rows = ar2.result();
159+
System.out.println("Got " + rows.size() + " rows ");
160+
preparedStatement.close();
161+
} else {
162+
System.out.println("Failure: " + ar2.cause().getMessage());
163+
}
164+
});
165+
} else {
166+
System.out.println("Failure: " + ar.cause().getMessage());
167+
}
168+
});
138169
}
139170

140171
public void usingConnections01(Vertx vertx, Pool pool) {

0 commit comments

Comments
 (0)