Coverage for polar/models/downloadable.py: 100%

30 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-12-05 16:17 +0000

1from datetime import datetime 1ab

2from enum import StrEnum 1ab

3from uuid import UUID 1ab

4 

5from sqlalchemy import ( 1ab

6 TIMESTAMP, 

7 ForeignKey, 

8 Integer, 

9 String, 

10 UniqueConstraint, 

11 Uuid, 

12) 

13from sqlalchemy.orm import Mapped, declared_attr, mapped_column, relationship 1ab

14 

15from polar.kit.db.models import RecordModel 1ab

16 

17from .benefit import Benefit 1ab

18from .customer import Customer 1ab

19from .file import File 1ab

20 

21 

22class DownloadableStatus(StrEnum): 1ab

23 granted = "granted" 1ab

24 revoked = "revoked" 1ab

25 

26 

27class Downloadable(RecordModel): 1ab

28 __tablename__ = "downloadables" 1ab

29 __table_args__ = (UniqueConstraint("customer_id", "file_id", "benefit_id"),) 1ab

30 

31 file_id: Mapped[UUID] = mapped_column( 1ab

32 Uuid, ForeignKey("files.id"), nullable=False, index=True 

33 ) 

34 

35 @declared_attr 1ab

36 def file(cls) -> Mapped[File]: 1ab

37 return relationship(File, lazy="raise") 1ab

38 

39 status: Mapped[DownloadableStatus] = mapped_column(String, nullable=False) 1ab

40 

41 customer_id: Mapped[UUID] = mapped_column( 1ab

42 Uuid, 

43 ForeignKey("customers.id", ondelete="cascade"), 

44 nullable=False, 

45 # Don't create an index for customer_id 

46 # as it's covered by the unique constraint, being the leading column of it 

47 index=False, 

48 ) 

49 

50 @declared_attr 1ab

51 def customer(cls) -> Mapped[Customer]: 1ab

52 return relationship("Customer", lazy="raise") 1ab

53 

54 benefit_id: Mapped[UUID] = mapped_column( 1ab

55 Uuid, 

56 ForeignKey("benefits.id", ondelete="cascade"), 

57 nullable=False, 

58 index=True, 

59 ) 

60 

61 @declared_attr 1ab

62 def benefit(cls) -> Mapped[Benefit]: 1ab

63 return relationship("Benefit", lazy="raise") 1ab

64 

65 downloaded: Mapped[int] = mapped_column(Integer, nullable=False, default=0) 1ab

66 

67 last_downloaded_at: Mapped[datetime | None] = mapped_column( 1ab

68 TIMESTAMP(timezone=True), 

69 nullable=True, 

70 )