diff --git a/gcloud/bigtable/happybase/__init__.py b/gcloud/bigtable/happybase/__init__.py new file mode 100644 index 000000000000..f425b09c2e78 --- /dev/null +++ b/gcloud/bigtable/happybase/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# 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 +# +# http://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. + +"""Google Cloud Bigtable HappyBase package. + +This package is intended to emulate the HappyBase library using +Google Cloud Bigtable as the backing store. +""" diff --git a/gcloud/bigtable/happybase/connection.py b/gcloud/bigtable/happybase/connection.py new file mode 100644 index 000000000000..475d80bfb01c --- /dev/null +++ b/gcloud/bigtable/happybase/connection.py @@ -0,0 +1,103 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# 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 +# +# http://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. + +"""Google Cloud Bigtable HappyBase connection module.""" + + +# Constants reproduced here for HappyBase compatibility, though values +# are all null. +COMPAT_MODES = None +THRIFT_TRANSPORTS = None +THRIFT_PROTOCOLS = None +DEFAULT_HOST = None +DEFAULT_PORT = None +DEFAULT_TRANSPORT = None +DEFAULT_COMPAT = None +DEFAULT_PROTOCOL = None + + +class Connection(object): + """Connection to Cloud Bigtable backend. + + .. note:: + + If you pass a ``cluster``, it will be :meth:`.Cluster.copy`-ed before + being stored on the new connection. This also copies the + :class:`.Client` that created the :class:`.Cluster` instance and the + :class:`Credentials ` stored on the + client. + + :type host: :data:`NoneType ` + :param host: Unused parameter. Provided for compatibility with HappyBase, + but irrelevant for Cloud Bigtable since it has a fixed host. + + :type port: :data:`NoneType ` + :param port: Unused parameter. Provided for compatibility with HappyBase, + but irrelevant for Cloud Bigtable since it has a fixed host. + + :type timeout: int + :param timeout: (Optional) The socket timeout in milliseconds. + + :type autoconnect: bool + :param autoconnect: (Optional) Whether the connection should be + :meth:`open`-ed during construction. + + :type table_prefix: str + :param table_prefix: (Optional) Prefix used to construct table names. + + :type table_prefix_separator: str + :param table_prefix_separator: (Optional) Separator used with + ``table_prefix``. Defaults to ``_``. + + :type compat: :data:`NoneType ` + :param compat: Unused parameter. Provided for compatibility with + HappyBase, but irrelevant for Cloud Bigtable since there + is only one version. + + :type transport: :data:`NoneType ` + :param transport: Unused parameter. Provided for compatibility with + HappyBase, but irrelevant for Cloud Bigtable since the + transport is fixed. + + :type protocol: :data:`NoneType ` + :param protocol: Unused parameter. Provided for compatibility with + HappyBase, but irrelevant for Cloud Bigtable since the + protocol is fixed. + + :raises: :class:`ValueError ` if any of the unused + parameters are specified with a value other than the defaults. + """ + + def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT, timeout=None, + autoconnect=True, table_prefix=None, + table_prefix_separator='_', compat=DEFAULT_COMPAT, + transport=DEFAULT_TRANSPORT, protocol=DEFAULT_PROTOCOL): + if host is not DEFAULT_HOST: + raise ValueError('Host cannot be set for gcloud HappyBase module') + if port is not DEFAULT_PORT: + raise ValueError('Port cannot be set for gcloud HappyBase module') + if compat is not DEFAULT_COMPAT: + raise ValueError('Compat cannot be set for gcloud ' + 'HappyBase module') + if transport is not DEFAULT_TRANSPORT: + raise ValueError('Transport cannot be set for gcloud ' + 'HappyBase module') + if protocol is not DEFAULT_PROTOCOL: + raise ValueError('Protocol cannot be set for gcloud ' + 'HappyBase module') + + self.timeout = timeout + self.autoconnect = autoconnect + self.table_prefix = table_prefix + self.table_prefix_separator = table_prefix_separator diff --git a/gcloud/bigtable/happybase/test_connection.py b/gcloud/bigtable/happybase/test_connection.py new file mode 100644 index 000000000000..bc1c3467b355 --- /dev/null +++ b/gcloud/bigtable/happybase/test_connection.py @@ -0,0 +1,70 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# 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 +# +# http://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. + + +import unittest2 + + +class TestConnection(unittest2.TestCase): + + def _getTargetClass(self): + from gcloud.bigtable.happybase.connection import Connection + return Connection + + def _makeOne(self, *args, **kwargs): + return self._getTargetClass()(*args, **kwargs) + + def test_constructor_defaults(self): + connection = self._makeOne() + self.assertEqual(connection.timeout, None) + self.assertTrue(connection.autoconnect) + self.assertEqual(connection.table_prefix, None) + self.assertEqual(connection.table_prefix_separator, '_') + + def test_constructor_explicit(self): + timeout = 12345 + autoconnect = False + table_prefix = 'table-prefix' + table_prefix_separator = 'sep' + + connection = self._makeOne( + timeout=timeout, + autoconnect=autoconnect, + table_prefix=table_prefix, + table_prefix_separator=table_prefix_separator) + self.assertEqual(connection.timeout, timeout) + self.assertFalse(connection.autoconnect) + self.assertEqual(connection.table_prefix, table_prefix) + self.assertEqual(connection.table_prefix_separator, + table_prefix_separator) + + def test_constructor_with_host(self): + with self.assertRaises(ValueError): + self._makeOne(host=object()) + + def test_constructor_with_port(self): + with self.assertRaises(ValueError): + self._makeOne(port=object()) + + def test_constructor_with_compat(self): + with self.assertRaises(ValueError): + self._makeOne(compat=object()) + + def test_constructor_with_transport(self): + with self.assertRaises(ValueError): + self._makeOne(transport=object()) + + def test_constructor_with_protocol(self): + with self.assertRaises(ValueError): + self._makeOne(protocol=object())