Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions gcloud/bigtable/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,31 @@
"""User friendly container for Google Cloud Bigtable Table."""


from gcloud.bigtable._generated import (
bigtable_table_service_messages_pb2 as messages_pb2)
from gcloud.bigtable.column_family import ColumnFamily
from gcloud.bigtable.row import Row


class Table(object):
"""Representation of a Google Cloud Bigtable Table.

.. note::

We don't define any properties on a table other than the name. As
the proto says, in a request:

The ``name`` field of the Table and all of its ColumnFamilies must
be left blank, and will be populated in the response.

This leaves only the ``current_operation`` and ``granularity``
fields. The ``current_operation`` is only used for responses while
``granularity`` is an enum with only one value.

We can use a :class:`Table` to:

* :meth:`create` the table

:type table_id: str
:param table_id: The ID of the table.

Expand Down Expand Up @@ -64,3 +82,40 @@ def __eq__(self, other):

def __ne__(self, other):
return not self.__eq__(other)

def create(self, initial_split_keys=None):
"""Creates this table.

.. note::

Though a :class:`._generated.bigtable_table_data_pb2.Table` is also
allowed (as the ``table`` property) in a create table request, we
do not support it in this method. As mentioned in the
:class:`Table` docstring, the name is the only useful property in
the table proto.

.. note::

A create request returns a
:class:`._generated.bigtable_table_data_pb2.Table` but we don't use
this response. The proto definition allows for the inclusion of a
``current_operation`` in the response, but it does not appear that
the Cloud Bigtable API returns any operation.

:type initial_split_keys: list
:param initial_split_keys: (Optional) List of row keys that will be
used to initially split the table into
several tablets (Tablets are similar to
HBase regions). Given two split keys,
``"s1"`` and ``"s2"``, three tablets will be
created, spanning the key ranges:
``[, s1)``, ``[s1, s2)``, ``[s2, )``.
"""
request_pb = messages_pb2.CreateTableRequest(
initial_split_keys=initial_split_keys or [],
name=self._cluster.name,
table_id=self.table_id,
)
client = self._cluster._client
# We expect a `._generated.bigtable_table_data_pb2.Table`
client._table_stub.CreateTable(request_pb, client.timeout_seconds)
70 changes: 70 additions & 0 deletions gcloud/bigtable/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,73 @@ def test___ne__(self):
table1 = self._makeOne('table_id1', 'cluster1')
table2 = self._makeOne('table_id2', 'cluster2')
self.assertNotEqual(table1, table2)

def _create_test_helper(self, initial_split_keys):
from gcloud.bigtable._generated import (
bigtable_table_data_pb2 as data_pb2)
from gcloud.bigtable._generated import (
bigtable_table_service_messages_pb2 as messages_pb2)
from gcloud.bigtable._testing import _FakeStub

project_id = 'project-id'
zone = 'zone'
cluster_id = 'cluster-id'
table_id = 'table-id'
timeout_seconds = 150
cluster_name = ('projects/' + project_id + '/zones/' + zone +
'/clusters/' + cluster_id)

client = _Client(timeout_seconds=timeout_seconds)
cluster = _Cluster(cluster_name, client=client)
table = self._makeOne(table_id, cluster)

# Create request_pb
request_pb = messages_pb2.CreateTableRequest(
initial_split_keys=initial_split_keys,
name=cluster_name,
table_id=table_id,
)

# Create response_pb
response_pb = data_pb2.Table()

# Patch the stub used by the API method.
client._table_stub = stub = _FakeStub(response_pb)

# Create expected_result.
expected_result = None # create() has no return value.

# Perform the method and check the result.
result = table.create(initial_split_keys=initial_split_keys)
self.assertEqual(result, expected_result)
self.assertEqual(stub.method_calls, [(
'CreateTable',
(request_pb, timeout_seconds),
{},
)])

def test_create(self):
initial_split_keys = None
self._create_test_helper(initial_split_keys)

def test_create_with_split_keys(self):
initial_split_keys = ['s1', 's2']
self._create_test_helper(initial_split_keys)


class _Client(object):

data_stub = None
cluster_stub = None
operations_stub = None
table_stub = None

def __init__(self, timeout_seconds=None):
self.timeout_seconds = timeout_seconds


class _Cluster(object):

def __init__(self, name, client=None):
self.name = name
self._client = client