This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch sbp
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/sbp by this push:
new 838e9a65 Add a table for release file states to the database
838e9a65 is described below
commit 838e9a65240dc525269336137efcb9e71521526d
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Mar 16 18:45:09 2026 +0000
Add a table for release file states to the database
---
atr/db/__init__.py | 26 +++++++++++++
atr/models/sql.py | 28 ++++++++++++++
migrations/versions/0059_2026.03.16_7dda4775.py | 50 +++++++++++++++++++++++++
3 files changed, 104 insertions(+)
diff --git a/atr/db/__init__.py b/atr/db/__init__.py
index 3236e117..83011f38 100644
--- a/atr/db/__init__.py
+++ b/atr/db/__init__.py
@@ -566,6 +566,32 @@ class Session(sqlalchemy.ext.asyncio.AsyncSession):
return Query(self, query)
+ def release_file_state(
+ self,
+ release_name: Opt[str] = NOT_SET,
+ path: Opt[str] = NOT_SET,
+ since_revision_seq: Opt[int] = NOT_SET,
+ present: Opt[bool] = NOT_SET,
+ content_hash: Opt[str | None] = NOT_SET,
+ classification: Opt[str | None] = NOT_SET,
+ ) -> Query[sql.ReleaseFileState]:
+ query = sqlmodel.select(sql.ReleaseFileState)
+
+ if is_defined(release_name):
+ query = query.where(sql.ReleaseFileState.release_name ==
release_name)
+ if is_defined(path):
+ query = query.where(sql.ReleaseFileState.path == path)
+ if is_defined(since_revision_seq):
+ query = query.where(sql.ReleaseFileState.since_revision_seq ==
since_revision_seq)
+ if is_defined(present):
+ query = query.where(sql.ReleaseFileState.present == present)
+ if is_defined(content_hash):
+ query = query.where(sql.ReleaseFileState.content_hash ==
content_hash)
+ if is_defined(classification):
+ query = query.where(sql.ReleaseFileState.classification ==
classification)
+
+ return Query(self, query)
+
def release_policy(
self,
id: Opt[int] = NOT_SET,
diff --git a/atr/models/sql.py b/atr/models/sql.py
index 7b24582f..d583b363 100644
--- a/atr/models/sql.py
+++ b/atr/models/sql.py
@@ -1226,6 +1226,34 @@ class Quarantined(sqlmodel.SQLModel, table=True):
self.status = QuarantineStatus(self.status)
+# ReleaseFileState: Revision
+class ReleaseFileState(sqlmodel.SQLModel, table=True):
+ release_name: str = sqlmodel.Field(primary_key=True,
**example("example-0.0.1"))
+ path: str = sqlmodel.Field(primary_key=True,
**example("apache-example-0.0.1-src.tar.gz"))
+ since_revision_seq: int = sqlmodel.Field(primary_key=True, **example(1))
+ present: bool = sqlmodel.Field(**example(True))
+ content_hash: str | None = sqlmodel.Field(default=None,
**example("blake3:7f83b1657ff1fc..."))
+ classification: str | None = sqlmodel.Field(default=None,
**example("source"))
+
+ __table_args__ = (
+ sqlalchemy.ForeignKeyConstraint(
+ ["release_name", "since_revision_seq"],
+ ["revision.release_name", "revision.seq"],
+ ondelete="CASCADE",
+ ),
+ sqlalchemy.CheckConstraint(
+ """
+ (
+ (present = 1 AND content_hash IS NOT NULL AND classification
IS NOT NULL)
+ OR
+ (present = 0 AND content_hash IS NULL AND classification IS
NULL)
+ )
+ """,
+ name="valid_release_file_state",
+ ),
+ )
+
+
# ReleasePolicy: Project
class ReleasePolicy(sqlmodel.SQLModel, table=True):
id: int = sqlmodel.Field(default=None, primary_key=True)
diff --git a/migrations/versions/0059_2026.03.16_7dda4775.py
b/migrations/versions/0059_2026.03.16_7dda4775.py
new file mode 100644
index 00000000..73dea89e
--- /dev/null
+++ b/migrations/versions/0059_2026.03.16_7dda4775.py
@@ -0,0 +1,50 @@
+"""Add release file state data
+
+Revision ID: 0059_2026.03.16_7dda4775
+Revises: 0058_2026.03.12_2ebee77e
+Create Date: 2026-03-16 17:10:20.840574+00:00
+"""
+
+from collections.abc import Sequence
+
+import sqlalchemy as sa
+from alembic import op
+
+# Revision identifiers, used by Alembic
+revision: str = "0059_2026.03.16_7dda4775"
+down_revision: str | None = "0058_2026.03.12_2ebee77e"
+branch_labels: str | Sequence[str] | None = None
+depends_on: str | Sequence[str] | None = None
+
+
+def upgrade() -> None:
+ op.create_table(
+ "releasefilestate",
+ sa.Column("release_name", sa.String(), nullable=False),
+ sa.Column("path", sa.String(), nullable=False),
+ sa.Column("since_revision_seq", sa.Integer(), nullable=False),
+ sa.Column("present", sa.Boolean(), nullable=False),
+ sa.Column("content_hash", sa.String(), nullable=True),
+ sa.Column("classification", sa.String(), nullable=True),
+ sa.ForeignKeyConstraint(
+ ["release_name", "since_revision_seq"],
+ ["revision.release_name", "revision.seq"],
+
name=op.f("fk_releasefilestate_release_name_since_revision_seq_revision"),
+ ondelete="CASCADE",
+ ),
+ sa.PrimaryKeyConstraint("release_name", "path", "since_revision_seq",
name=op.f("pk_releasefilestate")),
+ sa.CheckConstraint(
+ """
+ (
+ (present = 1 AND content_hash IS NOT NULL AND classification
IS NOT NULL)
+ OR
+ (present = 0 AND content_hash IS NULL AND classification IS
NULL)
+ )
+ """,
+ name=op.f("ck_releasefilestate_valid_release_file_state"),
+ ),
+ )
+
+
+def downgrade() -> None:
+ op.drop_table("releasefilestate")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]