Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cache to lookup event type ids in logbook #91576

Merged
merged 1 commit into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions homeassistant/components/logbook/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from homeassistant.components.recorder.filters import Filters
from homeassistant.components.recorder.models import (
bytes_to_uuid_hex_or_none,
extract_event_type_ids,
extract_metadata_ids,
process_datetime_to_timestamp,
process_timestamp_to_utc_isoformat,
Expand Down Expand Up @@ -153,17 +154,22 @@ def yield_rows(result: Result) -> Sequence[Row] | Result:

with session_scope(hass=self.hass, read_only=True) as session:
metadata_ids: list[int] | None = None
instance = get_instance(self.hass)
if self.entity_ids:
instance = get_instance(self.hass)
metadata_ids = extract_metadata_ids(
instance.states_meta_manager.get_many(
self.entity_ids, session, False
)
)
event_type_ids = tuple(
extract_event_type_ids(
instance.event_type_manager.get_many(self.event_types, session)
)
)
stmt = statement_for_request(
start_day,
end_day,
self.event_types,
event_type_ids,
self.entity_ids,
metadata_ids,
self.device_ids,
Expand Down
10 changes: 5 additions & 5 deletions homeassistant/components/logbook/queries/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
def statement_for_request(
start_day_dt: dt,
end_day_dt: dt,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
entity_ids: list[str] | None = None,
states_metadata_ids: Collection[int] | None = None,
device_ids: list[str] | None = None,
Expand All @@ -37,7 +37,7 @@ def statement_for_request(
return all_stmt(
start_day,
end_day,
event_types,
event_type_ids,
filters,
context_id_bin,
)
Expand All @@ -52,7 +52,7 @@ def statement_for_request(
return entities_devices_stmt(
start_day,
end_day,
event_types,
event_type_ids,
states_metadata_ids or [],
[json_dumps(entity_id) for entity_id in entity_ids],
[json_dumps(device_id) for device_id in device_ids],
Expand All @@ -63,7 +63,7 @@ def statement_for_request(
return entities_stmt(
start_day,
end_day,
event_types,
event_type_ids,
states_metadata_ids or [],
[json_dumps(entity_id) for entity_id in entity_ids],
)
Expand All @@ -73,6 +73,6 @@ def statement_for_request(
return devices_stmt(
start_day,
end_day,
event_types,
event_type_ids,
[json_dumps(device_id) for device_id in device_ids],
)
4 changes: 2 additions & 2 deletions homeassistant/components/logbook/queries/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
def all_stmt(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
filters: Filters | None,
context_id_bin: bytes | None = None,
) -> StatementLambdaElement:
"""Generate a logbook query for all entities."""
stmt = lambda_stmt(
lambda: select_events_without_states(start_day, end_day, event_types)
lambda: select_events_without_states(start_day, end_day, event_type_ids)
)
if context_id_bin is not None:
stmt += lambda s: s.where(Events.context_id_bin == context_id_bin).union_all(
Expand Down
9 changes: 4 additions & 5 deletions homeassistant/components/logbook/queries/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
StatesMeta,
)
from homeassistant.components.recorder.filters import like_domain_matchers
from homeassistant.components.recorder.queries import select_event_type_ids

from ..const import ALWAYS_CONTINUOUS_DOMAINS, CONDITIONALLY_CONTINUOUS_DOMAINS

Expand Down Expand Up @@ -112,13 +111,13 @@
def select_events_context_id_subquery(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
) -> Select:
"""Generate the select for a context_id subquery."""
return (
select(Events.context_id_bin)
.where((Events.time_fired_ts > start_day) & (Events.time_fired_ts < end_day))
.where(Events.event_type_id.in_(select_event_type_ids(event_types)))
.where(Events.event_type_id.in_(event_type_ids))
.outerjoin(EventTypes, (Events.event_type_id == EventTypes.event_type_id))
.outerjoin(EventData, (Events.data_id == EventData.data_id))
)
Expand All @@ -145,13 +144,13 @@ def select_states_context_only() -> Select:


def select_events_without_states(
start_day: float, end_day: float, event_types: tuple[str, ...]
start_day: float, end_day: float, event_type_ids: tuple[int, ...]
) -> Select:
"""Generate an events select that does not join states."""
return (
select(*EVENT_ROWS_NO_STATES, NOT_CONTEXT_ONLY)
.where((Events.time_fired_ts > start_day) & (Events.time_fired_ts < end_day))
.where(Events.event_type_id.in_(select_event_type_ids(event_types)))
.where(Events.event_type_id.in_(event_type_ids))
.outerjoin(EventTypes, (Events.event_type_id == EventTypes.event_type_id))
.outerjoin(EventData, (Events.data_id == EventData.data_id))
)
Expand Down
14 changes: 7 additions & 7 deletions homeassistant/components/logbook/queries/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@
def _select_device_id_context_ids_sub_query(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
json_quotable_device_ids: list[str],
) -> Select:
"""Generate a subquery to find context ids for multiple devices."""
inner = (
select_events_context_id_subquery(start_day, end_day, event_types)
select_events_context_id_subquery(start_day, end_day, event_type_ids)
.where(apply_event_device_id_matchers(json_quotable_device_ids))
.subquery()
)
Expand All @@ -47,14 +47,14 @@ def _apply_devices_context_union(
sel: Select,
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
json_quotable_device_ids: list[str],
) -> CompoundSelect:
"""Generate a CTE to find the device context ids and a query to find linked row."""
devices_cte: CTE = _select_device_id_context_ids_sub_query(
start_day,
end_day,
event_types,
event_type_ids,
json_quotable_device_ids,
).cte()
return sel.union_all(
Expand All @@ -77,18 +77,18 @@ def _apply_devices_context_union(
def devices_stmt(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
json_quotable_device_ids: list[str],
) -> StatementLambdaElement:
"""Generate a logbook query for multiple devices."""
stmt = lambda_stmt(
lambda: _apply_devices_context_union(
select_events_without_states(start_day, end_day, event_types).where(
select_events_without_states(start_day, end_day, event_type_ids).where(
apply_event_device_id_matchers(json_quotable_device_ids)
),
start_day,
end_day,
event_types,
event_type_ids,
json_quotable_device_ids,
).order_by(Events.time_fired_ts)
)
Expand Down
14 changes: 7 additions & 7 deletions homeassistant/components/logbook/queries/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
def _select_entities_context_ids_sub_query(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
states_metadata_ids: Collection[int],
json_quoted_entity_ids: list[str],
) -> Select:
"""Generate a subquery to find context ids for multiple entities."""
union = union_all(
select_events_context_id_subquery(start_day, end_day, event_types).where(
select_events_context_id_subquery(start_day, end_day, event_type_ids).where(
apply_event_entity_id_matchers(json_quoted_entity_ids)
),
apply_entities_hints(select(States.context_id_bin))
Expand All @@ -57,15 +57,15 @@ def _apply_entities_context_union(
sel: Select,
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
states_metadata_ids: Collection[int],
json_quoted_entity_ids: list[str],
) -> CompoundSelect:
"""Generate a CTE to find the entity and device context ids and a query to find linked row."""
entities_cte: CTE = _select_entities_context_ids_sub_query(
start_day,
end_day,
event_types,
event_type_ids,
states_metadata_ids,
json_quoted_entity_ids,
).cte()
Expand Down Expand Up @@ -95,19 +95,19 @@ def _apply_entities_context_union(
def entities_stmt(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
states_metadata_ids: Collection[int],
json_quoted_entity_ids: list[str],
) -> StatementLambdaElement:
"""Generate a logbook query for multiple entities."""
return lambda_stmt(
lambda: _apply_entities_context_union(
select_events_without_states(start_day, end_day, event_types).where(
select_events_without_states(start_day, end_day, event_type_ids).where(
apply_event_entity_id_matchers(json_quoted_entity_ids)
),
start_day,
end_day,
event_types,
event_type_ids,
states_metadata_ids,
json_quoted_entity_ids,
).order_by(Events.time_fired_ts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@
def _select_entities_device_id_context_ids_sub_query(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
states_metadata_ids: Collection[int],
json_quoted_entity_ids: list[str],
json_quoted_device_ids: list[str],
) -> Select:
"""Generate a subquery to find context ids for multiple entities and multiple devices."""
union = union_all(
select_events_context_id_subquery(start_day, end_day, event_types).where(
select_events_context_id_subquery(start_day, end_day, event_type_ids).where(
_apply_event_entity_id_device_id_matchers(
json_quoted_entity_ids, json_quoted_device_ids
)
Expand All @@ -60,15 +60,15 @@ def _apply_entities_devices_context_union(
sel: Select,
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
states_metadata_ids: Collection[int],
json_quoted_entity_ids: list[str],
json_quoted_device_ids: list[str],
) -> CompoundSelect:
devices_entities_cte: CTE = _select_entities_device_id_context_ids_sub_query(
start_day,
end_day,
event_types,
event_type_ids,
states_metadata_ids,
json_quoted_entity_ids,
json_quoted_device_ids,
Expand Down Expand Up @@ -103,22 +103,22 @@ def _apply_entities_devices_context_union(
def entities_devices_stmt(
start_day: float,
end_day: float,
event_types: tuple[str, ...],
event_type_ids: tuple[int, ...],
states_metadata_ids: Collection[int],
json_quoted_entity_ids: list[str],
json_quoted_device_ids: list[str],
) -> StatementLambdaElement:
"""Generate a logbook query for multiple entities."""
stmt = lambda_stmt(
lambda: _apply_entities_devices_context_union(
select_events_without_states(start_day, end_day, event_types).where(
select_events_without_states(start_day, end_day, event_type_ids).where(
_apply_event_entity_id_device_id_matchers(
json_quoted_entity_ids, json_quoted_device_ids
)
),
start_day,
end_day,
event_types,
event_type_ids,
states_metadata_ids,
json_quoted_entity_ids,
json_quoted_device_ids,
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/recorder/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
uuid_hex_to_bytes_or_none,
)
from .database import DatabaseEngine, DatabaseOptimizer, UnsupportedDialect
from .event import extract_event_type_ids
from .state import LazyState, extract_metadata_ids, row_to_compressed_state
from .statistics import (
CalendarStatisticPeriod,
Expand Down Expand Up @@ -43,6 +44,7 @@
"bytes_to_ulid_or_none",
"bytes_to_uuid_hex_or_none",
"datetime_to_timestamp_or_none",
"extract_event_type_ids",
"extract_metadata_ids",
"process_datetime_to_timestamp",
"process_timestamp",
Expand Down
13 changes: 13 additions & 0 deletions homeassistant/components/recorder/models/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Models events in for Recorder."""
from __future__ import annotations


def extract_event_type_ids(
event_type_to_event_type_id: dict[str, int | None],
) -> list[int]:
"""Extract event_type ids from event_type_to_event_type_id."""
return [
event_type_id
for event_type_id in event_type_to_event_type_id.values()
if event_type_id is not None
]