Google Cloud Spanner C++ Client  1.32.0
A C++ Client Library for Google Cloud Spanner
keys.h
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 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_KEYS_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_KEYS_H
17 
18 #include "google/cloud/spanner/value.h"
19 #include "google/cloud/spanner/version.h"
20 #include <google/spanner/v1/keys.pb.h>
21 #include <utility>
22 #include <vector>
23 
24 namespace google {
25 namespace cloud {
26 namespace spanner_internal {
27 inline namespace SPANNER_CLIENT_NS {
28 struct KeySetInternals;
29 } // namespace SPANNER_CLIENT_NS
30 } // namespace spanner_internal
31 
32 namespace spanner {
33 inline namespace SPANNER_CLIENT_NS {
34 
35 /**
36  * A `Key` is a collection of `Value` objects where the i'th value corresponds
37  * to the i'th component of the table or primary index key.
38  *
39  * In C++, this is implemented as a `std::vector<Value>`. See the `MakeKey`
40  * factory function below for an easy way to construct a valid `Key` instance.
41  */
42 using Key = std::vector<Value>;
43 
44 /**
45  * Constructs a `Key` from the given arguments.
46  *
47  * @par Example
48  * @snippet samples.cc make-key
49  */
50 template <typename... Ts>
51 Key MakeKey(Ts&&... ts) {
52  return Key{Value(std::forward<Ts>(ts))...};
53 }
54 
55 /**
56  * The `KeyBound` class is a regular type that represents an open or closed
57  * endpoint for a range of keys.
58  *
59  * A range of keys is defined by a starting `KeyBound` and an ending
60  * `KeyBound`, and it logically includes all intermediate keys, optionally
61  * including/excluding the bounds.
62  *
63  * `KeyBound`s can be "open", meaning the matching row will be excluded from
64  * the results, or "closed" meaning the matching row will be included.
65  * `KeyBound` instances should be created with the `MakeKeyBoundOpen()` or
66  * `MakeKeyBoundClosed()` factory functions.
67  *
68  * @par Example
69  * @snippet samples.cc make-keybound-open
70  *
71  * @par Example
72  * @snippet samples.cc make-keybound-closed
73  */
74 class KeyBound {
75  public:
76  /// An enum indicating whether the `Key` is included (closed) or excluded
77  /// (open).
78  enum class Bound { kClosed, kOpen };
79 
80  /// Not default constructible
81  KeyBound() = delete;
82 
83  /// Constructs an instance with the given @p key and @p bound.
84  KeyBound(Key key, Bound bound) : key_(std::move(key)), bound_(bound) {}
85 
86  /// @name Copy and move semantics.
87  ///@{
88  KeyBound(KeyBound const&) = default;
89  KeyBound& operator=(KeyBound const&) = default;
90  KeyBound(KeyBound&&) = default;
91  KeyBound& operator=(KeyBound&&) = default;
92  ///@}
93 
94  /// Returns the `Key`.
95  Key const& key() const& { return key_; }
96 
97  /// Returns the `Key` (by move).
98  Key&& key() && { return std::move(key_); }
99 
100  /// Returns the `Bound`.
101  Bound bound() const { return bound_; }
102 
103  /// @name Equality.
104  ///@{
105  friend bool operator==(KeyBound const& a, KeyBound const& b);
106  friend bool operator!=(KeyBound const& a, KeyBound const& b) {
107  return !(a == b);
108  }
109  ///@}
110 
111  private:
112  Key key_;
113  Bound bound_;
114 };
115 
116 /**
117  * Returns a "closed" `KeyBound` with a `Key` constructed from the given
118  * arguments.
119  *
120  * @par Example
121  * @snippet samples.cc make-keybound-closed
122  */
123 template <typename... Ts>
125  return KeyBound(MakeKey(std::forward<Ts>(ts)...), KeyBound::Bound::kClosed);
126 }
127 
128 /**
129  * Returns an "open" `KeyBound` with a `Key` constructed from the given
130  * arguments.
131  *
132  * @par Example
133  * @snippet samples.cc make-keybound-open
134  */
135 template <typename... Ts>
137  return KeyBound(MakeKey(std::forward<Ts>(ts)...), KeyBound::Bound::kOpen);
138 }
139 
140 /**
141  * The `KeySet` class is a regular type that represents a collection of `Key`s.
142  *
143  * Users can construct a `KeySet` instance, then add `Key`s and ranges of
144  * `Key`s to the set. The caller is responsible for ensuring that all keys in a
145  * given `KeySet` instance contain the same number and types of values.
146  *
147  * Users may also optionally construct an instance that
148  * represents all keys with `KeySet::All()`.
149  *
150  * @par Example
151  * @snippet samples.cc keyset-add-key
152  *
153  * @par Example
154  * @snippet samples.cc keyset-all
155  *
156  */
157 class KeySet {
158  public:
159  /**
160  * Returns a `KeySet` that represents the set of "All" keys for the index.
161  *
162  * @par Example
163  * @snippet samples.cc keyset-all
164  */
165  static KeySet All() {
166  KeySet ks;
167  ks.proto_.set_all(true);
168  return ks;
169  }
170 
171  /// Constructs an empty `KeySet`.
172  KeySet() = default;
173 
174  // Copy and move constructors and assignment operators.
175  KeySet(KeySet const&) = default;
176  KeySet& operator=(KeySet const&) = default;
177  KeySet(KeySet&&) = default;
178  KeySet& operator=(KeySet&&) = default;
179 
180  /**
181  * Adds the given @p key to the `KeySet`.
182  *
183  * @par Example
184  * @snippet samples.cc keyset-add-key
185  */
186  KeySet& AddKey(Key key);
187 
188  /**
189  * Adds a range of keys defined by the given `KeyBound`s.
190  *
191  * @par Example
192  * @snippet samples.cc keyset-add-key
193  */
194  KeySet& AddRange(KeyBound start, KeyBound end);
195 
196  /// @name Equality
197  ///@{
198  friend bool operator==(KeySet const& a, KeySet const& b);
199  friend bool operator!=(KeySet const& a, KeySet const& b) { return !(a == b); }
200  ///@}
201 
202  private:
203  friend struct spanner_internal::SPANNER_CLIENT_NS::KeySetInternals;
204  explicit KeySet(google::spanner::v1::KeySet proto)
205  : proto_(std::move(proto)) {}
206 
207  google::spanner::v1::KeySet proto_;
208 };
209 
210 } // namespace SPANNER_CLIENT_NS
211 } // namespace spanner
212 
213 namespace spanner_internal {
214 inline namespace SPANNER_CLIENT_NS {
215 struct KeySetInternals {
216  static ::google::spanner::v1::KeySet ToProto(spanner::KeySet&& ks) {
217  return std::move(ks.proto_);
218  }
219 
220  static spanner::KeySet FromProto(::google::spanner::v1::KeySet&& proto) {
221  return spanner::KeySet(std::move(proto));
222  }
223 };
224 
225 inline ::google::spanner::v1::KeySet ToProto(spanner::KeySet ks) {
226  return KeySetInternals::ToProto(std::move(ks));
227 }
228 
229 inline spanner::KeySet FromProto(::google::spanner::v1::KeySet ks) {
230  return KeySetInternals::FromProto(std::move(ks));
231 }
232 
233 } // namespace SPANNER_CLIENT_NS
234 } // namespace spanner_internal
235 } // namespace cloud
236 } // namespace google
237 
238 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_KEYS_H