Google Cloud Spanner C++ Client  1.32.0
A C++ Client Library for Google Cloud Spanner
row.cc
Go to the documentation of this file.
1 // Copyright 2019 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 // http://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/spanner/row.h"
16 #include "google/cloud/log.h"
17 #include "google/cloud/status.h"
18 #include "google/cloud/status_or.h"
19 #include <algorithm>
20 #include <iterator>
21 #include <utility>
22 
23 namespace google {
24 namespace cloud {
25 namespace spanner_internal {
26 inline namespace SPANNER_CLIENT_NS {
27 spanner::Row MakeRow(std::vector<spanner::Value> values,
28  std::shared_ptr<std::vector<std::string> const> columns) {
29  return spanner::Row(std::move(values), std::move(columns));
30 }
31 } // namespace SPANNER_CLIENT_NS
32 } // namespace spanner_internal
33 
34 namespace spanner {
35 inline namespace SPANNER_CLIENT_NS {
36 Row MakeTestRow(std::vector<std::pair<std::string, Value>> pairs) {
37  auto values = std::vector<Value>{};
38  auto columns = std::make_shared<std::vector<std::string>>();
39  for (auto& p : pairs) {
40  values.emplace_back(std::move(p.second));
41  columns->emplace_back(std::move(p.first));
42  }
43  return spanner_internal::MakeRow(std::move(values), std::move(columns));
44 }
45 
46 Row::Row() : Row({}, std::make_shared<std::vector<std::string>>()) {}
47 
48 Row::Row(std::vector<Value> values,
49  std::shared_ptr<const std::vector<std::string>> columns)
50  : values_(std::move(values)), columns_(std::move(columns)) {
51  if (values_.size() != columns_->size()) {
52  GCP_LOG(FATAL) << "Row's value and column sizes do not match: "
53  << values_.size() << " vs " << columns_->size();
54  }
55 }
56 
57 // NOLINTNEXTLINE(readability-identifier-naming)
58 StatusOr<Value> Row::get(std::size_t pos) const {
59  if (pos < values_.size()) return values_[pos];
60  return Status(StatusCode::kInvalidArgument, "position out of range");
61 }
62 
63 // NOLINTNEXTLINE(readability-identifier-naming)
64 StatusOr<Value> Row::get(std::string const& name) const {
65  auto it = std::find(columns_->begin(), columns_->end(), name);
66  if (it != columns_->end()) return get(std::distance(columns_->begin(), it));
67  return Status(StatusCode::kInvalidArgument, "column name not found");
68 }
69 
70 bool operator==(Row const& a, Row const& b) {
71  return a.values_ == b.values_ && *a.columns_ == *b.columns_;
72 }
73 
74 //
75 // RowStreamIterator
76 //
77 
79 
81  : row_(Row{}), source_(std::move(source)) {
82  ++*this;
83 }
84 
86  if (!row_) {
87  source_ = nullptr; // Last row was an error; become "end"
88  return *this;
89  }
90  row_ = source_();
91  if (row_ && row_->size() == 0) {
92  source_ = nullptr; // No more Rows to consume; become "end"
93  return *this;
94  }
95  return *this;
96 }
97 
99  auto old = *this;
100  ++*this;
101  return old;
102 }
103 
104 bool operator==(RowStreamIterator const& a, RowStreamIterator const& b) {
105  // Input iterators may only be compared to (copies of) themselves and end.
106  // See https://en.cppreference.com/w/cpp/named_req/InputIterator. Therefore,
107  // by definition, all input iterators are equal unless one is end and the
108  // other is not.
109  return !a.source_ == !b.source_;
110 }
111 
112 bool operator!=(RowStreamIterator const& a, RowStreamIterator const& b) {
113  return !(a == b);
114 }
115 
116 } // namespace SPANNER_CLIENT_NS
117 } // namespace spanner
118 } // namespace cloud
119 } // namespace google