Tools to add / remove indexes from collections
[mediagoblin.git] / mediagoblin / db / util.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011 Free Software Foundation, Inc
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 """
18 Utilities for database operations.
19
20 Some note on migration and indexing tools:
21
22 We store information about what the state of the database is in the
23 'mediagoblin' document of the 'app_metadata' collection. Keys in that
24 document relevant to here:
25
26 - 'migration_number': The integer representing the current state of
27 the migrations
28 """
29
30 import copy
31
32 # Imports that other modules might use
33 from pymongo import DESCENDING
34 from pymongo.errors import InvalidId
35 from mongokit import ObjectId
36
37 from mediagoblin.db.indexes import ACTIVE_INDEXES, DEPRECATED_INDEXES
38
39
40 def add_new_indexes(database, active_indexes=ACTIVE_INDEXES):
41 """
42 Add any new indexes to the database.
43
44 Returns:
45 A list of indexes added in form ('collection', 'index_name')
46 """
47 indexes_added = []
48
49 for collection_name, indexes in active_indexes.iteritems():
50 collection = database[collection_name]
51 collection_indexes = collection.index_information().keys()
52
53 for index_name, index_data in indexes.iteritems():
54 if not index_name in collection_indexes:
55 # Get a copy actually so we don't modify the actual
56 # structure
57 index_data = copy.copy(index_data)
58 index = index_data.pop('index')
59 collection.create_index(
60 index, name=index_name, **index_data)
61
62 indexes_added.append((collection_name, index_name))
63
64 return indexes_added
65
66
67 def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES):
68 """
69 Remove any deprecated indexes from the database.
70
71 Returns:
72 A list of indexes removed in form ('collection', 'index_name')
73 """
74 indexes_removed = []
75
76 for collection_name, indexes in deprecated_indexes.iteritems():
77 collection = database[collection_name]
78 collection_indexes = collection.index_information().keys()
79
80 for index_name, index_data in indexes.iteritems():
81 if index_name in collection_indexes:
82 collection.drop_index(index_name)
83
84 indexes_removed.append((collection_name, index_name))
85
86 return indexes_removed