dify/dify-agent/src/shellctl/server/db.py
zyssyz123 925f97be20
feat: daily sync (#38593)
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: 盐粒 Yanli <yanli@dify.ai>
2026-07-09 10:35:15 +00:00

53 lines
1.7 KiB
Python

"""SQLite models and engine helpers for shellctl."""
from __future__ import annotations
from typing import Any, cast
from sqlalchemy import event
from sqlalchemy.ext.asyncio import AsyncEngine
from sqlmodel import Field, SQLModel
class JobRow(SQLModel, table=True):
"""SQLite source-of-truth row for shellctl jobs.
The table intentionally combines immutable metadata, mutable lifecycle state,
and exit facts so state transitions can be expressed as single conditional
`UPDATE` statements without synchronizing separate records.
"""
__tablename__ = cast(Any, "jobs")
job_id: str = Field(primary_key=True)
script_path: str
output_path: str
cwd: str
terminal_cols: int
terminal_rows: int
status: str = Field(index=True)
session_name: str
pane_target: str
exit_code: int | None = Field(default=None, nullable=True)
reason: str | None = Field(default=None, nullable=True)
message: str | None = Field(default=None, nullable=True)
created_at: str = Field(index=True)
started_at: str | None = Field(default=None, nullable=True)
ended_at: str | None = Field(default=None, nullable=True, index=True)
updated_at: str
def configure_sqlite_engine(engine: AsyncEngine, *, busy_timeout_ms: int) -> None:
"""Install SQLite pragmas required by the proposal's concurrency model."""
@event.listens_for(engine.sync_engine, "connect")
def _set_pragmas(dbapi_connection: Any, _connection_record: Any) -> None:
cursor = dbapi_connection.cursor()
cursor.execute("PRAGMA journal_mode=WAL")
cursor.execute("PRAGMA foreign_keys=ON")
cursor.execute(f"PRAGMA busy_timeout={busy_timeout_ms}")
cursor.close()
__all__ = ["JobRow", "configure_sqlite_engine"]