Source code for matador.db.changes

# coding: utf-8
# Distributed under the terms of the MIT License.

""" This file implements an interface for querying the
__changelog_<collection> collections to allow for display and reversion
of particular database changes.

"""


from matador.db import make_connection_to_collection
from matador.utils.print_utils import print_warning, print_notify


[docs]class DatabaseChanges: """ Class to view and undo particular database changesets. """ def __init__(self, collection_name: str, changeset_ind=0, action='view', override=False, mongo_settings=None): """ Parse arguments and run changes interface. Parameters: collection_name (str): the base collection name to act upon Keyword arguments: changset_ind (int): the number of the changset to act upon (1 is oldest) action (str): either 'view' or 'undo' override (bool): override all options to positive answers for testing mongo_settings (dict): dictionary of already-sources mongo settings """ self.changelog_name = '__changelog_{}'.format(collection_name) _, _, self.collections = make_connection_to_collection(self.changelog_name, allow_changelog=True, override=override, mongo_settings=mongo_settings) self.repo = [self.collections[key] for key in self.collections][0] curs = list(self.repo.find()) if not curs: exit('No changesets found for {}'.format(collection_name)) # if no changeset specified, print summary if changeset_ind == 0: self.print_change_summary(curs) elif changeset_ind > len(curs): exit('No changeset {} found for collection called "{}".'.format(changeset_ind, collection_name)) # otherwise, try to act on particular changeset elif changeset_ind <= len(curs): self.change = curs[changeset_ind-1] self.view_changeset(self.change, changeset_ind-1) if action == 'undo': count = curs[changeset_ind-1]['count'] print_warning('An attempt will now be made to remove {} structures from {}.' .format(count, collection_name)) print_notify('Are you sure you want to do that? (y/n)') if override: response = 'y' else: response = input() if response.lower() == 'y': print_notify('You don\'t have any doubts at all? (y/n)') if override: next_response = 'n' else: next_response = input() if next_response.lower() == 'n': print('You\'re the boss, deleting structures now...') else: exit('As I thought...') else: exit() # proceed with deletion _, _, collections = make_connection_to_collection(collection_name, allow_changelog=False, override=override) collection_to_delete_from = [collections[key] for key in collections][0] result = collection_to_delete_from.delete_many({'_id': {'$in': self.change['id_list']}}) print('Deleted {}/{} successfully.'.format(result.deleted_count, self.change['count'])) print('Tidying up changelog database...') self.repo.delete_one({'_id': self.change['_id']}) if not self.repo.find_one(): print('No structures left remaining, deleting database...') collection_to_delete_from.drop() self.repo.drop() print('Success!')
[docs] @staticmethod def view_changeset(changeset, index): """ Prints all details about a particular changeset. Parameters: changeset (dict): changeset stored in changelog database index (int): changeset index """ print('Files added by changeset:') for src in changeset['src_list']: print('(+) {}'.format(src)) print('({}) {} {:>7d} additions'.format(index+1, changeset['date'], changeset['count']))
[docs] @staticmethod def print_change_summary(curs): """ Prints a summary of changes. Parameters: curs (list): cursor from changelog database """ for index, change in enumerate(curs): print('({}) {} {:>7d} additions'.format(index+1, change['date'], change['count']))