aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/db/util.py
blob: 37e6586f821be26e642a2a047bc1591d202fdef0 (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
102
103
104
105
106
107
108
# 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_name': {
            'identifier': {
                'index': [index_foo_goes_here],
                'unique': True}}

       (... although we really only need the 'identifier' here, as the
       rest of the information isn't used in this case.  But it's kept
       around so we can remember what it was)

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

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

        for index_name, index_data in indexes.iteritems():
            if index_name in collection_indexes:
                collection.drop_index(index_name)

                indexes_removed.append((collection_name, index_name))

    return indexes_removed