Hyper API for C++  0.0.15530
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  const uint8_t* const* values = nullptr;
187  const size_t* valuesSizes = nullptr;
189  size_t chunkSize = 0;
191  const Result* result = nullptr;
193  size_t rowCount = 0;
194 
195  friend class Row;
196  friend class ColumnIterator;
197  friend class Result;
198 };
199 
204 class Row final {
205  public:
216  template <typename ReturnType = Value>
217  ReturnType get(hyper_field_index_t columnIndex) const;
218 
224  const ResultSchema& getSchema() const noexcept;
225 
226  private:
232  Row(const Chunk& chunk, hyper_row_index_t chunkRowIndex) noexcept;
233 
235  Row(const Row&) = default;
236  Row(Row&&) = default;
237  Row& operator=(const Row&) = default;
238  Row& operator=(Row&&) = default;
239 
241  std::reference_wrapper<const Chunk> chunk;
243  hyper_row_index_t chunkRowIndex;
244 
245  friend class Chunk;
246  friend class ResultIterator;
247  friend class ColumnIterator;
248  friend class ChunkIterator;
249 };
250 
253 };
254 static constexpr IteratorBeginTag iteratorBeginTag = {};
255 
258 };
259 static constexpr IteratorEndTag iteratorEndTag = {};
260 
262 class ChunkIterator final {
263  public:
264  using iterator_category = std::input_iterator_tag;
265  using value_type = Row;
266  using difference_type = std::ptrdiff_t;
267  using pointer = const Row*;
268  using reference = const Row&;
269 
271  ChunkIterator(const Chunk& chunk, IteratorBeginTag) noexcept
272  : chunk(chunk), rowIndex(0), currentRow(chunk, 0) {
273  }
274 
276  ChunkIterator(const Chunk& chunk, IteratorEndTag) noexcept
277  : chunk(chunk), rowIndex(static_cast<hyper_row_index_t>(chunk.getRowCount())), currentRow(chunk, 0) {
278  }
279 
281  reference operator*() const noexcept;
282 
284  pointer operator->() const noexcept { return &**this; }
285 
287  ChunkIterator& operator++() noexcept;
288 
290  ChunkIterator operator++(int) noexcept;
291 
293  friend bool operator==(const ChunkIterator& lhs, const ChunkIterator& rhs) noexcept { return (lhs.chunk.get() == rhs.chunk.get()) && (lhs.rowIndex == rhs.rowIndex); }
294 
296  friend bool operator!=(const ChunkIterator& lhs, const ChunkIterator& rhs) noexcept { return !(lhs == rhs); }
297 
298  private:
299  std::reference_wrapper<const Chunk> chunk;
300  hyper_row_index_t rowIndex;
301  mutable Row currentRow;
302 
303  friend class ResultIterator;
304 };
305 
307 inline ChunkIterator begin(const Chunk& chunk) {
308  return {chunk, iteratorBeginTag};
309 }
310 
312 inline ChunkIterator end(const Chunk& chunk) noexcept {
313  return {chunk, iteratorEndTag};
314 }
315 
320 class Result final {
321  public:
327  Result() : currentChunkIterator(end(currentChunk)) {}
328 
329  ~Result() noexcept;
330 
332  Result(Result&& other) noexcept;
333 
335  Result& operator=(Result&& other) noexcept;
336 
338  Result& operator=(const Result& other) = delete;
339  Result(const Result& other) = delete;
340 
345  const ResultSchema& getSchema() const noexcept { return *schema; }
346 
355 
362 
367  bool isOpen() const noexcept;
368 
373  void close() noexcept;
374 
375  private:
386  explicit Result(hyper_rowset_t* rowset, Connection& conn);
387 
389  void fetchNextChunk();
390 
392  Chunk& getCurrentChunk();
393 
395  ChunkIterator& getCurrentChunkIterator();
396 
398  void createSchema();
399 
401  hyper_rowset_t* rowset = nullptr;
402 
404  Connection* conn = nullptr;
405 
407  mutable optional<ResultSchema> schema;
408 
410  Chunk currentChunk;
412  ChunkIterator currentChunkIterator;
413 
414  friend class Row;
415  friend class Connection;
416  friend class Chunk;
417  friend class ChunkedResultIterator;
418  friend class ResultIterator;
419  friend Result internal::executePreparedQuery(Connection& connection, const std::string& statement_name, hyper_rowset_result_format_t result_format);
420  friend Result internal::executeQueryParams(Connection& connection, const std::string& query, hyper_rowset_result_format_t result_format);
421  friend bool operator==(const ChunkedResultIterator& lhs, const ChunkedResultIterator& rhs) noexcept;
422  friend bool operator==(const ResultIterator& lhs, const ResultIterator& rhs) noexcept;
423  friend inline bool internal::hasCopyData(Result&);
424  friend inline internal::CopyData internal::getCopyData(Result& result);
425  friend inline hyper_rowset_type_t internal::getResultType(Result& result);
426 };
427 
429 struct Chunks {
431  Chunks(Result& result) : result(result) {
432  }
433 
436 };
437 
439 class ColumnIterator final {
440  public:
441  using iterator_category = std::input_iterator_tag;
442  using value_type = Value;
443  using difference_type = std::ptrdiff_t;
444  using pointer = const Value*;
445  using reference = const Value&;
446 
448  ColumnIterator(const Row& row, IteratorBeginTag) noexcept
449  : row(row), columnIndex(0) {
450  }
451 
453  ColumnIterator(const Row& row, IteratorEndTag) noexcept
454  : row(row), columnIndex(static_cast<hyper_field_index_t>(row.getSchema().getColumnCount())) {
455  }
456 
458  reference operator*() const noexcept;
459 
461  pointer operator->() const noexcept { return &**this; }
462 
464  ColumnIterator& operator++();
465 
467  ColumnIterator operator++(int);
468 
470  friend bool operator==(const ColumnIterator& lhs, const ColumnIterator& rhs) noexcept { return (&lhs.row.get() == &rhs.row.get()) && (lhs.columnIndex == rhs.columnIndex); }
471 
473  friend bool operator!=(const ColumnIterator& lhs, const ColumnIterator& rhs) noexcept { return !(lhs == rhs); }
474 
475  private:
476  std::reference_wrapper<const Row> row;
477  hyper_field_index_t columnIndex;
478  mutable Value currentValue;
479 };
480 
482 inline ColumnIterator begin(const Row& row) {
483  return {row, iteratorBeginTag};
484 }
485 
487 inline ColumnIterator end(const Row& row) noexcept {
488  return {row, iteratorEndTag};
489 }
490 
493  public:
494  using iterator_category = std::input_iterator_tag;
495  using value_type = Chunk;
496  using difference_type = std::ptrdiff_t;
497  using pointer = Chunk*;
498  using reference = Chunk&;
499 
504  : result(result), isEndIterator(true) {
505  }
506 
508  reference operator*() noexcept { return result.get().currentChunk; }
509 
511  pointer operator->() noexcept { return &**this; }
512 
514  ChunkedResultIterator& operator++();
515 
517  friend bool operator==(const ChunkedResultIterator& lhs, const ChunkedResultIterator& rhs) noexcept;
518 
520  friend bool operator!=(const ChunkedResultIterator& lhs, const ChunkedResultIterator& rhs) noexcept { return !(lhs == rhs); }
521 
522  private:
524  std::reference_wrapper<Result> result;
526  bool isEndIterator;
527 };
528 
530 inline ChunkedResultIterator begin(const Chunks& chunks) {
531  return {chunks.result, iteratorBeginTag};
532 }
533 
535 inline ChunkedResultIterator end(const Chunks& chunks) noexcept {
536  return {chunks.result, iteratorEndTag};
537 }
538 
545 class ResultIterator final {
546  public:
547  using iterator_category = std::input_iterator_tag;
548  using value_type = Row;
549  using difference_type = std::ptrdiff_t;
550  using pointer = const Row*;
551  using reference = const Row&;
552 
557  : result(result), isEndIterator(true) {
558  }
559 
561  reference operator*() const noexcept { return *result.get().getCurrentChunkIterator(); }
562 
564  pointer operator->() const noexcept { return &**this; }
565 
567  ResultIterator& operator++();
568 
570  friend bool operator==(const ResultIterator& lhs, const ResultIterator& rhs) noexcept;
571 
573  friend bool operator!=(const ResultIterator& lhs, const ResultIterator& rhs) noexcept { return !(lhs == rhs); }
574 
575  private:
577  std::reference_wrapper<Result> result;
579  bool isEndIterator;
580 };
581 
583 inline ResultIterator begin(Result& result) {
584  return {result, iteratorBeginTag};
585 }
586 
588 inline ResultIterator end(Result& result) noexcept {
589  return {result, iteratorEndTag};
590 }
591 }
592 
593 #include <hyperapi/impl/Result.impl.hpp>
594 
595 #endif
hyperapi::ResultIterator
Iterates over a hyperapi::Result in rows (hyperapi::Row).
Definition: Result.hpp:545
hyperapi::Row
A Row inside a chunk.
Definition: Result.hpp:204
hyperapi::Chunk::operator=
Chunk & operator=(Chunk &other)=delete
Copy assignment.
hyperapi::Chunks::Chunks
Chunks(Result &result)
Construct a Chunks object.
Definition: Result.hpp:431
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:453
string_view.hpp
hyperapi::ChunkedResultIterator::operator!=
friend bool operator!=(const ChunkedResultIterator &lhs, const ChunkedResultIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:520
hyperapi::ChunkIterator::operator++
ChunkIterator & operator++() noexcept
Advances the iterator.
hyperapi::ResultSchema
A result schema.
Definition: ResultSchema.hpp:20
hyperapi::Result::getAffectedRowCount
optional< size_t > getAffectedRowCount() const
Get the affected row count, if the statement had any.
Interval.hpp
hyperapi::Result::Result
Result()
Constructs an empty Result object.
Definition: Result.hpp:327
hyperapi::Result::isOpen
bool isOpen() const noexcept
Checks whether the result is open.
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:262
Date.hpp
hyperapi::ColumnIterator
Iterates over a hyperapi::Row in values (hyperapi::Value).
Definition: Result.hpp:439
hyperapi::ChunkIterator::operator*
reference operator*() const noexcept
Returns a reference to the current value.
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::Row::getSchema
const ResultSchema & getSchema() const noexcept
Returns the schema of the row.
hyperapi::ColumnIterator::ColumnIterator
ColumnIterator(const Row &row, IteratorBeginTag) noexcept
Constructs the begin-iterator.
Definition: Result.hpp:448
hyperapi::Result
Base class for a result of a query.
Definition: Result.hpp:320
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:312
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:435
hyperapi::Row::get
ReturnType get(hyper_field_index_t columnIndex) const
Returns the value of field at position columnIndex.
ResultSchema.hpp
hyperapi::Result::getSchema
const ResultSchema & getSchema() const noexcept
Returns schema of the result.
Definition: Result.hpp:345
hyperapi::ResultIterator::operator!=
friend bool operator!=(const ResultIterator &lhs, const ResultIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:573
Time.hpp
hyperapi::ChunkIterator::ChunkIterator
ChunkIterator(const Chunk &chunk, IteratorBeginTag) noexcept
Constructs the begin-iterator.
Definition: Result.hpp:271
hyperapi::Result::close
void close() noexcept
Closes the result.
hyperapi::operator==
bool operator==(const DatabaseName &a, const DatabaseName &b) noexcept
Equality operator.
Definition: DatabaseName.hpp:53
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:564
hyperapi::ChunkIterator::operator!=
friend bool operator!=(const ChunkIterator &lhs, const ChunkIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:296
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:473
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:307
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:257
hyperapi::ChunkedResultIterator::operator->
pointer operator->() noexcept
Returns a pointer to the current value.
Definition: Result.hpp:511
hyperapi::ColumnIterator::operator==
friend bool operator==(const ColumnIterator &lhs, const ColumnIterator &rhs) noexcept
Comparison operator.
Definition: Result.hpp:470
hyperapi::ChunkIterator::ChunkIterator
ChunkIterator(const Chunk &chunk, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:276
hyperapi::Chunks
A tag that makes a result iterable in chunks.
Definition: Result.hpp:429
hyperapi::ChunkedResultIterator::operator*
reference operator*() noexcept
Returns a reference to the current value.
Definition: Result.hpp:508
hyperapi::ChunkedResultIterator::ChunkedResultIterator
ChunkedResultIterator(Result &result, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:503
hyperapi::ResultIterator::operator*
reference operator*() const noexcept
Returns a reference to the current value.
Definition: Result.hpp:561
hyperapi::ResultIterator::ResultIterator
ResultIterator(Result &result, IteratorEndTag) noexcept
Constructs the end-iterator.
Definition: Result.hpp:556
hyperapi::ChunkedResultIterator
Iterates over a hyperapi::Result in hyperapi::Chunk.
Definition: Result.hpp:492
hyperapi::IteratorBeginTag
A tag for an iterator-begin constructor.
Definition: Result.hpp:252
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::Result::getConnection
Connection & getConnection()
Returns the connection of the SQL statement that yielded this result.
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).