Skip to content

Commit 8fd6068

Browse files
committed
ResultSet API for TarantoolClient
Extend an TarantoolClient API to be able to get data using type safe methods and conversions. Closes: #211
1 parent 244a493 commit 8fd6068

8 files changed

+1766
-2
lines changed

README.md

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,81 @@ against its integer IDs.
221221
and server's versions matches. It may take significant amount of time or even be
222222
a cause of request timeout.
223223
3. The client guarantees an order of synchronous requests per thread. Other cases such
224-
as asynchronous or multi-threaded requests may be out of order before the execution.
224+
as asynchronous or multi-threaded requests may be out of order before the execution.
225+
226+
### Getting a result
227+
228+
Traditionally, when a response is parsed by the internal MsgPack implementation the client
229+
will return it as a heterogeneous list of objects `List` that in most cases is inconvenient
230+
for users to use. It requires a type guessing as well as a writing more boilerplate code to work
231+
with typed data. Most of the methods which are provided by `TarantoolClientOps` (i.e. `select`)
232+
return raw de-serialized data via `List`.
233+
234+
Consider a small example how it is usually used:
235+
236+
```java
237+
// get an untyped array of tuples
238+
List<?> result = client.syncOps().execute(Requests.selectRequest("space", "pk"));
239+
for (int i = 0; i < result.size(); i++) {
240+
// get the first tuple (also untyped)
241+
List<?> row = result.get(i);
242+
// try to cast the first tuple as a couple of values
243+
int id = (int) row.get(0);
244+
String text = (String) row.get(1);
245+
processEntry(id, text);
246+
}
247+
```
248+
249+
There is an additional way to work with data using `TarantoolClient.executeRequest(TarantoolRequestConvertible)`
250+
method. This method returns a result wrapper over original data that allows to extract in a more
251+
typed manner rather than it is directly provided by MsgPack serialization. The `executeRequest`
252+
returns the `TarantoolResultSet` which provides a bunch of methods to get data. Inside the result
253+
set the data is represented as a list of rows (tuples) where each row has columns (fields).
254+
In general, it is possible that different rows have different size of their columns in scope of
255+
the same result.
256+
257+
```java
258+
TarantoolResultSet result = client.executeRequest(Requests.selectRequest("space", "pk"));
259+
while (result.next()) {
260+
long id = result.getLong(0);
261+
String text = result.getString(1);
262+
processEntry(id, text);
263+
}
264+
```
265+
266+
The `TarantoolResultSet` provides an implicit conversation between types if it's possible.
267+
268+
Numeric types internally can represent each other if a type range allows to do it. For example,
269+
byte 100 can be represented as a short, int and other types wider than byte. But 200 integer
270+
cannot be narrowed to a byte because of overflow (byte range is [-128..127]). If a floating
271+
point number is converted to a integer then the fraction part will be omitted. It is also
272+
possible to convert a valid string to a number.
273+
274+
Boolean type can be obtained from numeric types such as byte, short, int, long, BigInteger,
275+
float and double where 1 (1.0) means true and 0 (0.0) means false. Or it can be got from
276+
a string using well-known patterns such as "1", "t|true", "y|yes", "on" for true and
277+
"0", "f|false", "n|no", "off" for false respectively.
278+
279+
String type can be converted from a byte array and any numeric types. In case of `byte[]`
280+
all bytes will be interpreted as a UTF-8 sequence.
281+
282+
There is a special method called `getObject(int, Map)` where a user can provide its own
283+
mapping functions to be applied if a designated type matches a value one.
284+
285+
For instance, using the following map each strings will be transformed to an upper case and
286+
boolean values will be represented as strings "yes" or "no":
287+
288+
```java
289+
Map<Class<?>, Function<Object, Object>> mappers = new HashMap<>();
290+
mappers.put(
291+
String.class,
292+
v -> ((String) v).toUpperCase()
293+
);
294+
mappers.put(
295+
Boolean.class,
296+
v -> (boolean) v ? "yes" : "no"
297+
);
298+
```
225299

226300
## Spring NamedParameterJdbcTemplate usage example
227301

0 commit comments

Comments
 (0)