Best Python code snippet using autotest_python
mainDB.py
Source:mainDB.py
...267 ]268 for query in queries:269 self.connection.action(query)270 else:271 cur_db_version = self.get_db_version()272 if cur_db_version < MIN_DB_VERSION:273 logger.log_error_and_exit(274 "Your database version ({cur_db_version}) is too old to migrate from what this version of SickRage supports ({min_db_version}).\n"275 "Upgrade using a previous version (tag) build 496 to build 501 of SickRage first or remove database file to begin fresh.".format276 (cur_db_version=str(cur_db_version), min_db_version=str(MIN_DB_VERSION)))277 if cur_db_version > MAX_DB_VERSION:278 logger.log_error_and_exit(279 "Your database version ({cur_db_version}) has been incremented past what this version of SickRage supports ({max_db_version}).\n"280 "If you have used other forks of SickRage, your database may be unusable due to their modifications.".format281 (cur_db_version=str(cur_db_version), max_db_version=str(MAX_DB_VERSION)))282class AddSizeAndSceneNameFields(InitialSchema):283 def test(self):284 return self.get_db_version() >= 10285 def execute(self):286 backupDatabase(self.get_db_version())287 if not self.has_column("tv_episodes", "file_size"):288 self.add_column("tv_episodes", "file_size")289 if not self.has_column("tv_episodes", "release_name"):290 self.add_column("tv_episodes", "release_name", "TEXT", "")291 ep_results = self.connection.select("SELECT episode_id, location, file_size FROM tv_episodes")292 logger.log("Adding file size to all episodes in DB, please be patient")293 for cur_ep in ep_results:294 if not cur_ep[b"location"]:295 continue296 # if there is no size yet then populate it for us297 if (not cur_ep[b"file_size"] or not int(cur_ep[b"file_size"])) and ek(os.path.isfile, cur_ep[b"location"]):298 cur_size = ek(os.path.getsize, cur_ep[b"location"])299 self.connection.action("UPDATE tv_episodes SET file_size = ? WHERE episode_id = ?",300 [cur_size, int(cur_ep[b"episode_id"])])301 # check each snatch to see if we can use it to get a release name from302 history_results = self.connection.select("SELECT * FROM history WHERE provider != -1 ORDER BY date ASC")303 logger.log("Adding release name to all episodes still in history")304 for cur_result in history_results:305 # find the associated download, if there isn't one then ignore it306 download_results = self.connection.select(307 "SELECT resource FROM history WHERE provider = -1 AND showid = ? AND season = ? AND episode = ? AND date > ?",308 [cur_result[b"showid"], cur_result[b"season"], cur_result[b"episode"], cur_result[b"date"]])309 if not download_results:310 logger.log(311 "Found a snatch in the history for " + cur_result[b"resource"] + " but couldn't find the associated download, skipping it",312 logger.DEBUG313 )314 continue315 nzb_name = cur_result[b"resource"]316 file_name = ek(os.path.basename, download_results[0][b"resource"])317 # take the extension off the filename, it's not needed318 if '.' in file_name:319 file_name = file_name.rpartition('.')[0]320 # find the associated episode on disk321 ep_results = self.connection.select(322 "SELECT episode_id, status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ? AND location != ''",323 [cur_result[b"showid"], cur_result[b"season"], cur_result[b"episode"]])324 if not ep_results:325 logger.log(326 "The episode " + nzb_name + " was found in history but doesn't exist on disk anymore, skipping",327 logger.DEBUG)328 continue329 # get the status/quality of the existing ep and make sure it's what we expect330 ep_status, ep_quality = common.Quality.splitCompositeStatus(int(ep_results[0][b"status"]))331 if ep_status != common.DOWNLOADED:332 continue333 if ep_quality != int(cur_result[b"quality"]):334 continue335 # make sure this is actually a real release name and not a season pack or something336 for cur_name in (nzb_name, file_name):337 logger.log("Checking if " + cur_name + " is actually a good release name", logger.DEBUG)338 try:339 parse_result = NameParser(False).parse(cur_name)340 except (InvalidNameException, InvalidShowException):341 continue342 if parse_result.series_name and parse_result.season_number is not None and parse_result.episode_numbers and parse_result.release_group:343 # if all is well by this point we'll just put the release name into the database344 self.connection.action("UPDATE tv_episodes SET release_name = ? WHERE episode_id = ?",345 [cur_name, ep_results[0][b"episode_id"]])346 break347 # check each snatch to see if we can use it to get a release name from348 empty_results = self.connection.select("SELECT episode_id, location FROM tv_episodes WHERE release_name = ''")349 logger.log("Adding release name to all episodes with obvious scene filenames")350 for cur_result in empty_results:351 ep_file_name = ek(os.path.basename, cur_result[b"location"])352 ep_file_name = ek(os.path.splitext, ep_file_name)[0]353 # only want to find real scene names here so anything with a space in it is out354 if ' ' in ep_file_name:355 continue356 try:357 parse_result = NameParser(False).parse(ep_file_name)358 except (InvalidNameException, InvalidShowException):359 continue360 if not parse_result.release_group:361 continue362 logger.log(363 "Name " + ep_file_name + " gave release group of " + parse_result.release_group + ", seems valid",364 logger.DEBUG)365 self.connection.action("UPDATE tv_episodes SET release_name = ? WHERE episode_id = ?",366 [ep_file_name, cur_result[b"episode_id"]])367 self.increment_db_version()368class RenameSeasonFolders(AddSizeAndSceneNameFields):369 def test(self):370 return self.get_db_version() >= 11371 def execute(self):372 backupDatabase(self.get_db_version())373 # rename the column374 self.connection.action("DROP TABLE IF EXISTS tmp_tv_shows")375 self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")376 self.connection.action(377 "CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, location TEXT, show_name TEXT, tvdb_id NUMERIC, network TEXT, genre TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, tvr_id NUMERIC, tvr_name TEXT, air_by_date NUMERIC, lang TEXT)")378 self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows")379 # flip the values to be opposite of what they were before380 self.connection.action("UPDATE tv_shows SET flatten_folders = 2 WHERE flatten_folders = 1")381 self.connection.action("UPDATE tv_shows SET flatten_folders = 1 WHERE flatten_folders = 0")382 self.connection.action("UPDATE tv_shows SET flatten_folders = 0 WHERE flatten_folders = 2")383 self.connection.action("DROP TABLE tmp_tv_shows")384 self.increment_db_version()385class Add1080pAndRawHDQualities(RenameSeasonFolders):386 """Add support for 1080p related qualities along with RawHD387 Quick overview of what the upgrade needs to do:388 quality | old | new389 --------------------------390 hdwebdl | 1<<3 | 1<<5391 hdbluray | 1<<4 | 1<<7392 fullhdbluray | 1<<5 | 1<<8393 --------------------------394 rawhdtv | | 1<<3395 fullhdtv | | 1<<4396 fullhdwebdl | | 1<<6397 """398 def test(self):399 return self.get_db_version() >= 12400 def _update_status(self, old_status):401 (status, quality) = common.Quality.splitCompositeStatus(old_status)402 return common.Quality.compositeStatus(status, self._update_quality(quality))403 def _update_quality(self, old_quality):404 """Update bitwise flags to reflect new quality values405 Check flag bits (clear old then set their new locations) starting406 with the highest bits so we dont overwrite data we need later on407 """408 result = old_quality409 # move fullhdbluray from 1<<5 to 1<<8 if set410 if result & (1 << 5):411 result &= ~(1 << 5)412 result |= 1 << 8413 # move hdbluray from 1<<4 to 1<<7 if set414 if result & (1 << 4):415 result &= ~(1 << 4)416 result |= 1 << 7417 # move hdwebdl from 1<<3 to 1<<5 if set418 if result & (1 << 3):419 result &= ~(1 << 3)420 result |= 1 << 5421 return result422 def _update_composite_qualities(self, status):423 """Unpack, Update, Return new quality values424 Unpack the composite archive/initial values.425 Update either qualities if needed.426 Then return the new compsite quality value.427 """428 best = (status & (0xffff << 16)) >> 16429 initial = status & 0xffff430 best = self._update_quality(best)431 initial = self._update_quality(initial)432 result = ((best << 16) | initial)433 return result434 def execute(self):435 backupDatabase(self.get_db_version())436 # update the default quality so we dont grab the wrong qualities after migration437 sickbeard.QUALITY_DEFAULT = self._update_composite_qualities(sickbeard.QUALITY_DEFAULT)438 sickbeard.save_config()439 # upgrade previous HD to HD720p -- shift previous qualities to new placevalues440 old_hd = common.Quality.combineQualities(441 [common.Quality.HDTV, common.Quality.HDWEBDL >> 2, common.Quality.HDBLURAY >> 3], [])442 new_hd = common.Quality.combineQualities([common.Quality.HDTV, common.Quality.HDWEBDL, common.Quality.HDBLURAY],443 [])444 # update ANY -- shift existing qualities and add new 1080p qualities, note that rawHD was not added to the ANY template445 old_any = common.Quality.combineQualities(446 [common.Quality.SDTV, common.Quality.SDDVD, common.Quality.HDTV, common.Quality.HDWEBDL >> 2,447 common.Quality.HDBLURAY >> 3, common.Quality.UNKNOWN], [])448 new_any = common.Quality.combineQualities(449 [common.Quality.SDTV, common.Quality.SDDVD, common.Quality.HDTV, common.Quality.FULLHDTV,450 common.Quality.HDWEBDL, common.Quality.FULLHDWEBDL, common.Quality.HDBLURAY, common.Quality.FULLHDBLURAY,451 common.Quality.UNKNOWN], [])452 # update qualities (including templates)453 logger.log("[1/4] Updating pre-defined templates and the quality for each show...", logger.INFO)454 cl = []455 shows = self.connection.select("SELECT * FROM tv_shows")456 for cur_show in shows:457 if cur_show[b"quality"] == old_hd:458 new_quality = new_hd459 elif cur_show[b"quality"] == old_any:460 new_quality = new_any461 else:462 new_quality = self._update_composite_qualities(cur_show[b"quality"])463 cl.append(["UPDATE tv_shows SET quality = ? WHERE show_id = ?", [new_quality, cur_show[b"show_id"]]])464 self.connection.mass_action(cl)465 # update status that are are within the old hdwebdl (1<<3 which is 8) and better -- exclude unknown (1<<15 which is 32768)466 logger.log("[2/4] Updating the status for the episodes within each show...", logger.INFO)467 cl = []468 episodes = self.connection.select("SELECT * FROM tv_episodes WHERE status < 3276800 AND status >= 800")469 for cur_episode in episodes:470 cl.append(["UPDATE tv_episodes SET status = ? WHERE episode_id = ?",471 [self._update_status(cur_episode[b"status"]), cur_episode[b"episode_id"]]])472 self.connection.mass_action(cl)473 # make two seperate passes through the history since snatched and downloaded (action & quality) may not always coordinate together474 # update previous history so it shows the correct action475 logger.log("[3/4] Updating history to reflect the correct action...", logger.INFO)476 cl = []477 historyAction = self.connection.select("SELECT * FROM history WHERE action < 3276800 AND action >= 800")478 for cur_entry in historyAction:479 cl.append(["UPDATE history SET action = ? WHERE showid = ? AND date = ?",480 [self._update_status(cur_entry[b"action"]), cur_entry[b"showid"], cur_entry[b"date"]]])481 self.connection.mass_action(cl)482 # update previous history so it shows the correct quality483 logger.log("[4/4] Updating history to reflect the correct quality...", logger.INFO)484 cl = []485 historyQuality = self.connection.select("SELECT * FROM history WHERE quality < 32768 AND quality >= 8")486 for cur_entry in historyQuality:487 cl.append(["UPDATE history SET quality = ? WHERE showid = ? AND date = ?",488 [self._update_quality(cur_entry[b"quality"]), cur_entry[b"showid"], cur_entry[b"date"]]])489 self.connection.mass_action(cl)490 self.increment_db_version()491 # cleanup and reduce db if any previous data was removed492 logger.log("Performing a vacuum on the database.", logger.DEBUG)493 self.connection.action("VACUUM")494class AddShowidTvdbidIndex(Add1080pAndRawHDQualities):495 """ Adding index on tvdb_id (tv_shows) and showid (tv_episodes) to speed up searches/queries """496 def test(self):497 return self.get_db_version() >= 13498 def execute(self):499 backupDatabase(self.get_db_version())500 logger.log("Check for duplicate shows before adding unique index.")501 MainSanityCheck(self.connection).fix_duplicate_shows(b'tvdb_id')502 logger.log("Adding index on tvdb_id (tv_shows) and showid (tv_episodes) to speed up searches/queries.")503 if not self.has_table("idx_showid"):504 self.connection.action("CREATE INDEX idx_showid ON tv_episodes (showid);")505 if not self.has_table("idx_tvdb_id"):506 self.connection.action("CREATE UNIQUE INDEX idx_tvdb_id ON tv_shows (tvdb_id);")507 self.increment_db_version()508class AddLastUpdateTVDB(AddShowidTvdbidIndex):509 """ Adding column last_update_tvdb to tv_shows for controlling nightly updates """510 def test(self):511 return self.get_db_version() >= 14512 def execute(self):513 backupDatabase(self.get_db_version())514 logger.log("Adding column last_update_tvdb to tvshows")515 if not self.has_column("tv_shows", "last_update_tvdb"):516 self.add_column("tv_shows", "last_update_tvdb", default=1)517 self.increment_db_version()518class AddDBIncreaseTo15(AddLastUpdateTVDB):519 def test(self):520 return self.get_db_version() >= 15521 def execute(self):522 backupDatabase(self.get_db_version())523 self.increment_db_version()524class AddIMDbInfo(AddDBIncreaseTo15):525 def test(self):526 return self.get_db_version() >= 16527 def execute(self):528 backupDatabase(self.get_db_version())529 self.connection.action(530 "CREATE TABLE imdb_info (tvdb_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)")531 if not self.has_column("tv_shows", "imdb_id"):532 self.add_column("tv_shows", "imdb_id")533 self.increment_db_version()534class AddProperNamingSupport(AddIMDbInfo):535 def test(self):536 return self.get_db_version() >= 17537 def execute(self):538 backupDatabase(self.get_db_version())539 self.add_column("tv_episodes", "is_proper")540 self.increment_db_version()541class AddEmailSubscriptionTable(AddProperNamingSupport):542 def test(self):543 return self.get_db_version() >= 18544 def execute(self):545 backupDatabase(self.get_db_version())546 self.add_column('tv_shows', 'notify_list', 'TEXT', None)547 self.increment_db_version()548class AddProperSearch(AddEmailSubscriptionTable):549 def test(self):550 return self.get_db_version() >= 19551 def execute(self):552 backupDatabase(self.get_db_version())553 logger.log("Adding column last_proper_search to info")554 if not self.has_column("info", "last_proper_search"):555 self.add_column("info", "last_proper_search", default=1)556 self.increment_db_version()557class AddDvdOrderOption(AddProperSearch):558 def test(self):559 return self.get_db_version() >= 20560 def execute(self):561 backupDatabase(self.get_db_version())562 logger.log("Adding column dvdorder to tvshows")563 if not self.has_column("tv_shows", "dvdorder"):564 self.add_column("tv_shows", "dvdorder", "NUMERIC", "0")565 self.increment_db_version()566class AddSubtitlesSupport(AddDvdOrderOption):567 def test(self):568 return self.get_db_version() >= 21569 def execute(self):570 backupDatabase(self.get_db_version())571 if not self.has_column("tv_shows", "subtitles"):572 self.add_column("tv_shows", "subtitles")573 self.add_column("tv_episodes", "subtitles", "TEXT", "")574 self.add_column("tv_episodes", "subtitles_searchcount")575 self.add_column("tv_episodes", "subtitles_lastsearch", "TIMESTAMP", str(datetime.datetime.min))576 self.increment_db_version()577class ConvertTVShowsToIndexerScheme(AddSubtitlesSupport):578 def test(self):579 return self.get_db_version() >= 22580 def execute(self):581 backupDatabase(self.get_db_version())582 logger.log("Converting TV Shows table to Indexer Scheme...")583 self.connection.action("DROP TABLE IF EXISTS tmp_tv_shows")584 self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")585 self.connection.action("CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC)")586 self.connection.action(587 "INSERT INTO tv_shows (show_id, indexer_id, show_name, location, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, air_by_date, lang, subtitles, dvdorder) " +588 "SELECT show_id, tvdb_id as indexer_id, show_name, location, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, air_by_date, lang, subtitles, dvdorder FROM tmp_tv_shows"589 )590 self.connection.action("DROP TABLE tmp_tv_shows")591 self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);")592 self.connection.action("UPDATE tv_shows SET classification = 'Scripted'")593 self.connection.action("UPDATE tv_shows SET indexer = 1")594 self.increment_db_version()595class ConvertTVEpisodesToIndexerScheme(ConvertTVShowsToIndexerScheme):596 def test(self):597 return self.get_db_version() >= 23598 def execute(self):599 backupDatabase(self.get_db_version())600 logger.log("Converting TV Episodes table to Indexer Scheme...")601 self.connection.action("DROP TABLE IF EXISTS tmp_tv_episodes")602 self.connection.action("ALTER TABLE tv_episodes RENAME TO tmp_tv_episodes")603 self.connection.action(604 "CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer NUMERIC, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC)")605 self.connection.action(606 "INSERT INTO tv_episodes (episode_id, showid, indexerid, name, season, episode, description, airdate, hasnfo, hastbn, status, location, file_size, release_name, subtitles, subtitles_searchcount, subtitles_lastsearch) " +607 "SELECT episode_id, showid, tvdbid as indexerid, name, season, episode, description, airdate, hasnfo, hastbn, status, location, file_size, release_name, subtitles, subtitles_searchcount, subtitles_lastsearch FROM tmp_tv_episodes"608 )609 self.connection.action("DROP TABLE tmp_tv_episodes")610 self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);")611 self.connection.action("CREATE INDEX idx_showid ON tv_episodes (showid);")612 self.connection.action("CREATE INDEX idx_status ON tv_episodes (status,season,episode,airdate)")613 self.connection.action("CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate)")614 self.connection.action("CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate)")615 self.connection.action("UPDATE tv_episodes SET indexer = 1, is_proper = 0")616 self.increment_db_version()617class ConvertIMDBInfoToIndexerScheme(ConvertTVEpisodesToIndexerScheme):618 def test(self):619 return self.get_db_version() >= 24620 def execute(self):621 backupDatabase(self.get_db_version())622 logger.log("Converting IMDB Info table to Indexer Scheme...")623 self.connection.action("DROP TABLE IF EXISTS tmp_imdb_info")624 if self.has_table("imdb_info"):625 self.connection.action("ALTER TABLE imdb_info RENAME TO tmp_imdb_info")626 self.connection.action(627 "CREATE TABLE imdb_info (indexer_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)")628 if self.has_table("tmp_imdb_info"):629 self.connection.action("INSERT INTO imdb_info SELECT * FROM tmp_imdb_info")630 self.connection.action("DROP TABLE IF EXISTS tmp_imdb_info")631 self.increment_db_version()632class ConvertInfoToIndexerScheme(ConvertIMDBInfoToIndexerScheme):633 def test(self):634 return self.get_db_version() >= 25635 def execute(self):636 backupDatabase(self.get_db_version())637 logger.log("Converting Info table to Indexer Scheme...")638 self.connection.action("DROP TABLE IF EXISTS tmp_info")639 self.connection.action("ALTER TABLE info RENAME TO tmp_info")640 self.connection.action(641 "CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)")642 self.connection.action(643 "INSERT INTO info SELECT * FROM tmp_info")644 self.connection.action("DROP TABLE tmp_info")645 self.increment_db_version()646class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme):647 def test(self):648 return self.get_db_version() >= 26649 def execute(self):650 backupDatabase(self.get_db_version())651 logger.log("Adding column archive_firstmatch to tvshows")652 if not self.has_column("tv_shows", "archive_firstmatch"):653 self.add_column("tv_shows", "archive_firstmatch", "NUMERIC", "0")654 self.increment_db_version()655class AddSceneNumbering(AddArchiveFirstMatchOption):656 def test(self):657 return self.get_db_version() >= 27658 def execute(self):659 backupDatabase(self.get_db_version())660 if self.has_table("scene_numbering"):661 self.connection.action("DROP TABLE scene_numbering")662 self.connection.action(663 "CREATE TABLE scene_numbering (indexer TEXT, indexer_id INTEGER, season INTEGER, episode INTEGER, scene_season INTEGER, scene_episode INTEGER, PRIMARY KEY (indexer_id, season, episode, scene_season, scene_episode))")664 self.increment_db_version()665class ConvertIndexerToInteger(AddSceneNumbering):666 def test(self):667 return self.get_db_version() >= 28668 def execute(self):669 backupDatabase(self.get_db_version())670 cl = []671 logger.log("Converting Indexer to Integer ...", logger.INFO)672 cl.append(["UPDATE tv_shows SET indexer = ? WHERE LOWER(indexer) = ?", ["1", "tvdb"]])673 cl.append(["UPDATE tv_shows SET indexer = ? WHERE LOWER(indexer) = ?", ["2", "tvrage"]])674 cl.append(["UPDATE tv_episodes SET indexer = ? WHERE LOWER(indexer) = ?", ["1", "tvdb"]])675 cl.append(["UPDATE tv_episodes SET indexer = ? WHERE LOWER(indexer) = ?", ["2", "tvrage"]])676 cl.append(["UPDATE scene_numbering SET indexer = ? WHERE LOWER(indexer) = ?", ["1", "tvdb"]])677 cl.append(["UPDATE scene_numbering SET indexer = ? WHERE LOWER(indexer) = ?", ["2", "tvrage"]])678 self.connection.mass_action(cl)679 self.increment_db_version()680class AddRequireAndIgnoreWords(ConvertIndexerToInteger):681 """ Adding column rls_require_words and rls_ignore_words to tv_shows """682 def test(self):683 return self.get_db_version() >= 29684 def execute(self):685 backupDatabase(self.get_db_version())686 logger.log("Adding column rls_require_words to tvshows")687 if not self.has_column("tv_shows", "rls_require_words"):688 self.add_column("tv_shows", "rls_require_words", "TEXT", "")689 logger.log("Adding column rls_ignore_words to tvshows")690 if not self.has_column("tv_shows", "rls_ignore_words"):691 self.add_column("tv_shows", "rls_ignore_words", "TEXT", "")692 self.increment_db_version()693class AddSportsOption(AddRequireAndIgnoreWords):694 def test(self):695 return self.get_db_version() >= 30696 def execute(self):697 backupDatabase(self.get_db_version())698 logger.log("Adding column sports to tvshows")699 if not self.has_column("tv_shows", "sports"):700 self.add_column("tv_shows", "sports", "NUMERIC", "0")701 if self.has_column("tv_shows", "air_by_date") and self.has_column("tv_shows", "sports"):702 # update sports column703 logger.log("[4/4] Updating tv_shows to reflect the correct sports value...", logger.INFO)704 cl = []705 historyQuality = self.connection.select(706 "SELECT * FROM tv_shows WHERE LOWER(classification) = 'sports' AND air_by_date = 1 AND sports = 0")707 for cur_entry in historyQuality:708 cl.append(["UPDATE tv_shows SET sports = ? WHERE show_id = ?",709 [cur_entry[b"air_by_date"], cur_entry[b"show_id"]]])710 cl.append(["UPDATE tv_shows SET air_by_date = 0 WHERE show_id = ?", [cur_entry[b"show_id"]]])711 self.connection.mass_action(cl)712 self.increment_db_version()713class AddSceneNumberingToTvEpisodes(AddSportsOption):714 def test(self):715 return self.get_db_version() >= 31716 def execute(self):717 backupDatabase(self.get_db_version())718 logger.log("Adding column scene_season and scene_episode to tvepisodes")719 self.add_column("tv_episodes", "scene_season", "NUMERIC", "NULL")720 self.add_column("tv_episodes", "scene_episode", "NUMERIC", "NULL")721 self.increment_db_version()722class AddAnimeTVShow(AddSceneNumberingToTvEpisodes):723 def test(self):724 return self.get_db_version() >= 32725 def execute(self):726 backupDatabase(self.get_db_version())727 logger.log("Adding column anime to tv_episodes")728 self.add_column("tv_shows", "anime", "NUMERIC", "0")729 self.increment_db_version()730class AddAbsoluteNumbering(AddAnimeTVShow):731 def test(self):732 return self.get_db_version() >= 33733 def execute(self):734 backupDatabase(self.get_db_version())735 logger.log("Adding column absolute_number to tv_episodes")736 self.add_column("tv_episodes", "absolute_number", "NUMERIC", "0")737 self.increment_db_version()738class AddSceneAbsoluteNumbering(AddAbsoluteNumbering):739 def test(self):740 return self.get_db_version() >= 34741 def execute(self):742 backupDatabase(self.get_db_version())743 logger.log("Adding column absolute_number and scene_absolute_number to scene_numbering")744 self.add_column("scene_numbering", "absolute_number", "NUMERIC", "0")745 self.add_column("scene_numbering", "scene_absolute_number", "NUMERIC", "0")746 self.increment_db_version()747class AddAnimeBlacklistWhitelist(AddSceneAbsoluteNumbering):748 def test(self):749 return self.get_db_version() >= 35750 def execute(self):751 backupDatabase(self.get_db_version())752 cl = [753 ["CREATE TABLE blacklist (show_id INTEGER, range TEXT, keyword TEXT)"],754 ["CREATE TABLE whitelist (show_id INTEGER, range TEXT, keyword TEXT)"]755 ]756 self.connection.mass_action(cl)757 self.increment_db_version()758class AddSceneAbsoluteNumbering2(AddAnimeBlacklistWhitelist):759 def test(self):760 return self.get_db_version() >= 36761 def execute(self):762 backupDatabase(self.get_db_version())763 logger.log("Adding column scene_absolute_number to tv_episodes")764 self.add_column("tv_episodes", "scene_absolute_number", "NUMERIC", "0")765 self.increment_db_version()766class AddXemRefresh(AddSceneAbsoluteNumbering2):767 def test(self):768 return self.get_db_version() >= 37769 def execute(self):770 backupDatabase(self.get_db_version())771 logger.log("Creating table xem_refresh")772 self.connection.action(773 "CREATE TABLE xem_refresh (indexer TEXT, indexer_id INTEGER PRIMARY KEY, last_refreshed INTEGER)")774 self.increment_db_version()775class AddSceneToTvShows(AddXemRefresh):776 def test(self):777 return self.get_db_version() >= 38778 def execute(self):779 backupDatabase(self.get_db_version())780 logger.log("Adding column scene to tv_shows")781 self.add_column("tv_shows", "scene", "NUMERIC", "0")782 self.increment_db_version()783class AddIndexerMapping(AddSceneToTvShows):784 def test(self):785 return self.get_db_version() >= 39786 def execute(self):787 backupDatabase(self.get_db_version())788 if self.has_table("indexer_mapping"):789 self.connection.action("DROP TABLE indexer_mapping")790 logger.log("Adding table indexer_mapping")791 self.connection.action(792 "CREATE TABLE indexer_mapping (indexer_id INTEGER, indexer NUMERIC, mindexer_id INTEGER, mindexer NUMERIC, PRIMARY KEY (indexer_id, indexer))")793 self.increment_db_version()794class AddVersionToTvEpisodes(AddIndexerMapping):795 def test(self):796 return self.get_db_version() >= 40797 def execute(self):798 backupDatabase(self.get_db_version())799 logger.log("Adding column version to tv_episodes and history")800 self.add_column("tv_episodes", "version", "NUMERIC", "-1")801 self.add_column("tv_episodes", "release_group", "TEXT", "")802 self.add_column("history", "version", "NUMERIC", "-1")803 self.increment_db_version()804class AddDefaultEpStatusToTvShows(AddVersionToTvEpisodes):805 def test(self):806 return self.get_db_version() >= 41807 def execute(self):808 backupDatabase(self.get_db_version())809 logger.log("Adding column default_ep_status to tv_shows")810 self.add_column("tv_shows", "default_ep_status", "NUMERIC", "-1")811 self.increment_db_version()812class AlterTVShowsFieldTypes(AddDefaultEpStatusToTvShows):813 def test(self):814 return self.get_db_version() >= 42815 def execute(self):816 backupDatabase(self.get_db_version())817 logger.log("Converting column indexer and default_ep_status field types to numeric")818 self.connection.action("DROP TABLE IF EXISTS tmp_tv_shows")819 self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")820 self.connection.action("CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC, anime NUMERIC, scene NUMERIC, default_ep_status NUMERIC)")821 self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows")822 self.connection.action("DROP TABLE tmp_tv_shows")823 self.increment_db_version()824class AddMinorVersion(AlterTVShowsFieldTypes):825 def test(self):826 return self.has_column(b'db_version', b'db_minor_version')827 def increment_db_version(self):828 warnings.warn("Deprecated: Use inc_major_version or inc_minor_version instead", DeprecationWarning)829 def execute(self):830 backupDatabase(self.get_db_version())831 logger.log("Add minor version numbers to database")832 self.add_column(b'db_version', b'db_minor_version')833 self.inc_minor_version()834 logger.log('Updated to: {0:d}.{1:d}'.format(*self.connection.version))835class UseSickRageMetadataForSubtitle(AlterTVShowsFieldTypes):836 """837 Add a minor version for adding a show setting to use SR metadata for subtitles838 """839 def test(self):840 return self.has_column('tv_shows', 'sub_use_sr_metadata')841 def execute(self):842 backupDatabase(self.get_db_version())843 self.add_column('tv_shows', 'sub_use_sr_metadata', "NUMERIC", "0")844class ResetDBVersion(UseSickRageMetadataForSubtitle):845 def test(self):846 return False847 def execute(self):...
upgrade_db.py
Source:upgrade_db.py
...29 if len(lines) == 3:30 # table not yet populated31 return NULL_VERSION32 return lines[3]33def get_db_version():34 return parse_version_query(35 run_query(GET_VERSION_QUERY)36 )37def get_upgrade_files_gt(db_version, sql_scripts_dir):38 return sorted(39 filter(40 lambda fname: "upgrade" in fname and fname[:len(db_version)] > db_version,41 os.listdir(42 sql_scripts_dir,43 )44 )45 )46def get_downgrade_file(db_version):47 if db_version == NULL_VERSION:48 return None49 return "%s_downgrade.sql" % db_version50def get_previous_db_version(current_db_version, sql_scripts_dir):51 try:52 return sorted(53 filter(54 lambda fname: "downgrade" in fname and fname[:len(current_db_version)] < current_db_version,55 os.listdir(56 sql_scripts_dir,57 )58 )59 )[-1].replace("_downgrade.sql", "")60 except IndexError:61 return NULL_VERSION62def run_sql_file(sql_scripts_dir, sql_fname):63 run_command(64 "make db_shell < %s" % os.path.join(sql_scripts_dir, sql_fname)65 )66def update_db_version(canonical_version):67 run_query(68 """69 START TRANSACTION;70 TRUNCATE TABLE application_meta;71 INSERT INTO application_meta (latest_revision) VALUES(\\"{canonical_version}\\");72 COMMIT;73 """.format(74 canonical_version=canonical_version,75 ).replace("\n", "")76 )77def fname_to_canonical_version(fname):78 return fname.replace(79 "_upgrade.sql",80 "",81 ).replace(82 "_downgrade.sql",83 "",84 )85def upgrade_db(sql_scripts_dir):86 print "Upgrading..."87 upgrade_files = get_upgrade_files_gt(88 get_db_version(),89 sql_scripts_dir,90 )91 if not upgrade_files:92 print "Database is upgraded to the latest revision"93 return94 for upgrade_file in upgrade_files:95 run_sql_file(sql_scripts_dir, upgrade_file)96 update_db_version(97 fname_to_canonical_version(upgrade_file),98 )99 print "Database version is now set to %s" % get_db_version()100def downgrade_db(sql_scripts_dir):101 print "Downgrading..."102 current_version = get_db_version()103 downgrade_file = get_downgrade_file(current_version)104 if downgrade_file is None:105 print "Database is already in an empty state"106 return107 run_sql_file(sql_scripts_dir, downgrade_file)108 update_db_version(109 get_previous_db_version(110 current_version,111 sql_scripts_dir,112 ),113 )114if __name__ == "__main__":115 try:116 {...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!