1 // Copyright 2020 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/bigtable/examples/bigtable_examples_common.h"
16 #include "google/cloud/bigtable/table.h"
17 #include "google/cloud/bigtable/table_admin.h"
18 #include "google/cloud/internal/getenv.h"
19 #include "google/cloud/internal/random.h"
20 #include "google/cloud/testing_util/crash_handler.h"
21 #include <chrono>
22 #include <sstream>
23
24 namespace {
25
26 using google::cloud::bigtable::examples::Usage;
27 using std::chrono::microseconds;
28 using std::chrono::milliseconds;
29
FilterLimitRowSample(google::cloud::bigtable::Table table,std::vector<std::string> const &)30 void FilterLimitRowSample(google::cloud::bigtable::Table table,
31 std::vector<std::string> const&) {
32 //! [START bigtable_filters_limit_row_sample]
33 namespace cbt = google::cloud::bigtable;
34 using google::cloud::StatusOr;
35 [](cbt::Table table) {
36 // Filter the results, only include rows with a given probability
37 cbt::Filter filter = cbt::Filter::RowSample(0.75);
38
39 // Read and print the rows.
40 for (StatusOr<cbt::Row> const& row :
41 table.ReadRows(cbt::RowSet(cbt::RowRange::InfiniteRange()), filter)) {
42 if (!row) throw std::runtime_error(row.status().message());
43 std::cout << row->row_key() << " = ";
44 for (auto const& cell : row->cells()) {
45 std::cout << "[" << cell.family_name() << ", "
46 << cell.column_qualifier() << ", " << cell.value() << "],";
47 }
48 std::cout << "\n";
49 }
50 }
51 //! [END bigtable_filters_limit_row_sample]
52 (std::move(table));
53 }
54
FilterLimitRowRegex(google::cloud::bigtable::Table table,std::vector<std::string> const &)55 void FilterLimitRowRegex(google::cloud::bigtable::Table table,
56 std::vector<std::string> const&) {
57 //! [START bigtable_filters_limit_row_regex]
58 namespace cbt = google::cloud::bigtable;
59 using google::cloud::StatusOr;
60 [](cbt::Table table) {
61 // Create the range of rows to read.
62 auto range = cbt::RowRange::Range("key-000010", "key-000030");
63 // Filter the results, only include rows where row_key matchs given regular
64 // expression
65 cbt::Filter filter = cbt::Filter::RowKeysRegex("key.*9$");
66 // Read and print the rows.
67 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
68 if (!row) throw std::runtime_error(row.status().message());
69 std::cout << row->row_key() << " = ";
70 for (auto const& cell : row->cells()) {
71 std::cout << "[" << cell.family_name() << ", "
72 << cell.column_qualifier() << ", " << cell.value() << "],";
73 }
74 std::cout << "\n";
75 }
76 }
77 //! [END bigtable_filters_limit_row_regex]
78 (std::move(table));
79 }
80
FilterLimitCellsPerColumn(google::cloud::bigtable::Table table,std::vector<std::string> const &)81 void FilterLimitCellsPerColumn(google::cloud::bigtable::Table table,
82 std::vector<std::string> const&) {
83 //! [START bigtable_filters_limit_cells_per_col]
84 namespace cbt = google::cloud::bigtable;
85 using google::cloud::StatusOr;
86 [](cbt::Table table) {
87 // Create the range of rows to read.
88 auto range = cbt::RowRange::Range("key-000010", "key-000020");
89 // Filter the results, only include limited cells
90 cbt::Filter filter = cbt::Filter::Latest(2);
91 // Read and print the rows.
92 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
93 if (!row) throw std::runtime_error(row.status().message());
94 std::cout << row->row_key() << " = ";
95 for (auto const& cell : row->cells()) {
96 std::cout << "[" << cell.family_name() << ", "
97 << cell.column_qualifier() << ", " << cell.value() << "],";
98 }
99 std::cout << "\n";
100 }
101 }
102 //! [END bigtable_filters_limit_cells_per_col]
103 (std::move(table));
104 }
105
FilterLimitCellsPerRow(google::cloud::bigtable::Table table,std::vector<std::string> const &)106 void FilterLimitCellsPerRow(google::cloud::bigtable::Table table,
107 std::vector<std::string> const&) {
108 //! [START bigtable_filters_limit_cells_per_row]
109 namespace cbt = google::cloud::bigtable;
110 using google::cloud::StatusOr;
111 [](cbt::Table table) {
112 // Create the range of rows to read.
113 auto range = cbt::RowRange::Range("key-000010", "key-000020");
114 // Filter the results, only include limited cells per row
115 cbt::Filter filter = cbt::Filter::CellsRowLimit(2);
116 // Read and print the rows.
117 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
118 if (!row) throw std::runtime_error(row.status().message());
119 std::cout << row->row_key() << " = ";
120 for (auto const& cell : row->cells()) {
121 std::cout << "[" << cell.family_name() << ", "
122 << cell.column_qualifier() << ", " << cell.value() << "],";
123 }
124 std::cout << "\n";
125 }
126 }
127 //! [END bigtable_filters_limit_cells_per_row]
128 (std::move(table));
129 }
130
FilterLimitCellsPerRowOfset(google::cloud::bigtable::Table table,std::vector<std::string> const &)131 void FilterLimitCellsPerRowOfset(google::cloud::bigtable::Table table,
132 std::vector<std::string> const&) {
133 //! [START bigtable_filters_limit_cells_per_row_offset]
134 namespace cbt = google::cloud::bigtable;
135 using google::cloud::StatusOr;
136 [](cbt::Table table) {
137 // Create the range of rows to read.
138 auto range = cbt::RowRange::Range("key-000010", "key-000020");
139 cbt::Filter filter = cbt::Filter::CellsRowOffset(2);
140 // Read and print the rows.
141 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
142 if (!row) throw std::runtime_error(row.status().message());
143 std::cout << row->row_key() << " = ";
144 for (auto const& cell : row->cells()) {
145 std::cout << "[" << cell.family_name() << ", "
146 << cell.column_qualifier() << ", " << cell.value() << "],";
147 }
148 std::cout << "\n";
149 }
150 }
151 //! [END bigtable_filters_limit_cells_per_row_offset]
152 (std::move(table));
153 }
154
FilterLimitColFamilyRegex(google::cloud::bigtable::Table table,std::vector<std::string> const &)155 void FilterLimitColFamilyRegex(google::cloud::bigtable::Table table,
156 std::vector<std::string> const&) {
157 //! [START bigtable_filters_limit_col_family_regex]
158 namespace cbt = google::cloud::bigtable;
159 using google::cloud::StatusOr;
160 [](cbt::Table table) {
161 // Create the range of rows to read.
162 auto range = cbt::RowRange::Range("key-000011", "key-000015");
163 cbt::Filter filter = cbt::Filter::FamilyRegex("fam-1.*");
164 // Read and print the rows.
165 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
166 if (!row) throw std::runtime_error(row.status().message());
167 std::cout << row->row_key() << " = ";
168 for (auto const& cell : row->cells()) {
169 std::cout << "[" << cell.family_name() << ", "
170 << cell.column_qualifier() << ", " << cell.value() << "],";
171 }
172 std::cout << "\n";
173 }
174 }
175 //! [END bigtable_filters_limit_col_family_regex]
176 (std::move(table));
177 }
178
FilterLimitColQualifierRegex(google::cloud::bigtable::Table table,std::vector<std::string> const &)179 void FilterLimitColQualifierRegex(google::cloud::bigtable::Table table,
180 std::vector<std::string> const&) {
181 //! [START bigtable_filters_limit_col_qualifier_regex]
182 namespace cbt = google::cloud::bigtable;
183 using google::cloud::StatusOr;
184 [](cbt::Table table) {
185 // Create the range of rows to read.
186 auto range = cbt::RowRange::Range("key-000011", "key-000015");
187 cbt::Filter filter = cbt::Filter::ColumnRegex("col-[a,b].*$");
188 // Read and print the rows.
189 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
190 if (!row) throw std::runtime_error(row.status().message());
191 std::cout << row->row_key() << " = ";
192 for (auto const& cell : row->cells()) {
193 std::cout << "[" << cell.family_name() << ", "
194 << cell.column_qualifier() << ", " << cell.value() << "],";
195 }
196 std::cout << "\n";
197 }
198 }
199 //! [END bigtable_filters_limit_col_qualifier_regex]
200 (std::move(table));
201 }
202
FilterLimitColRange(google::cloud::bigtable::Table table,std::vector<std::string> const &)203 void FilterLimitColRange(google::cloud::bigtable::Table table,
204 std::vector<std::string> const&) {
205 //! [START bigtable_filters_limit_col_range]
206 namespace cbt = google::cloud::bigtable;
207 using google::cloud::StatusOr;
208 [](cbt::Table table) {
209 // Create the range of rows to read.
210 auto range = cbt::RowRange::Range("key-000011", "key-000015");
211 cbt::Filter filter = cbt::Filter::ColumnRange("fam-0", "col-a", "col-c");
212 // Read and print the rows.
213 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
214 if (!row) throw std::runtime_error(row.status().message());
215 std::cout << row->row_key() << " = ";
216 for (auto const& cell : row->cells()) {
217 std::cout << "[" << cell.family_name() << ", "
218 << cell.column_qualifier() << ", " << cell.value() << "],";
219 }
220 std::cout << "\n";
221 }
222 }
223 //! [END bigtable_filters_limit_col_range]
224 (std::move(table));
225 }
226
FilterLimitValueRange(google::cloud::bigtable::Table table,std::vector<std::string> const &)227 void FilterLimitValueRange(google::cloud::bigtable::Table table,
228 std::vector<std::string> const&) {
229 //! [START bigtable_filters_limit_value_range]
230 namespace cbt = google::cloud::bigtable;
231 using google::cloud::StatusOr;
232 [](cbt::Table table) {
233 // Create the range of rows to read.
234 auto range = cbt::RowRange::Range("key-000011", "key-000015");
235 cbt::Filter filter = cbt::Filter::ValueRange("value-0", "value-2");
236 // Read and print the rows.
237 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
238 if (!row) throw std::runtime_error(row.status().message());
239 std::cout << row->row_key() << " = ";
240 for (auto const& cell : row->cells()) {
241 std::cout << "[" << cell.family_name() << ", "
242 << cell.column_qualifier() << ", " << cell.value() << "],";
243 }
244 std::cout << "\n";
245 }
246 }
247 //! [END bigtable_filters_limit_value_range]
248 (std::move(table));
249 }
250
FilterLimitValueRegex(google::cloud::bigtable::Table table,std::vector<std::string> const &)251 void FilterLimitValueRegex(google::cloud::bigtable::Table table,
252 std::vector<std::string> const&) {
253 //! [START bigtable_filters_limit_value_regex]
254 namespace cbt = google::cloud::bigtable;
255 using google::cloud::StatusOr;
256 [](cbt::Table table) {
257 // Create the range of rows to read.
258 auto range = cbt::RowRange::Range("key-000011", "key-000015");
259 cbt::Filter filter = cbt::Filter::ValueRegex("value-0.*");
260 // Read and print the rows.
261 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
262 if (!row) throw std::runtime_error(row.status().message());
263 std::cout << row->row_key() << " = ";
264 for (auto const& cell : row->cells()) {
265 std::cout << "[" << cell.family_name() << ", "
266 << cell.column_qualifier() << ", " << cell.value() << "],";
267 }
268 std::cout << "\n";
269 }
270 }
271 //! [END bigtable_filters_limit_value_regex]
272 (std::move(table));
273 }
274
FilterLimitTimestampRange(google::cloud::bigtable::Table table,std::vector<std::string> const &)275 void FilterLimitTimestampRange(google::cloud::bigtable::Table table,
276 std::vector<std::string> const&) {
277 //! [START bigtable_filters_limit_timestamp_range]
278 namespace cbt = google::cloud::bigtable;
279 using google::cloud::StatusOr;
280 [](cbt::Table table) {
281 // Create the range of rows to read.
282 auto range = cbt::RowRange::Range("key-000011", "key-000015");
283 cbt::Filter filter =
284 cbt::Filter::TimestampRange(microseconds(1000), milliseconds(2));
285 // Read and print the rows.
286 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
287 if (!row) throw std::runtime_error(row.status().message());
288 std::cout << row->row_key() << " = ";
289 for (auto const& cell : row->cells()) {
290 std::cout << "[" << cell.family_name() << ", "
291 << cell.column_qualifier() << ", " << cell.value() << "],";
292 }
293 std::cout << "\n";
294 }
295 }
296 //! [END bigtable_filters_limit_timestamp_range]
297 (std::move(table));
298 }
299
FilterLimitBlockAll(google::cloud::bigtable::Table table,std::vector<std::string> const &)300 void FilterLimitBlockAll(google::cloud::bigtable::Table table,
301 std::vector<std::string> const&) {
302 //! [START bigtable_filters_limit_block_all]
303 namespace cbt = google::cloud::bigtable;
304 using google::cloud::StatusOr;
305 [](cbt::Table table) {
306 // Create the range of rows to read.
307 auto range = cbt::RowRange::Range("key-000000", "key-000050");
308 cbt::Filter filter = cbt::Filter::BlockAllFilter();
309 // Read and print the rows.
310 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
311 if (!row) throw std::runtime_error(row.status().message());
312 std::cout << row->row_key();
313 std::cout << row->row_key() << " = ";
314 for (auto const& cell : row->cells()) {
315 std::cout << "[" << cell.family_name() << ", "
316 << cell.column_qualifier() << ", " << cell.value() << "],";
317 }
318 std::cout << "\n";
319 }
320 }
321 //! [END bigtable_filters_limit_block_all]
322 (std::move(table));
323 }
324
FilterLimitPassAll(google::cloud::bigtable::Table table,std::vector<std::string> const &)325 void FilterLimitPassAll(google::cloud::bigtable::Table table,
326 std::vector<std::string> const&) {
327 //! [START bigtable_filters_limit_pass_all]
328 namespace cbt = google::cloud::bigtable;
329 using google::cloud::StatusOr;
330 [](cbt::Table table) {
331 // Create the range of rows to read.
332 auto range = cbt::RowRange::Range("key-000011", "key-000015");
333 cbt::Filter filter = cbt::Filter::PassAllFilter();
334 // Read and print the rows.
335 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
336 if (!row) throw std::runtime_error(row.status().message());
337 std::cout << row->row_key() << " = ";
338 for (auto const& cell : row->cells()) {
339 std::cout << "[" << cell.family_name() << ", "
340 << cell.column_qualifier() << ", " << cell.value() << "],";
341 }
342 std::cout << "\n";
343 }
344 }
345 //! [END bigtable_filters_limit_pass_all]
346 (std::move(table));
347 }
348
FilterModifyStripValue(google::cloud::bigtable::Table table,std::vector<std::string> const &)349 void FilterModifyStripValue(google::cloud::bigtable::Table table,
350 std::vector<std::string> const&) {
351 //! [START bigtable_filters_modify_strip_value]
352 namespace cbt = google::cloud::bigtable;
353 using google::cloud::StatusOr;
354 [](cbt::Table table) {
355 // Create the range of rows to read.
356 auto range = cbt::RowRange::Range("key-000011", "key-000015");
357 cbt::Filter filter = cbt::Filter::StripValueTransformer();
358 // Read and print the rows.
359 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
360 if (!row) throw std::runtime_error(row.status().message());
361 std::cout << row->row_key() << " = ";
362 for (auto const& cell : row->cells()) {
363 std::cout << "[" << cell.family_name() << ", "
364 << cell.column_qualifier() << ", " << cell.value() << "],";
365 }
366 std::cout << "\n";
367 }
368 }
369 //! [END bigtable_filters_modify_strip_value]
370 (std::move(table));
371 }
372
FilterModifyApplyLabel(google::cloud::bigtable::Table table,std::vector<std::string> const &)373 void FilterModifyApplyLabel(google::cloud::bigtable::Table table,
374 std::vector<std::string> const&) {
375 //! [START bigtable_filters_modify_apply_label]
376 namespace cbt = google::cloud::bigtable;
377 using google::cloud::StatusOr;
378 [](cbt::Table table) {
379 // Create the range of rows to read.
380 auto range = cbt::RowRange::Range("key-000011", "key-000015");
381 cbt::Filter filter = cbt::Filter::ApplyLabelTransformer("label-value");
382 // Read and print the rows.
383 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
384 if (!row) throw std::runtime_error(row.status().message());
385 std::cout << row->row_key() << " = ";
386 for (auto const& cell : row->cells()) {
387 std::cout << "[" << cell.family_name() << ", "
388 << cell.column_qualifier() << ", " << cell.value()
389 << ", label(";
390 for (auto const& label : cell.labels()) {
391 std::cout << label << ",";
392 }
393 std::cout << ")],";
394 }
395 std::cout << "\n";
396 }
397 }
398 //! [END bigtable_filters_modify_apply_label]
399 (std::move(table));
400 }
401
FilterComposingChain(google::cloud::bigtable::Table table,std::vector<std::string> const &)402 void FilterComposingChain(google::cloud::bigtable::Table table,
403 std::vector<std::string> const&) {
404 //! [START bigtable_filters_composing_chain]
405 namespace cbt = google::cloud::bigtable;
406 using google::cloud::StatusOr;
407 [](cbt::Table table) {
408 // Create the range of rows to read.
409 auto range = cbt::RowRange::Range("key-000011", "key-000015");
410 cbt::Filter filter = cbt::Filter::Chain(cbt::Filter::Latest(1),
411 cbt::Filter::FamilyRegex("fam-0"));
412 // Read and print the rows.
413 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
414 if (!row) throw std::runtime_error(row.status().message());
415 std::cout << row->row_key() << " = ";
416 for (auto const& cell : row->cells()) {
417 std::cout << "[" << cell.family_name() << ", "
418 << cell.column_qualifier() << ", " << cell.value() << "],";
419 }
420 std::cout << "\n";
421 }
422 }
423 //! [END bigtable_filters_composing_chain]
424 (std::move(table));
425 }
426
FilterComposingInterleave(google::cloud::bigtable::Table table,std::vector<std::string> const &)427 void FilterComposingInterleave(google::cloud::bigtable::Table table,
428 std::vector<std::string> const&) {
429 //! [START bigtable_filters_composing_interleave]
430 namespace cbt = google::cloud::bigtable;
431 using google::cloud::StatusOr;
432 [](cbt::Table table) {
433 // Create the range of rows to read.
434 auto range = cbt::RowRange::Range("key-000011", "key-000015");
435 cbt::Filter filter = cbt::Filter::Interleave(
436 cbt::Filter::FamilyRegex("fam-1"), cbt::Filter::ColumnRegex("col-c"));
437 // Read and print the rows.
438 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
439 if (!row) throw std::runtime_error(row.status().message());
440 std::cout << row->row_key() << " = ";
441 for (auto const& cell : row->cells()) {
442 std::cout << "[" << cell.family_name() << ", "
443 << cell.column_qualifier() << ", " << cell.value() << "],";
444 }
445 std::cout << "\n";
446 }
447 }
448 //! [END bigtable_filters_composing_interleave]
449 (std::move(table));
450 }
451
FilterComposingCondition(google::cloud::bigtable::Table table,std::vector<std::string> const &)452 void FilterComposingCondition(google::cloud::bigtable::Table table,
453 std::vector<std::string> const&) {
454 //! [START bigtable_filters_composing_condition]
455 namespace cbt = google::cloud::bigtable;
456 using google::cloud::StatusOr;
457 [](cbt::Table table) {
458 // Create the range of rows to read.
459 auto range = cbt::RowRange::Range("key-000000", "key-000005");
460 cbt::Filter filter = cbt::Filter::Condition(
461 cbt::Filter::Chain(cbt::Filter::FamilyRegex("fam-0"),
462 cbt::Filter::ColumnRegex("col-a")),
463 cbt::Filter::ApplyLabelTransformer("condition"),
464 cbt::Filter::StripValueTransformer());
465 // Read and print the rows.
466 for (StatusOr<cbt::Row> const& row : table.ReadRows(range, filter)) {
467 if (!row) throw std::runtime_error(row.status().message());
468 std::cout << row->row_key() << " = ";
469 for (auto const& cell : row->cells()) {
470 std::cout << "[" << cell.family_name() << ", "
471 << cell.column_qualifier() << ", " << cell.value()
472 << ", label(";
473 for (auto const& label : cell.labels()) {
474 std::cout << label << ",";
475 }
476 std::cout << ")],";
477 }
478 std::cout << "\n";
479 }
480 }
481 //! [END bigtable_filters_composing_condition]
482 (std::move(table));
483 }
484
485 // This command just generates data suitable for other examples to run. This
486 // code is not extracted into the documentation.
InsertTestData(google::cloud::bigtable::Table table,std::vector<std::string> const &)487 void InsertTestData(google::cloud::bigtable::Table table,
488 std::vector<std::string> const&) {
489 // Write several rows in a single operation, each row has some trivial data.
490 // This is not a code sample in the normal sense, we do not display this code
491 // in the documentation. We use it to populate data in the table used to run
492 // the actual examples during the CI builds.
493 namespace cbt = google::cloud::bigtable;
494 cbt::BulkMutation bulk;
495 for (int i = 0; i != 50; ++i) {
496 // Note: This example uses sequential numeric IDs for simplicity, but
497 // this can result in poor performance in a production application.
498 // Since rows are stored in sorted order by key, sequential keys can
499 // result in poor distribution of operations across nodes.
500 //
501 // For more information about how to design a Bigtable schema for the
502 // best performance, see the documentation:
503 //
504 // https://cloud.google.com/bigtable/docs/schema-design
505 char buf[32];
506 snprintf(buf, sizeof(buf), "key-%06d", i);
507 cbt::SingleRowMutation mutation(buf);
508 mutation.emplace_back(cbt::SetCell("fam-0", "col-a", milliseconds(1),
509 "value-0-" + std::to_string(i)));
510 mutation.emplace_back(cbt::SetCell("fam-0", "col-a", milliseconds(2),
511 "value-1-" + std::to_string(i)));
512 mutation.emplace_back(cbt::SetCell("fam-0", "col-b", milliseconds(1),
513 "value-0-" + std::to_string(i)));
514 mutation.emplace_back(cbt::SetCell("fam-0", "col-c", milliseconds(1),
515 "value-0-" + std::to_string(i)));
516 mutation.emplace_back(cbt::SetCell("fam-0", "col-c", milliseconds(2),
517 "value-1-" + std::to_string(i)));
518 mutation.emplace_back(cbt::SetCell("fam-0", "col-c", milliseconds(3),
519 "value-2-" + std::to_string(i)));
520 mutation.emplace_back(cbt::SetCell("fam-1", "col-a", milliseconds(1),
521 "value-0-" + std::to_string(i)));
522 bulk.emplace_back(std::move(mutation));
523 }
524 auto failures = table.BulkApply(std::move(bulk));
525 if (failures.empty()) {
526 return;
527 }
528 std::cerr << "The following mutations failed:\n";
529 for (auto const& f : failures) {
530 std::cerr << "index[" << f.original_index() << "]=" << f.status() << "\n";
531 }
532 throw std::runtime_error(failures.front().status().message());
533 }
534
DefaultTablePrefix()535 std::string DefaultTablePrefix() { return "tbl-data-"; }
536
RunAll(std::vector<std::string> const & argv)537 void RunAll(std::vector<std::string> const& argv) {
538 namespace examples = ::google::cloud::bigtable::examples;
539 namespace cbt = google::cloud::bigtable;
540
541 if (!argv.empty()) throw google::cloud::bigtable::examples::Usage{"auto"};
542 examples::CheckEnvironmentVariablesAreSet({
543 "GOOGLE_CLOUD_PROJECT",
544 "GOOGLE_CLOUD_CPP_BIGTABLE_TEST_INSTANCE_ID",
545 });
546 auto const project_id =
547 google::cloud::internal::GetEnv("GOOGLE_CLOUD_PROJECT").value();
548 auto const instance_id = google::cloud::internal::GetEnv(
549 "GOOGLE_CLOUD_CPP_BIGTABLE_TEST_INSTANCE_ID")
550 .value();
551
552 cbt::TableAdmin admin(
553 cbt::CreateDefaultAdminClient(project_id, cbt::ClientOptions{}),
554 instance_id);
555
556 // If a previous run of these samples crashes before cleaning up there may be
557 // old tables left over. As there are quotas on the total number of tables we
558 // remove stale tables after 48 hours.
559 examples::CleanupOldTables(DefaultTablePrefix(), admin);
560 examples::CleanupOldTables("mobile-time-series-", admin);
561
562 // Initialize a generator with some amount of entropy.
563 auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}());
564
565 auto table_id = examples::RandomTableId(DefaultTablePrefix(), generator);
566 auto schema = admin.CreateTable(
567 table_id, cbt::TableConfig({{"fam-0", cbt::GcRule::MaxNumVersions(10)},
568 {"fam-1", cbt::GcRule::MaxNumVersions(10)}},
569 {}));
570 if (!schema) throw std::runtime_error(schema.status().message());
571
572 google::cloud::bigtable::Table table(
573 google::cloud::bigtable::CreateDefaultDataClient(
574 admin.project(), admin.instance_id(),
575 google::cloud::bigtable::ClientOptions()),
576 table_id);
577
578 std::cout << "\nPreparing data for multiple examples" << std::endl;
579 InsertTestData(table, {});
580 std::cout << "Running FilterLimitRowSample() example [1]" << std::endl;
581 FilterLimitRowSample(table, {});
582 std::cout << "Running FilterLimitRowRegex() example [2]" << std::endl;
583 FilterLimitRowRegex(table, {});
584 std::cout << "Running FilterLimitCellsPerColumn() example [3]" << std::endl;
585 FilterLimitCellsPerColumn(table, {});
586 std::cout << "Running FilterLimitCellsPerRow() example [4]" << std::endl;
587 FilterLimitCellsPerRow(table, {});
588 std::cout << "Running FilterLimitCellsPerRowOffset() example [5]"
589 << std::endl;
590 FilterLimitCellsPerRowOfset(table, {});
591 std::cout << "Running FilterLimitColFamilyRegex() example [6]" << std::endl;
592 FilterLimitColFamilyRegex(table, {});
593 std::cout << "Running FilterLimitColQualifierRegex() example [7]"
594 << std::endl;
595 FilterLimitColQualifierRegex(table, {});
596 std::cout << "Running FilterLimitColRange() example [8]" << std::endl;
597 FilterLimitColRange(table, {});
598 std::cout << "Running FilterLimitValueRange() example [9]" << std::endl;
599 FilterLimitValueRange(table, {});
600 std::cout << "Running FilterLimitValueRegex() example [10]" << std::endl;
601 FilterLimitValueRegex(table, {});
602 std::cout << "Running FilterLimitTimestampRange() example [11]" << std::endl;
603 FilterLimitTimestampRange(table, {});
604 std::cout << "Running FilterLimitBlockAll() example [12]" << std::endl;
605 FilterLimitBlockAll(table, {});
606 std::cout << "Running FilterLimitPassAll() example [13]" << std::endl;
607 FilterLimitPassAll(table, {});
608 std::cout << "Running FilterModifyStripValue() example [14]" << std::endl;
609 FilterModifyStripValue(table, {});
610 std::cout << "Running FilterModifyApplyLabel() example [15]" << std::endl;
611 FilterModifyApplyLabel(table, {});
612 std::cout << "Running FilterComposingChain() example [16]" << std::endl;
613 FilterComposingChain(table, {});
614 std::cout << "Running FilterComposingInterleave() example [17]" << std::endl;
615 FilterComposingInterleave(table, {});
616 std::cout << "Running FilterComposingCondition() example [18]" << std::endl;
617 FilterComposingCondition(table, {});
618 admin.DeleteTable(table_id);
619 }
620
621 } // anonymous namespace
622
main(int argc,char * argv[])623 int main(int argc, char* argv[]) {
624 google::cloud::testing_util::InstallCrashHandler(argv[0]);
625
626 using google::cloud::bigtable::examples::MakeCommandEntry;
627 google::cloud::bigtable::examples::Commands commands = {
628 MakeCommandEntry("insert-test-data", {}, InsertTestData),
629 MakeCommandEntry("filter-limit-row-sample", {}, FilterLimitRowSample),
630 MakeCommandEntry("filter-limit-row-regex", {}, FilterLimitRowRegex),
631 MakeCommandEntry("filter-limit-cells-per-column", {},
632 FilterLimitCellsPerColumn),
633 MakeCommandEntry("filter-limit-cells-per-row", {},
634 FilterLimitCellsPerRow),
635 MakeCommandEntry("filter-limit-cells-per-row-offset", {},
636 FilterLimitCellsPerRowOfset),
637 MakeCommandEntry("filters-limit-col-family-regex", {},
638 FilterLimitColFamilyRegex),
639 MakeCommandEntry("filters-limit-col-qualifier-regex", {},
640 FilterLimitColQualifierRegex),
641 MakeCommandEntry("filters-limit-col-range", {}, FilterLimitColRange),
642 MakeCommandEntry("filters-limit-value-range", {}, FilterLimitValueRange),
643 MakeCommandEntry("filters-limit-value-regex", {}, FilterLimitValueRegex),
644 MakeCommandEntry("filters-limit-timestamp-range", {},
645 FilterLimitTimestampRange),
646 MakeCommandEntry("filters-limit-block-all", {}, FilterLimitBlockAll),
647 MakeCommandEntry("filters-limit-pass-all", {}, FilterLimitPassAll),
648 MakeCommandEntry("filters-modify-strip-value", {},
649 FilterModifyStripValue),
650 MakeCommandEntry("filters-modify-apply-label", {},
651 FilterModifyApplyLabel),
652 MakeCommandEntry("filters-composing-chain", {}, FilterComposingChain),
653 MakeCommandEntry("filters-composing-interleave", {},
654 FilterComposingInterleave),
655 MakeCommandEntry("filters-composing-condition", {},
656 FilterComposingCondition),
657 {"auto", RunAll},
658 };
659
660 google::cloud::bigtable::examples::Example example(std::move(commands));
661 return example.Run(argc, argv);
662 }
663