Skip to content

Commit

Permalink
Removing checks for dataset ID prefixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
dhermes committed Feb 13, 2016
1 parent 9df6c2b commit 090b187
Show file tree
Hide file tree
Showing 7 changed files with 5 additions and 197 deletions.
5 changes: 2 additions & 3 deletions gcloud/datastore/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"""

from gcloud.datastore import helpers
from gcloud.datastore.key import _projects_equal
from gcloud.datastore._generated import datastore_pb2 as _datastore_pb2


Expand Down Expand Up @@ -189,7 +188,7 @@ def put(self, entity):
if entity.key is None:
raise ValueError("Entity must have a key")

if not _projects_equal(self.project, entity.key.project):
if self.project != entity.key.project:
raise ValueError("Key must be from same project as batch")

if entity.key.is_partial:
Expand All @@ -212,7 +211,7 @@ def delete(self, key):
if key.is_partial:
raise ValueError("Key must be complete")

if not _projects_equal(self.project, key.project):
if self.project != key.project:
raise ValueError("Key must be from same project as batch")

key_pb = key.to_protobuf()
Expand Down
3 changes: 1 addition & 2 deletions gcloud/datastore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from gcloud.datastore.connection import Connection
from gcloud.datastore.batch import Batch
from gcloud.datastore.entity import Entity
from gcloud.datastore.key import _projects_equal
from gcloud.datastore.key import Key
from gcloud.datastore.query import Query
from gcloud.datastore.transaction import Transaction
Expand Down Expand Up @@ -276,7 +275,7 @@ def get_multi(self, keys, missing=None, deferred=None):

ids = set(key.project for key in keys)
for current_id in ids:
if not _projects_equal(current_id, self.project):
if current_id != self.project:
raise ValueError('Keys do not match project')

transaction = self.current_transaction
Expand Down
54 changes: 1 addition & 53 deletions gcloud/datastore/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def __eq__(self, other):
return False

return (self.flat_path == other.flat_path and
_projects_equal(self.project, other.project) and
self.project == other.project and
self.namespace == other.namespace)

def __ne__(self, other):
Expand Down Expand Up @@ -402,55 +402,3 @@ def _validate_project(project, parent):
raise ValueError("A Key must have a project set.")

return project


def _projects_equal(project1, project2):
"""Compares two projects for fuzzy equality.
Each may be prefixed or unprefixed (but not null, since project
is required on a key). The only allowed prefixes are 's~' and 'e~'.
Two identical prefixed match
>>> 's~foo' == 's~foo'
>>> 'e~bar' == 'e~bar'
while non-identical prefixed don't
>>> 's~foo' != 's~bar'
>>> 's~foo' != 'e~foo'
As for non-prefixed, they can match other non-prefixed or
prefixed:
>>> 'foo' == 'foo'
>>> 'foo' == 's~foo'
>>> 'foo' == 'e~foo'
>>> 'foo' != 'bar'
>>> 'foo' != 's~bar'
(Ties are resolved since 'foo' can only be an alias for one of
s~foo or e~foo in the backend.)
:type project1: string
:param project1: A project.
:type project2: string
:param project2: A project.
:rtype: bool
:returns: Boolean indicating if the projects are the same.
"""
if project1 == project2:
return True

if project1.startswith('s~') or project1.startswith('e~'):
# If `project1` is prefixed and not matching, then the only way
# they can match is if `project2` is unprefixed.
return project1[2:] == project2
elif project2.startswith('s~') or project2.startswith('e~'):
# Here we know `project1` is unprefixed and `project2`
# is prefixed.
return project1 == project2[2:]

return False
45 changes: 0 additions & 45 deletions gcloud/datastore/test_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,39 +129,6 @@ def test_put_entity_w_completed_key(self):
self.assertTrue(spam_values[2].exclude_from_indexes)
self.assertFalse('frotz' in prop_dict)

def test_put_entity_w_completed_key_prefixed_project(self):
from gcloud.datastore.helpers import _property_tuples

_PROJECT = 'PROJECT'
_PROPERTIES = {
'foo': 'bar',
'baz': 'qux',
'spam': [1, 2, 3],
'frotz': [], # will be ignored
}
connection = _Connection()
client = _Client(_PROJECT, connection)
batch = self._makeOne(client)
entity = _Entity(_PROPERTIES)
entity.exclude_from_indexes = ('baz', 'spam')
key = entity.key = _Key('s~' + _PROJECT)

batch.put(entity)

mutated_entity = _mutated_pb(self, batch.mutations, 'upsert')
self.assertEqual(mutated_entity.key, key._key)

prop_dict = dict(_property_tuples(mutated_entity))
self.assertEqual(len(prop_dict), 3)
self.assertFalse(prop_dict['foo'].exclude_from_indexes)
self.assertTrue(prop_dict['baz'].exclude_from_indexes)
self.assertFalse(prop_dict['spam'].exclude_from_indexes)
spam_values = prop_dict['spam'].array_value.values
self.assertTrue(spam_values[0].exclude_from_indexes)
self.assertTrue(spam_values[1].exclude_from_indexes)
self.assertTrue(spam_values[2].exclude_from_indexes)
self.assertFalse('frotz' in prop_dict)

def test_delete_w_partial_key(self):
_PROJECT = 'PROJECT'
connection = _Connection()
Expand Down Expand Up @@ -193,18 +160,6 @@ def test_delete_w_completed_key(self):
mutated_key = _mutated_pb(self, batch.mutations, 'delete')
self.assertEqual(mutated_key, key._key)

def test_delete_w_completed_key_w_prefixed_project(self):
_PROJECT = 'PROJECT'
connection = _Connection()
client = _Client(_PROJECT, connection)
batch = self._makeOne(client)
key = _Key('s~' + _PROJECT)

batch.delete(key)

mutated_key = _mutated_pb(self, batch.mutations, 'delete')
self.assertEqual(mutated_key, key._key)

def test_begin(self):
_PROJECT = 'PROJECT'
client = _Client(_PROJECT, None)
Expand Down
49 changes: 0 additions & 49 deletions gcloud/datastore/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,55 +456,6 @@ def test_get_multi_hit_multiple_keys_different_project(self):
with self.assertRaises(ValueError):
client.get_multi([key1, key2])

def test_get_multi_diff_prefixes(self):
from gcloud.datastore.key import Key

PROJECT1 = 'PROJECT'
PROJECT2 = 'e~PROJECT'
PROJECT3 = 's~PROJECT'
KIND = 'Kind'
ID1 = 1234
ID2 = 2345
ID3 = 3456

# Make found entity pbs to be returned from mock backend.
entity_pb1 = _make_entity_pb(PROJECT1, KIND, ID1)
entity_pb2 = _make_entity_pb(PROJECT2, KIND, ID2)
entity_pb3 = _make_entity_pb(PROJECT3, KIND, ID3)

creds = object()
client = self._makeOne(credentials=creds)
client.connection._add_lookup_result([entity_pb1,
entity_pb2,
entity_pb3])

key1 = Key(KIND, ID1, project=PROJECT1)
key2 = Key(KIND, ID2, project=PROJECT2)
key3 = Key(KIND, ID3, project=PROJECT3)

retrieved_all = client.get_multi([key1, key2, key3])
retrieved1, retrieved2, retrieved3 = retrieved_all

# Check values & keys match.
self.assertEqual(retrieved1.key.path, key1.path)
self.assertEqual(retrieved2.key.path, key2.path)
self.assertEqual(retrieved3.key.path, key3.path)

def test_get_multi_diff_projects_w_prefix(self):
from gcloud.datastore.key import Key

PROJECT1 = 'e~PROJECT'
PROJECT2 = 's~PROJECT-ALT'

key1 = Key('KIND', 1234, project=PROJECT1)
key2 = Key('KIND', 1234, project=PROJECT2)

creds = object()
client = self._makeOne(credentials=creds)

with self.assertRaises(ValueError):
client.get_multi([key1, key2])

def test_get_multi_max_loops(self):
from gcloud._testing import _Monkey
from gcloud.datastore import client as _MUT
Expand Down
2 changes: 1 addition & 1 deletion gcloud/datastore/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def test_nested_entity_no_key(self):
from gcloud.datastore._generated import entity_pb2
from gcloud.datastore.helpers import _new_value_pb

PROJECT = 's~FOO'
PROJECT = 'FOO'
KIND = 'KIND'
INSIDE_NAME = 'IFOO'
OUTSIDE_NAME = 'OBAR'
Expand Down
44 changes: 0 additions & 44 deletions gcloud/datastore/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,6 @@ def test___eq_____ne___same_kind_and_id_different_namespace(self):
self.assertFalse(key1 == key2)
self.assertTrue(key1 != key2)

def test___eq_____ne___same_kind_and_id_different_project_pfx(self):
_PROJECT = 'PROJECT'
_PROJECT_W_PFX = 's~PROJECT'
_KIND = 'KIND'
_ID = 1234
key1 = self._makeOne(_KIND, _ID, project=_PROJECT)
key2 = self._makeOne(_KIND, _ID, project=_PROJECT_W_PFX)
self.assertTrue(key1 == key2)
self.assertFalse(key1 != key2)

def test___eq_____ne___same_kind_different_names(self):
_PROJECT = 'PROJECT'
_KIND = 'KIND'
Expand Down Expand Up @@ -273,16 +263,6 @@ def test___eq_____ne___same_kind_and_name_different_namespace(self):
self.assertFalse(key1 == key2)
self.assertTrue(key1 != key2)

def test___eq_____ne___same_kind_and_name_different_project_pfx(self):
_PROJECT = 'PROJECT'
_PROJECT_W_PFX = 's~PROJECT'
_KIND = 'KIND'
_NAME = 'one'
key1 = self._makeOne(_KIND, _NAME, project=_PROJECT)
key2 = self._makeOne(_KIND, _NAME, project=_PROJECT_W_PFX)
self.assertTrue(key1 == key2)
self.assertFalse(key1 != key2)

def test___hash___incomplete(self):
_PROJECT = 'PROJECT'
_KIND = 'KIND'
Expand Down Expand Up @@ -449,27 +429,3 @@ def test_parent_multiple_calls(self):
self.assertEqual(parent.path, _PARENT_PATH)
new_parent = key.parent
self.assertTrue(parent is new_parent)


class Test__projects_equal(unittest2.TestCase):

def _callFUT(self, project1, project2):
from gcloud.datastore.key import _projects_equal
return _projects_equal(project1, project2)

def test_identical_prefixed(self):
self.assertTrue(self._callFUT('s~foo', 's~foo'))
self.assertTrue(self._callFUT('e~bar', 'e~bar'))

def test_different_prefixed(self):
self.assertFalse(self._callFUT('s~foo', 's~bar'))
self.assertFalse(self._callFUT('s~foo', 'e~foo'))

def test_all_unprefixed(self):
self.assertTrue(self._callFUT('foo', 'foo'))
self.assertFalse(self._callFUT('foo', 'bar'))

def test_unprefixed_with_prefixed(self):
self.assertTrue(self._callFUT('foo', 's~foo'))
self.assertTrue(self._callFUT('foo', 'e~foo'))
self.assertFalse(self._callFUT('foo', 's~bar'))

0 comments on commit 090b187

Please sign in to comment.