Skip to content

Commit 4d68c52

Browse files
committed
Update README.md
It was completely outdated in the part about decoding.
1 parent d5a6af8 commit 4d68c52

File tree

1 file changed

+58
-83
lines changed

1 file changed

+58
-83
lines changed

README.md

Lines changed: 58 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -200,105 +200,80 @@ msgpacks. See section below to understand how to decode tuples.
200200
### Data manipulation
201201

202202
Now let's consider a bit more sophisticated requests.
203-
Assume we have space with `id = 512` and following format on the server:
204-
`CREATE TABLE t(id INT PRIMARY KEY, a TEXT, b DOUBLE);`
205-
Preparing analogue of `t:replace(1, "111", 1.01);` request can be done this way:
203+
Assume we have a space with `id = 512` and following format on the server:
204+
`CREATE TABLE t(id INT PRIMARY KEY, name TEXT, coef DOUBLE);`
205+
Preparing analogue of `t:replace{1, "111", 1.01};` request can be done this way:
206206

207207
```
208-
std::tuple data = std::make_tuple(1 /* field 1*/, "111" /* field 2*/, 1.01 /* field 3*/);
209-
rid_t replace = conn.space[512].replace(data);
208+
std::tuple data = std::make_tuple(1 /*id*/, "111" /*name*/, 1.01 /*coef*/);
209+
rid_t my_replace = conn.space[512].replace(data);
210210
```
211-
To execute select query `t.index[1]:select({1}, {limit = 1})`:
212-
213-
```
214-
auto i = conn.space[512].index[1];
215-
rid_t select = i.select(std::make_tuple(1), 1, 0 /*offset*/, IteratorType::EQ);
216-
```
217-
218-
### Data readers
219211

220-
Responses from server contain raw data (i.e. encoded into msgpuck tuples). To
221-
decode client's data, users have to write their own decoders (based on featured
222-
schema). Let's define structure describing data stored in space `t`:
212+
As a good alternative, we could use structure instead of std::tuple, but we
213+
would have to provide once a way how it must be encoded:
223214

224215
```
225216
struct UserTuple {
226-
uint64_t field1;
227-
std::string field2;
228-
double field3;
217+
uint64_t id;
218+
std::string name;
219+
double coef;
220+
221+
static constexpr auto mpp = std::make_tuple(
222+
&UserTuple::id, &UserTuple::name, &UserTuple::coef);
229223
};
224+
225+
...
226+
227+
UserTuple tuple{.id = 1, .name = "aa", .coef = 1.01};
228+
rid_t my_replace = conn.space[512].replace(data);
230229
```
231230

232-
Prototype of the base reader is given in `src/mpp/Dec.hpp`:
231+
To execute select query `t.index[1]:select({1}, {limit = 1})`:
232+
233233
```
234-
template <class BUFFER, Type TYPE>
235-
struct SimpleReaderBase : DefaultErrorHandler {
236-
using BufferIterator_t = typename BUFFER::iterator;
237-
/* Allowed type of values to be parsed. */
238-
static constexpr Type VALID_TYPES = TYPE;
239-
BufferIterator_t* StoreEndIterator() { return nullptr; }
240-
};
234+
auto i = conn.space[512].index[1];
235+
rid_t my_select = i.select(std::make_tuple(1), 1, 0 /*offset*/, IteratorType::EQ);
241236
```
242-
So every new reader should inherit from it or directly from `DefaultErrorHandler`.
243-
To parse particular value, we should define `Value()` method. First two arguments
244-
are common and unused as a rule, but the third - defines parsed value. So in
245-
case of POD stuctures it's enough to provide byte-to-byte copy. Since in our
246-
schema there are fields of three different types, let's descripe three `Value()`
247-
functions:
237+
238+
### Decoding result
239+
240+
Responses from server contain raw data (i.e. encoded into msgpuck tuples).
241+
To decode client's data, we have to provide user storage that implicitly
242+
describes tuple format. For example, we know that the space (and each tuple)
243+
has three fields: unsigned, string and number.
244+
Then std::tuple<uint64_t, std::string, double> can be used as complete storage
245+
for decoding tuples of such space. Since select returns a dynamic array of
246+
tuples, the storage also must be a dynamic array (for example, vector):
247+
248248
```
249-
struct UserTupleValueReader : mpp::DefaultErrorHandler {
250-
/* Store instance of tuple to be parsed. */
251-
UserTuple& tuple;
252-
/* Enumerate all types which can be parsed. Otherwise */
253-
static constexpr mpp::Type VALID_TYPES = mpp::MP_UINT | mpp::MP_STR | mpp::MP_DBL;
254-
UserTupleValueReader(UserTuple& t) : tuple(t) {}
255-
256-
/* Value's extractors. */
257-
void Value(const BufIter_t&, mpp::compact::Type, uint64_t u)
258-
{
259-
tuple.field1 = u;
260-
}
261-
void Value(const BufIter_t&, mpp::compact::Type, double d)
262-
{
263-
tuple.field3 = d;
264-
}
265-
void Value(const BufIter_t& itr, mpp::compact::Type, mpp::StrValue v)
266-
{
267-
BufIter_t tmp = itr;
268-
tmp += v.offset;
269-
std::string &dst = tuple.field2;
270-
while (v.size) {
271-
dst.push_back(*tmp);
272-
++tmp;
273-
--v.size;
274-
}
275-
}
276-
};
249+
rid_t my_select = i.select(....);
250+
// wait for response...
251+
assert(conn.futureIsReady(my_select));
252+
auto response = conn.getResponse(my_select);
253+
std::vector<std::tuple<uint64_t, std::string, double>> results;
254+
response.body.data.decode(results);
255+
// use results...
277256
```
278-
It is worth mentioning that tuple itself is wrapped into array, so in fact
279-
firstly we should parse array. Let's define another one reader:
257+
258+
std::tuple is good since it has clearly readable format, but common structures
259+
are much more convenient to use. To decode structures we have to declare their
260+
format for decoder:
261+
280262
```
281-
template <class BUFFER>
282-
struct UserTupleReader : mpp::SimpleReaderBase<BUFFER, mpp::MP_ARR> {
283-
mpp::Dec<BUFFER>& dec;
284-
UserTuple& tuple;
285-
286-
UserTupleReader(mpp::Dec<BUFFER>& d, UserTuple& t) : dec(d), tuple(t) {}
287-
void Value(const iterator_t<BUFFER>&, mpp::compact::Type, mpp::ArrValue)
288-
{
289-
dec.SetReader(false, UserTupleValueReader{tuple});
290-
}
263+
struct UserTuple {
264+
uint64_t id;
265+
std::string name;
266+
double coef;
267+
268+
static constexpr auto mpp = std::make_tuple(
269+
&UserTuple::id, &UserTuple::name, &UserTuple::coef);
291270
};
292-
```
293-
`SetReader();` sets the reader which is invoked while every entry of the array is
294-
parsed. Now, to make these two readers work, we should create decoder, set
295-
its iterator to the position of encoded tuple and invoke `Read()` method:
296-
```
297-
UserTuple tuple;
298-
mpp::Dec dec(conn.getInBuf());
299-
dec.SetPosition(*t.begin);
300-
dec.SetReader(false, UserTupleReader<BUFFER>{dec, tuple});
301-
dec.Read();
271+
272+
// Perform select and wait for result...
273+
auto response = conn.getResponse(my_select);
274+
std::vector<UserTuple> results;
275+
response.body.data.decode(results);
276+
// use results...
302277
```
303278

304279
### Writing custom buffer and network provider

0 commit comments

Comments
 (0)