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
48 changes: 48 additions & 0 deletions gcloud/bigtable/row.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
class Row(object):
"""Representation of a Google Cloud Bigtable Row.

.. note::

A :class:`Row` accumulates mutations locally via the :meth:`set_cell`,
:meth:`delete`, :meth:`delete_cell` and :meth:`delete_cells` methods.
To actually send these mutations to the Google Cloud Bigtable API, you
must call :meth:`commit`. If a ``filter_`` is set on the :class:`Row`,
the mutations must have an associated state: :data:`True` or
:data:`False`. The mutations will be applied conditionally, based on
whether the filter matches any cells in the :class:`Row` or not.

:type row_key: bytes
:param row_key: The key for the current row.

Expand All @@ -43,6 +53,14 @@ def __init__(self, row_key, table, filter_=None):
self._table = table
self._filter = filter_
self._rule_pb_list = []
if self._filter is None:
self._pb_mutations = []
self._true_pb_mutations = None
self._false_pb_mutations = None
else:
self._pb_mutations = None
self._true_pb_mutations = []
self._false_pb_mutations = []

def append_cell_value(self, column_family_id, column, value):
"""Appends a value to an existing cell.
Expand Down Expand Up @@ -75,6 +93,36 @@ def append_cell_value(self, column_family_id, column, value):
append_value=value)
self._rule_pb_list.append(rule_pb)

def _get_mutations(self, state=None):
"""Gets the list of mutations for a given state.

If the state is :data`None` but there is a filter set, then we've
reached an invalid state. Similarly if no filter is set but the
state is not :data:`None`.

:type state: bool
:param state: (Optional) The state that the mutation should be
applied in. Unset if the mutation is not conditional,
otherwise :data:`True` or :data:`False`.

:rtype: list
:returns: The list to add new mutations to (for the current state).
:raises: :class:`ValueError <exceptions.ValueError>`
"""
if state is None:
if self._filter is not None:
raise ValueError('A filter is set on the current row, but no '
'state given for the mutation')
return self._pb_mutations
else:
if self._filter is None:
raise ValueError('No filter was set on the current row, but a '
'state was given for the mutation')
if state:
return self._true_pb_mutations
else:
return self._false_pb_mutations


class RowFilter(object):
"""Basic filter to apply to cells in a row.
Expand Down
40 changes: 40 additions & 0 deletions gcloud/bigtable/test_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,46 @@ def test_constructor_with_non_bytes(self):
with self.assertRaises(TypeError):
self._makeOne(row_key, None)

def _get_mutations_helper(self, filter_=None, state=None):
row_key = b'row_key'
row = self._makeOne(row_key, None, filter_=filter_)
# Mock the mutations with unique objects so we can compare.
row._pb_mutations = no_bool = object()
row._true_pb_mutations = true_mutations = object()
row._false_pb_mutations = false_mutations = object()

mutations = row._get_mutations(state)
return (no_bool, true_mutations, false_mutations), mutations

def test__get_mutations_no_filter(self):
(no_bool, _, _), mutations = self._get_mutations_helper()
self.assertTrue(mutations is no_bool)

def test__get_mutations_no_filter_bad_state(self):
state = object() # State should be null when no filter.
with self.assertRaises(ValueError):
self._get_mutations_helper(state=state)

def test__get_mutations_with_filter_true_state(self):
filter_ = object()
state = True
(_, true_filter, _), mutations = self._get_mutations_helper(
filter_=filter_, state=state)
self.assertTrue(mutations is true_filter)

def test__get_mutations_with_filter_false_state(self):
filter_ = object()
state = False
(_, _, false_filter), mutations = self._get_mutations_helper(
filter_=filter_, state=state)
self.assertTrue(mutations is false_filter)

def test__get_mutations_with_filter_bad_state(self):
filter_ = object()
state = None
with self.assertRaises(ValueError):
self._get_mutations_helper(filter_=filter_, state=state)

def test_append_cell_value(self):
from gcloud.bigtable._generated import bigtable_data_pb2 as data_pb2

Expand Down