feat: complete transfer and eviction execution
This commit is contained in:
@@ -11,7 +11,7 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SCHEMA_VERSION = 2
|
||||
SCHEMA_VERSION = 3
|
||||
|
||||
|
||||
class CommandConflict(RuntimeError):
|
||||
@@ -58,6 +58,10 @@ class ClientStore:
|
||||
if version == 1:
|
||||
connection.executescript(_SCHEMA_V2)
|
||||
connection.execute("PRAGMA user_version = 2")
|
||||
version = 2
|
||||
if version == 2:
|
||||
connection.executescript(_SCHEMA_V3)
|
||||
connection.execute("PRAGMA user_version = 3")
|
||||
if connection.execute("PRAGMA foreign_key_check").fetchall():
|
||||
raise RuntimeError("client database foreign-key check failed")
|
||||
if not existed:
|
||||
@@ -268,6 +272,57 @@ class ClientStore:
|
||||
).fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def put_job_artifact(
|
||||
self, job_id: str, kind: str, value: dict[str, object]
|
||||
) -> dict[str, object]:
|
||||
encoded = _canonical(value)
|
||||
with self._connect() as connection:
|
||||
connection.execute("BEGIN IMMEDIATE")
|
||||
existing = connection.execute(
|
||||
"""
|
||||
SELECT value_json FROM job_artifacts
|
||||
WHERE job_id = ? AND kind = ?
|
||||
""",
|
||||
(job_id, kind),
|
||||
).fetchone()
|
||||
if existing is not None and existing["value_json"] != encoded:
|
||||
raise JobConflict(f"job artifact {kind} is immutable")
|
||||
connection.execute(
|
||||
"""
|
||||
INSERT INTO job_artifacts (job_id, kind, value_json)
|
||||
VALUES (?, ?, ?)
|
||||
ON CONFLICT(job_id, kind) DO NOTHING
|
||||
""",
|
||||
(job_id, kind, encoded),
|
||||
)
|
||||
row = connection.execute(
|
||||
"""
|
||||
SELECT job_id, kind, value_json FROM job_artifacts
|
||||
WHERE job_id = ? AND kind = ?
|
||||
""",
|
||||
(job_id, kind),
|
||||
).fetchone()
|
||||
result = dict(row)
|
||||
result["value"] = json.loads(str(result.pop("value_json")))
|
||||
return result
|
||||
|
||||
def get_job_artifact(
|
||||
self, job_id: str, kind: str
|
||||
) -> dict[str, object] | None:
|
||||
with self._connect() as connection:
|
||||
row = connection.execute(
|
||||
"""
|
||||
SELECT job_id, kind, value_json FROM job_artifacts
|
||||
WHERE job_id = ? AND kind = ?
|
||||
""",
|
||||
(job_id, kind),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
return None
|
||||
result = dict(row)
|
||||
result["value"] = json.loads(str(result.pop("value_json")))
|
||||
return result
|
||||
|
||||
def record_job_event(
|
||||
self,
|
||||
*,
|
||||
@@ -567,3 +622,13 @@ CREATE TABLE route_attempt_updates (
|
||||
PRIMARY KEY(command_id, sequence)
|
||||
);
|
||||
"""
|
||||
|
||||
|
||||
_SCHEMA_V3 = """
|
||||
CREATE TABLE job_artifacts (
|
||||
job_id TEXT NOT NULL REFERENCES jobs(job_id),
|
||||
kind TEXT NOT NULL,
|
||||
value_json TEXT NOT NULL,
|
||||
PRIMARY KEY(job_id, kind)
|
||||
);
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user