Skip to content
Closed
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
2 changes: 1 addition & 1 deletion pymongo/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def _index_list(key_or_list, direction=None):
else:
if isinstance(key_or_list, string_type):
return [(key_or_list, ASCENDING)]
elif not isinstance(key_or_list, (list, tuple)):
elif not isinstance(key_or_list, (list, tuple, SON)):
raise TypeError("if no direction is specified, "
"key_or_list must be an instance of list")
return key_or_list
Expand Down
39 changes: 38 additions & 1 deletion pymongo/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from pymongo.common import validate_boolean, validate_is_mapping
from pymongo.helpers import _gen_index_name, _index_document, _index_list
import bson


class _WriteOp(object):
Expand Down Expand Up @@ -236,7 +237,10 @@ def __init__(self, keys, **kwargs):
keys = _index_list(keys)
if "name" not in kwargs:
kwargs["name"] = _gen_index_name(keys)
kwargs["key"] = _index_document(keys)
if isinstance(keys, bson.SON):
kwargs["key"] = keys
else:
kwargs["key"] = _index_document(keys)
self.__document = kwargs

@property
Expand All @@ -245,3 +249,36 @@ def document(self):
command.
"""
return self.__document

@staticmethod
def from_son(kwargs):
"""
SON documents returned from collection.list_indexes()

:param kwargs:
:return:
"""
attrs = dict(kwargs)
return IndexModel(attrs.pop("key"), **attrs)

def __eq__(self, other):
"""
An IndexModel is equal even if the names are not the same.
Assuming one is constructed by the user and another is returned by the
driver.

:param other:
:return:
"""
if isinstance(other, IndexModel):
other = other.document
skipped_keys = ["v", "ns", "background", "name"]
all_keys = set(list(self.document.keys()) + list(other.keys()))
filtered_keys = [key for key in all_keys if key not in skipped_keys]
for key in filtered_keys:
if self.document.get(key) != other.get(key):
return False
return True

def __ne__(self, other):
return not self == other
9 changes: 5 additions & 4 deletions test/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,16 +277,17 @@ def map_indexes(indexes):
db.test.create_index("hello")
indexes = list(db.test.list_indexes())
self.assertEqual(len(indexes), 2)
self.assertEqual(map_indexes(indexes)["hello_1"]["key"],
SON([("hello", ASCENDING)]))
self.assertEqual(IndexModel(SON([("hello", ASCENDING)])),
map_indexes(indexes)["hello_1"])

db.test.create_index([("hello", DESCENDING), ("world", ASCENDING)],
unique=True)
indexes = list(db.test.list_indexes())
self.assertEqual(len(indexes), 3)
index_map = map_indexes(indexes)
self.assertEqual(index_map["hello_-1_world_1"]["key"],
SON([("hello", DESCENDING), ("world", ASCENDING)]))
self.assertEqual(IndexModel(SON([("hello", DESCENDING),
("world", ASCENDING)]), unique=True),
index_map["hello_-1_world_1"])
self.assertEqual(True, index_map["hello_-1_world_1"]["unique"])

def test_index_info(self):
Expand Down