diff --git a/bot/cpl-workspace.json b/bot/cpl-workspace.json index d08ceb87..060dd42b 100644 --- a/bot/cpl-workspace.json +++ b/bot/cpl-workspace.json @@ -21,7 +21,8 @@ "checks": "tools/checks/checks.json", "get-version": "tools/get_version/get-version.json", "post-build": "tools/post_build/post-build.json", - "set-version": "tools/set_version/set-version.json" + "set-version": "tools/set_version/set-version.json", + "migration-to-sql": "tools/migration_to_sql/tools/migration-to-sql.json" }, "Scripts": { "format": "black ./", diff --git a/bot/src/modules/database/database_extension.py b/bot/src/modules/database/database_extension.py index cdfe28fa..9bb71f64 100644 --- a/bot/src/modules/database/database_extension.py +++ b/bot/src/modules/database/database_extension.py @@ -3,6 +3,7 @@ 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/__init__.py b/bot/tools/migration_to_sql/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/bot/tools/migration_to_sql/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/bot/tools/migration_to_sql/application.py b/bot/tools/migration_to_sql/application.py new file mode 100644 index 00000000..b8831dd6 --- /dev/null +++ b/bot/tools/migration_to_sql/application.py @@ -0,0 +1,15 @@ +from cpl_core.application import ApplicationABC +from cpl_core.configuration import ConfigurationABC +from cpl_core.console import Console +from cpl_core.dependency_injection import ServiceProviderABC + + +class Application(ApplicationABC): + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) + + async def configure(self): + pass + + async def main(self): + Console.write_line("Hello World") diff --git a/bot/tools/migration_to_sql/appsettings.json b/bot/tools/migration_to_sql/appsettings.json new file mode 100644 index 00000000..2a5f9ac8 --- /dev/null +++ b/bot/tools/migration_to_sql/appsettings.json @@ -0,0 +1,22 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + "LoggingSettings": { + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "ERROR", + "FileLogLevel": "WARN" + }, + "BotLoggingSettings": { + "Database": { + "Path": "logs/$date_now/", + "Filename": "database.log", + "ConsoleLogLevel": "ERROR", + "FileLogLevel": "INFO" + } + } +} diff --git a/bot/tools/migration_to_sql/main.py b/bot/tools/migration_to_sql/main.py new file mode 100644 index 00000000..ae4fa735 --- /dev/null +++ b/bot/tools/migration_to_sql/main.py @@ -0,0 +1,26 @@ +import asyncio + +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.startup import Startup +from migration_to_sql.startup_mock_extension import StartupMockExtension +from modules.database.database_extension import DatabaseExtension + + +async def main(): + app_builder = ( + ApplicationBuilder(Application) + .use_extension(StartupMockExtension) + .use_extension(StartupMigrationExtension) + .use_extension(DatabaseExtension) + .use_startup(Startup) + ) + + app: Application = await app_builder.build_async() + await app.run_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/bot/tools/migration_to_sql/migration-to-sql.json b/bot/tools/migration_to_sql/migration-to-sql.json new file mode 100644 index 00000000..5e4a62f8 --- /dev/null +++ b/bot/tools/migration_to_sql/migration-to-sql.json @@ -0,0 +1,46 @@ +{ + "ProjectSettings": { + "Name": "migration-to-sql", + "Version": { + "Major": "0", + "Minor": "0", + "Micro": "0" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "cpl-core>=2023.10.0" + ], + "DevDependencies": [ + "cpl-cli>=2023.4.0.post3" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "console", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "migration_to_sql.main", + "EntryPoint": "migration-to-sql", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/bot/tools/migration_to_sql/mock/__init__.py b/bot/tools/migration_to_sql/mock/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bot/tools/migration_to_sql/mock/mock_cursor.py b/bot/tools/migration_to_sql/mock/mock_cursor.py new file mode 100644 index 00000000..f201d33e --- /dev/null +++ b/bot/tools/migration_to_sql/mock/mock_cursor.py @@ -0,0 +1,15 @@ +from mysql.connector.cursor import MySQLCursorBuffered + + +class MockCursor(MySQLCursorBuffered): + def __init__(self): + MySQLCursorBuffered.__init__(self) + + 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 new file mode 100644 index 00000000..4f7a7fa0 --- /dev/null +++ b/bot/tools/migration_to_sql/mock/mock_db_context.py @@ -0,0 +1,23 @@ +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) + + @property + def cursor(self) -> MockCursor: + return MockCursor() + + def connect(self, database_settings: DatabaseSettings): + pass + + def save_changes(self): + pass + + def select(self, statement: str) -> list[tuple]: + pass diff --git a/bot/tools/migration_to_sql/startup.py b/bot/tools/migration_to_sql/startup.py new file mode 100644 index 00000000..095b28db --- /dev/null +++ b/bot/tools/migration_to_sql/startup.py @@ -0,0 +1,45 @@ +from typing import Optional, Type, Callable + +from cpl_core.application import StartupABC +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceCollectionABC +from cpl_core.dependency_injection import ServiceProviderABC +from cpl_core.environment import ApplicationEnvironment + +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 + + +class Startup(StartupABC): + def __init__(self): + StartupABC.__init__(self) + + def configure_configuration( + self, configuration: ConfigurationABC, environment: ApplicationEnvironment + ) -> ConfigurationABC: + configuration.add_json_file("appsettings.json") + configuration.add_configuration(FeatureFlagsSettings, FeatureFlagsSettings()) + self._configure_settings_with_sub_settings( + configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key + ) + return configuration + + def configure_services( + self, services: ServiceCollectionABC, environment: ApplicationEnvironment + ) -> ServiceProviderABC: + services.add_logging() + services.add_singleton(CustomFileLoggerABC, DatabaseLogger) + return services.build_service_provider() + + @staticmethod + def _configure_settings_with_sub_settings( + config: ConfigurationABC, settings_type: Type, list_atr: Callable, atr: Callable + ): + settings: Optional[settings_type] = config.get_configuration(settings_type) + if settings is None: + return + + for sub_settings in list_atr(settings): + config.add_configuration(f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings) diff --git a/bot/tools/migration_to_sql/startup_mock_extension.py b/bot/tools/migration_to_sql/startup_mock_extension.py new file mode 100644 index 00000000..0d5a4c31 --- /dev/null +++ b/bot/tools/migration_to_sql/startup_mock_extension.py @@ -0,0 +1,20 @@ +from cpl_core.application import StartupExtensionABC +from cpl_core.configuration import ConfigurationABC +from cpl_core.database import DatabaseSettings +from cpl_core.database.context import DatabaseContextABC +from cpl_core.dependency_injection import ServiceCollectionABC +from cpl_core.environment import ApplicationEnvironmentABC + +from migration_to_sql.mock.mock_db_context import MockDBContext + + +class StartupMockExtension(StartupExtensionABC): + def __init__(self): + pass + + def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): + pass + + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + services.add_db_context(MockDBContext, DatabaseSettings()) + services.add_transient(DatabaseContextABC, MockDBContext)