Skip to content

Commit

Permalink
feat(bigtable): table resource name as a class
Browse files Browse the repository at this point in the history
  • Loading branch information
dbolduc committed Jun 29, 2022
1 parent a5b052d commit 7e86f6c
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 0 deletions.
3 changes: 3 additions & 0 deletions google/cloud/bigtable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ add_library(
table_admin.h
table_config.cc
table_config.h
table_resource.cc
table_resource.h
version.cc
version.h
version_info.h
Expand Down Expand Up @@ -381,6 +383,7 @@ if (BUILD_TESTING)
table_readmodifywriterow_test.cc
table_readrow_test.cc
table_readrows_test.cc
table_resource_test.cc
table_sample_row_keys_test.cc
table_test.cc
testing/cleanup_stale_resources_test.cc
Expand Down
1 change: 1 addition & 0 deletions google/cloud/bigtable/bigtable_client_unit_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ bigtable_client_unit_tests = [
"table_readmodifywriterow_test.cc",
"table_readrow_test.cc",
"table_readrows_test.cc",
"table_resource_test.cc",
"table_sample_row_keys_test.cc",
"table_test.cc",
"testing/cleanup_stale_resources_test.cc",
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/bigtable/google_cloud_cpp_bigtable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ google_cloud_cpp_bigtable_hdrs = [
"table.h",
"table_admin.h",
"table_config.h",
"table_resource.h",
"version.h",
"version_info.h",
"wait_for_consistency.h",
Expand Down Expand Up @@ -194,6 +195,7 @@ google_cloud_cpp_bigtable_srcs = [
"table.cc",
"table_admin.cc",
"table_config.cc",
"table_resource.cc",
"version.cc",
"wait_for_consistency.cc",
]
58 changes: 58 additions & 0 deletions google/cloud/bigtable/table_resource.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/bigtable/table_resource.h"
#include <ostream>
#include <regex>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

TableResource::TableResource(InstanceResource instance, std::string table_id)
: instance_(std::move(instance)), table_id_(std::move(table_id)) {}

std::string TableResource::FullName() const {
return instance_.FullName() + "/tables/" + table_id_;
}

bool operator==(TableResource const& a, TableResource const& b) {
return a.instance_ == b.instance_ && a.table_id_ == b.table_id_;
}

bool operator!=(TableResource const& a, TableResource const& b) {
return !(a == b);
}

std::ostream& operator<<(std::ostream& os, TableResource const& db) {
return os << db.FullName();
}

StatusOr<TableResource> MakeTableResource(std::string const& full_name) {
std::regex re("projects/([^/]+)/instances/([^/]+)/tables/([^/]+)");
std::smatch matches;
if (!std::regex_match(full_name, matches, re)) {
return Status(StatusCode::kInvalidArgument,
"Improperly formatted TableResource: " + full_name);
}
return TableResource(
InstanceResource(Project(std::move(matches[1])), std::move(matches[2])),
std::move(matches[3]));
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google
89 changes: 89 additions & 0 deletions google/cloud/bigtable/table_resource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_TABLE_RESOURCE_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_TABLE_RESOURCE_H

#include "google/cloud/bigtable/instance_resource.h"
#include "google/cloud/bigtable/version.h"
#include "google/cloud/status_or.h"
#include <iosfwd>
#include <string>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

/**
* This class identifies a Cloud Bigtable Table.
*
* Bigtable stores data in massively scalable tables, each of which is a sorted
* key/value map. A Cloud Bigtable table is identified by the instance it is
* contained in and its `table_id`.
*
* @note This class makes no effort to validate the components of the
* table name. It is the application's responsibility to provide valid
* project, instance, and table ids. Passing invalid values will not be
* checked until the table name is used in a RPC to Bigtable.
*
* @see https://cloud.google.com/bigtable/docs/overview for an overview of the
* Cloud Bigtable data model.
*/
class TableResource {
public:
/**
* Constructs a TableResource object identified by the given @p instance and
* @p table_id.
*/
TableResource(InstanceResource instance, std::string table_id);

/// Returns the `InstanceResource` containing this table.
InstanceResource const& instance() const { return instance_; }

/// Returns the Table ID.
std::string const& table_id() const { return table_id_; }

/**
* Returns the fully qualified table name as a string of the form:
* "projects/<project-id>/instances/<instance-id>/tables/<table-id>"
*/
std::string FullName() const;

/// @name Equality operators
//@{
friend bool operator==(TableResource const& a, TableResource const& b);
friend bool operator!=(TableResource const& a, TableResource const& b);
//@}

/// Output the `FullName()` format.
friend std::ostream& operator<<(std::ostream&, TableResource const&);

private:
InstanceResource instance_;
std::string table_id_;
};

/**
* Constructs a `TableResource` from the given @p full_name.
* Returns a non-OK Status if `full_name` is improperly formed.
*/
StatusOr<TableResource> MakeTableResource(std::string const& full_name);

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google

#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_TABLE_RESOURCE_H
90 changes: 90 additions & 0 deletions google/cloud/bigtable/table_resource_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/bigtable/table_resource.h"
#include "google/cloud/testing_util/status_matchers.h"
#include <gmock/gmock.h>
#include <sstream>
#include <string>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace {

using ::google::cloud::testing_util::StatusIs;

TEST(TableResource, Basics) {
InstanceResource in(Project("p1"), "i1");
TableResource tr(in, "t1");
EXPECT_EQ("t1", tr.table_id());
EXPECT_EQ(in, tr.instance());
EXPECT_EQ("projects/p1/instances/i1/tables/t1", tr.FullName());

auto copy = tr;
EXPECT_EQ(copy, tr);
EXPECT_EQ("t1", copy.table_id());
EXPECT_EQ(in, copy.instance());
EXPECT_EQ("projects/p1/instances/i1/tables/t1", copy.FullName());

auto moved = std::move(copy);
EXPECT_EQ(moved, tr);
EXPECT_EQ("t1", moved.table_id());
EXPECT_EQ(in, moved.instance());
EXPECT_EQ("projects/p1/instances/i1/tables/t1", moved.FullName());

InstanceResource in2(Project("p2"), "i2");
TableResource tr2(in2, "t2");
EXPECT_NE(tr2, tr);
EXPECT_EQ("t2", tr2.table_id());
EXPECT_EQ(in2, tr2.instance());
EXPECT_EQ("projects/p2/instances/i2/tables/t2", tr2.FullName());
}

TEST(TableResource, OutputStream) {
InstanceResource in(Project("p1"), "i1");
TableResource tr(in, "t1");
std::ostringstream os;
os << tr;
EXPECT_EQ("projects/p1/instances/i1/tables/t1", os.str());
}

TEST(TableResource, MakeTableResource) {
auto tr = TableResource(InstanceResource(Project("p1"), "i1"), "t1");
EXPECT_EQ(tr, MakeTableResource(tr.FullName()).value());

for (std::string invalid : {
"",
"projects/",
"projects/p1",
"projects/p1/instances/",
"projects/p1/instances/i1",
"projects/p1/instances/i1/tables",
"projects/p1/instances/i1/tables/",
"/projects/p1/instances/i1/tables/t1",
"projects/p1/instances/i1/tables/t1/",
"projects/p1/instances/i1/tables/t1/etc",
}) {
auto tr = MakeTableResource(invalid);
EXPECT_THAT(tr, StatusIs(StatusCode::kInvalidArgument,
"Improperly formatted TableResource: " + invalid));
}
}

} // namespace
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google

0 comments on commit 7e86f6c

Please sign in to comment.