Skip to content

Commit fc368be

Browse files
committed
Attempt single query for service and opening times
1 parent 103dd58 commit fc368be

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

application/common/dos.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,29 @@ def db_rows_to_spec_open_times(db_rows: Iterable[dict]) -> list[SpecifiedOpening
264264
return specified_opening_times
265265

266266

267+
def db_big_rows_to_spec_open_times(db_rows: Iterable[dict]) -> list[SpecifiedOpeningTime]:
268+
"""Turns a set of dos database rows into a list of SpecifiedOpenTime objects.
269+
270+
note: The rows must to be for the same service.
271+
"""
272+
specified_opening_times = []
273+
date_sorted_rows = sorted(db_rows, key=lambda row: (row["date"], row["starttime"]))
274+
for date, db_rows in groupby(date_sorted_rows, lambda row: row["date"]):
275+
is_open = True
276+
open_periods = []
277+
specified_op_times_ids = []
278+
for row in list(db_rows):
279+
if row["ssot_id"] is not None and row["ssot_id"] not in specified_op_times_ids:
280+
specified_op_times_ids.append = row["ssot_id"]
281+
if row["isclosed"] is True:
282+
is_open = False
283+
else:
284+
open_periods.append(OpenPeriod(row["starttime"], row["endtime"]))
285+
specified_opening_times.append(SpecifiedOpeningTime(open_periods, date, is_open))
286+
287+
return specified_opening_times
288+
289+
267290
def db_rows_to_std_open_times(db_rows: Iterable[dict]) -> StandardOpeningTimes:
268291
"""Turns a set of dos database rows into a StandardOpeningTime object.
269292
@@ -279,6 +302,24 @@ def db_rows_to_std_open_times(db_rows: Iterable[dict]) -> StandardOpeningTimes:
279302
return standard_opening_times
280303

281304

305+
def db_big_rows_to_std_open_times(db_rows: Iterable[dict]) -> StandardOpeningTimes:
306+
"""Turns a set of dos database rows into a StandardOpeningTime object.
307+
308+
note: The rows must be for the same service.
309+
"""
310+
standard_opening_times = StandardOpeningTimes()
311+
std_op_times_ids = []
312+
for row in db_rows:
313+
if row["sdot_id"] is not None and row["sdot_id"] not in std_op_times_ids:
314+
std_op_times_ids.append = row["sdot_id"]
315+
weekday = row["name"].lower()
316+
start = row["day_starttime"]
317+
end = row["day_endtime"]
318+
open_period = OpenPeriod(start, end)
319+
standard_opening_times.add_open_period(open_period, weekday)
320+
return standard_opening_times
321+
322+
282323
def has_palliative_care(service: DoSService, connection: Connection) -> bool:
283324
"""Checks if a service has palliative care.
284325

application/service_sync/data_processing/get_data.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from .service_histories import ServiceHistories
55
from common.dos import (
66
DoSService,
7+
db_big_rows_to_spec_open_times,
8+
db_big_rows_to_std_open_times,
79
get_specified_opening_times_from_db,
810
get_standard_opening_times_from_db,
911
has_blood_pressure,
@@ -67,3 +69,60 @@ def get_dos_service_and_history(service_id: int) -> tuple[DoSService, ServiceHis
6769
service_histories.create_service_histories_entry()
6870
# Connection closed by context manager
6971
return service, service_histories
72+
73+
74+
def get_dos_service_and_history_one_query(service_id: int) -> tuple[DoSService, ServiceHistories]:
75+
"""Retrieves DoS Services from DoS database.
76+
77+
Args:
78+
service_id (str): Id of service to retrieve
79+
80+
Returns:
81+
Tuple[DoSService, ServiceHistories]: Tuple of DoS service and service history
82+
83+
"""
84+
sql_query = (
85+
"SELECT s.id, uid, s.name, odscode, address, town, postcode, web, typeid, statusid, ss.name status_name, "
86+
"publicphone, publicname, st.name service_type_name, easting, northing, latitude, longitude, "
87+
'sdo.id as "sdo_id", sdo.dayid, otd.name, sdot.id as "sdot_id", sdot.starttime as "day_starttime", '
88+
'sdot.endtime as "day_endtime", ssod.id as "ssod_id", ssod.date, ssot.id as "ssot_id", '
89+
"ssot.starttime, ssot.endtime, ssot.isclosed "
90+
"FROM services s "
91+
"INNER JOIN servicetypes st ON s.typeid = st.id INNER JOIN servicestatuses ss on s.statusid = ss.id "
92+
"LEFT JOIN servicedayopenings sdo ON s.id = sdo.serviceid "
93+
"LEFT JOIN openingtimedays otd ON sdo.dayid = otd.id "
94+
"LEFT JOIN servicedayopeningtimes sdot ON sdo.id = sdot.servicedayopeningid "
95+
"LEFT JOIN servicespecifiedopeningdates ssod ON s.id = ssod.serviceid "
96+
"LEFT JOIN servicespecifiedopeningtimes ssot ON ssod.id = ssot.servicespecifiedopeningdateid "
97+
"WHERE s.id = %(SERVICE_ID)s"
98+
)
99+
query_vars = {"SERVICE_ID": service_id}
100+
# Connect to the DoS database
101+
with connect_to_db_writer() as connection:
102+
# Query the DoS database for the service
103+
cursor = query_dos_db(connection=connection, query=sql_query, query_vars=query_vars)
104+
rows: DictRow = cursor.fetchall()
105+
if len(rows) == 1:
106+
# Select first row (service) and create DoSService object
107+
service = DoSService(rows[0])
108+
logger.append_keys(service_name=service.name)
109+
logger.append_keys(service_uid=service.uid)
110+
logger.append_keys(type_id=service.typeid)
111+
elif not rows:
112+
msg = f"Service ID {service_id} not found"
113+
raise ValueError(msg)
114+
# Set up remaining service data
115+
service.standard_opening_times = db_big_rows_to_std_open_times(rows)
116+
service.specified_opening_times = db_big_rows_to_spec_open_times(rows)
117+
# Set up palliative care flag
118+
service.palliative_care = has_palliative_care(service=service, connection=connection)
119+
# Set up blood pressure flag
120+
service.blood_pressure = has_blood_pressure(service=service)
121+
# Set up contraception flag
122+
service.contraception = has_contraception(service=service)
123+
# Set up service history
124+
service_histories = ServiceHistories(service_id=service_id)
125+
service_histories.get_service_history_from_db(connection)
126+
service_histories.create_service_histories_entry()
127+
# Connection closed by context manager
128+
return service, service_histories

0 commit comments

Comments
 (0)