diff --git a/bot/src/modules/database/database_extension.py b/bot/src/modules/database/database_extension.py index 9bb71f64..cdfe28fa 100644 --- a/bot/src/modules/database/database_extension.py +++ b/bot/src/modules/database/database_extension.py @@ -3,7 +3,6 @@ from datetime import datetime from cpl_core.application.application_extension_abc import ApplicationExtensionABC from cpl_core.configuration import ConfigurationABC -from cpl_core.database.context import DatabaseContextABC from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.logging import LoggerABC diff --git a/bot/tools/migration_to_sql/application.py b/bot/tools/migration_to_sql/application.py index b8831dd6..b9215496 100644 --- a/bot/tools/migration_to_sql/application.py +++ b/bot/tools/migration_to_sql/application.py @@ -12,4 +12,4 @@ class Application(ApplicationABC): pass async def main(self): - Console.write_line("Hello World") + Console.write_line("Finished") diff --git a/bot/tools/migration_to_sql/main.py b/bot/tools/migration_to_sql/main.py index ae4fa735..93d4edf6 100644 --- a/bot/tools/migration_to_sql/main.py +++ b/bot/tools/migration_to_sql/main.py @@ -4,9 +4,9 @@ from cpl_core.application import ApplicationBuilder from bot_data.startup_migration_extension import StartupMigrationExtension from migration_to_sql.application import Application +from migration_to_sql.mock.database_extension import DatabaseExtension from migration_to_sql.startup import Startup from migration_to_sql.startup_mock_extension import StartupMockExtension -from modules.database.database_extension import DatabaseExtension async def main(): diff --git a/bot/tools/migration_to_sql/mock/database_extension.py b/bot/tools/migration_to_sql/mock/database_extension.py new file mode 100644 index 00000000..ca49d8b3 --- /dev/null +++ b/bot/tools/migration_to_sql/mock/database_extension.py @@ -0,0 +1,17 @@ +from datetime import datetime + +from cpl_core.application.application_extension_abc import ApplicationExtensionABC +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceProviderABC + +from migration_to_sql.mock.migration_service import MigrationService + + +class DatabaseExtension(ApplicationExtensionABC): + def __init__(self): + pass + + async def run(self, config: ConfigurationABC, services: ServiceProviderABC): + config.add_configuration("Database_StartTime", str(datetime.now())) + migrations: MigrationService = services.get_service(MigrationService) + migrations.migrate() diff --git a/bot/tools/migration_to_sql/mock/migration_service.py b/bot/tools/migration_to_sql/mock/migration_service.py new file mode 100644 index 00000000..5137e4b7 --- /dev/null +++ b/bot/tools/migration_to_sql/mock/migration_service.py @@ -0,0 +1,36 @@ +from cpl_core.console import Console +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_query.extension import List + +from bot_data.abc.migration_abc import MigrationABC +from bot_data.model.migration_history import MigrationHistory +from migration_to_sql.mock.mock_db_context import MockDBContext + + +class MigrationService: + def __init__( + self, + services: ServiceProviderABC, + db: MockDBContext, + ): + self._services = services + + self._db = db + self._cursor = db.cursor + + self._migrations: List[MigrationABC] = ( + List(type, MigrationABC.__subclasses__()).order_by(lambda x: x.name.split("_")[0]).then_by(lambda x: x.prio) + ) + + def migrate(self): + for migration in self._migrations: + migration_id = migration.__name__ + try: + migration_as_service: MigrationABC = self._services.get_service(migration) + self._db.set_migration(migration_as_service.name) + migration_as_service.upgrade() + self._cursor.execute(MigrationHistory(migration_id).insert_string) + self._db.save_changes() + + except Exception as e: + Console.error(e) diff --git a/bot/tools/migration_to_sql/mock/mock_cursor.py b/bot/tools/migration_to_sql/mock/mock_cursor.py index f201d33e..2f106ec3 100644 --- a/bot/tools/migration_to_sql/mock/mock_cursor.py +++ b/bot/tools/migration_to_sql/mock/mock_cursor.py @@ -7,9 +7,3 @@ class MockCursor(MySQLCursorBuffered): def fetchone(self, *args, **kwargs): pass - - def execute(self, query: str, *args, **kwargs): - if "MigrationHistory" in query: - return None - else: - pass diff --git a/bot/tools/migration_to_sql/mock/mock_db_context.py b/bot/tools/migration_to_sql/mock/mock_db_context.py index 4f7a7fa0..25f38c15 100644 --- a/bot/tools/migration_to_sql/mock/mock_db_context.py +++ b/bot/tools/migration_to_sql/mock/mock_db_context.py @@ -1,23 +1,53 @@ +import os +import textwrap +from typing import Optional + from cpl_core.database import DatabaseSettings from cpl_core.database.context import DatabaseContextABC -from bot_core.logging.database_logger import DatabaseLogger from migration_to_sql.mock.mock_cursor import MockCursor class MockDBContext(DatabaseContextABC): def __init__(self): DatabaseContextABC.__init__(self) + self._migration_version: Optional[str] = None + self._migration_name: Optional[str] = None + self._migration_script: Optional[str] = None @property def cursor(self) -> MockCursor: - return MockCursor() + cursor = MockCursor() + cursor.execute = self.execute + return cursor + + def set_migration(self, name: str): + self._migration_name = name.split("_")[1].replace("Migration", "") + self._migration_version = name.split("_")[0] + self._migration_script = "" def connect(self, database_settings: DatabaseSettings): pass - def save_changes(self): - pass - def select(self, statement: str) -> list[tuple]: pass + + def execute(self, query: str, *args, **kwargs): + if "MigrationHistory" in query: + return None + else: + self._migration_script += f"{textwrap.dedent(query)}\n\n" + + def save_changes(self): + path = f"../../src/bot_data/scripts/{self._migration_version}" + if not os.path.exists(path): + os.makedirs(path) + + script = textwrap.dedent(self._migration_script) + with open(f"{path}/{self._migration_name}.sql", "w+") as f: + f.write(script) + f.close() + + self._migration_name = None + self._migration_version = None + self._migration_script = None diff --git a/bot/tools/migration_to_sql/startup.py b/bot/tools/migration_to_sql/startup.py index 095b28db..b63480db 100644 --- a/bot/tools/migration_to_sql/startup.py +++ b/bot/tools/migration_to_sql/startup.py @@ -10,6 +10,7 @@ from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC from bot_core.configuration.bot_logging_settings import BotLoggingSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.logging.database_logger import DatabaseLogger +from migration_to_sql.mock.migration_service import MigrationService class Startup(StartupABC): @@ -31,6 +32,7 @@ class Startup(StartupABC): ) -> ServiceProviderABC: services.add_logging() services.add_singleton(CustomFileLoggerABC, DatabaseLogger) + services.add_transient(MigrationService) return services.build_service_provider() @staticmethod