mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-01 13:37:24 +08:00
refactor: isolate transfer and download history queries
This commit is contained in:
+3
-188
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"model_decorators": {
|
||||
"by_kind": {
|
||||
"async_db_query": 27,
|
||||
"async_db_query": 18,
|
||||
"async_db_update": 0,
|
||||
"db_query": 48,
|
||||
"db_query": 20,
|
||||
"db_update": 0
|
||||
},
|
||||
"count": 75,
|
||||
"count": 38,
|
||||
"methods": [
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
@@ -38,86 +38,6 @@
|
||||
"file": "app/db/models/agenttaskrun.py",
|
||||
"method": "AgentTaskRun.list_for_task"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadFiles.get_by_fullpath"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadFiles.get_by_hash"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadFiles.get_by_savepath"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.async_count"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.async_count_by_title"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.async_list_by_page"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.async_list_by_title"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.get_by_hash"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.get_by_hashes"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.get_by_media_identity"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.get_by_path"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.get_last_by"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.list_by_date"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.list_by_page"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.list_by_type"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/downloadhistory.py",
|
||||
"method": "DownloadHistory.list_by_user_date"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/mediaserver.py",
|
||||
@@ -233,111 +153,6 @@
|
||||
"file": "app/db/models/systemconfig.py",
|
||||
"method": "SystemConfig.get_by_key"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.async_count"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.async_count_by_title"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.async_list_by_page"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.async_list_by_title"
|
||||
},
|
||||
{
|
||||
"decorator": "async_db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.async_statistic"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.count"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.count_by_title"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.get_by_dest"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.get_by_hash"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.get_by_media_identity"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.get_by_src"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.get_success_by_src"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_by"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_by_date"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_by_hash"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_by_page"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_by_title"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_success_by_src"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.list_success_move_by_dest"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.monthly_media_statistics"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferhistory.py",
|
||||
"method": "TransferHistory.statistic"
|
||||
},
|
||||
{
|
||||
"decorator": "db_query",
|
||||
"file": "app/db/models/transferpending.py",
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
"""Transfer/Download History 查询兼容层的会话与旧插件 ABI 验证。"""
|
||||
|
||||
import asyncio
|
||||
|
||||
from app.db import decorators
|
||||
from app.db.models.downloadhistory import DownloadHistory
|
||||
from app.db.models.transferhistory import TransferHistory
|
||||
from app.db.oper.downloadhistory import DownloadHistoryOper
|
||||
from app.db.oper.transferhistory import TransferHistoryOper
|
||||
from app.db.session import SessionFactory, async_session_scope
|
||||
|
||||
|
||||
def test_oper_reuses_explicit_sync_session(db, monkeypatch):
|
||||
"""显式同步会话绑定到 Oper 后,查询不能再创建兼容会话。"""
|
||||
row = db.add(TransferHistory(src="/compat/transfer.mkv", src_storage="local"))
|
||||
monkeypatch.setattr(
|
||||
decorators,
|
||||
"ScopedSession",
|
||||
lambda: (_ for _ in ()).throw(AssertionError("不应创建额外同步会话")),
|
||||
)
|
||||
|
||||
assert TransferHistoryOper(db.session).get_by_src("/compat/transfer.mkv").id == row.id
|
||||
assert DownloadHistoryOper(db.session).get_by_hash("missing") is None
|
||||
|
||||
|
||||
def test_model_legacy_sync_calls_preserve_business_arguments(db, monkeypatch):
|
||||
"""旧插件省略 db 时,第一个位置参数仍须作为业务参数传入。"""
|
||||
row = db.add(TransferHistory(src="/compat/legacy.mkv", src_storage="local"))
|
||||
created = []
|
||||
monkeypatch.setattr(
|
||||
decorators,
|
||||
"ScopedSession",
|
||||
lambda: (created.append(True) or SessionFactory()),
|
||||
)
|
||||
|
||||
assert TransferHistory.get_by_src("/compat/legacy.mkv").id == row.id
|
||||
assert created == [True]
|
||||
|
||||
|
||||
def test_download_model_legacy_sync_call_preserves_keyword_arguments(db, monkeypatch):
|
||||
"""旧插件使用关键字查询时,兼容层仍须自动补入 db。"""
|
||||
row = db.add(
|
||||
DownloadHistory(
|
||||
path="/compat/download",
|
||||
type="电视剧",
|
||||
download_hash="compat-hash",
|
||||
title="兼容",
|
||||
)
|
||||
)
|
||||
created = []
|
||||
monkeypatch.setattr(
|
||||
decorators,
|
||||
"ScopedSession",
|
||||
lambda: (created.append(True) or SessionFactory()),
|
||||
)
|
||||
|
||||
assert DownloadHistory.get_by_hash(download_hash="compat-hash").id == row.id
|
||||
assert created == [True]
|
||||
|
||||
|
||||
def test_oper_reuses_explicit_async_session(db, monkeypatch):
|
||||
"""显式异步会话绑定到 Oper 后,异步查询不能再创建兼容作用域。"""
|
||||
db.add(
|
||||
DownloadHistory(
|
||||
path="/compat/async-download",
|
||||
type="电视剧",
|
||||
title="异步兼容",
|
||||
download_hash="async-compat",
|
||||
)
|
||||
)
|
||||
|
||||
async def check() -> None:
|
||||
async with async_session_scope() as session:
|
||||
monkeypatch.setattr(
|
||||
decorators,
|
||||
"async_session_scope",
|
||||
lambda: (_ for _ in ()).throw(AssertionError("不应创建额外异步会话")),
|
||||
)
|
||||
result = await DownloadHistoryOper(session).async_list_by_page(count=10)
|
||||
assert any(item.download_hash == "async-compat" for item in result)
|
||||
|
||||
asyncio.run(check())
|
||||
|
||||
|
||||
def test_model_legacy_async_calls_support_explicit_and_implicit_sessions(db, monkeypatch):
|
||||
"""异步 Model 查询同时保留显式会话调用与旧插件无会话调用。"""
|
||||
db.add(
|
||||
DownloadHistory(
|
||||
path="/compat/async-legacy",
|
||||
type="电视剧",
|
||||
title="异步旧 ABI",
|
||||
download_hash="async-legacy",
|
||||
)
|
||||
)
|
||||
original_scope = decorators.async_session_scope
|
||||
created = []
|
||||
|
||||
def tracked_scope():
|
||||
"""记录兼容层是否创建了异步会话作用域。"""
|
||||
created.append(True)
|
||||
return original_scope()
|
||||
|
||||
async def check() -> None:
|
||||
async with original_scope() as session:
|
||||
assert await DownloadHistory.async_count(session) >= 1
|
||||
monkeypatch.setattr(decorators, "async_session_scope", tracked_scope)
|
||||
result = await DownloadHistory.async_list_by_title(title="异步旧 ABI")
|
||||
assert result[0].download_hash == "async-legacy"
|
||||
|
||||
asyncio.run(check())
|
||||
assert created == [True]
|
||||
Reference in New Issue
Block a user