You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
12 KiB
274 lines
12 KiB
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import Boolean, DateTime, ForeignKey, Index, Integer, String, Text, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base
|
|
|
|
|
|
class TimestampMixin:
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
server_default=func.now(),
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
)
|
|
|
|
|
|
class User(TimestampMixin, Base):
|
|
__tablename__ = "users"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
username: Mapped[str] = mapped_column(String, unique=True, nullable=False)
|
|
password_hash: Mapped[str] = mapped_column(String, nullable=False)
|
|
|
|
|
|
class AuthSession(TimestampMixin, Base):
|
|
__tablename__ = "auth_sessions"
|
|
__table_args__ = (
|
|
Index("idx_auth_sessions_user_status", "user_id", "revoked_at", "expires_at"),
|
|
Index("idx_auth_sessions_token_hash", "token_hash", unique=True),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
user_id: Mapped[str] = mapped_column(String, ForeignKey("users.id"), nullable=False)
|
|
token_hash: Mapped[str] = mapped_column(String, nullable=False)
|
|
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
|
revoked_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class Directory(TimestampMixin, Base):
|
|
__tablename__ = "directories"
|
|
__table_args__ = (
|
|
Index("idx_directories_parent_id", "parent_id"),
|
|
Index("idx_directories_path_key", "path_key"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
parent_id: Mapped[Optional[str]] = mapped_column(
|
|
String,
|
|
ForeignKey("directories.id"),
|
|
nullable=True,
|
|
)
|
|
name: Mapped[str] = mapped_column(String, nullable=False)
|
|
path_key: Mapped[str] = mapped_column(String, unique=True, nullable=False)
|
|
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class FileEntry(TimestampMixin, Base):
|
|
__tablename__ = "file_entries"
|
|
__table_args__ = (
|
|
Index("idx_file_entries_directory_name", "directory_id", "name", "is_deleted", unique=True),
|
|
Index("idx_file_entries_current_version_id", "current_version_id"),
|
|
Index("idx_file_entries_deleted_at", "deleted_at"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
directory_id: Mapped[str] = mapped_column(
|
|
String,
|
|
ForeignKey("directories.id"),
|
|
nullable=False,
|
|
)
|
|
name: Mapped[str] = mapped_column(String, nullable=False)
|
|
mime_type: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
current_version_id: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="0")
|
|
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class FileVersion(Base):
|
|
__tablename__ = "file_versions"
|
|
__table_args__ = (
|
|
Index("idx_file_versions_file_entry_id", "file_entry_id"),
|
|
Index("idx_file_versions_content_hash", "content_hash"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
file_entry_id: Mapped[str] = mapped_column(
|
|
String,
|
|
ForeignKey("file_entries.id"),
|
|
nullable=False,
|
|
)
|
|
content_hash: Mapped[str] = mapped_column(String, nullable=False)
|
|
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
storage_layout: Mapped[str] = mapped_column(String, nullable=False)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
server_default=func.now(),
|
|
)
|
|
|
|
|
|
class Blob(Base):
|
|
__tablename__ = "blobs"
|
|
__table_args__ = (
|
|
Index("idx_blobs_file_version_index", "file_version_id", "blob_index", unique=True),
|
|
Index("idx_blobs_content_hash", "content_hash"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
file_version_id: Mapped[str] = mapped_column(
|
|
String,
|
|
ForeignKey("file_versions.id"),
|
|
nullable=False,
|
|
)
|
|
blob_index: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
kind: Mapped[str] = mapped_column(String, nullable=False)
|
|
content_hash: Mapped[str] = mapped_column(String, nullable=False)
|
|
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
logical_offset: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
nullable=False,
|
|
server_default=func.now(),
|
|
)
|
|
|
|
|
|
class Backend(TimestampMixin, Base):
|
|
__tablename__ = "backends"
|
|
__table_args__ = (
|
|
Index("idx_backends_enabled", "is_enabled"),
|
|
Index("idx_backends_priority", "write_priority", "read_priority"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
name: Mapped[str] = mapped_column(String, unique=True, nullable=False)
|
|
type: Mapped[str] = mapped_column(String, nullable=False)
|
|
stability_class: Mapped[str] = mapped_column(String, nullable=False)
|
|
read_priority: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
write_priority: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
is_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="1")
|
|
config_json: Mapped[str] = mapped_column(Text, nullable=False)
|
|
capacity_hint_bytes: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
|
last_health_status: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
last_health_checked_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class PlacementPolicy(TimestampMixin, Base):
|
|
__tablename__ = "placement_policies"
|
|
__table_args__ = (
|
|
Index("idx_placement_policies_file_class", "file_class", unique=True),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
file_class: Mapped[str] = mapped_column(String, nullable=False)
|
|
require_local: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="1")
|
|
stable_replica_count: Mapped[int] = mapped_column(Integer, nullable=False, default=1, server_default="1")
|
|
opportunistic_replica_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
|
|
preferred_backend_ids_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]", server_default="[]")
|
|
excluded_backend_ids_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]", server_default="[]")
|
|
max_non_local_size_bytes: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
|
|
|
|
|
class BlobReplica(TimestampMixin, Base):
|
|
__tablename__ = "blob_replicas"
|
|
__table_args__ = (
|
|
Index("idx_blob_replicas_blob_backend", "blob_id", "backend_id", unique=True),
|
|
Index("idx_blob_replicas_backend_status", "backend_id", "status"),
|
|
Index("idx_blob_replicas_storage_key", "storage_key"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
blob_id: Mapped[str] = mapped_column(String, ForeignKey("blobs.id"), nullable=False)
|
|
backend_id: Mapped[str] = mapped_column(String, ForeignKey("backends.id"), nullable=False)
|
|
storage_key: Mapped[str] = mapped_column(String, nullable=False)
|
|
status: Mapped[str] = mapped_column(String, nullable=False)
|
|
etag: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
checksum: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
last_verified_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class UploadSession(TimestampMixin, Base):
|
|
__tablename__ = "upload_sessions"
|
|
__table_args__ = (
|
|
Index("idx_upload_sessions_status", "status"),
|
|
Index("idx_upload_sessions_updated_at", "updated_at"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
directory_id: Mapped[Optional[str]] = mapped_column(String, ForeignKey("directories.id"), nullable=True)
|
|
filename: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
total_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
received_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
status: Mapped[str] = mapped_column(String, nullable=False)
|
|
temp_path: Mapped[str] = mapped_column(String, nullable=False)
|
|
tus_upload_url: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
upload_metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
class UploadSessionPart(TimestampMixin, Base):
|
|
__tablename__ = "upload_session_parts"
|
|
__table_args__ = (
|
|
Index("idx_upload_session_parts_unique", "upload_session_id", "part_number", unique=True),
|
|
Index("idx_upload_session_parts_upload_id", "upload_session_id"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
upload_session_id: Mapped[str] = mapped_column(
|
|
String,
|
|
ForeignKey("upload_sessions.id"),
|
|
nullable=False,
|
|
)
|
|
part_number: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
byte_offset: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
checksum: Mapped[Optional[str]] = mapped_column(String, nullable=True)
|
|
status: Mapped[str] = mapped_column(String, nullable=False)
|
|
|
|
|
|
class Job(TimestampMixin, Base):
|
|
__tablename__ = "jobs"
|
|
__table_args__ = (
|
|
Index("idx_jobs_status_run_after", "status", "run_after"),
|
|
Index("idx_jobs_kind_status", "kind", "status"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
kind: Mapped[str] = mapped_column(String, nullable=False)
|
|
status: Mapped[str] = mapped_column(String, nullable=False)
|
|
payload_json: Mapped[str] = mapped_column(Text, nullable=False)
|
|
attempt_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
|
|
max_attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=5, server_default="5")
|
|
run_after: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
|
last_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
class PreviewArtifact(TimestampMixin, Base):
|
|
__tablename__ = "preview_artifacts"
|
|
__table_args__ = (
|
|
Index("idx_preview_artifacts_version_type", "file_version_id", "artifact_type", unique=True),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
file_version_id: Mapped[str] = mapped_column(String, ForeignKey("file_versions.id"), nullable=False)
|
|
artifact_type: Mapped[str] = mapped_column(String, nullable=False)
|
|
blob_id: Mapped[str] = mapped_column(String, ForeignKey("blobs.id"), nullable=False)
|
|
status: Mapped[str] = mapped_column(String, nullable=False)
|
|
|
|
|
|
class CacheEntry(TimestampMixin, Base):
|
|
__tablename__ = "cache_entries"
|
|
__table_args__ = (
|
|
Index("idx_cache_entries_blob_id", "blob_id"),
|
|
Index("idx_cache_entries_last_accessed_at", "last_accessed_at"),
|
|
Index("idx_cache_entries_expires_at", "expires_at"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True)
|
|
blob_id: Mapped[str] = mapped_column(String, ForeignKey("blobs.id"), nullable=False)
|
|
local_path: Mapped[str] = mapped_column(String, nullable=False)
|
|
cache_kind: Mapped[str] = mapped_column(String, nullable=False)
|
|
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
status: Mapped[str] = mapped_column(String, nullable=False)
|
|
last_accessed_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
|
expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|