Hola, mundo en C++

Este ejemplo es una aplicación sencilla de "hola mundo" escrita en C++ que muestra cómo hacer lo siguiente:

  • Configurar la autenticación
  • Conéctate a una instancia de Bigtable.
  • Crea una tabla.
  • Escribe datos en la tabla.
  • Lee los datos.
  • Elimina la tabla.

Configurar la autenticación

Para usar las C++ muestras de esta página en un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, a continuación, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

    Instala Google Cloud CLI.

    Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

    If you're using a local shell, then create local authentication credentials for your user account:

    gcloud auth application-default login

    You don't need to do this if you're using Cloud Shell.

    If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

Para obtener más información, consulta Set up authentication for a local development environment.

Ejecutar la muestra

En este ejemplo se usa el paquete Cloud Bigtable de la Google Cloud biblioteca de cliente para C++ para comunicarse con Bigtable.

Para ejecutar este programa de ejemplo, sigue las instrucciones de GitHub.

Usar la biblioteca de cliente Google Cloud con Bigtable

La aplicación de ejemplo se conecta a Bigtable y muestra algunas operaciones sencillas.

Instalar e importar la biblioteca de cliente

Descarga o clona la biblioteca de cliente de C++ de Bigtable de GitHub y, a continuación, compílala. Sigue las instrucciones del compilador que se indican en el README de nivel superior.

Incluye los encabezados obligatorios.

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

Conectarse a Bigtable

Usa MakeBigtableTableAdminConnection() para crear un BigtableTableAdminClient, que usarás para crear una tabla.

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

Crear una tabla

Define un esquema para la tabla que tiene una familia de columnas. Define una regla de recolección de elementos no utilizados para la familia de columnas de forma que se conserve un máximo de una versión de cada valor. Usa ese esquema para crear una instancia de un objeto de tabla con BigtableTableAdminClient::CreateTable(). A continuación, crea un cliente de datos que puedas usar para introducir y extraer datos de tu tabla.

// 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));

Escribir filas en una tabla

Recorre una lista de cadenas de saludo para crear algunas filas en la tabla. En cada iteración, usa SingleRowMutation para definir una fila y asignarle una clave y un valor. A continuación, llama a Table::Apply() para aplicar la mutación a la fila.

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

Crear un filtro

Antes de leer los datos que has escrito, crea un filtro con Filter::ColumnRangeClosed() para limitar los datos que devuelve Bigtable. Este filtro indica a Bigtable que devuelva solo la versión más reciente de cada valor, aunque la tabla contenga celdas antiguas que hayan caducado pero que aún no se hayan eliminado mediante la recolección de elementos no utilizados.

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

Leer una fila por su clave

Llama a la función Table::ReadRow() y pasa la clave de la fila y el filtro para obtener una versión de cada valor de esa fila.

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

Analizar todas las filas de la tabla

Usa Table::ReadRows() para leer un intervalo de filas de la tabla.

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

Eliminar una tabla.

Elimina la tabla con BigtableTableAdminClient::DeleteTable().

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

Visión de conjunto

Aquí tienes el ejemplo completo sin comentarios.



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