Files
sub-provider/app/db_models.py
riglen 0a46ebf0a8 db
2026-04-20 11:09:36 +08:00

150 lines
7.1 KiB
Python

from __future__ import annotations
from datetime import datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
class Base(DeclarativeBase):
pass
class TimestampMixin:
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
updated_at: Mapped[datetime] = mapped_column(
DateTime,
default=datetime.utcnow,
onupdate=datetime.utcnow,
nullable=False,
)
class AppSettingORM(Base, TimestampMixin):
__tablename__ = "app_settings"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
value: Mapped[str | None] = mapped_column(Text, nullable=True)
class SourceORM(Base, TimestampMixin):
__tablename__ = "sources"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
kind: Mapped[str] = mapped_column(String(50), nullable=False)
url: Mapped[str] = mapped_column(Text, nullable=False)
display_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
headers_json: Mapped[str] = mapped_column(Text, default="{}", nullable=False)
include_regex: Mapped[str | None] = mapped_column(Text, nullable=True)
exclude_regex: Mapped[str | None] = mapped_column(Text, nullable=True)
prefix: Mapped[str] = mapped_column(String(255), default="", nullable=False)
suffix: Mapped[str] = mapped_column(String(255), default="", nullable=False)
cache_ttl_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
class ProfileORM(Base, TimestampMixin):
__tablename__ = "profiles"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
title: Mapped[str] = mapped_column(String(255), nullable=False)
provider_interval: Mapped[int] = mapped_column(Integer, default=21600, nullable=False)
rule_interval: Mapped[int] = mapped_column(Integer, default=86400, nullable=False)
test_url: Mapped[str] = mapped_column(Text, nullable=False)
test_interval: Mapped[int] = mapped_column(Integer, default=300, nullable=False)
main_policy: Mapped[str] = mapped_column(String(255), nullable=False)
source_policy: Mapped[str] = mapped_column(String(255), nullable=False)
mixed_auto_policy: Mapped[str] = mapped_column(String(255), nullable=False)
manual_policy: Mapped[str] = mapped_column(String(255), nullable=False)
direct_policy: Mapped[str] = mapped_column(String(255), nullable=False)
mode: Mapped[str] = mapped_column(String(50), default="rule", nullable=False)
allow_lan: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
ipv6: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
mixed_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
socks_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
log_level: Mapped[str | None] = mapped_column(String(50), nullable=True)
source_links: Mapped[list["ProfileSourceORM"]] = relationship(
back_populates="profile",
cascade="all, delete-orphan",
)
rule_links: Mapped[list["ProfileRuleModuleORM"]] = relationship(
back_populates="profile",
cascade="all, delete-orphan",
)
groups: Mapped[list["PolicyGroupORM"]] = relationship(
back_populates="profile",
cascade="all, delete-orphan",
)
class ProfileSourceORM(Base):
__tablename__ = "profile_sources"
__table_args__ = (UniqueConstraint("profile_id", "source_id", name="uq_profile_source"),)
id: Mapped[int] = mapped_column(Integer, primary_key=True)
profile_id: Mapped[int] = mapped_column(ForeignKey("profiles.id"), nullable=False)
source_id: Mapped[int] = mapped_column(ForeignKey("sources.id"), nullable=False)
order_index: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
profile: Mapped[ProfileORM] = relationship(back_populates="source_links")
source: Mapped[SourceORM] = relationship()
class RuleModuleORM(Base, TimestampMixin):
__tablename__ = "rule_modules"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
key: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
file_path: Mapped[str | None] = mapped_column(Text, nullable=True)
behavior: Mapped[str] = mapped_column(String(50), nullable=False)
format: Mapped[str] = mapped_column(String(50), nullable=False)
policy: Mapped[str] = mapped_column(String(255), nullable=False)
no_resolve: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
payload_json: Mapped[str] = mapped_column(Text, default="[]", nullable=False)
profile_links: Mapped[list["ProfileRuleModuleORM"]] = relationship(
back_populates="rule_module",
cascade="all, delete-orphan",
)
class ProfileRuleModuleORM(Base):
__tablename__ = "profile_rule_modules"
__table_args__ = (UniqueConstraint("profile_id", "rule_module_id", name="uq_profile_rule_module"),)
id: Mapped[int] = mapped_column(Integer, primary_key=True)
profile_id: Mapped[int] = mapped_column(ForeignKey("profiles.id"), nullable=False)
rule_module_id: Mapped[int] = mapped_column(ForeignKey("rule_modules.id"), nullable=False)
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
order_index: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
policy_override: Mapped[str | None] = mapped_column(String(255), nullable=True)
payload_override_json: Mapped[str | None] = mapped_column(Text, nullable=True)
no_resolve_override: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
profile: Mapped[ProfileORM] = relationship(back_populates="rule_links")
rule_module: Mapped[RuleModuleORM] = relationship(back_populates="profile_links")
class PolicyGroupORM(Base, TimestampMixin):
__tablename__ = "policy_groups"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
profile_id: Mapped[int] = mapped_column(ForeignKey("profiles.id"), nullable=False)
group_kind: Mapped[str] = mapped_column(String(50), nullable=False)
name: Mapped[str] = mapped_column(String(255), nullable=False)
type: Mapped[str] = mapped_column(String(50), nullable=False)
order_index: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
proxies_json: Mapped[str | None] = mapped_column(Text, nullable=True)
filter_regex: Mapped[str | None] = mapped_column(Text, nullable=True)
tolerance: Mapped[int | None] = mapped_column(Integer, nullable=True)
url: Mapped[str | None] = mapped_column(Text, nullable=True)
interval: Mapped[int | None] = mapped_column(Integer, nullable=True)
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
profile: Mapped[ProfileORM] = relationship(back_populates="groups")