aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/db/util.py
blob: 70c37945d06f0a0c75e51fcc091a1f6349424373 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011 Free Software Foundation, Inc
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
Utilities for database operations.

Some note on migration and indexing tools:

We store information about what the state of the database is in the
'mediagoblin' document of the 'app_metadata' collection.  Keys in that
document relevant to here:

 - 'migration_number': The integer representing the current state of
   the migrations
"""

import copy

# Imports that other modules might use
from pymongo import ASCENDING, DESCENDING
from pymongo.errors import InvalidId
from mongokit import ObjectId

from mediagoblin.db.indexes import ACTIVE_INDEXES, DEPRECATED_INDEXES


def add_new_indexes(database, active_indexes=ACTIVE_INDEXES):
    """
    Add any new indexes to the database.

    Args:
     - database: pymongo or mongokit database instance.
     - active_indexes: indexes to possibly add in the pattern of:
       {'collection_name': {
            'identifier': {
                'index': [index_foo_goes_here],
                'unique': True}}
       where 'index' is the index to add and all other options are
       arguments for collection.create_index.

    Returns:
      A list of indexes added in form ('collection', 'index_name')
    """
    indexes_added = []

    for collection_name, indexes in active_indexes.iteritems():
        collection = database[collection_name]
        collection_indexes = collection.index_information().keys()

        for index_name, index_data in indexes.iteritems():
            if not index_name in collection_indexes:
                # Get a copy actually so we don't modify the actual
                # structure
                index_data = copy.copy(index_data)
                index = index_data.pop('index')
                collection.create_index(
                    index, name=index_name, **index_data)

                indexes_added.append((collection_name, index_name))

    return indexes_added


def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES):
    """
    Remove any deprecated indexes from the database.

    Args:
     - database: pymongo or mongokit database instance.
     - deprecated_indexes: the indexes to deprecate in the pattern of:
       {'collection': ['index_identifier1', 'index_identifier2']}

    Returns:
      A list of indexes removed in form ('collection', 'index_name')
    """
    indexes_removed = []

    for collection_name, index_names in deprecated_indexes.iteritems():
        collection = database[collection_name]
        collection_indexes = collection.index_information().keys()

        for index_name in index_names:
            if index_name in collection_indexes:
                collection.drop_index(index_name)

                indexes_removed.append((collection_name, index_name))

    return indexes_removed