=======
Indexes
=======

Let's test our dummy index concept. We currently support create, list and drop
indexes. We do not use them right now. But some usefull informations about
indexes are available:

  >>> import json
  >>> from pymongo import IndexModel
  >>> from pymongo import ASCENDING
  >>> from pymongo import DESCENDING
  >>> import m01.fake
  >>> import m01.fake.testing

Get a test client:

  >>> client = m01.fake.testing.getTestClient()

and get a collection:

  >>> collection = m01.fake.testing.getTestCollection()


create_indexes
--------------

Let's create some indexs:

  >>> idx = IndexModel([
  ...     ('key', ASCENDING),
  ...     ('counter', DESCENDING),
  ...     ])
  >>> idx2 = IndexModel([
  ...     ('two', ASCENDING),
  ...     ])
  >>> collection.create_indexes([idx, idx2])
  [u'key_1_counter_-1', u'two_1']


create_index
------------

Let's create an index:

  >>> collection.create_index([('three', ASCENDING),
  ...                          ('another', DESCENDING)])
  u'three_1_another_-1'


ensure_index
------------

  >>> key_or_list = 'foo'
  >>> cache_for = 5
  >>> kwargs = {
  ...     'drop_dups': True,
  ... }
  >>> collection.ensure_index(key_or_list, cache_for=cache_for, **kwargs)
  u'foo_1'

  >>> key_or_list = [
  ...     ('three', ASCENDING),
  ...     ('another', DESCENDING),
  ...     ]
  >>> collection.ensure_index(key_or_list, cache_for=cache_for, **kwargs)
  'three_1_another_-1'


reindex
-------

Rebuilds all indexes on this collection:

  >>> print json.dumps(collection.reindex(), indent=4, sort_keys=True)
  {
      "indexes": [
          {
              "key": {
                  "_id": 1
              },
              "name": "_id_",
              "ns": "m01_fake_database.test"
          },
          {
              "key": {
                  "counter": -1,
                  "key": 1
              },
              "name": "key_1_counter_-1",
              "ns": "m01_fake_database.test"
          },
          {
              "key": {
                  "two": 1
              },
              "name": "two_1",
              "ns": "m01_fake_database.test"
          },
          {
              "key": {
                  "another": -1,
                  "three": 1
              },
              "name": "three_1_another_-1",
              "ns": "m01_fake_database.test"
          },
          {
              "key": {
                  "foo": 1
              },
              "name": "foo_1",
              "ns": "m01_fake_database.test"
          }
      ],
      "nIndexes": 5,
      "nIndexesWas": 5,
      "ok": 1.0
  }

list_indexes
------------

Get a cursor over the index documents for this collection:

  >>> for idx in collection.list_indexes():
  ...     idx
  SON([(u'v', 1), (u'key', SON([(u'_id', 1)])), (u'name', u'_id_'), (u'ns', u'm01_fake_database.test')])
  SON([(u'v', 1), (u'key', SON([(u'key', 1), (u'counter', -1)])), (u'name', u'key_1_counter_-1'), (u'ns', u'm01_fake_database.test')])
  SON([(u'v', 1), (u'key', SON([(u'two', 1)])), (u'name', u'two_1'), (u'ns', u'm01_fake_database.test')])
  SON([(u'v', 1), (u'key', SON([(u'three', 1), (u'another', -1)])), (u'name', u'three_1_another_-1'), (u'ns', u'm01_fake_database.test')])
  SON([(u'v', 1), (u'key', SON([(u'foo', 1)])), (u'name', u'foo_1'), (u'ns', u'm01_fake_database.test')])


index_information
-----------------

Get information on this collection's indexes:

  >>> information = collection.index_information()

  >>> print json.dumps(information, indent=4, sort_keys=True)
  {
      "_id_": {
          "key": [
              [
                  "_id",
                  1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      },
      "foo_1": {
          "key": [
              [
                  "foo",
                  1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      },
      "key_1_counter_-1": {
          "key": [
              [
                  "key",
                  1
              ],
              [
                  "counter",
                  -1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      },
      "three_1_another_-1": {
          "key": [
              [
                  "three",
                  1
              ],
              [
                  "another",
                  -1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      },
      "two_1": {
          "key": [
              [
                  "two",
                  1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      }
  }


drop_index
----------

Drops the specified index on this collection

  >>> index_or_name = 'key_1_counter_-1'
  >>> collection.drop_index(index_or_name)

  >>> index_or_name = 'three_1_another_-1'
  >>> collection.drop_index(index_or_name)

  >>> index_or_name = 'two_1'
  >>> collection.drop_index(index_or_name)

  >>> information = collection.index_information()
  >>> print json.dumps(information, indent=4, sort_keys=True)
  {
      "_id_": {
          "key": [
              [
                  "_id",
                  1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      },
      "foo_1": {
          "key": [
              [
                  "foo",
                  1
              ]
          ],
          "ns": "m01_fake_database.test",
          "v": 1
      }
  }

and an error get raised if we drop an unknonw index:

  >>> index_or_name = 'unknown'
  >>> collection.drop_index(index_or_name)
  Traceback (most recent call last):
  ...
  OperationFailure:...index not found with name [unknown]


drop_indexes
------------

Drops all indexes on this collection

  >>> collection.drop_indexes()

As you can see, the _id index ist still intact:

  >>> collection.index_information()
  {u'_id_': {u'ns': u'm01_fake_database.test', u'key': [(u'_id', 1)], u'v': 1}}


unique
------

Check default unique _id_ index concept:

  >>> doc = {
  ...     '_id': u'42',
  ...     'key': u'1',
  ... }
  >>> collection.insert(doc)
  '42'

Another document with the same _id will raise an error:

  >>> doc = {
  ...     '_id': u'42',
  ...     'key': u'2',
  ... }
  >>> collection.insert(doc)
  Traceback (most recent call last):
  ...
  DuplicateKeyError: E11000 duplicate key error index: m01_fake_database.test.$_id_ dup key: { : "42" }

Add another index an make a custom value unique:

  >>> collection.create_index('custom', unique=True)
  u'custom_1'

  >>> doc = {
  ...     '_id': u'43',
  ...     'custom': u'1',
  ... }
  >>> collection.insert(doc)
  '43'

  >>> doc = {
  ...     '_id': u'44',
  ...     'custom': u'1',
  ... }
  >>> collection.insert(doc)
  Traceback (most recent call last):
  ...
  DuplicateKeyError: E11000 duplicate key error index: m01_fake_database.test.$custom_1 dup key: { : "1" }

