# retoor <retoor@molodetz.nl>
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from devplacepy_services.base.auth import internal_user
from devplacepy_services.base.schemas import InternalUser
from devplacepy_services.database.invoke_registry import _encode_result
from devplacepy_services.database.routes import DbOpIn, _db_query, _db_table_op, _db_tables
from devplacepy_services.devii.store_brokers import broker_for
router = APIRouter()
class StoreDbOpIn(BaseModel):
op: str
table: str | None = None
method: str | None = None
args: list[Any] = Field(default_factory=list)
kwargs: dict[str, Any] = Field(default_factory=dict)
write: bool = False
def _make_handler(store_name: str):
async def handler(body: StoreDbOpIn, _: InternalUser = Depends(internal_user)):
broker = broker_for(store_name)
if body.op == "tables":
return await broker.read(_db_tables)
if body.op == "query":
sql = body.args[0] if body.args else ""
rows = await broker.read(_db_query, sql, **body.kwargs)
return [_encode_result(row) for row in rows]
if body.op == "table_op":
if not body.table or not body.method:
return {"error": "table and method required", "code": "invalid_request"}
write_methods = {"insert", "update", "delete", "create_column_by_example"}
write = body.write or body.method in write_methods
if write:
return await broker.write(
_db_table_op, body.table, body.method, body.args, body.kwargs
)
return await broker.read(
_db_table_op, body.table, body.method, body.args, body.kwargs
)
return {"error": f"Unknown op: {body.op}", "code": "unknown_op"}
return handler
router.add_api_route(
"/internal/store/devii_tasks/db-op",
_make_handler("devii_tasks"),
methods=["POST"],
)
router.add_api_route(
"/internal/store/devii_lessons/db-op",
_make_handler("devii_lessons"),
methods=["POST"],
)