Hyper API for C++  0.0.16638
Hyper client library for C++ applications
Result.hpp
Go to the documentation of this file.
1 
5 #ifndef TABLEAU_HYPER_RESULT_HPP
6 #define TABLEAU_HYPER_RESULT_HPP
7 
8 #include <hyperapi/ByteSpan.hpp>
9 #include <hyperapi/Date.hpp>
11 #include <hyperapi/Interval.hpp>
12 #include <hyperapi/Numeric.hpp>
15 #include <hyperapi/Time.hpp>
16 #include <hyperapi/Timestamp.hpp>
17 #include <hyperapi/string_view.hpp>
18 #include <hyperapi/hyperapi.h>
19 
20 #include <functional>
21 #include <iterator>
22 #include <string>
23 
24 namespace hyperapi {
25 
26 class ChunkIterator;
27 struct Chunks;
28 class ColumnIterator;
29 class Connection;
30 class Result;
31 class Row;
32 class ChunkedResultIterator;
33 class ResultIterator;
34 namespace internal {
35 inline bool hasCopyData(Result& result);
36 struct CopyData;
37 inline CopyData getCopyData(Result& result);
38 inline hyper_rowset_type_t getResultType(Result& result);
39 }
40 
44 class Value final {
45  public:
47  Value(hyper_value_t value, SqlType type, string_view columnName) noexcept
48  : value(value), type(type), columnName(columnName) {
49  }
50 
52  Value() noexcept {}
53 
58  template <typename ReturnType>
59  operator ReturnType() const { return get<ReturnType>(); }
60 
87  template <typename ReturnType>
88  ReturnType get() const;
89 
91  SqlType getType() const noexcept { return type; }
92 
94  bool isNull() const noexcept { return !value.value; }
95 
97  friend std::ostream& operator<<(std::ostream& os, const Value& value);
98 
100  friend bool operator==(const Value& lhs, const Value& rhs) noexcept { return lhs.value.value == rhs.value.value; }
101 
103  friend bool operator!=(const Value& lhs, const Value& rhs) noexcept { return !(lhs == rhs); }
104 
105  private:
106  friend class ColumnIterator;
107  template <typename ReturnType>
108  friend struct internal::ValueAccess;
109  friend class Connection;
110 
112  Value(const Value&) = default;
113  Value(Value&&) = default;
114  Value& operator=(const Value&) = default;
115  Value& operator=(Value&&) = default;
116 
118  hyper_value_t value{nullptr, 0};
120  SqlType type{TypeTag::Unsupported, 0};
122  string_view columnName = "";
123 };
124 
128 class Chunk final {
129  public:
133  Chunk() noexcept = default;
134 
136  ~Chunk() noexcept;
137 
139  Chunk(Chunk& other) = delete;
141  Chunk& operator=(Chunk& other) = delete;
142 
144  Chunk(Chunk&& other) noexcept;
146  Chunk& operator=(Chunk&& other) noexcept;
147 
154  Row getRowAt(hyper_row_index_t chunkRowIndex) const noexcept;
155 
160  size_t getRowCount() const noexcept { return rowCount; }
161 
163  bool isOpen() const noexcept { return (chunk != nullptr); }
164 
166  operator bool() const noexcept { return isOpen(); }
167 
169  friend bool operator==(const Chunk& lhs, const Chunk& rhs) noexcept { return lhs.chunk == rhs.chunk; }
170 
172  friend bool operator!=(const Chunk& lhs, const Chunk& rhs) noexcept { return !(lhs == rhs); }
173 
174  private:
180  Chunk(hyper_rowset_chunk_t* chunk, const Result& result) noexcept;
181 
183  hyper_rowset_chunk_t* chunk = nullptr;
185  mutable const uint8_t* const* values = nullptr;
187  mutable const size_t* valuesSizes = nullptr;
189  size_t chunkSize = 0;
191  const Result* result = nullptr;
193  size_t rowCount = 0;
194 
196  const uint8_t* const* getValues() const noexcept;
198  const size_t* getValuesSizes() const noexcept;
199 
200  friend class Row;
201  friend class ColumnIterator;
202  friend class Result;
203 };
204 
209 class Row final {
210  public:
221  template <typename ReturnType = Value>
222  ReturnType get(hyper_field_index_t columnIndex) const;
223 
229  const ResultSchema& getSchema() const noexcept;
230 
231  private:
237  Row(const Chunk& chunk, hyper_row_index_t chunkRowIndex) noexcept;
238 
240  Row(const Row&) = default;
241  Row(Row&&) = default;
242  Row& operator=(const Row&) = default;
243  Row& operator=(Row&&) = default;
244 
246  std::reference_wrapper<const Chunk> chunk;
248  hyper_row_index_t chunkRowIndex;
249 
250  friend class Chunk;
251  friend class ResultIterator;
252  friend class ColumnIterator;
253  friend class ChunkIterator;
254 };
255 
258 };
259 static constexpr IteratorBeginTag iteratorBeginTag = {};
260 
263 };
264 static constexpr IteratorEndTag iteratorEndTag = {};
265 
267 class ChunkIterator final {
268  public:
269  using iterator_category = std::input_iterator_tag;
270  using value_type = Row;
271  using difference_type = std::ptrdiff_t;
272  using pointer = const Row*;
273  using reference = const Row&;
274 
276  ChunkIterator(const Chunk& chunk, IteratorBeginTag) noexcept
277  : chunk(chunk), rowIndex(0), currentRow(chunk, 0) {
278  }
279 
281  ChunkIterator(const Chunk& chunk, IteratorEndTag) noexcept
282  : chunk(chunk), rowIndex(static_cast<hyper_row_index_t>(chunk.getRowCount())), currentRow(chunk, 0) {
283  }
284 
286  reference operator*() const noexcept;
287 
289  pointer operator->() const noexcept { return &**this; }
290 
292  ChunkIterator& operator++() noexcept;
293 
295  ChunkIterator operator++(int) noexcept;
296 
298  friend bool operator==(const ChunkIterator& lhs, const ChunkIterator& rhs) noexcept { return (lhs.chunk.get() == rhs.chunk.get()) && (lhs.rowIndex == rhs.rowIndex); }
299 
301  friend bool operator!=(const ChunkIterator& lhs, const ChunkIterator& rhs) noexcept { return !(lhs == rhs); }
302 
303  private:
304  std::reference_wrapper<const Chunk> chunk;
305  hyper_row_index_t rowIndex;
306  mutable Row currentRow;
307 
308  friend class ResultIterator;
309 };
310 
312 inline ChunkIterator begin(const Chunk& chunk) {
313  return {chunk, iteratorBeginTag};
314 }
315 
317 inline ChunkIterator end(const Chunk& chunk) noexcept {
318  return {chunk, iteratorEndTag};
319 }
320 
325 class Result final {
326  public:
332  Result() : currentChunkIterator(end(currentChunk)) {}
333 
334  ~Result() noexcept;
335 
337  Result(Result&& other) noexcept;
338 
340  Result& operator=(Result&& other) noexcept;
341 
343  Result& operator=(const Result& other) = delete;
344  Result(const Result& other) = delete;
345 
350  const ResultSchema& getSchema() const noexcept { return *schema; }
351 
359  optional<size_t> getAffectedRowCount() const;
360 
366  Connection& getConnection();
367 
372  bool isOpen() const noexcept;
373 
378  void close() noexcept;
379 
380  private:
391  explicit Result(hyper_rowset_t* rowset, Connection& conn);
392 
394  void fetchNextChunk();
395 
397  Chunk& getCurrentChunk();
398 
400  ChunkIterator& getCurrentChunkIterator();
401 
403  void createSchema();
404 
406  hyper_rowset_t* rowset = nullptr;
407 
409  Connection* conn = nullptr;
410 
412  mutable optional<ResultSchema> schema;
413 
415  Chunk currentChunk;
417  ChunkIterator currentChunkIterator;
418 
419  friend class Row;
420  friend class Connection;
421  friend class Chunk;
422  friend class ChunkedResultIterator;
423  friend class ResultIterator;
424  friend Result internal::executePreparedQuery(Connection& connection, const std::string& statement_name, hyper_rowset_result_format_t result_format);
425  friend Result internal::executeQueryParams(Connection& connection, const std::string& query, hyper_rowset_result_format_t result_format);
426  friend bool operator==(const ChunkedResultIterator& lhs, const ChunkedResultIterator& rhs) noexcept;
427  friend bool operator==(const ResultIterator& lhs, const ResultIterator& rhs) noexcept;
428  friend inline bool internal::hasCopyData(Result&);
429  friend inline internal::CopyData internal::getCopyData(Result& result);
430  friend inline hyper_rowset_type_t internal::getResultType(Result& result);
431 };
432 
434 struct Chunks {
436  Chunks(Result& result) : result(result) {
437  }
438 
441 };
442 
444 class ColumnIterator final {
445  public:
446  using iterator_category = std::input_iterator_tag;
447  using value_type = Value;
448  using difference_type = std::ptrdiff_t;
449  using pointer = const Value*;
450  using reference = const Value&;
451 
453  ColumnIterator(const Row& row, IteratorBeginTag) noexcept
454  : row(row), columnIndex(0) {
455  }
456 
458  ColumnIterator(const Row& row, IteratorEndTag) noexcept
459  : row(row), columnIndex(static_cast<hyper_field_index_t>(row.getSchema().getColumnCount())) {
460  }
461 
463  reference operator*() const noexcept;
464 
466  pointer operator->() const noexcept { return &**this; }
467 
469  ColumnIterator& operator++();
470 
472  ColumnIterator operator++(int);
473 
475  friend bool operator==(const ColumnIterator& lhs, const ColumnIterator& rhs) noexcept { return (&lhs.row.get() == &rhs.row.get()) && (lhs.columnIndex == rhs.columnIndex); }
476 
478  friend bool operator!=(const ColumnIterator& lhs, const ColumnIterator& rhs) noexcept { return !(lhs == rhs); }
479 
480  private:
481  std::reference_wrapper<const Row> row;
482  hyper_field_index_t columnIndex;
483  mutable Value currentValue;
484 };
485 
487 inline ColumnIterator begin(const Row& row) {
488  return {row, iteratorBeginTag};
489 }
490 
492 inline ColumnIterator end(const Row& row) noexcept {
493  return {row, iteratorEndTag};
494 }
495 
498  public:
499  using iterator_category = std::input_iterator_tag;
500  using value_type = Chunk;
501  using difference_type = std::ptrdiff_t;
502  using pointer = Chunk*;
503  using reference = Chunk&;
504 
509  : result(result), isEndIterator(true) {
510  }
511 
513  reference operator*() noexcept { return result.get().currentChunk; }
514 
516  pointer operator->() noexcept { return &**this; }
517 
519  ChunkedResultIterator& operator++();
520 
522  friend bool operator==(const ChunkedResultIterator& lhs, const ChunkedResultIterator& rhs) noexcept;
523 
525  friend bool operator!=(const ChunkedResultIterator& lhs, const ChunkedResultIterator& rhs) noexcept { return !(lhs == rhs); }
526 
527  private:
529  std::reference_wrapper<Result> result;
531  bool isEndIterator;
532 };
533 
535 inline ChunkedResultIterator begin(const Chunks& chunks) {
536  return {chunks.result, iteratorBeginTag};
537 }
538 
540 inline ChunkedResultIterator end(const Chunks& chunks) noexcept {
541  return {chunks.result, iteratorEndTag};
542 }
543 
550 class ResultIterator final {
551  public:
552  using iterator_category = std::input_iterator_tag;
553  using value_type = Row;
554  using difference_type = std::ptrdiff_t;
555  using pointer = const Row*;
556  using reference = const Row&;
557 
562  : result(result), isEndIterator(true) {
563  }
564 
566  reference operator*() const noexcept { return *result.get().getCurrentChunkIterator(); }
567 
569  pointer operator->() const noexcept { return &**this; }
570 
572  ResultIterator& operator++();
573 
575  friend bool operator==(const ResultIterator& lhs, const ResultIterator& rhs) noexcept;
576 
578  friend bool operator!=(const ResultIterator& lhs, const ResultIterator& rhs) noexcept { return !(lhs == rhs); }
579 
580  private:
582  std::reference_wrapper<Result> result;
584  bool isEndIterator;
585 };
586 
588 inline ResultIterator begin(Result& result) {
589  return {result, iteratorBeginTag};
590 }
591 
593 inline ResultIterator end(Result& result) noexcept {
594  return {result, iteratorEndTag};
595 }
596 }
597 
598 #include <hyperapi/impl/Result.impl.hpp>
599 
600 #endif
hyperapi::ResultIterator
Iterates over a hyperapi::Result in rows (hyperapi::Row).
Definition: Result.hpp:550
hyperapi::Row
A Row inside a chunk.
Definition: Result.hpp:209
hyperapi::Chunk::operator=
Chunk & operator=(Chunk &other)=delete
Copy assignment.
hyperapi::Chunks::Chunks
Chunks(Result &result)
Construct a Chunks object.
Definition: Result.hpp:436
hyperapi::SqlType
A Hyper SQL type.
Definition: SqlType.hpp:43
hyperapi::Value::get
ReturnType get() const
Get the value as one of the supported types.
hyperapi::ColumnIterator::ColumnIterator
ColumnIterator(const Row &row, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:458
string_view.hpp
hyperapi::ChunkedResultIterator::operator!=
friend bool operator!=(const ChunkedResultIterator &lhs, const ChunkedResultIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:525
hyperapi::ResultSchema
A result schema.
Definition: ResultSchema.hpp:20
Interval.hpp
hyperapi::Result::Result
Result()
Constructs an empty Result object.
Definition: Result.hpp:332
hyperapi::Value::Value
Value(hyper_value_t value, SqlType type, string_view columnName) noexcept
Constructs a Value object.
Definition: Result.hpp:47
hyperapi::Chunk::getRowCount
size_t getRowCount() const noexcept
Definition: Result.hpp:160
hyperapi::Chunk::~Chunk
~Chunk() noexcept
Destructor.
hyperapi::ChunkIterator
Iterates over a hyperapi::Chunk in rows (hyperapi::Row).
Definition: Result.hpp:267
Date.hpp
hyperapi::ColumnIterator
Iterates over a hyperapi::Row in values (hyperapi::Value).
Definition: Result.hpp:444
HyperException.hpp
hyperapi::Chunk::Chunk
Chunk() noexcept=default
Constructor, constructs a closed chunk.
hyperapi::string_view
Describes an object that can refer to a constant, contiguous sequence of char-like objects.
Definition: string_view.hpp:26
hyperapi::Value
A value inside a row.
Definition: Result.hpp:44
ByteSpan.hpp
hyperapi::ColumnIterator::ColumnIterator
ColumnIterator(const Row &row, IteratorBeginTag) noexcept
Constructs the begin-iterator.
Definition: Result.hpp:453
hyperapi::Result
Base class for a result of a query.
Definition: Result.hpp:325
hyperapi::optional
Surrogate for C++17 std::optional
Definition: optional.hpp:40
hyperapi::end
ChunkIterator end(const Chunk &chunk) noexcept
Returns the end-iterator for the rows of the given chunk.
Definition: Result.hpp:317
hyperapi::Chunk::operator!=
friend bool operator!=(const Chunk &lhs, const Chunk &rhs) noexcept
Comparison operator.
Definition: Result.hpp:172
hyperapi::Chunk::operator==
friend bool operator==(const Chunk &lhs, const Chunk &rhs) noexcept
Comparison operator.
Definition: Result.hpp:169
hyperapi::Value::Value
Value() noexcept
Default constructs a Value object.
Definition: Result.hpp:52
hyperapi::Connection
Defines a Hyper connection.
Definition: Connection.hpp:42
hyperapi::Chunks::result
Result & result
the result
Definition: Result.hpp:440
ResultSchema.hpp
hyperapi::ResultIterator::operator!=
friend bool operator!=(const ResultIterator &lhs, const ResultIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:578
Time.hpp
hyperapi::ChunkIterator::ChunkIterator
ChunkIterator(const Chunk &chunk, IteratorBeginTag) noexcept
Constructs the begin-iterator.
Definition: Result.hpp:276
hyperapi
The primary namespace of the Hyper API for C++.
Definition: ByteSpan.hpp:15
hyperapi::ResultIterator::operator->
pointer operator->() const noexcept
Returns a pointer to the current value.
Definition: Result.hpp:569
hyperapi::ChunkIterator::operator!=
friend bool operator!=(const ChunkIterator &lhs, const ChunkIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:301
hyperapi::Value::operator!=
friend bool operator!=(const Value &lhs, const Value &rhs) noexcept
Comparison operator.
Definition: Result.hpp:103
hyperapi::ColumnIterator::operator!=
friend bool operator!=(const ColumnIterator &lhs, const ColumnIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:478
OffsetTimestamp.hpp
hyperapi::Chunk
A chunk of a result.
Definition: Result.hpp:128
hyperapi::Value::operator<<
friend std::ostream & operator<<(std::ostream &os, const Value &value)
Stream output operator.
hyperapi::begin
ChunkIterator begin(const Chunk &chunk)
Returns the begin-iterator for the rows of the given chunk.
Definition: Result.hpp:312
hyperapi::Value::operator==
friend bool operator==(const Value &lhs, const Value &rhs) noexcept
Comparison operator.
Definition: Result.hpp:100
Numeric.hpp
Timestamp.hpp
hyperapi::Value::getType
SqlType getType() const noexcept
Get the type of the value.
Definition: Result.hpp:91
hyperapi::IteratorEndTag
A tag for an iterator-end constructor.
Definition: Result.hpp:262
hyperapi::ChunkedResultIterator::operator->
pointer operator->() noexcept
Returns a pointer to the current value.
Definition: Result.hpp:516
hyperapi::ColumnIterator::operator==
friend bool operator==(const ColumnIterator &lhs, const ColumnIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:475
hyperapi::ChunkIterator::ChunkIterator
ChunkIterator(const Chunk &chunk, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:281
hyperapi::Chunks
A tag that makes a result iterable in chunks.
Definition: Result.hpp:434
hyperapi::ChunkedResultIterator::operator*
reference operator*() noexcept
Returns a reference to the current value.
Definition: Result.hpp:513
hyperapi::ChunkedResultIterator::ChunkedResultIterator
ChunkedResultIterator(Result &result, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:508
hyperapi::ResultIterator::operator*
reference operator*() const noexcept
Returns a reference to the current value.
Definition: Result.hpp:566
hyperapi::ResultIterator::ResultIterator
ResultIterator(Result &result, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:561
hyperapi::ChunkedResultIterator
Iterates over a hyperapi::Result in hyperapi::Chunk.
Definition: Result.hpp:497
hyperapi::IteratorBeginTag
A tag for an iterator-begin constructor.
Definition: Result.hpp:257
hyperapi::Value::isNull
bool isNull() const noexcept
Returns whether the value is null.
Definition: Result.hpp:94
hyperapi::Chunk::isOpen
bool isOpen() const noexcept
Returns whether the chunk is valid.
Definition: Result.hpp:163
hyperapi::Chunk::getRowAt
Row getRowAt(hyper_row_index_t chunkRowIndex) const noexcept
Retrieves the row at the given index inside the chunk (starting at 0).