Skip to content

Commit 1322718

Browse files
authored
feat(bigtable): add support for QueryRow (#15565)
* feat(bigtable): add support for QueryRow
1 parent 8689a95 commit 1322718

File tree

8 files changed

+1279
-0
lines changed

8 files changed

+1279
-0
lines changed

google/cloud/bigtable/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ add_library(
229229
options.h
230230
polling_policy.cc
231231
polling_policy.h
232+
query_row.cc
233+
query_row.h
232234
read_modify_write_rule.h
233235
resource_names.cc
234236
resource_names.h
@@ -348,6 +350,7 @@ if (GOOGLE_CLOUD_CPP_WITH_MOCKS)
348350
admin/mocks/mock_bigtable_instance_admin_connection.h
349351
admin/mocks/mock_bigtable_table_admin_connection.h
350352
mocks/mock_data_connection.h
353+
mocks/mock_query_row.h
351354
mocks/mock_row_reader.cc
352355
mocks/mock_row_reader.h)
353356
target_link_libraries(
@@ -477,6 +480,7 @@ if (BUILD_TESTING)
477480
mutation_batcher_test.cc
478481
mutations_test.cc
479482
polling_policy_test.cc
483+
query_row_test.cc
480484
read_modify_write_rule_test.cc
481485
row_range_test.cc
482486
row_reader_test.cc

google/cloud/bigtable/bigtable_client_unit_tests.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ bigtable_client_unit_tests = [
7575
"mutation_batcher_test.cc",
7676
"mutations_test.cc",
7777
"polling_policy_test.cc",
78+
"query_row_test.cc",
7879
"read_modify_write_rule_test.cc",
7980
"row_range_test.cc",
8081
"row_reader_test.cc",

google/cloud/bigtable/google_cloud_cpp_bigtable.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ google_cloud_cpp_bigtable_hdrs = [
117117
"mutations.h",
118118
"options.h",
119119
"polling_policy.h",
120+
"query_row.h",
120121
"read_modify_write_rule.h",
121122
"resource_names.h",
122123
"retry_policy.h",
@@ -217,6 +218,7 @@ google_cloud_cpp_bigtable_srcs = [
217218
"mutation_batcher.cc",
218219
"mutations.cc",
219220
"polling_policy.cc",
221+
"query_row.cc",
220222
"resource_names.cc",
221223
"row_range.cc",
222224
"row_reader.cc",

google/cloud/bigtable/google_cloud_cpp_bigtable_mocks.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ google_cloud_cpp_bigtable_mocks_hdrs = [
2020
"admin/mocks/mock_bigtable_instance_admin_connection.h",
2121
"admin/mocks/mock_bigtable_table_admin_connection.h",
2222
"mocks/mock_data_connection.h",
23+
"mocks/mock_query_row.h",
2324
"mocks/mock_row_reader.h",
2425
]
2526

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_MOCKS_MOCK_QUERY_ROW_H
16+
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_MOCKS_MOCK_QUERY_ROW_H
17+
18+
#include "google/cloud/bigtable/query_row.h"
19+
#include "google/cloud/bigtable/value.h"
20+
#include "google/cloud/version.h"
21+
#include <string>
22+
#include <utility>
23+
#include <vector>
24+
25+
namespace google {
26+
namespace cloud {
27+
namespace bigtable_mocks {
28+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
29+
30+
/**
31+
* Creates a `bigtable::QueryRow` with the specified column names and values.
32+
*
33+
* This overload accepts a vector of pairs, allowing the caller to specify both
34+
* the column names and the `bigtable::Value` that goes in each column.
35+
*
36+
* This function is intended for application developers who are mocking the
37+
* results of a `Client::ReadRows` call.
38+
*/
39+
inline bigtable::QueryRow MakeQueryRow(
40+
std::vector<std::pair<std::string, bigtable::Value>> const& columns) {
41+
auto names = std::make_shared<std::vector<std::string>>();
42+
std::vector<bigtable::Value> values;
43+
for (auto const& c : columns) {
44+
names->push_back(c.first);
45+
values.push_back(c.second);
46+
}
47+
return bigtable_internal::QueryRowFriend::MakeQueryRow(values, names);
48+
}
49+
50+
/**
51+
* Creates a `bigtable::QueryRow` with `bigtable::Value`s created from the given
52+
* arguments and with auto-generated column names.
53+
*
54+
* This overload accepts a variadic list of arguments that will be used to
55+
* create the `bigtable::Value`s in the row. The column names will be implicitly
56+
* generated, the first column being "0", the second "1", and so on,
57+
* corresponding to the argument's position.
58+
*
59+
* This function is intended for application developers who are mocking the
60+
* results of a `Client::ReadRows` call.
61+
*/
62+
template <typename... Ts>
63+
bigtable::QueryRow MakeQueryRow(Ts&&... values) {
64+
auto names = std::make_shared<std::vector<std::string>>();
65+
int i = 0;
66+
for (auto const& v : {bigtable::Value(values)...}) {
67+
(void)v;
68+
names->push_back(std::to_string(i++));
69+
}
70+
return bigtable_internal::QueryRowFriend::MakeQueryRow(
71+
{bigtable::Value(values)...}, names);
72+
}
73+
74+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
75+
} // namespace bigtable_mocks
76+
} // namespace cloud
77+
} // namespace google
78+
79+
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_MOCKS_MOCK_QUERY_ROW_H

google/cloud/bigtable/query_row.cc

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/bigtable/query_row.h"
16+
#include "google/cloud/internal/make_status.h"
17+
#include "google/cloud/log.h"
18+
#include "google/cloud/status.h"
19+
#include "google/cloud/status_or.h"
20+
#include <algorithm>
21+
#include <iterator>
22+
#include <utility>
23+
24+
namespace google {
25+
namespace cloud {
26+
namespace bigtable_internal {
27+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
28+
bigtable::QueryRow QueryRowFriend::MakeQueryRow(
29+
std::vector<bigtable::Value> values,
30+
std::shared_ptr<std::vector<std::string> const> columns) {
31+
return bigtable::QueryRow(std::move(values), std::move(columns));
32+
}
33+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
34+
} // namespace bigtable_internal
35+
36+
namespace bigtable {
37+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
38+
39+
QueryRow::QueryRow()
40+
: QueryRow({}, std::make_shared<std::vector<std::string>>()) {}
41+
42+
QueryRow::QueryRow(std::vector<Value> values,
43+
std::shared_ptr<std::vector<std::string> const> columns)
44+
: values_(std::move(values)), columns_(std::move(columns)) {
45+
if (values_.size() != columns_->size()) {
46+
GCP_LOG(FATAL) << "QueryRow's value and column sizes do not match: "
47+
<< values_.size() << " vs " << columns_->size();
48+
}
49+
}
50+
51+
StatusOr<Value> QueryRow::get(std::size_t pos) const {
52+
if (pos < values_.size()) return values_[pos];
53+
return internal::InvalidArgumentError("position out of range",
54+
GCP_ERROR_INFO());
55+
}
56+
57+
StatusOr<Value> QueryRow::get(std::string const& name) const {
58+
auto it = std::find(columns_->begin(), columns_->end(), name);
59+
if (it != columns_->end()) return get(std::distance(columns_->begin(), it));
60+
return internal::InvalidArgumentError("column name not found",
61+
GCP_ERROR_INFO());
62+
}
63+
64+
bool operator==(QueryRow const& a, QueryRow const& b) {
65+
return a.values_ == b.values_ && *a.columns_ == *b.columns_;
66+
}
67+
68+
//
69+
// QueryRowStreamIterator
70+
//
71+
72+
QueryRowStreamIterator::QueryRowStreamIterator() = default;
73+
74+
QueryRowStreamIterator::QueryRowStreamIterator(Source source)
75+
: source_(std::move(source)) {
76+
++*this;
77+
}
78+
79+
QueryRowStreamIterator& QueryRowStreamIterator::operator++() {
80+
if (!row_ok_) {
81+
source_ = nullptr; // Last row was an error; become "end"
82+
return *this;
83+
}
84+
row_ = source_();
85+
row_ok_ = row_.ok();
86+
if (row_ && row_->size() == 0) {
87+
source_ = nullptr; // No more Rows to consume; become "end"
88+
return *this;
89+
}
90+
return *this;
91+
}
92+
93+
QueryRowStreamIterator QueryRowStreamIterator::operator++(int) {
94+
auto old = *this;
95+
++*this;
96+
return old;
97+
}
98+
99+
bool operator==(QueryRowStreamIterator const& a,
100+
QueryRowStreamIterator const& b) {
101+
// Input iterators may only be compared to (copies of) themselves and end.
102+
// See https://en.cppreference.com/w/cpp/named_req/InputIterator. Therefore,
103+
// by definition, all input iterators are equal unless one is end and the
104+
// other is not.
105+
return !a.source_ == !b.source_;
106+
}
107+
108+
bool operator!=(QueryRowStreamIterator const& a,
109+
QueryRowStreamIterator const& b) {
110+
return !(a == b);
111+
}
112+
113+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
114+
} // namespace bigtable
115+
} // namespace cloud
116+
} // namespace google

0 commit comments

Comments
 (0)