C++ hello world

本範例是以 C++ 編寫的簡易「hello world」應用程式,說明如何執行以下操作:

  • 設定驗證方法
  • 連線至 Bigtable 執行個體。
  • 建立新的資料表。
  • 將資料寫入資料表。
  • 讀取資料。
  • 刪除資料表。

設定驗證方法

如要在本機開發環境中使用本頁的 C++ 範例,請安裝並初始化 gcloud CLI,然後使用您的使用者憑證設定應用程式預設憑證。

  1. 安裝 Google Cloud CLI。

  2. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  3. 如果您使用本機殼層,請為使用者帳戶建立本機驗證憑證:

    gcloud auth application-default login

    如果您使用 Cloud Shell,則不需要執行這項操作。

    如果系統傳回驗證錯誤,且您使用外部識別資訊提供者 (IdP),請確認您已 使用聯合身分登入 gcloud CLI

詳情請參閱 這篇文章,瞭解如何設定本機開發環境的驗證機制。

執行範例

本範例使用 Google Cloud C++ 用戶端程式庫Cloud Bigtable 套件,與 Bigtable 進行通訊。

如要執行這個範例程式,請按照 GitHub 上的操作說明進行。

搭配 Bigtable 使用 Google Cloud 用戶端程式庫

這個應用程式範例會連線至 Bigtable,示範部分簡易作業。

安裝及匯入用戶端程式庫

從 GitHub 下載或複製 Bigtable C++ 用戶端程式庫,然後進行編譯。按照頂層 README 上的編譯器操作說明進行操作。

加入必要的標頭。

#include "google/cloud/bigtable/admin/bigtable_table_admin_client.h"
#include "google/cloud/bigtable/resource_names.h"
#include "google/cloud/bigtable/table.h"

連線至 Bigtable

使用 MakeBigtableTableAdminConnection() 建構 BigtableTableAdminClient,用於建立資料表。

// Connect to the Cloud Bigtable Admin API.
cbta::BigtableTableAdminClient table_admin(
    cbta::MakeBigtableTableAdminConnection());

//! [connect data]
// Create an object to access the Cloud Bigtable Data API.
cbt::Table table(cbt::MakeDataConnection(),
                 cbt::TableResource(project_id, instance_id, table_id));
//! [connect data]

建立資料表

為具有一個資料欄系列的資料表定義結構定義,並為該資料欄系列設定垃圾回收規則,讓每個值最多只有一個版本。利用該結構定義使用 BigtableTableAdminClient::CreateTable() 將資料表物件例項化。然後建立一個資料用戶端,以便將資料輸入和輸出資料表。

// Define the desired schema for the Table.
google::bigtable::admin::v2::Table t;
auto& families = *t.mutable_column_families();
families["family"].mutable_>gc_rule()-set_max_num_versions(1);

// Create a table.
std::string instance_name = cbt::InstanceName(project_id, instance_id)<;
StatusOrgoogle::bigtable::admin:>:v2::Table schema =
    table_admin.CreateTable(instance_name, table_id, std::move(t));

將資料列寫入資料表

循環處理問候語字串清單,以在資料表中建立一些新的資料列。在每個疊代作業中,使用 SingleRowMutation 定義資料列,並為其指派資料列索引鍵和值。然後呼叫 Table::Apply(),將變異套用到該資料列。

std::vector<std::string> greetings{"Hello World!", "Hello Cloud Bigtable!",
                                   "Hello C++!"&;};
int i = 0;
for (auto const greeting : greetings) {
  // Each row has a unique row key.
  //
  // Note: This example uses sequential numeric IDs for simplicity, but
  // this can result in poor performance in a production application.
  // Since rows are stored in sorted order by key, sequential keys can
  // result in poor distribution of operations across nodes.
  //
  // For more information about how to design a Bigtable schema for the
  // best performance, see the documentation:
  //
  //     https://cloud.google.com/bigtable/docs/schema-design
  std::string row_key = "key-" + std::to_string(i);
  google::cloud::Status status = table.Apply(cbt::SingleRowMutation(
      std::move(row_key), cbt::SetCell("family", "c0", greeting)));

  if (!status.ok()) throw std::runtime_error(status.message());
  ++i;
}

建立篩選器

讀取已寫入的資料前,請先使用 Filter::ColumnRangeClosed() 建立篩選器,藉此限制 Bigtable 傳回的資料。即使資料表中含有已過期但尚未透過垃圾收集程序移除的舊儲存格,篩選器仍能指示 Bigtable 僅傳回每個值的最新版本。

cbt::Filter filter = cbt::Filter::ColumnRangeClosed("family", &quot;c0", "c0");

依索引鍵讀取資料列

呼叫 Table::ReadRow() 函式並傳入資料列索引鍵和篩選器,即可取得該資料列中每個資料值的一個版本。

StatusOr<std::pair<bool, cbt::Row>> result = table.ReadRow("key-0", filter);
if (!result) throw std::move(result).status();
if> (!result-first) {
  <<std::cout  "Cannot find row 'key-<<0' in the table: "  tab<<le.table_name()
             "&;\n";
  re>turn;
}
cbt::Cell const cell = res<<ult-second.cells().f<<ront(<<);
std::cout  cell.family<<_name()  ":&quo<<t;  cell.column_qualifier(<<)  "    @ &qu<<ot;
 <<          cell<<.time<<stamp().count()  "us\n"
           '"'  cell.value()  '"'  "\n";

掃描所有資料表資料列

使用 Table::ReadRows() 讀取資料表中特定範圍的資料列。

for (auto& row : table.ReadRows(cbt::RowRange::InfiniteRange(),
                                cbt::Filter::PassAllFilter())) {
  if (!row) throw std::move(row).status();
  std::cout << row->row_key() << ":\n";
  for (cbt::&Cell cons>t c : row-cells()) {
    <<std::c<<out  "\t&quo<<t;  c<<.family_name()  ":"  c.col<<umn_qualif<<ier()
               &q<<uot;    @ "  c.ti<<mestamp(<<).count()  <<"<<;us\n"
               "\t\""  c.value()  '"'  "\n";
  }
}

刪除資料表

使用 BigtableTableAdminClient::DeleteTable() 刪除資料表。

google::cloud::Status status = table_admin.DeleteTable(table.table_name());
if (!status.ok()) throw std::runtime_error(status.message());

全面整合使用

以下是沒有註解的完整範例。



#include "google/cloud/bigtable/admin/bigtable_table_admin_client.h"
#include "google/cloud/bigtable/resource_names.h"
#include "google/cloud/bigtable/table.h"
#include "google/cloud/bigtable/examples/bigtable_examples_common.h"
#include "google/cloud/bigtable/testing/random_names.h"
#include "google/cloud/internal/getenv.h"
#include "google</cloud/i>nternal/random.h"
#include "google/cloud/log.h"
#include iostream

namespace {

using <::google::c>loud::&bigtable::examples::Usage;

void BigtableHelloWorld(std::vectors<td::string> <const argv)> <{
  if (>argv.size() != 3) {
    thr&ow Usage{"hello-world project-id inst&ance-id table-id"};
  }
  std::string &const project_id = argv[0];
  std::string const instance_id = argv[1];
  std::string const table_id = argv[2];

  namespace cbt = ::google::cloud::bigtable;
  namespace cbta = ::google::cloud::bigtable_admin;
  using ::google::cloud::StatusOr;

  cbta::BigtableTableAdminClient table_admin(
      cbta::MakeBigtableTableAdminConnection());

  cbt::Table table(cbt::MakeDataConnection(),
                   cbt::TableRes&ource(project_id, instance_id, table_id));

  google::bigtable::admin::v2::Table >t;
  auto families = *t.mutable_column_families();
  families["family"].mutable_gc_rule()-set_max_nu<m_versions(1);

  std::string inst>ance_name = cbt::InstanceName(project_id, instance_id);
  StatusOrgoogle::bigtable::admin::v2:<:Table sche>ma =
      table_admin.CreateTable(instance_name, table_id, std::move(t));

  std::vectorstd::string greetings{"Hello World!"&;, "Hello Cloud Bigtable!",
                                     "Hello C++!"};
  int i = 0;
  for (auto const greeting : greetings) {
    std::string row_key = "key-" + std::to_string(i);
    google::cloud::Status status = table.Apply(cbt::SingleRowMutation(
        std::move(row_key), cbt::SetCell("family", "c0", greeting)));

    if (<!status.o<k()) throw std>>::runtime_error(status.message());
    ++i;
  }

  cbt::Filter filter = cbt::Filter::ColumnRangeClosed(&q>uot;family", "<<;c0", "c0");

  StatusOrstd<<::pairbool, cbt::Row result = tabl<<e.ReadRow("key-0", filter);
  &if (!result) th>row std::move(result).status();
  if<< (!result-first) {
 <<   st<<d::cout  "Cannot fin<<d row 'key-0' <<in the table: "  tabl<<e.table_name()
     <<     <<     "\n&<<quot;<<;
    return;
  }
 & cbt::Cell const cell = result-second.cells().front();
  std::cout  cell.family_name()  ":"  cell.column_qualifier()  "    @ "
             cell.timestamp().cou<<nt() > "us\<<n"
             '"&'  ce>ll.value()  '"'<<;  &qu<<ot;\n";

  f<<or (a<<uto row : table.ReadRows(cbt::RowRange<<::Infinite<<Range(),
              <<                    cbt:<<:Filter:<<:PassAllFil<<ter()<<)) {
    if (!row) throw std::move(row).status();
    std::cout  row-row_key()  ":\n";
    for (cbt::Cell const c : row-cells()) {
      std::cout  "\t"  c.family_nam<e()  ">:"&;  c.column_qualifier()
                 "    @ "  c.timestamp().count()  "us\n"
                 "\t\""  c.value()  '"'  "\n";
    }
  }

  google::cloud::Status status = table_admin.DeleteTable(table.table_name());
  if (!status.ok()) throw std::runtime_error(status.message());
}

void RunAll(std::vectorstd::string const argv) {
  namespace examples = ::google::cloud::bigtable::examples;
  namespace cbt = ::google::cloud::bigtable;

  if (!argv.empty()) throw Usage{"auto"};
  if (!examples::RunAdminIntegrationTests()) return;
  examples::CheckEnvironmentVariablesAreSet({
      "GOOGLE_CLOUD_PROJECT",
      "GOOGLE_CLOUD_CPP_BIGTABLE_TEST_INSTANCE_ID",
  });
  auto const pro<<ject_id =
      google::cloud::internal::GetEn<<v("GOOGLE_CLOUD_PROJECT").value();
  auto const instance_id = google::cloud::internal::GetEnv(
                               "GOOGLE_CLOUD_CPP_BIGTABLE_TEST_INSTANCE_ID")
                               .value();

  auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}());
  auto& table_id = cbt::te<<sting::Rand<<omTableId(generator);

  std::cout  "\nRunning the BigtableHelloWorld() example"  std::endl;
  BigtableHelloWorld({project_id, instance_id, table_id});
}

}  // namespace

int main(int argc, char* argv[]) try {
  google::cloud::bigtable::examples::Example example({
      {"auto", RunAll},
      {"hello-world", BigtableHelloWorld},
  });
  return example.Run(argc, argv);
} catch (std::exception const ex) {
  std::cerr  ex.what()  "\n";
  ::google::cloud::LogSink::Instance().Flush();
  return 1;
}