# Copyright 2026 zhaoxi826 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from kilostar.core.postgres_database.model.individual import ( BaseIndividualModel, SpecialistIndividualModel, OrdinaryIndividualModel, SpecialIndividualModel, ) from sqlalchemy import select from typing import List, Optional from kilostar.core.postgres_database.database_exception import database_exception from ulid import ULID _AGENT_TYPE_MODEL_MAP = { "specialist": SpecialistIndividualModel, "ordinary": OrdinaryIndividualModel, "special": SpecialIndividualModel, } class IndividualDatabase: """Individual 表族(Base/Specialist/Ordinary/Special)的 DAO,按 agent_type 选择具体子表。""" def __init__(self, async_session_maker): self.async_session_maker = async_session_maker @staticmethod def _select_model(agent_type: str): return _AGENT_TYPE_MODEL_MAP.get(agent_type, BaseIndividualModel) @database_exception async def add_worker_individual(self, **kwargs): """新建一个 Worker Individual:自动生成 ULID,按 ``agent_type`` 选择对应子表写入。""" async with self.async_session_maker() as session: agent_id = str(ULID()) agent_type = kwargs.get("agent_type", "base") model_cls = self._select_model(agent_type) individual = model_cls(agent_id=agent_id, **kwargs) session.add(individual) await session.commit() await session.refresh(individual) return individual @database_exception async def get_worker_individual(self, agent_id: str): """按 agent_id 取单个 Individual;不存在返回 None。""" async with self.async_session_maker() as session: statement = select(BaseIndividualModel).where( BaseIndividualModel.agent_id == agent_id ) results = await session.execute(statement) return results.scalar_one_or_none() @database_exception async def get_worker_individual_list(self, owner_id: str): """读取某用户名下的所有 Individual。""" async with self.async_session_maker() as session: statement = select(BaseIndividualModel).where( BaseIndividualModel.owner_id == owner_id ) results = await session.execute(statement) return list(results.scalars().all()) @database_exception async def update_worker_individual(self, agent_id: str, **kwargs): """部分更新 Individual:只覆盖 kwargs 中非 None 的字段;找不到返回 None。""" async with self.async_session_maker() as session: statement = select(BaseIndividualModel).where( BaseIndividualModel.agent_id == agent_id ) results = await session.execute(statement) individual = results.scalar_one_or_none() if not individual: return None for key, value in kwargs.items(): if value is not None: setattr(individual, key, value) session.add(individual) await session.commit() await session.refresh(individual) return individual @database_exception async def delete_worker_individual(self, agent_id: str) -> bool: """删除 Individual;不存在返回 False,删除成功返回 True。""" async with self.async_session_maker() as session: statement = select(BaseIndividualModel).where( BaseIndividualModel.agent_id == agent_id ) results = await session.execute(statement) individual = results.scalar_one_or_none() if not individual: return False session.delete(individual) await session.commit() return True @database_exception async def get_all_worker_individual(self): """返回数据库中全部 Individual。""" async with self.async_session_maker() as session: statement = select(BaseIndividualModel) results = await session.execute(statement) return list(results.scalars().all())