DAO layer for presence schedules and overrides #20
@@ -11,7 +11,7 @@ Semantics per the done-condition and Feature 05:
|
||||
- A child has AT MOST ONE presence schedule (schema UNIQUE); upserting
|
||||
by child updates the existing row rather than raising.
|
||||
- A child with NO schedule row is present every day — the absence of a
|
||||
row is meaningful state, expressed by :meth:`PresenceSchedulesDao.get`
|
||||
row is meaningful state, expressed by :meth:`PresenceSchedulesDao.get_by_child`
|
||||
returning None, never by an empty pattern row.
|
||||
- Overrides beat the pattern for their date range (that resolution is
|
||||
the presence engine's job, Feature 05); the DAO only stores and
|
||||
|
||||
@@ -166,10 +166,13 @@ def test_upsert_concurrent_same_child_serializes(tmp_path) -> None:
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
hass = MagicMock()
|
||||
# Gate exactly ONE job: the first executor job issued after
|
||||
# Gate exactly ONE job: the first _fetch_one issued after
|
||||
# arming, which is task A's child-existence SELECT inside its
|
||||
# transaction (A holds the connection lock from that moment).
|
||||
# Everything before arming (open, migrations, child create)
|
||||
# transaction. The transaction's BEGIN runs first and is NOT
|
||||
# gated, so when the gated fetch signals, BEGIN has executed
|
||||
# and SQLite is inside the open transaction (A holds the
|
||||
# connection lock from BEGIN until commit). Everything before
|
||||
# arming (open, migrations, child create)
|
||||
# and everything after (B's jobs, A's remaining jobs, reads)
|
||||
# pass straight through.
|
||||
armed = {"active": False, "gated": False}
|
||||
|
||||
Reference in New Issue
Block a user