Files
disknext/models/physical_file.py
于小丘 446d219aca Refactor import statements for ResponseBase in API routers
- Updated import statements in the following files to import ResponseBase directly from models instead of models.response:
  - routers/api/v1/share/__init__.py
  - routers/api/v1/site/__init__.py
  - routers/api/v1/slave/__init__.py
  - routers/api/v1/tag/__init__.py
  - routers/api/v1/user/__init__.py
  - routers/api/v1/vas/__init__.py
  - routers/api/v1/webdav/__init__.py

Enhance user registration and related endpoints in user router

- Changed return type annotations from models.response.ResponseBase to models.ResponseBase in multiple functions.
- Updated return statements to reflect the new import structure.
- Improved documentation for clarity.

Add PhysicalFile model and storage service implementation

- Introduced PhysicalFile model to represent actual files on disk with reference counting logic.
- Created storage service module with local storage implementation, including file operations and error handling.
- Defined exceptions for storage operations to improve error handling.
- Implemented naming rule parser for generating file and directory names based on templates.

Update dependency management in uv.lock

- Added aiofiles version 25.1.0 to the project dependencies.
2025-12-23 12:20:06 +08:00

91 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
物理文件模型
表示磁盘上的实际文件。多个 Object 可以引用同一个 PhysicalFile
实现文件共享而不复制物理文件。
引用计数逻辑:
- 每个引用此文件的 Object 都会增加引用计数
- 当 Object 被删除时,减少引用计数
- 只有当引用计数为 0 时,才物理删除文件
"""
from typing import TYPE_CHECKING
from uuid import UUID
from sqlmodel import Field, Relationship, Index
from .base import SQLModelBase
from .mixin import UUIDTableBaseMixin
if TYPE_CHECKING:
from .object import Object
from .policy import Policy
class PhysicalFileBase(SQLModelBase):
"""物理文件基础模型"""
storage_path: str = Field(max_length=512)
"""物理存储路径(相对于存储策略根目录)"""
size: int = 0
"""文件大小(字节)"""
checksum_md5: str | None = Field(default=None, max_length=32)
"""MD5校验和用于文件去重和完整性校验"""
class PhysicalFile(PhysicalFileBase, UUIDTableBaseMixin):
"""
物理文件模型
表示磁盘上的实际文件。多个 Object 可以引用同一个 PhysicalFile
实现文件共享而不复制物理文件。
"""
__table_args__ = (
Index("ix_physical_file_policy_path", "policy_id", "storage_path"),
Index("ix_physical_file_checksum", "checksum_md5"),
)
policy_id: UUID = Field(
foreign_key="policy.id",
index=True,
ondelete="RESTRICT",
)
"""存储策略UUID"""
reference_count: int = Field(default=1, ge=0)
"""引用计数(有多少个 Object 引用此物理文件)"""
# 关系
policy: "Policy" = Relationship()
"""存储策略"""
objects: list["Object"] = Relationship(back_populates="physical_file")
"""引用此物理文件的所有逻辑对象"""
def increment_reference(self) -> int:
"""
增加引用计数
:return: 更新后的引用计数
"""
self.reference_count += 1
return self.reference_count
def decrement_reference(self) -> int:
"""
减少引用计数
:return: 更新后的引用计数
"""
if self.reference_count > 0:
self.reference_count -= 1
return self.reference_count
@property
def can_be_deleted(self) -> bool:
"""是否可以物理删除引用计数为0"""
return self.reference_count == 0