mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-04 23:17:20 +08:00
refactor: make model sessions explicit
This commit is contained in:
@@ -5,7 +5,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class AgentChat(Base):
|
||||
@@ -50,7 +49,6 @@ class AgentChat(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_session(
|
||||
cls, db: Session, session_id: str, user_id: Optional[str] = None
|
||||
) -> Optional["AgentChat"]:
|
||||
@@ -63,7 +61,6 @@ class AgentChat(Base):
|
||||
return db.execute(statement.order_by(cls.id.desc())).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_session(
|
||||
cls, db: AsyncSession, session_id: str, user_id: Optional[str] = None
|
||||
) -> Optional["AgentChat"]:
|
||||
@@ -77,7 +74,6 @@ class AgentChat(Base):
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_page(
|
||||
cls,
|
||||
db: Session,
|
||||
@@ -103,7 +99,6 @@ class AgentChat(Base):
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_page(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
|
||||
+11
-31
@@ -4,7 +4,6 @@ from sqlalchemy import Boolean, Index, Integer, String, Text, select, update
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_db_query
|
||||
|
||||
|
||||
def _get_for_user_statement(
|
||||
@@ -85,47 +84,28 @@ class AgentTask(Base):
|
||||
return task.id
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_for_user(
|
||||
cls,
|
||||
db: Session | int | None = None,
|
||||
task_id: int | None = None,
|
||||
db: Session,
|
||||
task_id: int,
|
||||
user_id: Optional[str] = None,
|
||||
) -> Optional["AgentTask"]:
|
||||
"""
|
||||
按任务 ID 和可选用户 ID 查询,并保留无 Session 的旧插件调用方式。
|
||||
"""
|
||||
if task_id is None and isinstance(db, int):
|
||||
task_id, db = db, None
|
||||
if task_id is None:
|
||||
raise TypeError("task_id is required")
|
||||
|
||||
def query(session: Session) -> Optional["AgentTask"]:
|
||||
"""在给定会话中读取单个 Agent 任务。"""
|
||||
return session.execute(
|
||||
_get_for_user_statement(cls, task_id=task_id, user_id=user_id)
|
||||
).scalars().first()
|
||||
|
||||
return query(db)
|
||||
"""在调用方会话中按任务 ID 和可选用户 ID 查询。"""
|
||||
return db.execute(
|
||||
_get_for_user_statement(cls, task_id=task_id, user_id=user_id)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_for_user(
|
||||
cls,
|
||||
db: Session | None = None,
|
||||
db: Session,
|
||||
user_id: Optional[str] = None,
|
||||
enabled: Optional[bool] = None,
|
||||
) -> list["AgentTask"]:
|
||||
"""
|
||||
按用户和启用状态查询,并保留无 Session 的旧插件调用方式。
|
||||
"""
|
||||
def query(session: Session) -> list["AgentTask"]:
|
||||
"""在给定会话中读取 Agent 任务列表。"""
|
||||
return list(session.execute(
|
||||
_list_for_user_statement(cls, user_id=user_id, enabled=enabled)
|
||||
).scalars().all())
|
||||
|
||||
return query(db)
|
||||
"""在调用方会话中按用户和启用状态查询。"""
|
||||
return list(db.execute(
|
||||
_list_for_user_statement(cls, user_id=user_id, enabled=enabled)
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
def update_task(
|
||||
|
||||
@@ -4,7 +4,6 @@ from sqlalchemy import Index, Integer, String, Text, delete, select, update
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_db_query
|
||||
from app.db.models.agenttask import AgentTask
|
||||
|
||||
|
||||
@@ -249,7 +248,6 @@ class AgentTaskRun(Base):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_run_id(
|
||||
cls,
|
||||
db: Session,
|
||||
@@ -261,7 +259,6 @@ class AgentTaskRun(Base):
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_for_task(
|
||||
cls,
|
||||
db: Session,
|
||||
|
||||
@@ -6,7 +6,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MediaSource
|
||||
|
||||
@@ -77,7 +76,6 @@ class DownloadHistory(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_hash(cls, db: Session, download_hash: str):
|
||||
return db.execute(
|
||||
select(DownloadHistory)
|
||||
@@ -86,7 +84,6 @@ class DownloadHistory(Base):
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_hashes(cls, db: Session, download_hashes: List[str]):
|
||||
"""
|
||||
批量查询多个下载任务的最新历史记录,避免在上层形成 N+1 查询。
|
||||
@@ -119,7 +116,6 @@ class DownloadHistory(Base):
|
||||
]
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_media_identity(
|
||||
cls, db: Session, media_source: MediaSource, media_id: str,
|
||||
music_type: Optional[str] = None,
|
||||
@@ -136,7 +132,6 @@ class DownloadHistory(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_page(
|
||||
cls, db: Session, page: int = 1, count: int = 30
|
||||
):
|
||||
@@ -148,7 +143,6 @@ class DownloadHistory(Base):
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_page(
|
||||
cls, db: AsyncSession, page: int = 1, count: int = 30
|
||||
):
|
||||
@@ -161,7 +155,6 @@ class DownloadHistory(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_title(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
@@ -177,13 +170,11 @@ class DownloadHistory(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_count(cls, db: AsyncSession):
|
||||
result = await db.execute(select(func.count(cls.id)))
|
||||
return result.scalar()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_count_by_title(cls, db: AsyncSession, title: str):
|
||||
result = await db.execute(
|
||||
select(func.count(cls.id)).filter(_title_like(cls.title, title))
|
||||
@@ -191,14 +182,12 @@ class DownloadHistory(Base):
|
||||
return result.scalar()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_path(cls, db: Session, path: str):
|
||||
return db.execute(
|
||||
select(DownloadHistory).where(DownloadHistory.path == path)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_last_by(
|
||||
cls,
|
||||
db: Session,
|
||||
@@ -237,7 +226,6 @@ class DownloadHistory(Base):
|
||||
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_user_date(cls, db: Session, date: str, username: Optional[str] = None):
|
||||
"""
|
||||
查询某用户某时间之前的下载历史。
|
||||
@@ -256,7 +244,6 @@ class DownloadHistory(Base):
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_date(
|
||||
cls,
|
||||
db: Session,
|
||||
@@ -282,7 +269,6 @@ class DownloadHistory(Base):
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_type(cls, db: Session, mtype: str, days: int):
|
||||
return list(db.execute(
|
||||
select(DownloadHistory).where(
|
||||
@@ -345,7 +331,6 @@ class DownloadFiles(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_hash(cls, db: Session, download_hash: str, state: Optional[int] = None):
|
||||
statement = select(cls).where(cls.download_hash == download_hash)
|
||||
if state is not None:
|
||||
@@ -353,7 +338,6 @@ class DownloadFiles(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_fullpath(cls, db: Session, fullpath: str, all_files: bool = False):
|
||||
result = db.execute(
|
||||
select(cls).where(cls.fullpath == fullpath).order_by(cls.id.desc())
|
||||
@@ -361,7 +345,6 @@ class DownloadFiles(Base):
|
||||
return list(result.all()) if all_files else result.first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_savepath(cls, db: Session, savepath: str):
|
||||
return list(db.execute(select(cls).where(cls.savepath == savepath)).scalars().all())
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MediaSource
|
||||
|
||||
@@ -53,12 +52,10 @@ class MediaServerItem(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_itemid(cls, db: Session, item_id: str):
|
||||
return db.execute(select(cls).where(cls.item_id == item_id)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_server_itemid(cls, db: Session, server: str, item_id: str):
|
||||
return db.execute(
|
||||
select(cls).where(cls.server == server, cls.item_id == item_id)
|
||||
@@ -97,7 +94,6 @@ class MediaServerItem(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def exist_by_media_identity(
|
||||
cls, db: Session, media_source: MediaSource, media_id: str, mtype: str,
|
||||
):
|
||||
@@ -109,7 +105,6 @@ class MediaServerItem(Base):
|
||||
)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def exists_by_title(cls, db: Session, title: str, mtype: str, year: str):
|
||||
statement = select(cls).where(cls.title == title)
|
||||
if mtype:
|
||||
@@ -119,13 +114,11 @@ class MediaServerItem(Base):
|
||||
return db.execute(statement).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_itemid(cls, db: AsyncSession, item_id: str):
|
||||
result = await db.execute(select(cls).filter(cls.item_id == item_id))
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_exist_by_media_identity(
|
||||
cls, db: AsyncSession, media_source: MediaSource, media_id: str, mtype: str,
|
||||
):
|
||||
@@ -138,7 +131,6 @@ class MediaServerItem(Base):
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_exists_by_title(cls, db: AsyncSession, title: str, mtype: str, year: str):
|
||||
if not mtype and not year:
|
||||
result = await db.execute(select(cls).filter(cls.title == title))
|
||||
|
||||
+45
-73
@@ -5,7 +5,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class Message(Base):
|
||||
@@ -49,33 +48,25 @@ class Message(Base):
|
||||
return self.to_dict()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_page(
|
||||
cls,
|
||||
db: Session | None = None,
|
||||
db: Session,
|
||||
page: int = 1,
|
||||
count: int = 30,
|
||||
) -> List["Message"]:
|
||||
"""
|
||||
分页获取消息记录,兼容显式会话和旧插件无会话调用。
|
||||
"""
|
||||
def query(session: Session) -> List["Message"]:
|
||||
"""在给定同步会话中执行消息分页查询。"""
|
||||
return list(session.execute(
|
||||
select(cls)
|
||||
.order_by(cls.reg_time.desc(), cls.id.desc())
|
||||
.offset((page - 1) * count)
|
||||
.limit(count)
|
||||
).scalars().all())
|
||||
|
||||
return query(db)
|
||||
"""在调用方同步会话中分页获取消息记录。"""
|
||||
return list(db.execute(
|
||||
select(cls)
|
||||
.order_by(cls.reg_time.desc(), cls.id.desc())
|
||||
.offset((page - 1) * count)
|
||||
.limit(count)
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def exists_by_source(
|
||||
cls,
|
||||
db: Session | str | None = None,
|
||||
source: str | None = None,
|
||||
db: Session,
|
||||
source: str,
|
||||
) -> bool:
|
||||
"""
|
||||
判断指定来源标识的消息记录是否存在。
|
||||
@@ -84,44 +75,29 @@ class Message(Base):
|
||||
:param source: 消息来源唯一标识
|
||||
:return: 是否存在匹配记录
|
||||
"""
|
||||
if source is None and isinstance(db, str):
|
||||
source, db = db, None
|
||||
if source is None:
|
||||
raise TypeError("source is required")
|
||||
|
||||
def query(session: Session) -> bool:
|
||||
"""在给定同步会话中执行来源存在性查询。"""
|
||||
return session.execute(
|
||||
select(cls.id).where(cls.source == source).limit(1)
|
||||
).scalars().first() is not None
|
||||
|
||||
return query(db)
|
||||
return db.execute(
|
||||
select(cls.id).where(cls.source == source).limit(1)
|
||||
).scalars().first() is not None
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_page(
|
||||
cls, db: AsyncSession | None = None, page: int = 1, count: int = 30
|
||||
cls, db: AsyncSession, page: int = 1, count: int = 30
|
||||
) -> List["Message"]:
|
||||
"""
|
||||
异步分页获取消息记录。
|
||||
"""
|
||||
async def query(session: AsyncSession) -> List["Message"]:
|
||||
"""在给定异步会话中执行消息分页查询。"""
|
||||
result = await session.execute(
|
||||
select(cls)
|
||||
.order_by(cls.reg_time.desc(), cls.id.desc())
|
||||
.offset((page - 1) * count)
|
||||
.limit(count)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
return await query(db)
|
||||
result = await db.execute(
|
||||
select(cls)
|
||||
.order_by(cls.reg_time.desc(), cls.id.desc())
|
||||
.offset((page - 1) * count)
|
||||
.limit(count)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_sent_by_page(
|
||||
cls,
|
||||
db: AsyncSession | None = None,
|
||||
db: AsyncSession,
|
||||
page: int = 1,
|
||||
count: int = 30,
|
||||
all_clear_before: Optional[str] = None,
|
||||
@@ -131,35 +107,31 @@ class Message(Base):
|
||||
"""
|
||||
分页获取系统发送的通知消息。
|
||||
"""
|
||||
async def query(session: AsyncSession) -> List["Message"]:
|
||||
"""在给定异步会话中执行通知消息分页查询。"""
|
||||
statement = select(cls).where(cls.action == 1)
|
||||
if all_clear_before:
|
||||
statement = statement.where(cls.reg_time > all_clear_before)
|
||||
if system_clear_before:
|
||||
statement = statement.where(
|
||||
or_(
|
||||
and_(cls.image.isnot(None), cls.image != ""),
|
||||
cls.reg_time > system_clear_before,
|
||||
)
|
||||
statement = select(cls).where(cls.action == 1)
|
||||
if all_clear_before:
|
||||
statement = statement.where(cls.reg_time > all_clear_before)
|
||||
if system_clear_before:
|
||||
statement = statement.where(
|
||||
or_(
|
||||
and_(cls.image.isnot(None), cls.image != ""),
|
||||
cls.reg_time > system_clear_before,
|
||||
)
|
||||
if media_clear_before:
|
||||
statement = statement.where(
|
||||
or_(
|
||||
cls.image.is_(None),
|
||||
cls.image == "",
|
||||
cls.reg_time > media_clear_before,
|
||||
)
|
||||
)
|
||||
result = await session.execute(
|
||||
statement
|
||||
.order_by(cls.reg_time.desc(), cls.id.desc())
|
||||
.offset((page - 1) * count)
|
||||
.limit(count)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
return await query(db)
|
||||
if media_clear_before:
|
||||
statement = statement.where(
|
||||
or_(
|
||||
cls.image.is_(None),
|
||||
cls.image == "",
|
||||
cls.reg_time > media_clear_before,
|
||||
)
|
||||
)
|
||||
result = await db.execute(
|
||||
statement
|
||||
.order_by(cls.reg_time.desc(), cls.id.desc())
|
||||
.offset((page - 1) * count)
|
||||
.limit(count)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
def delete_before(
|
||||
|
||||
+16
-44
@@ -5,10 +5,6 @@ from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
from datetime import datetime
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import (
|
||||
legacy_async_db_query,
|
||||
legacy_db_query,
|
||||
)
|
||||
|
||||
|
||||
def _get_by_user_id_statement(model: type["PassKey"], user_id: int):
|
||||
@@ -54,75 +50,51 @@ class PassKey(Base):
|
||||
transports: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_user_id(
|
||||
cls,
|
||||
db: Session | int | None = None,
|
||||
user_id: int | None = None,
|
||||
db: Session,
|
||||
user_id: int,
|
||||
):
|
||||
"""获取用户的所有 PassKey,并保留无 Session 的旧插件调用方式。"""
|
||||
if user_id is None and isinstance(db, int):
|
||||
user_id, db = db, None
|
||||
if user_id is None:
|
||||
raise TypeError("user_id is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行启用凭证查询。"""
|
||||
return list(session.execute(
|
||||
_get_by_user_id_statement(cls, user_id)
|
||||
).scalars().all())
|
||||
|
||||
return query(db)
|
||||
"""在调用方 Session 中获取用户的所有启用 PassKey。"""
|
||||
return list(db.execute(
|
||||
_get_by_user_id_statement(cls, user_id)
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_user_id(cls, db: AsyncSession, user_id: int):
|
||||
"""异步获取用户的所有 PassKey,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 AsyncSession 中获取用户的所有启用 PassKey。"""
|
||||
result = await db.execute(
|
||||
_get_by_user_id_statement(cls, user_id)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_credential_id(
|
||||
cls,
|
||||
db: Session | str | None = None,
|
||||
credential_id: str | None = None,
|
||||
db: Session,
|
||||
credential_id: str,
|
||||
):
|
||||
"""按凭证 ID 获取 PassKey,并保留无 Session 的旧插件调用方式。"""
|
||||
if credential_id is None and isinstance(db, str):
|
||||
credential_id, db = db, None
|
||||
if credential_id is None:
|
||||
raise TypeError("credential_id is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行启用凭证查询。"""
|
||||
return session.execute(
|
||||
_get_by_credential_id_statement(cls, credential_id)
|
||||
).scalars().first()
|
||||
|
||||
return query(db)
|
||||
"""在调用方 Session 中按凭证 ID 获取启用 PassKey。"""
|
||||
return db.execute(
|
||||
_get_by_credential_id_statement(cls, credential_id)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_credential_id(cls, db: AsyncSession, credential_id: str):
|
||||
"""异步根据凭证 ID 获取 PassKey,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 AsyncSession 中根据凭证 ID 获取启用 PassKey。"""
|
||||
result = await db.execute(
|
||||
_get_by_credential_id_statement(cls, credential_id)
|
||||
)
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_id(cls, db: Session, passkey_id: int):
|
||||
"""根据 ID 获取 PassKey,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 Session 中根据 ID 获取 PassKey。"""
|
||||
return db.execute(select(cls).where(cls.id == passkey_id)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_id(cls, db: AsyncSession, passkey_id: int):
|
||||
"""异步根据 ID 获取 PassKey,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 AsyncSession 中根据 ID 获取 PassKey。"""
|
||||
result = await db.execute(
|
||||
select(cls).filter(cls.id == passkey_id)
|
||||
)
|
||||
|
||||
+12
-31
@@ -4,7 +4,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class PluginData(Base):
|
||||
@@ -21,44 +20,32 @@ class PluginData(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_plugin_data(cls, db: Session | None = None, plugin_id: str | None = None):
|
||||
"""在调用方 Session 中读取插件全部数据,并兼容旧无会话入口。"""
|
||||
if plugin_id is None:
|
||||
raise TypeError("plugin_id is required")
|
||||
def get_plugin_data(cls, db: Session, plugin_id: str):
|
||||
"""在调用方 Session 中读取插件全部数据。"""
|
||||
return list(db.execute(select(cls).where(cls.plugin_id == plugin_id)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_plugin_data(
|
||||
cls, db: AsyncSession | None = None, plugin_id: str | None = None
|
||||
cls, db: AsyncSession, plugin_id: str
|
||||
):
|
||||
"""在调用方 AsyncSession 中读取插件全部数据,并兼容旧无会话入口。"""
|
||||
if plugin_id is None:
|
||||
raise TypeError("plugin_id is required")
|
||||
"""在调用方 AsyncSession 中读取插件全部数据。"""
|
||||
result = await db.execute(select(cls).where(cls.plugin_id == plugin_id))
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_plugin_data_by_key(
|
||||
cls, db: Session | None = None, plugin_id: str | None = None, key: str | None = None
|
||||
cls, db: Session, plugin_id: str, key: str
|
||||
):
|
||||
"""在调用方 Session 中按键读取插件数据,并兼容旧无会话入口。"""
|
||||
if plugin_id is None or key is None:
|
||||
raise TypeError("plugin_id and key are required")
|
||||
"""在调用方 Session 中按键读取插件数据。"""
|
||||
return db.execute(
|
||||
select(cls).where(cls.plugin_id == plugin_id, cls.key == key)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_plugin_data_by_key(
|
||||
cls, db: AsyncSession | None = None, plugin_id: str | None = None, key: str | None = None
|
||||
cls, db: AsyncSession, plugin_id: str, key: str
|
||||
):
|
||||
"""在调用方 AsyncSession 中按键读取插件数据,并兼容旧无会话入口。"""
|
||||
if plugin_id is None or key is None:
|
||||
raise TypeError("plugin_id and key are required")
|
||||
"""在调用方 AsyncSession 中按键读取插件数据。"""
|
||||
result = await db.execute(
|
||||
select(cls).where(cls.plugin_id == plugin_id, cls.key == key)
|
||||
)
|
||||
@@ -75,22 +62,16 @@ class PluginData(Base):
|
||||
db.execute(delete(cls).where(cls.plugin_id == plugin_id))
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_plugin_data_by_plugin_id(
|
||||
cls, db: Session | None = None, plugin_id: str | None = None
|
||||
cls, db: Session, plugin_id: str
|
||||
):
|
||||
"""在调用方 Session 中按插件 ID 读取数据,并兼容旧无会话入口。"""
|
||||
if plugin_id is None:
|
||||
raise TypeError("plugin_id is required")
|
||||
"""在调用方 Session 中按插件 ID 读取数据。"""
|
||||
return list(db.execute(select(cls).where(cls.plugin_id == plugin_id)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_plugin_data_by_plugin_id(
|
||||
cls, db: AsyncSession | None = None, plugin_id: str | None = None
|
||||
cls, db: AsyncSession, plugin_id: str
|
||||
):
|
||||
"""在调用方 AsyncSession 中按插件 ID 读取数据,并兼容旧无会话入口。"""
|
||||
if plugin_id is None:
|
||||
raise TypeError("plugin_id is required")
|
||||
"""在调用方 AsyncSession 中按插件 ID 读取数据。"""
|
||||
result = await db.execute(select(cls).where(cls.plugin_id == plugin_id))
|
||||
return list(result.scalars().all())
|
||||
|
||||
+35
-92
@@ -6,7 +6,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class Site(Base):
|
||||
@@ -58,122 +57,66 @@ class Site(Base):
|
||||
downloader: Mapped[Optional[str]] = mapped_column(String)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_domain(cls, db: Session | str | None = None, domain: str | None = None):
|
||||
"""按域名查询站点,兼容显式会话和旧插件无会话调用。"""
|
||||
if domain is None and isinstance(db, str):
|
||||
domain, db = db, None
|
||||
if domain is None:
|
||||
raise TypeError("domain is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在给定同步会话中执行域名查询。"""
|
||||
return session.execute(select(cls).where(cls.domain == domain)).scalars().first()
|
||||
|
||||
return query(db)
|
||||
def get_by_domain(cls, db: Session, domain: str):
|
||||
"""在调用方 Session 中按域名查询站点。"""
|
||||
return db.execute(select(cls).where(cls.domain == domain)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_domain(
|
||||
cls,
|
||||
db: AsyncSession | str | None = None,
|
||||
domain: str | None = None,
|
||||
db: AsyncSession,
|
||||
domain: str,
|
||||
):
|
||||
"""异步按域名查询站点,兼容显式会话和旧插件无会话调用。"""
|
||||
if domain is None and isinstance(db, str):
|
||||
domain, db = db, None
|
||||
if domain is None:
|
||||
raise TypeError("domain is required")
|
||||
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行域名查询。"""
|
||||
result = await session.execute(select(cls).where(cls.domain == domain))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中按域名查询站点。"""
|
||||
result = await db.execute(select(cls).where(cls.domain == domain))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_name(
|
||||
cls,
|
||||
db: AsyncSession | str | None = None,
|
||||
name: str | None = None,
|
||||
db: AsyncSession,
|
||||
name: str,
|
||||
):
|
||||
"""异步按站点名称查询,兼容显式会话和旧插件无会话调用。"""
|
||||
if name is None and isinstance(db, str):
|
||||
name, db = db, None
|
||||
if name is None:
|
||||
raise TypeError("name is required")
|
||||
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行名称查询。"""
|
||||
result = await session.execute(select(cls).where(cls.name == name))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中按站点名称查询。"""
|
||||
result = await db.execute(select(cls).where(cls.name == name))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_actives(cls, db: Session | None = None):
|
||||
"""查询启用站点,兼容显式会话和旧插件无会话调用。"""
|
||||
def query(session: Session):
|
||||
"""在给定同步会话中执行启用站点查询。"""
|
||||
return list(session.execute(select(cls).where(cls.is_active.is_(True))).scalars().all())
|
||||
|
||||
return query(db)
|
||||
def get_actives(cls, db: Session):
|
||||
"""在调用方 Session 中查询启用站点。"""
|
||||
return list(db.execute(
|
||||
select(cls).where(cls.is_active.is_(True))
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_actives(cls, db: AsyncSession | None = None):
|
||||
"""异步查询启用站点,兼容显式会话和旧插件无会话调用。"""
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行启用站点查询。"""
|
||||
result = await session.execute(select(cls).where(cls.is_active.is_(True)))
|
||||
return list(result.scalars().all())
|
||||
|
||||
return await query(db)
|
||||
async def async_get_actives(cls, db: AsyncSession):
|
||||
"""在调用方 AsyncSession 中查询启用站点。"""
|
||||
result = await db.execute(select(cls).where(cls.is_active.is_(True)))
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_order_by_pri(cls, db: Session | None = None):
|
||||
"""按优先级升序查询站点,兼容显式会话和旧插件无会话调用。"""
|
||||
def query(session: Session):
|
||||
"""在给定同步会话中执行优先级查询。"""
|
||||
return list(session.execute(select(cls).order_by(cls.pri)).scalars().all())
|
||||
|
||||
return query(db)
|
||||
def list_order_by_pri(cls, db: Session):
|
||||
"""在调用方 Session 中按优先级升序查询站点。"""
|
||||
return list(db.execute(select(cls).order_by(cls.pri)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_order_by_pri(cls, db: AsyncSession | None = None):
|
||||
"""异步按优先级升序查询站点,兼容显式会话和旧插件无会话调用。"""
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行优先级查询。"""
|
||||
result = await session.execute(select(cls).order_by(cls.pri))
|
||||
return list(result.scalars().all())
|
||||
|
||||
return await query(db)
|
||||
async def async_list_order_by_pri(cls, db: AsyncSession):
|
||||
"""在调用方 AsyncSession 中按优先级升序查询站点。"""
|
||||
result = await db.execute(select(cls).order_by(cls.pri))
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_domains_by_ids(
|
||||
cls,
|
||||
db: Session | list[int] | None = None,
|
||||
ids: list[int] | None = None,
|
||||
db: Session,
|
||||
ids: list[int],
|
||||
):
|
||||
"""按 ID 查询域名,兼容显式会话和旧插件无会话调用。"""
|
||||
if ids is None and isinstance(db, list):
|
||||
ids, db = db, None
|
||||
if ids is None:
|
||||
raise TypeError("ids is required")
|
||||
"""在调用方 Session 中按 ID 查询域名。"""
|
||||
if not ids:
|
||||
return []
|
||||
|
||||
def query(session: Session):
|
||||
"""在给定同步会话中执行域名投影查询。"""
|
||||
return list(session.execute(select(cls.domain).where(cls.id.in_(ids))).scalars().all())
|
||||
|
||||
return query(db)
|
||||
return list(db.execute(
|
||||
select(cls.domain).where(cls.id.in_(ids))
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
def reset(cls, db: Session):
|
||||
|
||||
@@ -4,7 +4,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query
|
||||
|
||||
|
||||
class SiteIcon(Base):
|
||||
@@ -27,19 +26,11 @@ class SiteIcon(Base):
|
||||
return db.execute(select(cls).where(cls.domain == domain)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_domain(
|
||||
cls,
|
||||
db: AsyncSession | None = None,
|
||||
domain: str | None = None,
|
||||
db: AsyncSession,
|
||||
domain: str,
|
||||
):
|
||||
"""在调用方 AsyncSession 中查询站点图标。"""
|
||||
if domain is None:
|
||||
raise TypeError("domain is required")
|
||||
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行站点图标查询。"""
|
||||
result = await session.execute(select(cls).where(cls.domain == domain))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
return await query(db)
|
||||
result = await db.execute(select(cls).where(cls.domain == domain))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@@ -6,7 +6,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import legacy_async_db_query
|
||||
|
||||
|
||||
class SiteStatistic(Base):
|
||||
@@ -35,22 +34,14 @@ class SiteStatistic(Base):
|
||||
return db.execute(select(cls).where(cls.domain == domain)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_domain(
|
||||
cls,
|
||||
db: AsyncSession | None = None,
|
||||
domain: str | None = None,
|
||||
db: AsyncSession,
|
||||
domain: str,
|
||||
):
|
||||
"""在调用方 AsyncSession 中查询站点统计,并兼容旧无会话调用。"""
|
||||
if domain is None:
|
||||
raise TypeError("domain is required")
|
||||
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行站点统计查询。"""
|
||||
result = await session.execute(select(cls).where(cls.domain == domain))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中查询站点统计。"""
|
||||
result = await db.execute(select(cls).where(cls.domain == domain))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@classmethod
|
||||
def reset(cls, db: Session):
|
||||
|
||||
@@ -6,7 +6,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class SiteUserData(Base):
|
||||
@@ -61,7 +60,6 @@ class SiteUserData(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_domain(cls, db: Session, domain: str, workdate: Optional[str] = None, worktime: Optional[str] = None):
|
||||
statement = select(cls).where(cls.domain == domain)
|
||||
if workdate and worktime:
|
||||
@@ -72,7 +70,6 @@ class SiteUserData(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_domain(cls, db: AsyncSession, domain: str, workdate: Optional[str] = None, worktime: Optional[str] = None):
|
||||
query = select(cls).filter(cls.domain == domain)
|
||||
if workdate and worktime:
|
||||
@@ -83,12 +80,10 @@ class SiteUserData(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_date(cls, db: Session, date: str):
|
||||
return list(db.execute(select(cls).where(cls.updated_day == date)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_latest(cls, db: Session):
|
||||
"""
|
||||
获取各站点最新一天的数据
|
||||
@@ -113,7 +108,6 @@ class SiteUserData(Base):
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_latest(cls, db: AsyncSession):
|
||||
"""
|
||||
异步获取各站点最新一天的数据
|
||||
|
||||
+107
-210
@@ -6,7 +6,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MUSIC_ENTITY_RECORDING, MediaSource
|
||||
|
||||
@@ -140,9 +139,8 @@ class Subscribe(Base):
|
||||
return condition
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def exists(
|
||||
cls, db: Session | MediaSource | None = None,
|
||||
cls, db: Session,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
season: Optional[int] = None,
|
||||
@@ -150,27 +148,21 @@ class Subscribe(Base):
|
||||
music_type: Optional[str] = None,
|
||||
):
|
||||
"""按媒体身份、季号与剧集组查询已有订阅。"""
|
||||
if db is not None and not isinstance(db, Session):
|
||||
media_source, media_id, db = db, media_source, None
|
||||
condition = cls._identity_condition(
|
||||
media_source, media_id, music_type
|
||||
)
|
||||
if condition is None:
|
||||
return None
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行订阅身份查询。"""
|
||||
statement = select(cls).where(condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
return session.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
).scalars().first()
|
||||
return query(db)
|
||||
statement = select(cls).where(condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
return db.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_exists(
|
||||
cls, db: AsyncSession | MediaSource | None = None,
|
||||
cls, db: AsyncSession,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
season: Optional[int] = None,
|
||||
@@ -178,28 +170,22 @@ class Subscribe(Base):
|
||||
music_type: Optional[str] = None,
|
||||
):
|
||||
"""异步按媒体身份、季号与剧集组查询已有订阅。"""
|
||||
if db is not None and not isinstance(db, AsyncSession):
|
||||
media_source, media_id, db = db, media_source, None
|
||||
condition = cls._identity_condition(
|
||||
media_source, media_id, music_type
|
||||
)
|
||||
if condition is None:
|
||||
return None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行订阅身份查询。"""
|
||||
statement = select(cls).where(condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await session.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
)
|
||||
return result.scalars().first()
|
||||
return await query(db)
|
||||
statement = select(cls).where(condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await db.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
)
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def exists_by_username(
|
||||
cls, db: Session | str | None = None,
|
||||
cls, db: Session,
|
||||
username: str | MediaSource | None = None,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
@@ -210,8 +196,6 @@ class Subscribe(Base):
|
||||
"""
|
||||
按订阅 owner、媒体身份、季号与剧集组查询订阅行。
|
||||
"""
|
||||
if db is not None and not isinstance(db, Session):
|
||||
username, media_source, media_id, db = db, username, media_source, None
|
||||
if not username:
|
||||
return None
|
||||
condition = cls._identity_condition(
|
||||
@@ -219,20 +203,16 @@ class Subscribe(Base):
|
||||
)
|
||||
if condition is None:
|
||||
return None
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行订阅 owner 查询。"""
|
||||
statement = select(cls).where(cls.username == username, condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
return session.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
).scalars().first()
|
||||
return query(db)
|
||||
statement = select(cls).where(cls.username == username, condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
return db.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_exists_by_username(
|
||||
cls, db: AsyncSession | str | None = None,
|
||||
cls, db: AsyncSession,
|
||||
username: str | MediaSource | None = None,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None, season: Optional[int] = None,
|
||||
@@ -242,8 +222,6 @@ class Subscribe(Base):
|
||||
"""
|
||||
异步按订阅 owner、媒体身份、季号与剧集组查询订阅行。
|
||||
"""
|
||||
if db is not None and not isinstance(db, AsyncSession):
|
||||
username, media_source, media_id, db = db, username, media_source, None
|
||||
if not username:
|
||||
return None
|
||||
condition = cls._identity_condition(
|
||||
@@ -251,112 +229,76 @@ class Subscribe(Base):
|
||||
)
|
||||
if condition is None:
|
||||
return None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行订阅 owner 查询。"""
|
||||
statement = select(cls).where(cls.username == username, condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await session.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
)
|
||||
return result.scalars().first()
|
||||
return await query(db)
|
||||
statement = select(cls).where(cls.username == username, condition)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await db.execute(
|
||||
statement.where(cls.episode_group == episode_group)
|
||||
)
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_state(cls, db: Session | str | None = None, state: str | None = None):
|
||||
"""按状态列表查询订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, Session):
|
||||
state, db = db if state is None else state, None
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行状态查询。"""
|
||||
statement = select(cls)
|
||||
if state:
|
||||
statement = statement.where(cls.state.in_(state.split(',')))
|
||||
return list(session.execute(statement).scalars().all())
|
||||
return query(db)
|
||||
def get_by_state(cls, db: Session, state: str | None = None):
|
||||
"""在调用方 Session 中按状态列表查询订阅。"""
|
||||
statement = select(cls)
|
||||
if state:
|
||||
statement = statement.where(cls.state.in_(state.split(',')))
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_state(
|
||||
cls, db: AsyncSession | str | None = None, state: str | None = None
|
||||
cls, db: AsyncSession, state: str | None = None
|
||||
):
|
||||
"""异步按状态列表查询订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, AsyncSession):
|
||||
state, db = db if state is None else state, None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行状态查询。"""
|
||||
statement = select(cls)
|
||||
if state:
|
||||
statement = statement.where(cls.state.in_(state.split(',')))
|
||||
result = await session.execute(statement)
|
||||
return list(result.scalars().all())
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中按状态列表查询订阅。"""
|
||||
statement = select(cls)
|
||||
if state:
|
||||
statement = statement.where(cls.state.in_(state.split(',')))
|
||||
result = await db.execute(statement)
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_title(
|
||||
cls, db: Session | str | None = None, title: str | None = None,
|
||||
cls, db: Session, title: str,
|
||||
season: Optional[int] = None,
|
||||
):
|
||||
"""按标题查询订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, Session):
|
||||
title, db = db if title is None else title, None
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行标题查询。"""
|
||||
statement = select(cls).where(cls.name == title)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
return session.execute(statement).scalars().first()
|
||||
return query(db)
|
||||
"""在调用方 Session 中按标题查询订阅。"""
|
||||
statement = select(cls).where(cls.name == title)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
return db.execute(statement).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_title(
|
||||
cls, db: AsyncSession | str | None = None, title: str | None = None,
|
||||
cls, db: AsyncSession, title: str,
|
||||
season: Optional[int] = None,
|
||||
):
|
||||
"""异步按标题查询订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, AsyncSession):
|
||||
title, db = db if title is None else title, None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行标题查询。"""
|
||||
statement = select(cls).where(cls.name == title)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await session.execute(statement)
|
||||
return result.scalars().first()
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中按标题查询订阅。"""
|
||||
statement = select(cls).where(cls.name == title)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await db.execute(statement)
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_title(
|
||||
cls, db: AsyncSession | str | None = None, title: str | None = None,
|
||||
cls, db: AsyncSession, title: str,
|
||||
season: Optional[int] = None,
|
||||
):
|
||||
"""异步按标题查询候选订阅列表,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, AsyncSession):
|
||||
title, db = db if title is None else title, None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行标题列表查询。"""
|
||||
statement = select(cls).where(cls.name == title)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await session.execute(statement)
|
||||
return list(result.scalars().all())
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中按标题查询候选订阅列表。"""
|
||||
statement = select(cls).where(cls.name == title)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
result = await db.execute(statement)
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_media_identity(
|
||||
cls, db: Session | MediaSource | None = None,
|
||||
cls, db: Session,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
music_type: Optional[str] = None,
|
||||
):
|
||||
"""同步按统一媒体身份查询候选订阅列表。"""
|
||||
if db is not None and not isinstance(db, Session):
|
||||
media_source, media_id, db = db, media_source, None
|
||||
condition = cls._identity_condition(
|
||||
media_source=media_source,
|
||||
media_id=media_id,
|
||||
@@ -364,22 +306,16 @@ class Subscribe(Base):
|
||||
)
|
||||
if condition is None:
|
||||
return []
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行媒体身份列表查询。"""
|
||||
return list(session.execute(select(cls).where(condition)).scalars().all())
|
||||
return query(db)
|
||||
return list(db.execute(select(cls).where(condition)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_media_identity(
|
||||
cls, db: AsyncSession | MediaSource | None = None,
|
||||
cls, db: AsyncSession,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
music_type: Optional[str] = None,
|
||||
):
|
||||
"""异步按统一媒体身份查询候选订阅列表。"""
|
||||
if db is not None and not isinstance(db, AsyncSession):
|
||||
media_source, media_id, db = db, media_source, None
|
||||
condition = cls._identity_condition(
|
||||
media_source=media_source,
|
||||
media_id=media_id,
|
||||
@@ -387,16 +323,12 @@ class Subscribe(Base):
|
||||
)
|
||||
if condition is None:
|
||||
return []
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行媒体身份列表查询。"""
|
||||
result = await session.execute(select(cls).where(condition))
|
||||
return list(result.scalars().all())
|
||||
return await query(db)
|
||||
result = await db.execute(select(cls).where(condition))
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by(
|
||||
cls, db: Session | str | None = None,
|
||||
cls, db: Session,
|
||||
type: str | MediaSource | None = None,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
@@ -406,8 +338,6 @@ class Subscribe(Base):
|
||||
"""
|
||||
根据条件查询订阅
|
||||
"""
|
||||
if db is not None and not isinstance(db, Session):
|
||||
type, media_source, media_id, db = db, type, media_source, None
|
||||
condition = cls._identity_condition(
|
||||
media_source, media_id, music_type
|
||||
)
|
||||
@@ -416,15 +346,11 @@ class Subscribe(Base):
|
||||
statement = select(cls).where(condition, cls.type == type)
|
||||
if season is not None:
|
||||
statement = statement.where(cls.season == season)
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行类型媒体查询。"""
|
||||
return session.execute(statement).scalars().first()
|
||||
return query(db)
|
||||
return db.execute(statement).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by(
|
||||
cls, db: AsyncSession | str | None = None,
|
||||
cls, db: AsyncSession,
|
||||
type: str | MediaSource | None = None,
|
||||
media_source: MediaSource | str | None = None,
|
||||
media_id: str | None = None,
|
||||
@@ -434,8 +360,6 @@ class Subscribe(Base):
|
||||
"""
|
||||
根据条件查询订阅
|
||||
"""
|
||||
if db is not None and not isinstance(db, AsyncSession):
|
||||
type, media_source, media_id, db = db, type, media_source, None
|
||||
condition = cls._identity_condition(
|
||||
media_source, media_id, music_type
|
||||
)
|
||||
@@ -444,76 +368,49 @@ class Subscribe(Base):
|
||||
query = select(cls).filter(condition, cls.type == type)
|
||||
if season is not None:
|
||||
query = query.filter(cls.season == season)
|
||||
async def execute_query(session: AsyncSession):
|
||||
"""在给定异步会话中执行类型媒体查询。"""
|
||||
result = await session.execute(query)
|
||||
return result.scalars().first()
|
||||
return await execute_query(db)
|
||||
result = await db.execute(query)
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_username(cls, db: Session | str | None = None, username: str | None = None,
|
||||
def list_by_username(cls, db: Session, username: str,
|
||||
state: Optional[str] = None, mtype: Optional[str] = None):
|
||||
"""按用户筛选订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, Session):
|
||||
username, db = db if username is None else username, None
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行用户筛选查询。"""
|
||||
statement = select(cls).where(cls.username == username)
|
||||
if state:
|
||||
statement = statement.where(cls.state == state)
|
||||
if mtype:
|
||||
statement = statement.where(cls.type == mtype)
|
||||
return list(session.execute(statement).scalars().all())
|
||||
return query(db)
|
||||
"""在调用方 Session 中按用户筛选订阅。"""
|
||||
statement = select(cls).where(cls.username == username)
|
||||
if state:
|
||||
statement = statement.where(cls.state == state)
|
||||
if mtype:
|
||||
statement = statement.where(cls.type == mtype)
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_username(cls, db: AsyncSession | str | None = None,
|
||||
username: str | None = None, state: Optional[str] = None,
|
||||
async def async_list_by_username(cls, db: AsyncSession,
|
||||
username: str, state: Optional[str] = None,
|
||||
mtype: Optional[str] = None):
|
||||
"""异步按用户筛选订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, AsyncSession):
|
||||
username, db = db if username is None else username, None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行用户筛选查询。"""
|
||||
statement = select(cls).where(cls.username == username)
|
||||
if state:
|
||||
statement = statement.where(cls.state == state)
|
||||
if mtype:
|
||||
statement = statement.where(cls.type == mtype)
|
||||
result = await session.execute(statement)
|
||||
return list(result.scalars().all())
|
||||
return await query(db)
|
||||
"""在调用方 AsyncSession 中按用户筛选订阅。"""
|
||||
statement = select(cls).where(cls.username == username)
|
||||
if state:
|
||||
statement = statement.where(cls.state == state)
|
||||
if mtype:
|
||||
statement = statement.where(cls.type == mtype)
|
||||
result = await db.execute(statement)
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_type(cls, db: Session | str | None = None, mtype: str | None = None, days: int = 7):
|
||||
"""按类型查询最近时间窗内的订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, Session):
|
||||
mtype, db = db if mtype is None else mtype, None
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行时间窗订阅查询。"""
|
||||
return list(session.execute(select(cls).where(
|
||||
cls.type == mtype,
|
||||
cls.date >= time.strftime("%Y-%m-%d %H:%M:%S",
|
||||
time.localtime(time.time() - 86400 * int(days)))
|
||||
)).scalars().all())
|
||||
return query(db)
|
||||
def list_by_type(cls, db: Session, mtype: str, days: int = 7):
|
||||
"""在调用方 Session 中按类型查询最近时间窗内的订阅。"""
|
||||
return list(db.execute(select(cls).where(
|
||||
cls.type == mtype,
|
||||
cls.date >= time.strftime("%Y-%m-%d %H:%M:%S",
|
||||
time.localtime(time.time() - 86400 * int(days)))
|
||||
)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_type(cls, db: AsyncSession | str | None = None,
|
||||
mtype: str | None = None, days: int = 7):
|
||||
"""异步按类型查询最近时间窗内的订阅,兼容显式会话和旧插件无会话调用。"""
|
||||
if not isinstance(db, AsyncSession):
|
||||
mtype, db = db if mtype is None else mtype, None
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行时间窗订阅查询。"""
|
||||
result = await session.execute(select(cls).where(
|
||||
cls.type == mtype,
|
||||
cls.date >= time.strftime("%Y-%m-%d %H:%M:%S",
|
||||
time.localtime(time.time() - 86400 * int(days)))
|
||||
))
|
||||
return list(result.scalars().all())
|
||||
return await query(db)
|
||||
async def async_list_by_type(cls, db: AsyncSession,
|
||||
mtype: str, days: int = 7):
|
||||
"""在调用方 AsyncSession 中按类型查询最近时间窗内的订阅。"""
|
||||
result = await db.execute(select(cls).where(
|
||||
cls.type == mtype,
|
||||
cls.date >= time.strftime("%Y-%m-%d %H:%M:%S",
|
||||
time.localtime(time.time() - 86400 * int(days)))
|
||||
))
|
||||
return list(result.scalars().all())
|
||||
|
||||
@@ -5,7 +5,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MUSIC_ENTITY_RECORDING, MediaSource
|
||||
|
||||
@@ -107,9 +106,8 @@ class SubscribeHistory(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_type(cls, db: Session, mtype: str, page: int = 1, count: int = 30):
|
||||
"""按媒体类型分页查询订阅历史,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 Session 中按媒体类型分页查询订阅历史。"""
|
||||
return list(db.execute(
|
||||
select(cls).where(
|
||||
cls.type == mtype
|
||||
@@ -119,9 +117,8 @@ class SubscribeHistory(Base):
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_type(cls, db: AsyncSession, mtype: str, page: int = 1, count: int = 30):
|
||||
"""异步按媒体类型分页查询订阅历史,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 AsyncSession 中按媒体类型分页查询订阅历史。"""
|
||||
result = await db.execute(
|
||||
select(cls).filter(
|
||||
cls.type == mtype
|
||||
@@ -132,7 +129,6 @@ class SubscribeHistory(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_type_and_username(
|
||||
cls,
|
||||
db: AsyncSession,
|
||||
@@ -177,7 +173,6 @@ class SubscribeHistory(Base):
|
||||
return condition
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def exists(
|
||||
cls, db: Session, media_source: MediaSource, media_id: str,
|
||||
season: Optional[int] = None,
|
||||
@@ -197,7 +192,6 @@ class SubscribeHistory(Base):
|
||||
return db.execute(statement).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_exists(
|
||||
cls, db: AsyncSession, media_source: MediaSource, media_id: str,
|
||||
season: Optional[int] = None,
|
||||
|
||||
@@ -4,7 +4,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class SystemConfig(Base):
|
||||
@@ -18,15 +17,13 @@ class SystemConfig(Base):
|
||||
value: Mapped[Optional[Any]] = mapped_column(JSON)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_key(cls, db: Session, key: str):
|
||||
"""按配置键查询系统配置,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 Session 中按配置键查询系统配置。"""
|
||||
return db.execute(select(cls).where(cls.key == key)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_key(cls, db: AsyncSession, key: str):
|
||||
"""异步按配置键查询系统配置,并保留旧插件无 Session 调用。"""
|
||||
"""在调用方 AsyncSession 中按配置键查询系统配置。"""
|
||||
result = await db.execute(select(cls).where(cls.key == key))
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import (
|
||||
legacy_async_db_query,
|
||||
legacy_db_query,
|
||||
)
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MUSIC_ENTITY_ALBUM, MUSIC_ENTITY_RECORDING, MediaSource, MediaType
|
||||
|
||||
@@ -97,7 +93,6 @@ class TransferHistory(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_title(cls, db: Session, title: str, page: int = 1, count: int = 30,
|
||||
status: Optional[bool] = None, wildcard: bool = False):
|
||||
if wildcard:
|
||||
@@ -124,7 +119,6 @@ class TransferHistory(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_title(cls, db: AsyncSession, title: str, page: int = 1, count: int = 30,
|
||||
status: Optional[bool] = None, wildcard: bool = False):
|
||||
if wildcard:
|
||||
@@ -152,7 +146,6 @@ class TransferHistory(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_page(cls, db: Session, page: int = 1, count: int = 30, status: Optional[bool] = None):
|
||||
statement = select(cls)
|
||||
if status is not None:
|
||||
@@ -166,7 +159,6 @@ class TransferHistory(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_list_by_page(cls, db: AsyncSession, page: int = 1, count: int = 30,
|
||||
status: Optional[bool] = None):
|
||||
if status is not None:
|
||||
@@ -188,30 +180,19 @@ class TransferHistory(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_hash(
|
||||
cls,
|
||||
db: Session | str | None = None,
|
||||
download_hash: str | None = None,
|
||||
db: Session,
|
||||
download_hash: str,
|
||||
):
|
||||
"""按下载哈希查询最新记录,兼容旧插件无会话调用。"""
|
||||
if download_hash is None and isinstance(db, str):
|
||||
download_hash, db = db, None
|
||||
if download_hash is None:
|
||||
raise TypeError("download_hash is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在调用方提供的同步会话中执行哈希查询。"""
|
||||
return session.execute(
|
||||
select(cls).where(cls.download_hash == download_hash)
|
||||
).scalars().first()
|
||||
|
||||
return query(db)
|
||||
"""在调用方 Session 中按下载哈希查询最新记录。"""
|
||||
return db.execute(
|
||||
select(cls).where(cls.download_hash == download_hash)
|
||||
).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_src(
|
||||
cls, db: Session | str | None = None, src: str | None = None,
|
||||
cls, db: Session, src: str,
|
||||
storage: Optional[str] = None
|
||||
) -> Optional["TransferHistory"]:
|
||||
"""
|
||||
@@ -222,26 +203,14 @@ class TransferHistory(Base):
|
||||
:param storage: 源存储类型
|
||||
:return: 命中的整理记录,未命中时返回 None
|
||||
"""
|
||||
if src is None and isinstance(db, str):
|
||||
src, db = db, None
|
||||
if src is None:
|
||||
raise TypeError("src is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在调用方提供的同步会话中执行源路径查询。"""
|
||||
statement = select(cls).where(cls.src == src)
|
||||
if storage:
|
||||
statement = statement.where(cls.src_storage == storage)
|
||||
return session.execute(
|
||||
statement.order_by(cls.id.desc())
|
||||
).scalars().first()
|
||||
|
||||
return query(db)
|
||||
statement = select(cls).where(cls.src == src)
|
||||
if storage:
|
||||
statement = statement.where(cls.src_storage == storage)
|
||||
return db.execute(statement.order_by(cls.id.desc())).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_success_by_src(
|
||||
cls, db: Session | str | None = None, src: str | None = None,
|
||||
cls, db: Session, src: str,
|
||||
storage: Optional[str] = None
|
||||
) -> Optional["TransferHistory"]:
|
||||
"""
|
||||
@@ -254,26 +223,14 @@ class TransferHistory(Base):
|
||||
:param storage: 源存储类型
|
||||
:return: 命中的成功整理记录,未命中时返回 None
|
||||
"""
|
||||
if src is None and isinstance(db, str):
|
||||
src, db = db, None
|
||||
if src is None:
|
||||
raise TypeError("src is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在调用方提供的同步会话中执行成功源路径查询。"""
|
||||
statement = select(cls).where(cls.src == src, cls.status.is_(True))
|
||||
if storage:
|
||||
statement = statement.where(cls.src_storage == storage)
|
||||
return session.execute(
|
||||
statement.order_by(cls.id.desc())
|
||||
).scalars().first()
|
||||
|
||||
return query(db)
|
||||
statement = select(cls).where(cls.src == src, cls.status.is_(True))
|
||||
if storage:
|
||||
statement = statement.where(cls.src_storage == storage)
|
||||
return db.execute(statement.order_by(cls.id.desc())).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_dest(
|
||||
cls, db: Session | str | None = None, dest: str | None = None,
|
||||
cls, db: Session, dest: str,
|
||||
storage: Optional[str] = None
|
||||
) -> Optional["TransferHistory"]:
|
||||
"""
|
||||
@@ -284,24 +241,12 @@ class TransferHistory(Base):
|
||||
:param storage: 目标存储类型
|
||||
:return: 命中的整理记录,未命中时返回 None
|
||||
"""
|
||||
if dest is None and isinstance(db, str):
|
||||
dest, db = db, None
|
||||
if dest is None:
|
||||
raise TypeError("dest is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在调用方提供的同步会话中执行目标路径查询。"""
|
||||
statement = select(cls).where(cls.dest == dest)
|
||||
if storage:
|
||||
statement = statement.where(cls.dest_storage == storage)
|
||||
return session.execute(
|
||||
statement.order_by(cls.id.desc())
|
||||
).scalars().first()
|
||||
|
||||
return query(db)
|
||||
statement = select(cls).where(cls.dest == dest)
|
||||
if storage:
|
||||
statement = statement.where(cls.dest_storage == storage)
|
||||
return db.execute(statement.order_by(cls.id.desc())).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_success_by_src(
|
||||
cls,
|
||||
db: Session,
|
||||
@@ -341,7 +286,6 @@ class TransferHistory(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_success_move_by_dest(
|
||||
cls,
|
||||
db: Session,
|
||||
@@ -384,14 +328,12 @@ class TransferHistory(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_hash(cls, db: Session, download_hash: str):
|
||||
return list(db.execute(
|
||||
select(cls).where(cls.download_hash == download_hash)
|
||||
).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def statistic(cls, db: Session, days: int = 7):
|
||||
"""
|
||||
统计最近days天的下载历史数量,按日期分组返回每日数量
|
||||
@@ -408,7 +350,6 @@ class TransferHistory(Base):
|
||||
).all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def monthly_media_statistics(cls, db: Session):
|
||||
"""
|
||||
统计当月成功整理的电影、电视剧、剧集和音乐数量。
|
||||
@@ -474,7 +415,6 @@ class TransferHistory(Base):
|
||||
return 1
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_statistic(cls, db: AsyncSession, days: int = 7):
|
||||
"""
|
||||
统计最近days天的下载历史数量,按日期分组返回每日数量
|
||||
@@ -489,7 +429,6 @@ class TransferHistory(Base):
|
||||
return result.all()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def count(cls, db: Session, status: Optional[bool] = None):
|
||||
statement = select(func.count(cls.id))
|
||||
if status is not None:
|
||||
@@ -497,7 +436,6 @@ class TransferHistory(Base):
|
||||
return db.execute(statement).scalar()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_count(cls, db: AsyncSession, status: Optional[bool] = None):
|
||||
if status is not None:
|
||||
result = await db.execute(
|
||||
@@ -510,7 +448,6 @@ class TransferHistory(Base):
|
||||
return result.scalar()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def count_by_title(cls, db: Session, title: str, status: Optional[bool] = None, wildcard: bool = False):
|
||||
if wildcard:
|
||||
text_filter = or_(
|
||||
@@ -530,7 +467,6 @@ class TransferHistory(Base):
|
||||
return db.execute(statement).scalar()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_count_by_title(cls, db: AsyncSession, title: str, status: Optional[bool] = None, wildcard: bool = False):
|
||||
if wildcard:
|
||||
text_filter = or_(
|
||||
@@ -551,7 +487,6 @@ class TransferHistory(Base):
|
||||
return result.scalar()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by(cls, db: Session, mtype: Optional[str] = None, title: Optional[str] = None, year: Optional[str] = None,
|
||||
season: Optional[str] = None,
|
||||
episode: Optional[str] = None,
|
||||
@@ -589,7 +524,6 @@ class TransferHistory(Base):
|
||||
return list(db.execute(statement).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_media_identity(
|
||||
cls, db: Session, media_source: MediaSource, media_id: str,
|
||||
mtype: Optional[str] = None,
|
||||
@@ -636,7 +570,6 @@ class TransferHistory(Base):
|
||||
return history
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_by_date(cls, db: Session, date: str):
|
||||
"""
|
||||
查询某时间之后的转移历史
|
||||
|
||||
@@ -4,7 +4,6 @@ from sqlalchemy import Index, String, delete, select
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import legacy_db_query
|
||||
|
||||
|
||||
class TransferPending(Base):
|
||||
@@ -73,7 +72,6 @@ class TransferPending(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def list_all(cls, db: Session, limit: Optional[int] = 5000) -> List["TransferPending"]:
|
||||
"""
|
||||
列出全部待整理登记,供启动回放使用。
|
||||
|
||||
+17
-58
@@ -4,7 +4,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class User(Base):
|
||||
@@ -35,78 +34,38 @@ class User(Base):
|
||||
settings: Mapped[Optional[Any]] = mapped_column(JSON, default=dict)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_name(
|
||||
cls,
|
||||
db: Session | str | None = None,
|
||||
name: str | None = None,
|
||||
db: Session,
|
||||
name: str,
|
||||
):
|
||||
"""按用户名查询用户,兼容显式会话和旧插件无会话调用。"""
|
||||
if name is None and isinstance(db, str):
|
||||
name, db = db, None
|
||||
if name is None:
|
||||
raise TypeError("name is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行用户名查询。"""
|
||||
return session.execute(select(cls).where(cls.name == name)).scalars().first()
|
||||
|
||||
return query(db)
|
||||
"""在调用方同步会话中按用户名查询用户。"""
|
||||
return db.execute(select(cls).where(cls.name == name)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_name(
|
||||
cls,
|
||||
db: AsyncSession | str | None = None,
|
||||
name: str | None = None,
|
||||
db: AsyncSession,
|
||||
name: str,
|
||||
):
|
||||
"""异步按用户名查询,兼容显式会话和旧插件无会话调用。"""
|
||||
if name is None and isinstance(db, str):
|
||||
name, db = db, None
|
||||
if name is None:
|
||||
raise TypeError("name is required")
|
||||
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行用户名查询。"""
|
||||
result = await session.execute(select(cls).filter(cls.name == name))
|
||||
return result.scalars().first()
|
||||
|
||||
return await query(db)
|
||||
"""在调用方异步会话中按用户名查询用户。"""
|
||||
result = await db.execute(select(cls).filter(cls.name == name))
|
||||
return result.scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_id(cls, db: Session | int | None = None, user_id: int | None = None):
|
||||
"""按用户 ID 查询用户,兼容显式会话和旧插件无会话调用。"""
|
||||
if user_id is None and isinstance(db, int):
|
||||
user_id, db = db, None
|
||||
if user_id is None:
|
||||
raise TypeError("user_id is required")
|
||||
|
||||
def query(session: Session):
|
||||
"""在给定会话中执行用户 ID 查询。"""
|
||||
return session.execute(select(cls).where(cls.id == user_id)).scalars().first()
|
||||
|
||||
return query(db)
|
||||
def get_by_id(cls, db: Session, user_id: int):
|
||||
"""在调用方同步会话中按用户 ID 查询用户。"""
|
||||
return db.execute(select(cls).where(cls.id == user_id)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_id(
|
||||
cls,
|
||||
db: AsyncSession | int | None = None,
|
||||
user_id: int | None = None,
|
||||
db: AsyncSession,
|
||||
user_id: int,
|
||||
):
|
||||
"""异步按用户 ID 查询,兼容显式会话和旧插件无会话调用。"""
|
||||
if user_id is None and isinstance(db, int):
|
||||
user_id, db = db, None
|
||||
if user_id is None:
|
||||
raise TypeError("user_id is required")
|
||||
|
||||
async def query(session: AsyncSession):
|
||||
"""在给定异步会话中执行用户 ID 查询。"""
|
||||
result = await session.execute(select(cls).filter(cls.id == user_id))
|
||||
return result.scalars().first()
|
||||
|
||||
return await query(db)
|
||||
"""在调用方异步会话中按用户 ID 查询用户。"""
|
||||
result = await db.execute(select(cls).filter(cls.id == user_id))
|
||||
return result.scalars().first()
|
||||
|
||||
def delete_by_name(self, db: Session, name: str):
|
||||
user = self.get_by_name(db, name)
|
||||
|
||||
@@ -7,7 +7,6 @@ from sqlalchemy.orm import Mapped, mapped_column
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import legacy_async_db_query, legacy_db_query
|
||||
|
||||
|
||||
class Workflow(Base):
|
||||
@@ -56,18 +55,15 @@ class Workflow(Base):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_enabled_workflows(cls, db):
|
||||
return list(db.execute(select(cls).where(cls.state != 'P')).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_enabled_workflows(cls, db: AsyncSession):
|
||||
result = await db.execute(select(cls).where(cls.state != 'P'))
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_timer_triggered_workflows(cls, db):
|
||||
"""获取定时触发的工作流"""
|
||||
return list(db.execute(select(cls).where(
|
||||
@@ -81,7 +77,6 @@ class Workflow(Base):
|
||||
)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_timer_triggered_workflows(cls, db: AsyncSession):
|
||||
"""异步获取定时触发的工作流"""
|
||||
result = await db.execute(select(cls).where(
|
||||
@@ -96,7 +91,6 @@ class Workflow(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_event_triggered_workflows(cls, db):
|
||||
"""获取事件触发的工作流"""
|
||||
return list(db.execute(select(cls).where(
|
||||
@@ -107,7 +101,6 @@ class Workflow(Base):
|
||||
)).scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_event_triggered_workflows(cls, db: AsyncSession):
|
||||
"""异步获取事件触发的工作流"""
|
||||
result = await db.execute(select(cls).where(
|
||||
@@ -119,12 +112,10 @@ class Workflow(Base):
|
||||
return list(result.scalars().all())
|
||||
|
||||
@classmethod
|
||||
@legacy_db_query
|
||||
def get_by_name(cls, db, name: str):
|
||||
return db.execute(select(cls).where(cls.name == name)).scalars().first()
|
||||
|
||||
@classmethod
|
||||
@legacy_async_db_query
|
||||
async def async_get_by_name(cls, db: AsyncSession, name: str):
|
||||
result = await db.execute(select(cls).where(cls.name == name))
|
||||
return result.scalars().first()
|
||||
|
||||
Reference in New Issue
Block a user