Hello World C++

Questo esempio è una semplice applicazione "Hello World", scritta in C++, che illustra come eseguire le seguenti operazioni:

  • Configura l'autenticazione
  • Connettiti a un'istanza Bigtable.
  • Crea una nuova tabella.
  • Scrivi i dati nella tabella.
  • Leggi di nuovo i dati.
  • Elimina la tabella.

Configura l'autenticazione

Per utilizzare gli esempi di C++ in questa pagina in un ambiente di sviluppo locale, installa e inizializza gcloud CLI, quindi configura Credenziali predefinite dell'applicazione con le tue credenziali utente.

  1. Installa Google Cloud CLI.

  2. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  3. Se utilizzi una shell locale, crea le credenziali di autenticazione locali per il tuo account utente:

    gcloud auth application-default login

    Non devi eseguire questa operazione se utilizzi Cloud Shell.

    Se viene restituito un errore di autenticazione e utilizzi un provider di identità (IdP) esterno, verifica di aver acceduto a gcloud CLI con la tua identità federata.

Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

Esegui l'esempio

Questo esempio utilizza il pacchetto Cloud Bigtable della libreria client per C++ per comunicare con Bigtable.Google Cloud

Per eseguire questo programma di esempio, segui le istruzioni su GitHub.

Utilizza la Google Cloud libreria client con Bigtable

L'applicazione di esempio si connette a Bigtable e mostra alcune operazioni semplici.

Installa e importa la libreria client

Scarica o clona la libreria client Bigtable C++ da GitHub, quindi compilala. Segui le istruzioni del compilatore nel file READMEdi primo livello.

Includi le intestazioni richieste.

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

Connettiti a Bigtable

Utilizza MakeBigtableTableAdminConnection() per creare un BigtableTableAdminClient, che utilizzerai per creare una tabella.

// 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]

Crea una tabella

Definisci uno schema per la tabella con una famiglia di colonne. Imposta una regola di garbage collection per la famiglia di colonne in modo da conservare al massimo una versione di ogni valore. Utilizza questo schema per creare un'istanza di un oggetto tabella utilizzando BigtableTableAdminClient::CreateTable(). Quindi crea un client di dati che puoi utilizzare per inserire e recuperare i dati dalla tabella.

// 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);
StatusOr<google::bigtable::admin::v2::Table> schema =
    table_admin.CreateTable(instance_name, table_id, std::move(t));

Scrivi righe in una tabella

Scorri un elenco di stringhe di saluto per creare alcune nuove righe per la tabella. In ogni iterazione, utilizza SingleRowMutation per definire una riga e assegnarle una chiave di riga e un valore. Quindi chiama Table::Apply() per applicare la mutazione alla riga.

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;
}

Crea un filtro

Prima di leggere i dati che hai scritto, crea un filtro, utilizzando Filter::ColumnRangeClosed(), per limitare i dati restituiti da Bigtable. Questo filtro indica a Bigtable di restituire solo la versione più recente di ogni valore, anche se la tabella contiene celle precedenti scadute ma non ancora rimosse dalla garbage collection.

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

Leggi una riga in base alla chiave

Chiama la funzione Table::ReadRow(), passando la chiave di riga e il filtro, per ottenere una versione di ogni valore nella riga.

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: " << table.table_name()
            << "\n";
  return;
}
cbt::Cell const& cell = result->second.cells().front();
std::cout << cell.family_name() << ":" << cell.column_qualifier() << "    @ "
          << cell.timestamp().count() << "us\n"
          << '"' << cell.value() << '"' << "\n";

Scansiona tutte le righe della tabella

Utilizza Table::ReadRows() per leggere un intervallo di righe dalla tabella.

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 const& c : row->cells()) {
    std::cout << "\t" << c.family_name() << ":" << c.column_qualifier()
              << "    @ " << c.timestamp().count() << "us\n"
              << "\t\"" << c.value() << '"' << "\n";
  }
}

Elimina una tabella

Elimina la tabella con BigtableTableAdminClient::DeleteTable().

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

In sintesi

Ecco l'esempio completo senza commenti.



#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/internal/random.h"
#include "google/cloud/log.h"
#include <iostream>

namespace {

using ::google::cloud::bigtable::examples::Usage;

void BigtableHelloWorld(std::vector<std::string> const& argv) {
  if (argv.size() != 3) {
    throw Usage{"hello-world <project-id> <instance-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::TableResource(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_num_versions(1);

  std::string instance_name = cbt::InstanceName(project_id, instance_id);
  StatusOr<google::bigtable::admin::v2::Table> schema =
      table_admin.CreateTable(instance_name, table_id, std::move(t));

  std::vector<std::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.ok()) throw std::runtime_error(status.message());
    ++i;
  }

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

  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: " << table.table_name()
              << "\n";
    return;
  }
  cbt::Cell const& cell = result->second.cells().front();
  std::cout << cell.family_name() << ":" << cell.column_qualifier() << "    @ "
            << cell.timestamp().count() << "us\n"
            << '"' << cell.value() << '"' << "\n";

  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 const& c : row->cells()) {
      std::cout << "\t" << c.family_name() << ":" << 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::vector<std::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 project_id =
      google::cloud::internal::GetEnv("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::testing::RandomTableId(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;
}