Added version logic & fixed downgrade scripts #428
This commit is contained in:
parent
e01c738cf0
commit
fe5b0207c0
@ -1,4 +1,4 @@
|
|||||||
DROP TABLE `AutoRole`;
|
|
||||||
|
|
||||||
DROP TABLE `AutoRoleRules`;
|
DROP TABLE `AutoRoleRules`;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE `AutoRoles`;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
DROP TABLE `AuthUsers`;
|
|
||||||
|
|
||||||
DROP TABLE `AuthUserUsersRelations`;
|
DROP TABLE `AuthUserUsersRelations`;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE `AuthUsers`;
|
@ -1,6 +1,8 @@
|
|||||||
DROP TABLE `GameServers`;
|
|
||||||
|
|
||||||
DROP TABLE `UserJoinedGameServer`;
|
DROP TABLE `UserJoinedGameServer`;
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE `UserGameIdents`;
|
DROP TABLE `UserGameIdents`;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE `GameServers`;
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
DROP TABLE `UserGotAchievements`;
|
||||||
|
|
||||||
DROP TABLE `Achievements`;
|
DROP TABLE `Achievements`;
|
||||||
|
|
||||||
ALTER TABLE Users DROP COLUMN MessageCount;
|
ALTER TABLE Users DROP COLUMN MessageCount;
|
||||||
|
|
||||||
ALTER TABLE Users DROP COLUMN ReactionCount;
|
ALTER TABLE Users DROP COLUMN ReactionCount;
|
||||||
|
|
||||||
|
DROP TABLE `AchievementsHistory`;
|
||||||
|
|
||||||
|
@ -1,8 +1,24 @@
|
|||||||
|
DROP TABLE `CFG_ServerTeamRoleIds`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_ServerTeamRoleIdsHistory`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_ServerAFKChannelIds`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_ServerAFKChannelIdsHistory`;
|
||||||
|
|
||||||
DROP TABLE `CFG_Server`;
|
DROP TABLE `CFG_Server`;
|
||||||
|
|
||||||
DROP TABLE `CFG_Technician`;
|
DROP TABLE `CFG_ServerHistory`;
|
||||||
|
|
||||||
DROP TABLE `CFG_TechnicianPingUrls`;
|
DROP TABLE `CFG_TechnicianPingUrls`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_TechnicianPingUrlsHistory`;
|
||||||
|
|
||||||
DROP TABLE `CFG_TechnicianIds`;
|
DROP TABLE `CFG_TechnicianIds`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_TechnicianIdsHistory`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_Technician`;
|
||||||
|
|
||||||
|
DROP TABLE `CFG_TechnicianHistory`;
|
||||||
|
|
||||||
|
@ -2,11 +2,10 @@ DROP TABLE `SteamSpecialOffers`;
|
|||||||
|
|
||||||
|
|
||||||
ALTER TABLE CFG_Server
|
ALTER TABLE CFG_Server
|
||||||
DROP COLUMN ShortRoleNameSetOnlyHighest;
|
DROP COLUMN GameOfferNotificationChatId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE CFG_ServerHistory
|
ALTER TABLE CFG_ServerHistory
|
||||||
DROP COLUMN ShortRoleNameSetOnlyHighest;
|
DROP COLUMN GameOfferNotificationChatId;
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@ import os
|
|||||||
from cpl_core.database.context import DatabaseContextABC
|
from cpl_core.database.context import DatabaseContextABC
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
from cpl_core.dependency_injection import ServiceProviderABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
from packaging import version
|
||||||
|
|
||||||
|
import bot
|
||||||
from bot_core.logging.database_logger import DatabaseLogger
|
from bot_core.logging.database_logger import DatabaseLogger
|
||||||
from bot_data.model.migration import Migration
|
from bot_data.model.migration import Migration
|
||||||
from bot_data.model.migration_history import MigrationHistory
|
from bot_data.model.migration_history import MigrationHistory
|
||||||
@ -23,7 +25,7 @@ class MigrationService:
|
|||||||
self._db = db
|
self._db = db
|
||||||
self._cursor = db.cursor
|
self._cursor = db.cursor
|
||||||
|
|
||||||
def _migrate_from_old_to_new(self):
|
def _get_migration_history(self) -> List[MigrationHistory]:
|
||||||
results = self._db.select(
|
results = self._db.select(
|
||||||
"""
|
"""
|
||||||
SELECT * FROM `MigrationHistory`
|
SELECT * FROM `MigrationHistory`
|
||||||
@ -33,7 +35,15 @@ class MigrationService:
|
|||||||
for result in results:
|
for result in results:
|
||||||
applied_migrations.add(MigrationHistory(result[0], result[1]))
|
applied_migrations.add(MigrationHistory(result[0], result[1]))
|
||||||
|
|
||||||
for migration in applied_migrations:
|
return applied_migrations
|
||||||
|
|
||||||
|
def _migrate_from_old_to_new(self):
|
||||||
|
self._cursor.execute("SHOW TABLES LIKE 'MigrationHistory'")
|
||||||
|
result = self._cursor.fetchone()
|
||||||
|
if not result:
|
||||||
|
return
|
||||||
|
|
||||||
|
for migration in self._get_migration_history():
|
||||||
if not migration.migration_id.endswith("Migration"):
|
if not migration.migration_id.endswith("Migration"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -41,20 +51,37 @@ class MigrationService:
|
|||||||
self._cursor.execute(migration.change_id_string(migration.migration_id.replace("Migration", "")))
|
self._cursor.execute(migration.change_id_string(migration.migration_id.replace("Migration", "")))
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
|
|
||||||
def _load_up_scripts(self) -> List[Migration]:
|
def _load_scripts(self, upgrade: bool = True) -> List[Migration]:
|
||||||
migrations = List(Migration)
|
migrations = List(Migration)
|
||||||
path = "../../src/bot_data/scripts"
|
path = "../../src/bot_data/scripts"
|
||||||
|
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise Exception("Migration path not found")
|
raise Exception("Migration path not found")
|
||||||
|
|
||||||
folders = List(str, glob.glob(f"{path}/*")).order_by()
|
folders = List(str, glob.glob(f"{path}/*"))
|
||||||
|
if upgrade:
|
||||||
|
folders = folders.order_by()
|
||||||
|
else:
|
||||||
|
folders = folders.order_by_descending()
|
||||||
|
|
||||||
for folder in folders:
|
for folder in folders:
|
||||||
splitted = folder.split("/")
|
splitted = folder.split("/")
|
||||||
version = splitted[len(splitted) - 1]
|
version_str = splitted[len(splitted) - 1]
|
||||||
|
|
||||||
for file in List(str, os.listdir(folder)).where(lambda x: x.endswith("_up.sql")).order_by().to_list():
|
# upgrade do not run migrations from higher versions
|
||||||
|
if upgrade and version.Version(version_str) > version.Version(bot.__version__):
|
||||||
|
break
|
||||||
|
# downgrade run migrations from higher versions
|
||||||
|
if not upgrade and version.Version(version_str) <= version.Version(bot.__version__):
|
||||||
|
continue
|
||||||
|
|
||||||
|
files = List(str, os.listdir(folder)).where(lambda x: x.endswith(f"_{'up' if upgrade else 'down'}.sql"))
|
||||||
|
if upgrade:
|
||||||
|
files = files.order_by()
|
||||||
|
else:
|
||||||
|
files = files.order_by_descending()
|
||||||
|
|
||||||
|
for file in files.to_list():
|
||||||
if not file.endswith(".sql"):
|
if not file.endswith(".sql"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -70,11 +97,11 @@ class MigrationService:
|
|||||||
script = f.read()
|
script = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
migrations.add(Migration(name, version, script))
|
migrations.add(Migration(name, version_str, script))
|
||||||
|
|
||||||
return migrations
|
return migrations
|
||||||
|
|
||||||
def _execute(self, migrations: List[Migration]):
|
def _execute(self, migrations: List[Migration], upgrade: bool = True):
|
||||||
for migration in migrations:
|
for migration in migrations:
|
||||||
active_statement = ""
|
active_statement = ""
|
||||||
try:
|
try:
|
||||||
@ -88,10 +115,14 @@ class MigrationService:
|
|||||||
f"Running SQL Command: {MigrationHistory.get_select_by_id_string(migration.name)}",
|
f"Running SQL Command: {MigrationHistory.get_select_by_id_string(migration.name)}",
|
||||||
)
|
)
|
||||||
migration_from_db = self._db.select(MigrationHistory.get_select_by_id_string(migration.name))
|
migration_from_db = self._db.select(MigrationHistory.get_select_by_id_string(migration.name))
|
||||||
if migration_from_db is not None and len(migration_from_db) > 0:
|
if upgrade and migration_from_db is not None and len(migration_from_db) > 0:
|
||||||
|
continue
|
||||||
|
elif not upgrade and (migration_from_db is None or len(migration_from_db) == 0):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Running migration: {migration.name}")
|
self._logger.debug(
|
||||||
|
__name__, f"Running {'upgrade' if upgrade else 'downgrade'} migration: {migration.name}"
|
||||||
|
)
|
||||||
|
|
||||||
for statement in migration.script.split("\n\n"):
|
for statement in migration.script.split("\n\n"):
|
||||||
if statement in ["", "\n"]:
|
if statement in ["", "\n"]:
|
||||||
@ -99,11 +130,18 @@ class MigrationService:
|
|||||||
active_statement = statement
|
active_statement = statement
|
||||||
self._cursor.execute(statement + ";")
|
self._cursor.execute(statement + ";")
|
||||||
|
|
||||||
self._cursor.execute(MigrationHistory(migration.name).insert_string)
|
self._cursor.execute(
|
||||||
|
MigrationHistory(migration.name).insert_string
|
||||||
|
if upgrade
|
||||||
|
else MigrationHistory(migration.name).delete_string
|
||||||
|
)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.fatal(__name__, f"Migration failed: {migration.name}\n{active_statement}", e)
|
self._logger.fatal(
|
||||||
|
__name__, f"Migration failed: {migration.version}-{migration.name}\n{active_statement}", e
|
||||||
|
)
|
||||||
|
|
||||||
def migrate(self):
|
def migrate(self):
|
||||||
self._migrate_from_old_to_new()
|
self._migrate_from_old_to_new()
|
||||||
self._execute(self._load_up_scripts())
|
self._execute(self._load_scripts())
|
||||||
|
self._execute(self._load_scripts(False), False)
|
||||||
|
Loading…
Reference in New Issue
Block a user