From ea702379c37d81704f2b634f4afe94c214d56358 Mon Sep 17 00:00:00 2001 From: Prinz23 Date: Tue, 13 Sep 2016 19:50:05 +0100 Subject: [PATCH] Add rollback capability to undo database changes made during tests. --- CHANGES.md | 7 +++++- SickBeard.py | 40 +++++++++++++++++++++++--------- sickbeard/databases/cache_db.py | 3 +++ sickbeard/databases/failed_db.py | 2 ++ sickbeard/db.py | 36 ++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3c95c390..e60c419e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,9 @@ -### 0.11.14 (2016-07-25 03:10:00 UTC) +### 0.11.15 (2016-09-13 19:50:00 UTC) + +* Add rollback capability to undo database changes made during tests + + +### 0.11.14 (2016-07-25 03:10:00 UTC) * Fix BeyondHD torrent provider diff --git a/SickBeard.py b/SickBeard.py index 451d64b7..9ad9de57 100755 --- a/SickBeard.py +++ b/SickBeard.py @@ -270,18 +270,36 @@ class SickGear(object): sickbeard.CFG = ConfigObj(sickbeard.CONFIG_FILE) - CUR_DB_VERSION = db.DBConnection().checkDBVersion() + # check all db versions + for d, min_v, max_v, mo in [ + ('failed.db', sickbeard.failed_db.MIN_DB_VERSION, sickbeard.failed_db.MAX_DB_VERSION, 'FailedDb'), + ('cache.db', sickbeard.cache_db.MIN_DB_VERSION, sickbeard.cache_db.MAX_DB_VERSION, 'CacheDb'), + ('sickbeard.db', sickbeard.mainDB.MIN_DB_VERSION, sickbeard.mainDB.MAX_DB_VERSION, 'MainDb') + ]: + cur_db_version = db.DBConnection(d).checkDBVersion() - if CUR_DB_VERSION > 0: - if CUR_DB_VERSION < MIN_DB_VERSION: - print(u'Your database version (%s) is too old to migrate from with this version of SickGear' \ - % CUR_DB_VERSION) - sys.exit(u'Upgrade using a previous version of SG first, or start with no database file to begin fresh') - if CUR_DB_VERSION > MAX_DB_VERSION: - print(u'Your database version (%s) has been incremented past what this version of SickGear supports' \ - % CUR_DB_VERSION) - sys.exit( - u'If you have used other forks of SG, your database may be unusable due to their modifications') + if cur_db_version > 0: + if cur_db_version < min_v: + print(u'Your [%s] database version (%s) is too old to migrate from with this version of SickGear' + % (d, cur_db_version)) + sys.exit(u'Upgrade using a previous version of SG first,' + + u' or start with no database file to begin fresh') + if cur_db_version > max_v: + print(u'Your [%s] database version (%s) has been incremented past' + u' what this version of SickGear supports. Trying to rollback now. Please wait...' % + (d, cur_db_version)) + try: + rollback_loaded = db.get_rollback_module() + if None is not rollback_loaded: + rollback_loaded.__dict__[mo]().run(max_v) + else: + print(u'ERROR: Could not download Rollback Module.') + except (StandardError, Exception): + pass + if db.DBConnection(d).checkDBVersion() > max_v: + print(u'Rollback failed.') + sys.exit(u'If you have used other forks, your database may be unusable due to their changes') + print(u'Rollback of [%s] successful.' % d) # Initialize the config and our threads sickbeard.initialize(consoleLogging=self.consoleLogging) diff --git a/sickbeard/databases/cache_db.py b/sickbeard/databases/cache_db.py index cfe02fb4..42d24a31 100644 --- a/sickbeard/databases/cache_db.py +++ b/sickbeard/databases/cache_db.py @@ -18,6 +18,9 @@ from sickbeard import db +MIN_DB_VERSION = 1 +MAX_DB_VERSION = 2 + # Add new migrations at the bottom of the list; subclass the previous migration. class InitialSchema(db.SchemaUpgrade): def test(self): diff --git a/sickbeard/databases/failed_db.py b/sickbeard/databases/failed_db.py index f53514ce..7d78abd0 100644 --- a/sickbeard/databases/failed_db.py +++ b/sickbeard/databases/failed_db.py @@ -19,6 +19,8 @@ from sickbeard import db from sickbeard.common import Quality +MIN_DB_VERSION = 1 +MAX_DB_VERSION = 1 # Add new migrations at the bottom of the list; subclass the previous migration. class InitialSchema(db.SchemaUpgrade): diff --git a/sickbeard/db.py b/sickbeard/db.py index f4392b4f..044f37ea 100644 --- a/sickbeard/db.py +++ b/sickbeard/db.py @@ -472,9 +472,45 @@ def MigrationCode(myDB): else: logger.log_error_and_exit(u'Failed to restore database version: %s' % db_version) + def backup_database(filename, version): logger.log(u'Backing up database before upgrade') if not sickbeard.helpers.backupVersionedFile(dbFilename(filename), version): logger.log_error_and_exit(u'Database backup failed, abort upgrading database') else: logger.log(u'Proceeding with upgrade') + + +def get_rollback_module(): + import imp + + module_urls = [ + 'https://raw.githubusercontent.com/SickGear/sickgear.extdata/master/SickGear/Rollback/rollback.py'] + + try: + hdr = '# SickGear Rollback Module' + module = '' + fetched = False + + for t in range(1, 4): + for url in module_urls: + try: + module = helpers.getURL(url) + if module and module.startswith(hdr): + fetched = True + break + except (StandardError, Exception): + continue + if fetched: + break + time.sleep(30) + + if fetched: + loaded = imp.new_module('DbRollback') + exec(module, loaded.__dict__) + return loaded + + except (StandardError, Exception): + pass + + return None