Skip to content

Commit 5a0d16d

Browse files
committed
The oracle row reader implements SQL client RowSet which can lead to a class cast exception. Instead it should build the result from the collector that the command provides and let the client build the RowSet through the collector.
fixes #1053
1 parent ed8c1e7 commit 5a0d16d

File tree

2 files changed

+24
-89
lines changed

2 files changed

+24
-89
lines changed

vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java

Lines changed: 21 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -10,55 +10,54 @@
1010
*/
1111
package io.vertx.oracleclient.impl;
1212

13-
import io.vertx.core.Context;
1413
import io.vertx.core.Future;
1514
import io.vertx.core.Promise;
1615
import io.vertx.core.impl.ContextInternal;
17-
import io.vertx.sqlclient.PropertyKind;
1816
import io.vertx.sqlclient.Row;
19-
import io.vertx.sqlclient.RowIterator;
20-
import io.vertx.sqlclient.RowSet;
21-
import io.vertx.sqlclient.desc.ColumnDescriptor;
2217
import io.vertx.sqlclient.impl.QueryResultHandler;
2318
import io.vertx.sqlclient.impl.RowDesc;
2419

25-
import java.util.ArrayList;
26-
import java.util.Iterator;
27-
import java.util.List;
2820
import java.util.concurrent.Flow;
2921
import java.util.concurrent.atomic.AtomicBoolean;
3022
import java.util.concurrent.atomic.AtomicInteger;
23+
import java.util.stream.Collector;
3124

32-
public class RowReader implements Flow.Subscriber<Row> {
25+
public class RowReader<R, A> implements Flow.Subscriber<Row> {
3326

3427
private final Flow.Publisher<Row> publisher;
3528
private final ContextInternal context;
3629
private final RowDesc description;
37-
private final QueryResultHandler<RowSet<Row>> handler;
30+
private final QueryResultHandler<R> handler;
3831
private volatile Flow.Subscription subscription;
3932
private final Promise<Void> subscriptionPromise;
4033
private Promise<Void> readPromise;
4134
private volatile boolean completed;
4235
private volatile Throwable failed;
43-
private volatile OracleRowSet collector;
36+
private final Collector<Row, A, R> collector;
37+
private A accumulator;
38+
private int count;
4439
private final AtomicInteger toRead = new AtomicInteger();
4540

4641
private final AtomicBoolean wip = new AtomicBoolean();
4742

48-
public RowReader(Flow.Publisher<Row> publisher, RowDesc description, Promise<Void> promise,
49-
QueryResultHandler<RowSet<Row>> handler,
43+
public RowReader(Flow.Publisher<Row> publisher, Collector<Row, A, R> collector, RowDesc description, Promise<Void> promise,
44+
QueryResultHandler<R> handler,
5045
ContextInternal context) {
5146
this.publisher = publisher;
5247
this.description = description;
5348
this.subscriptionPromise = promise;
5449
this.handler = handler;
5550
this.context = context;
51+
this.collector = collector;
5652
}
5753

58-
public static Future<RowReader> create(Flow.Publisher<Row> publisher, ContextInternal context,
59-
QueryResultHandler<RowSet<Row>> handler, RowDesc description) {
54+
public static <R> Future<RowReader<R, ?>> create(Flow.Publisher<Row> publisher,
55+
Collector<Row, ?, R> collector,
56+
ContextInternal context,
57+
QueryResultHandler<R> handler,
58+
RowDesc description) {
6059
Promise<Void> promise = context.promise();
61-
RowReader reader = new RowReader(publisher, description, promise, handler, context);
60+
RowReader<R, ?> reader = new RowReader<>(publisher, collector, description, promise, handler, context);
6261
reader.subscribe();
6362
return promise.future().map(reader);
6463
}
@@ -75,7 +74,8 @@ public Future<Void> read(int fetchSize) {
7574
}
7675
if (wip.compareAndSet(false, true)) {
7776
toRead.set(fetchSize);
78-
collector = new OracleRowSet(description);
77+
accumulator = collector.supplier().get();
78+
count = 0;
7979
readPromise = context.promise();
8080
subscription.request(fetchSize);
8181
return readPromise.future();
@@ -96,10 +96,12 @@ public void onSubscribe(Flow.Subscription subscription) {
9696

9797
@Override
9898
public void onNext(Row item) {
99-
collector.add(item);
99+
collector.accumulator().accept(accumulator, item);
100+
count++;
100101
if (toRead.decrementAndGet() == 0 && wip.compareAndSet(true, false)) {
102+
R result = collector.finisher().apply(accumulator);
101103
try {
102-
handler.handleResult(collector.rowCount(), collector.size(), description, collector, null);
104+
handler.handleResult(count, count, description, result, null);
103105
} catch (Exception e) {
104106
e.printStackTrace();
105107
}
@@ -122,69 +124,4 @@ public void onComplete() {
122124
context.runOnContext(x -> readPromise.complete(null));
123125
}
124126
}
125-
126-
private class OracleRowSet implements RowSet<Row> {
127-
128-
private final List<Row> rows = new ArrayList<>();
129-
private final RowDesc desc;
130-
131-
private OracleRowSet(RowDesc desc) {
132-
this.desc = desc;
133-
}
134-
135-
@Override
136-
public RowIterator<Row> iterator() {
137-
Iterator<Row> iterator = rows.iterator();
138-
return new RowIterator<>() {
139-
@Override
140-
public boolean hasNext() {
141-
return iterator.hasNext();
142-
}
143-
144-
@Override
145-
public Row next() {
146-
return iterator.next();
147-
}
148-
};
149-
}
150-
151-
@Override
152-
public int rowCount() {
153-
return rows.size();
154-
}
155-
156-
@Override
157-
public List<String> columnsNames() {
158-
return desc.columnNames();
159-
}
160-
161-
@Override
162-
public List<ColumnDescriptor> columnDescriptors() {
163-
return desc.columnDescriptor();
164-
}
165-
166-
@Override
167-
public int size() {
168-
return rows.size();
169-
}
170-
171-
@Override
172-
public <V> V property(PropertyKind<V> propertyKind) {
173-
return null; // TODO
174-
}
175-
176-
@Override
177-
public RowSet<Row> value() {
178-
return this;
179-
}
180-
181-
@Override
182-
public RowSet<Row> next() {
183-
return null;
184-
}
185-
186-
public void add(Row item) {
187-
rows.add(item);
188-
}
189-
}
190127
}

vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
import io.vertx.oracleclient.impl.OracleRow;
2020
import io.vertx.oracleclient.impl.RowReader;
2121
import io.vertx.sqlclient.Row;
22-
import io.vertx.sqlclient.RowSet;
2322
import io.vertx.sqlclient.Tuple;
24-
import io.vertx.sqlclient.desc.ColumnDescriptor;
25-
import io.vertx.sqlclient.impl.QueryResultHandler;
2623
import io.vertx.sqlclient.impl.RowDesc;
2724
import io.vertx.sqlclient.impl.command.ExtendedQueryCommand;
2825
import oracle.jdbc.OracleConnection;
@@ -71,7 +68,7 @@ public Future<OracleResponse<R>> execute(OracleConnection conn, ContextInternal
7168

7269
}
7370

74-
public Future<RowReader> createRowReader(PreparedStatement sqlStatement, ContextInternal context) {
71+
public Future<RowReader<R, ?>> createRowReader(PreparedStatement sqlStatement, ContextInternal context) {
7572
OraclePreparedStatement oraclePreparedStatement =
7673
unwrapOraclePreparedStatement(sqlStatement);
7774
try {
@@ -86,8 +83,9 @@ public Future<RowReader> createRowReader(PreparedStatement sqlStatement, Context
8683
}
8784
return RowReader.create(ors.publisherOracle(
8885
or -> Helper.getOrHandleSQLException(() -> transform(types, description, or))),
86+
command.collector(),
8987
context,
90-
(QueryResultHandler<RowSet<Row>>) command.resultHandler(), description);
88+
command.resultHandler(), description);
9189
} catch (SQLException e) {
9290
return context.failedFuture(e);
9391
}

0 commit comments

Comments
 (0)