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