diff --git a/src/gnomik/gnomik/__main__.py b/src/gnomik/gnomik/__main__.py index 2d591ba..e4f17f0 100644 --- a/src/gnomik/gnomik/__main__.py +++ b/src/gnomik/gnomik/__main__.py @@ -12,6 +12,8 @@ async def main(): block_loader("standard", "database", safe=False), block_loader("standard", "command_helper"), block_loader("standard", "roles", safe=False), + block_loader("standard", "fsm_database_storage", safe=False), + block_loader("external", "create_report_apps"), # block_loader("experimental", "message_db_logger", safe=False), block_loader("standard", "info"), block_loader("standard", "help"), diff --git a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/__init__.py b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/__init__.py new file mode 100644 index 0000000..e3e4a0b --- /dev/null +++ b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/__init__.py @@ -0,0 +1 @@ +from .piccolo_app import APP_CONFIG diff --git a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_app.py b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_app.py new file mode 100644 index 0000000..c3a309a --- /dev/null +++ b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_app.py @@ -0,0 +1,15 @@ +import os + +from karkas_piccolo.conf.apps import AppConfig + +from .tables import FSMData + +CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__)) + +APP_CONFIG = AppConfig( + app_name="standard.fsm_database_storage", + migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "piccolo_migrations"), + table_classes=[FSMData], + migration_dependencies=[], + commands=[], +) diff --git a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_migrations/__init__.py b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_migrations/standardfsm_database_storage_2024_08_20t15_07_25_276545.py b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_migrations/standardfsm_database_storage_2024_08_20t15_07_25_276545.py new file mode 100644 index 0000000..46d8d08 --- /dev/null +++ b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/piccolo_migrations/standardfsm_database_storage_2024_08_20t15_07_25_276545.py @@ -0,0 +1,85 @@ +from piccolo.apps.migrations.auto.migration_manager import MigrationManager +from piccolo.columns.column_types import Text +from piccolo.columns.indexes import IndexMethod + +ID = "2024-08-20T15:07:25:276545" +VERSION = "1.16.0" +DESCRIPTION = "" + + +async def forwards(): + manager = MigrationManager( + migration_id=ID, + app_name="standard.fsm_database_storage", + description=DESCRIPTION, + ) + + manager.add_table( + class_name="FSMData", tablename="fsm_data", schema=None, columns=None + ) + + manager.add_column( + table_class_name="FSMData", + tablename="fsm_data", + column_name="key", + db_column_name="key", + column_class_name="Text", + column_class=Text, + params={ + "primary": True, + "default": "", + "null": False, + "primary_key": False, + "unique": False, + "index": False, + "index_method": IndexMethod.btree, + "choices": None, + "db_column_name": None, + "secret": False, + }, + schema=None, + ) + + manager.add_column( + table_class_name="FSMData", + tablename="fsm_data", + column_name="state", + db_column_name="state", + column_class_name="Text", + column_class=Text, + params={ + "default": "", + "null": True, + "primary_key": False, + "unique": False, + "index": False, + "index_method": IndexMethod.btree, + "choices": None, + "db_column_name": None, + "secret": False, + }, + schema=None, + ) + + manager.add_column( + table_class_name="FSMData", + tablename="fsm_data", + column_name="data", + db_column_name="data", + column_class_name="Text", + column_class=Text, + params={ + "default": "", + "null": True, + "primary_key": False, + "unique": False, + "index": False, + "index_method": IndexMethod.btree, + "choices": None, + "db_column_name": None, + "secret": False, + }, + schema=None, + ) + + return manager diff --git a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/tables.py b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/tables.py new file mode 100644 index 0000000..69a7fc7 --- /dev/null +++ b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/db/tables.py @@ -0,0 +1,8 @@ +from piccolo.columns import Text +from piccolo.table import Table + + +class FSMData(Table): + key = Text(primary=True) + state = Text(null=True) + data = Text(null=True) diff --git a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/fsm.py b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/fsm.py index 1716158..464b0cb 100644 --- a/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/fsm.py +++ b/src/karkas_blocks/karkas_blocks/standard/fsm_database_storage/fsm.py @@ -1,5 +1,5 @@ import json -from typing import TYPE_CHECKING, Any, Dict, Optional +from typing import Any, Dict, Optional from aiogram.fsm.state import State from aiogram.fsm.storage.base import BaseStorage, StorageKey @@ -7,14 +7,54 @@ from aiogram.fsm.storage.base import BaseStorage, StorageKey from karkas_core.modules_system.public_api import get_module, log from karkas_core.modules_system.public_api.public_api import set_fsm -if TYPE_CHECKING: - from karkas_blocks.standard.database.repositories import ( - FSMDataRepository as IFSMDataRepository, - ) +from .db.tables import FSMData -FSMDataRepository: "type[IFSMDataRepository]" = get_module( - "standard.database", "repositories.FSMDataRepository" -) + +class FSMDataRepository: + def get(self, key: str): + return FSMData.select().where(FSMData.key == key).first().run_sync() + + def set_state(self, key: str, state: str): + returning = ( + FSMData.update( + { + FSMData.state: state, + } + ) + .where(FSMData.key == key) + .returning(FSMData.key) + .run_sync() + ) + + if len(returning) == 0: + FSMData.insert( + FSMData( + key=key, + state=state, + data=None, + ) + ).run_sync() + + def set_data(self, key: str, data: str): + returning = ( + FSMData.update( + { + FSMData.data: data, + } + ) + .where(FSMData.key == key) + .returning(FSMData.key) + .run_sync() + ) + + if len(returning) == 0: + FSMData.insert( + FSMData( + key=key, + data=data, + state=None, + ) + ).run_sync() def serialize_key(key: StorageKey) -> str: @@ -68,7 +108,7 @@ class SQLStorage(BaseStorage): try: s_state = self.repo.get(s_key) - return s_state.state if s_state else None + return s_state["state"] if s_state else None except Exception as e: log(f"FSM Storage database error: {e}") return None @@ -99,7 +139,7 @@ class SQLStorage(BaseStorage): try: s_data = self.repo.get(s_key) - return deserialize_object(s_data.data) if s_data else None + return deserialize_object(s_data["data"]) if s_data else None except Exception as e: log(f"FSM Storage database error: {e}") return None @@ -126,4 +166,9 @@ class SQLStorage(BaseStorage): async def module_init(): + register_app_config = get_module("standard.database", "register_app_config") + from .db import APP_CONFIG + + register_app_config(APP_CONFIG) + set_fsm(SQLStorage())