/* * Copyright 2015 Cloudius Systems */ #pragma once #include "core/shared_ptr.hh" #include "query-request.hh" #include "query-result.hh" #include "schema.hh" #include #include #include namespace query { class no_such_column : public std::runtime_error { public: using runtime_error::runtime_error; }; class null_column_value : public std::runtime_error { public: using runtime_error::runtime_error; }; // Result set row is a set of cells that are associated with a row // including regular column cells, partition keys, as well as static values. class result_set_row { schema_ptr _schema; std::unordered_map _cells; public: result_set_row(schema_ptr schema, std::unordered_map&& cells) : _schema{schema} , _cells{std::move(cells)} { } bool has(const sstring& column_name) const { return _cells.count(column_name) > 0; } // Look up a deserialized row cell value by column name. const data_value& get_data_value(const sstring& column_name) const throw (no_such_column) { auto it = _cells.find(column_name); if (it == _cells.end()) { throw no_such_column(column_name); } return it->second; } // Look up a deserialized row cell value by column name. template std::experimental::optional get(const sstring& column_name) const throw (no_such_column) { auto&& value = get_data_value(column_name).value(); if (value.empty()) { return std::experimental::nullopt; } return std::experimental::optional{boost::any_cast(value)}; } template T get_nonnull(const sstring& column_name) const throw (no_such_column, null_column_value) { auto v = get(column_name); if (v) { return *v; } throw null_column_value(column_name); } friend inline bool operator==(const result_set_row& x, const result_set_row& y); friend inline bool operator!=(const result_set_row& x, const result_set_row& y); friend std::ostream& operator<<(std::ostream& out, const result_set_row& row); }; inline bool operator==(const result_set_row& x, const result_set_row& y) { return x._schema == y._schema && x._cells == y._cells; } inline bool operator!=(const result_set_row& x, const result_set_row& y) { return !(x == y); } // Result set is an in-memory representation of query results in // deserialized format. To obtain a result set, use the result_set_builder // class as a visitor to query_result::consume() function. class result_set { schema_ptr _schema; std::vector _rows; public: static result_set from_raw_result(schema_ptr, const partition_slice&, const result&); result_set(schema_ptr s, const std::vector& rows) : _schema(std::move(s)), _rows{std::move(rows)} { } bool empty() const { return _rows.empty(); } const result_set_row& row(size_t idx) const throw (std::out_of_range) { if (idx >= _rows.size()) { throw std::out_of_range("no such row in result set: " + std::to_string(idx)); } return _rows[idx]; } const std::vector& rows() const { return _rows; } const schema_ptr& schema() const { return _schema; } friend inline bool operator==(const result_set& x, const result_set& y); friend std::ostream& operator<<(std::ostream& out, const result_set& rs); }; inline bool operator==(const result_set& x, const result_set& y) { return x._rows == y._rows; } }