Apache Ignite C++ Client
Loading...
Searching...
No Matches
ignite_tuple.h
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#include "ignite/common/ignite_error.h"
21#include "ignite/common/primitive.h"
22
23#include <initializer_list>
24#include <string_view>
25#include <unordered_map>
26#include <utility>
27#include <vector>
28
29namespace ignite {
30// Forward declaration.
31class ignite_tuple;
32
33namespace detail {
34ignite_tuple concat(const ignite_tuple &left, const ignite_tuple &right);
35}
36
40class ignite_tuple {
41 friend ignite_tuple detail::concat(const ignite_tuple &left, const ignite_tuple &right);
42
43public:
44 // Default
45 ignite_tuple() = default;
46
52 explicit ignite_tuple(size_t capacity) {
53 m_pairs.reserve(capacity);
54 m_indices.reserve(capacity);
55 }
56
62 ignite_tuple(std::initializer_list<std::pair<std::string, primitive>> pairs)
63 : m_pairs(pairs)
64 , m_indices() {
65 m_indices.reserve(pairs.size());
66 for (size_t i = 0; i < m_pairs.size(); ++i)
67 m_indices.emplace(std::make_pair(parse_name(m_pairs[i].first), i));
68 }
69
75 [[nodiscard]] std::int32_t column_count() const noexcept { return std::int32_t(m_pairs.size()); }
76
83 [[nodiscard]] const primitive &get(uint32_t idx) const {
84 if (idx > m_pairs.size()) {
85 throw ignite_error(error::code::ILLEGAL_ARGUMENT,
86 "Index is too large: idx=" + std::to_string(idx) + ", columns_num=" + std::to_string(m_pairs.size()));
87 }
88 return m_pairs[idx].second;
89 }
90
98 template<typename T>
99 [[nodiscard]] T get(uint32_t idx) const {
100 return get(idx).template get<T>();
101 }
102
110 template<typename T>
111 void set(uint32_t idx, T &&value) {
112 if (idx > m_pairs.size()) {
113 throw ignite_error(error::code::ILLEGAL_ARGUMENT,
114 "Index is too large: idx=" + std::to_string(idx) + ", columns_num=" + std::to_string(m_pairs.size()));
115 }
116 m_pairs[idx].second = std::forward<T>(value);
117 }
118
125 [[nodiscard]] const primitive &get(std::string_view name) const {
126 auto it = m_indices.find(parse_name(name));
127 if (it == m_indices.end())
128 throw ignite_error(error::code::ILLEGAL_ARGUMENT,
129 "Can not find column with the name '" + std::string(name) + "' in the tuple");
130 auto idx = it->second;
131 return m_pairs[idx].second;
132 }
133
141 template<typename T>
142 [[nodiscard]] T get(std::string_view name) const {
143 return get(name).template get<T>();
144 }
145
153 template<typename T>
154 void set(std::string_view name, T &&value) {
155 auto parsed_name = parse_name(name);
156 auto it = m_indices.find(parsed_name);
157 if (it != m_indices.end()) {
158 auto idx = it->second;
159 m_pairs[idx].second = std::forward<T>(value);
160 return;
161 }
162
163 m_pairs.emplace_back(name, std::forward<T>(value));
164 m_indices.emplace(parsed_name, m_pairs.size() - 1);
165 }
166
173 [[nodiscard]] const std::string &column_name(uint32_t idx) const {
174 if (idx > m_pairs.size()) {
175 throw ignite_error(error::code::ILLEGAL_ARGUMENT,
176 "Index is too large: idx=" + std::to_string(idx) + ", columns_num=" + std::to_string(m_pairs.size()));
177 }
178 return m_pairs[idx].first;
179 }
180
188 [[nodiscard]] std::int32_t column_ordinal(std::string_view name) const {
189 auto it = m_indices.find(parse_name(name));
190 if (it == m_indices.end())
191 return -1;
192 return std::int32_t(it->second);
193 }
194
195private:
203 std::vector<std::pair<std::string, primitive>> &&pairs, std::unordered_map<std::string, size_t> indices)
204 : m_pairs(std::move(pairs))
205 , m_indices(std::move(indices)) {}
206
213 [[nodiscard]] static std::string parse_name(std::string_view name) {
214 if (name.size() >= 2 && name.front() == '"' && name.back() == '"')
215 name = name.substr(1, name.size() - 2);
216
217 if (name.empty())
218 throw ignite_error("Column name can not be an empty string");
219
220 std::string res;
221 res.reserve(name.size());
222
223 for (auto c : name) {
224 res.push_back(char(std::toupper(c)));
225 }
226
227 return res;
228 }
229
231 std::vector<std::pair<std::string, primitive>> m_pairs;
232
234 std::unordered_map<std::string, std::size_t> m_indices;
235};
236
237} // namespace ignite
Definition ignite_error.h:35
Definition ignite_tuple.h:40
ignite_tuple(size_t capacity)
Definition ignite_tuple.h:52
std::int32_t column_count() const noexcept
Definition ignite_tuple.h:75
void set(uint32_t idx, T &&value)
Definition ignite_tuple.h:111
const std::string & column_name(uint32_t idx) const
Definition ignite_tuple.h:173
ignite_tuple(std::initializer_list< std::pair< std::string, primitive > > pairs)
Definition ignite_tuple.h:62
std::int32_t column_ordinal(std::string_view name) const
Definition ignite_tuple.h:188
const primitive & get(std::string_view name) const
Definition ignite_tuple.h:125
T get(std::string_view name) const
Definition ignite_tuple.h:142
const primitive & get(uint32_t idx) const
Definition ignite_tuple.h:83
void set(std::string_view name, T &&value)
Definition ignite_tuple.h:154
T get(uint32_t idx) const
Definition ignite_tuple.h:99
Definition primitive.h:43