Merge branch 'stable'
[mediagoblin.git] / mediagoblin / db / util.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
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 import sys
18
19 from mediagoblin import mg_globals as mgg
20 from mediagoblin.db.models import MediaEntry, Tag, MediaTag, Collection
21 from mediagoblin.gmg_commands.dbupdate import gather_database_data
22
23 from mediagoblin.tools.transition import DISABLE_GLOBALS
24
25 if not DISABLE_GLOBALS:
26 from mediagoblin.db.base import Session
27
28 ##########################
29 # Random utility functions
30 ##########################
31
32
33 def atomic_update(table, query_dict, update_values):
34 table.query.filter_by(**query_dict).update(update_values,
35 synchronize_session=False)
36 Session.commit()
37
38
39 def check_media_slug_used(uploader_id, slug, ignore_m_id):
40 query = MediaEntry.query.filter_by(uploader=uploader_id, slug=slug)
41 if ignore_m_id is not None:
42 query = query.filter(MediaEntry.id != ignore_m_id)
43 does_exist = query.first() is not None
44 return does_exist
45
46
47 def media_entries_for_tag_slug(dummy_db, tag_slug):
48 return MediaEntry.query \
49 .join(MediaEntry.tags_helper) \
50 .join(MediaTag.tag_helper) \
51 .filter(
52 (MediaEntry.state == u'processed')
53 & (Tag.slug == tag_slug))
54
55
56 def clean_orphan_tags(commit=True):
57 """Search for unused MediaTags and delete them"""
58 q1 = Session.query(Tag).outerjoin(MediaTag).filter(MediaTag.id==None)
59 for t in q1:
60 Session.delete(t)
61 # The "let the db do all the work" version:
62 # q1 = Session.query(Tag.id).outerjoin(MediaTag).filter(MediaTag.id==None)
63 # q2 = Session.query(Tag).filter(Tag.id.in_(q1))
64 # q2.delete(synchronize_session = False)
65 if commit:
66 Session.commit()
67
68
69 def check_collection_slug_used(creator_id, slug, ignore_c_id):
70 filt = (Collection.creator == creator_id) \
71 & (Collection.slug == slug)
72 if ignore_c_id is not None:
73 filt = filt & (Collection.id != ignore_c_id)
74 does_exist = Session.query(Collection.id).filter(filt).first() is not None
75 return does_exist
76
77
78 def check_db_up_to_date():
79 """Check if the database is up to date and quit if not"""
80 dbdatas = gather_database_data(mgg.global_config.get('plugins', {}).keys())
81
82 for dbdata in dbdatas:
83 session = Session()
84 try:
85 migration_manager = dbdata.make_migration_manager(session)
86 if migration_manager.database_current_migration is None or \
87 migration_manager.migrations_to_run():
88 sys.exit("Your database is not up to date. Please run "
89 "'gmg dbupdate' before starting MediaGoblin.")
90 finally:
91 Session.rollback()
92 Session.remove()
93
94
95 if __name__ == '__main__':
96 from mediagoblin.db.open import setup_connection_and_db_from_config
97
98 db = setup_connection_and_db_from_config({'sql_engine':'sqlite:///mediagoblin.db'})
99
100 clean_orphan_tags()