11use std:: collections:: HashMap ;
22
3- use chrono:: { DateTime , NaiveDateTime , Utc } ;
3+ use chrono:: NaiveDateTime ;
44use futures:: { stream:: FuturesUnordered , StreamExt } ;
55use tokio_postgres:: { Client , NoTls } ;
66use tracing:: error;
@@ -20,10 +20,8 @@ pub struct Stinfosys {
2020 levels : LevelTable ,
2121}
2222
23- type StationTotimeMap = HashMap < i32 , DateTime < Utc > > ;
24- type StationFromtimeMap = HashMap < i32 , DateTime < Utc > > ;
25- type ObsPgmTotimeMap = HashMap < MetTimeseriesKey , DateTime < Utc > > ;
26- type ObsPgmFromtimeMap = HashMap < MetTimeseriesKey , DateTime < Utc > > ;
23+ type StationFromTotimeMap = HashMap < i32 , OpenTimerange > ;
24+ type ObsPgmFromTotimeMap = HashMap < MetTimeseriesKey , OpenTimerange > ;
2725
2826impl Stinfosys {
2927 pub fn new ( conn_string : String , levels : LevelTable ) -> Self {
@@ -37,10 +35,8 @@ impl Stinfosys {
3735 & self ,
3836 ) -> Result <
3937 (
40- HashMap < MetTimeseriesKey , DateTime < Utc > > ,
41- HashMap < MetTimeseriesKey , DateTime < Utc > > ,
42- HashMap < i32 , DateTime < Utc > > ,
43- HashMap < i32 , DateTime < Utc > > ,
38+ HashMap < MetTimeseriesKey , OpenTimerange > ,
39+ HashMap < i32 , OpenTimerange > ,
4440 ) ,
4541 Error ,
4642 > {
@@ -53,27 +49,18 @@ impl Stinfosys {
5349 } ) ;
5450
5551 // Fetch all deactivated timeseries in Stinfosys
56- let ( obs_pgm_fromtime, obs_pgm_totime, station_fromtime, station_totime) = tokio:: try_join!(
57- fetch_obs_pgm_fromtime( self . levels. clone( ) , & client) ,
58- fetch_obs_pgm_totime( self . levels. clone( ) , & client) ,
59- fetch_station_fromtime( & client) ,
60- fetch_station_totime( & client) ,
52+ let ( obs_pgm_times, station_times) = tokio:: try_join!(
53+ fetch_obs_pgm_times( self . levels. clone( ) , & client) ,
54+ fetch_station_times( & client) ,
6155 ) ?;
6256
63- Ok ( (
64- obs_pgm_fromtime,
65- obs_pgm_totime,
66- station_fromtime,
67- station_totime,
68- ) )
57+ Ok ( ( obs_pgm_times, station_times) )
6958 }
7059}
7160
7261pub async fn fetch_from_to_for_update (
73- obs_pgm_fromtime : & HashMap < MetTimeseriesKey , DateTime < Utc > > ,
74- obs_pgm_totime : & HashMap < MetTimeseriesKey , DateTime < Utc > > ,
75- station_fromtime : & HashMap < i32 , DateTime < Utc > > ,
76- station_totime : & HashMap < i32 , DateTime < Utc > > ,
62+ obs_pgm_times : & HashMap < MetTimeseriesKey , OpenTimerange > ,
63+ station_times : & HashMap < i32 , OpenTimerange > ,
7764 ts_from_to : HashMap < i64 , OpenTimerange > ,
7865 labels : Vec < MetLabel > ,
7966) -> Result < Vec < TSupdateTimeseries > , Error > {
@@ -83,15 +70,21 @@ pub async fn fetch_from_to_for_update(
8370 // check we have this key for the TS
8471 if ts_from_to. contains_key ( & label. id ) {
8572 // use obs_pgm if exists, or else station if exists, or else will be none
86- let fromtime = obs_pgm_fromtime
87- . get ( & label. key )
88- . or ( station_fromtime. get ( & label. key . station_id ) )
89- . copied ( ) ;
90-
91- let totime = obs_pgm_totime
92- . get ( & label. key )
93- . or ( station_totime. get ( & label. key . station_id ) )
94- . copied ( ) ;
73+ let fromtime = match obs_pgm_times. get ( & label. key ) {
74+ Some ( pgm_fromto) => pgm_fromto. from ,
75+ None => match station_times. get ( & label. key . station_id ) {
76+ Some ( station_fromto) => station_fromto. from ,
77+ None => None ,
78+ } ,
79+ } ;
80+
81+ let totime = match obs_pgm_times. get ( & label. key ) {
82+ Some ( pgm_fromto) => pgm_fromto. to ,
83+ None => match station_times. get ( & label. key . station_id ) {
84+ Some ( station_fromto) => station_fromto. to ,
85+ None => None ,
86+ } ,
87+ } ;
9588
9689 if fromtime. is_none ( ) && totime. is_none ( ) {
9790 // no metadata, keep the ts from/to
@@ -160,7 +153,10 @@ pub async fn fetch_from_to_for_update(
160153 Ok ( ts_update)
161154}
162155
163- async fn fetch_obs_pgm_totime ( levels : LevelTable , conn : & Client ) -> Result < ObsPgmTotimeMap , Error > {
156+ async fn fetch_obs_pgm_times (
157+ levels : LevelTable ,
158+ conn : & Client ,
159+ ) -> Result < ObsPgmFromTotimeMap , Error > {
164160 // The funny looking ARRAY_AGG is needed because each timeseries can have multiple from/to times.
165161 // Most likely related to the fact that stations in the `station` tables can also have
166162 // multiple entries, see [fetch_station_totime]
@@ -174,54 +170,15 @@ async fn fetch_obs_pgm_totime(levels: LevelTable, conn: &Client) -> Result<ObsPg
174170 hlevel, \
175171 nsensor, \
176172 priority_messageid, \
173+ MIN(fromtime), \
177174 (ARRAY_AGG(totime ORDER BY totime DESC NULLS FIRST))[1] \
178175 FROM obs_pgm \
179176 GROUP BY stationid, paramid, hlevel, nsensor, priority_messageid \
180177 HAVING (ARRAY_AGG(totime ORDER BY totime DESC NULLS FIRST))[1] IS NOT NULL";
181178
182179 let rows = conn. query ( OBS_PGM_QUERY , & [ ] ) . await ?;
183180
184- let mut map = ObsPgmTotimeMap :: new ( ) ;
185- for row in rows {
186- let param_id: i32 = row. get ( 1 ) ;
187-
188- let level = row. get ( 2 ) ;
189- let level = param_get_level ( levels. clone ( ) , param_id, level) ?;
190-
191- let key = MetTimeseriesKey {
192- station_id : row. get ( 0 ) ,
193- param_id,
194- level,
195- sensor : row. get ( 3 ) ,
196- type_id : row. get ( 4 ) ,
197- } ;
198-
199- let totime: NaiveDateTime = row. get ( 5 ) ;
200- map. insert ( key, totime. and_utc ( ) ) ;
201- }
202-
203- Ok ( map)
204- }
205-
206- async fn fetch_obs_pgm_fromtime (
207- levels : LevelTable ,
208- conn : & Client ,
209- ) -> Result < ObsPgmFromtimeMap , Error > {
210- const OBS_PGM_QUERY : & str = "\
211- SELECT \
212- stationid, \
213- paramid, \
214- hlevel, \
215- nsensor, \
216- priority_messageid, \
217- (ARRAY_AGG(fromtime ORDER BY fromtime ASC))[1] \
218- FROM obs_pgm \
219- GROUP BY stationid, paramid, hlevel, nsensor, priority_messageid \
220- HAVING (ARRAY_AGG(fromtime ORDER BY fromtime ASC))[1] IS NOT NULL";
221-
222- let rows = conn. query ( OBS_PGM_QUERY , & [ ] ) . await ?;
223-
224- let mut map = ObsPgmFromtimeMap :: new ( ) ;
181+ let mut map = ObsPgmFromTotimeMap :: new ( ) ;
225182 for row in rows {
226183 let param_id: i32 = row. get ( 1 ) ;
227184
@@ -236,14 +193,21 @@ async fn fetch_obs_pgm_fromtime(
236193 type_id : row. get ( 4 ) ,
237194 } ;
238195
239- let totime: NaiveDateTime = row. get ( 5 ) ;
240- map. insert ( key, totime. and_utc ( ) ) ;
196+ let fromtime: NaiveDateTime = row. get ( 5 ) ;
197+ let totime: NaiveDateTime = row. get ( 6 ) ;
198+ map. insert (
199+ key,
200+ OpenTimerange {
201+ from : Some ( fromtime. and_utc ( ) ) ,
202+ to : Some ( totime. and_utc ( ) ) ,
203+ } ,
204+ ) ;
241205 }
242206
243207 Ok ( map)
244208}
245209
246- async fn fetch_station_totime ( conn : & Client ) -> Result < StationTotimeMap , Error > {
210+ async fn fetch_station_times ( conn : & Client ) -> Result < StationFromTotimeMap , Error > {
247211 // The funny looking ARRAY_AGG is needed because each station can have multiple from/to times.
248212 // For example, the timeseries might have been "reset" after a change of the station position,
249213 // even though the station ID did not change.
@@ -253,6 +217,7 @@ async fn fetch_station_totime(conn: &Client) -> Result<StationTotimeMap, Error>
253217 const STATION_QUERY : & str = "\
254218 SELECT \
255219 stationid, \
220+ MIN(fromtime), \
256221 (ARRAY_AGG(totime ORDER BY totime DESC NULLS FIRST))[1] \
257222 FROM station \
258223 GROUP BY stationid \
@@ -263,30 +228,16 @@ async fn fetch_station_totime(conn: &Client) -> Result<StationTotimeMap, Error>
263228 Ok ( rows
264229 . iter ( )
265230 . map ( |row| {
266- let totime: NaiveDateTime = row. get ( 1 ) ;
267-
268- ( row. get ( 0 ) , totime. and_utc ( ) )
269- } )
270- . collect ( ) )
271- }
272-
273- async fn fetch_station_fromtime ( conn : & Client ) -> Result < StationFromtimeMap , Error > {
274- const STATION_QUERY : & str = "\
275- SELECT \
276- stationid, \
277- (ARRAY_AGG(fromtime ORDER BY fromtime ASC))[1] \
278- FROM station \
279- GROUP BY stationid \
280- HAVING (ARRAY_AGG(fromtime ORDER BY fromtime ASC))[1] IS NOT NULL";
281-
282- let rows = conn. query ( STATION_QUERY , & [ ] ) . await ?;
283-
284- Ok ( rows
285- . iter ( )
286- . map ( |row| {
287- let totime: NaiveDateTime = row. get ( 1 ) ;
288-
289- ( row. get ( 0 ) , totime. and_utc ( ) )
231+ let fromtime: NaiveDateTime = row. get ( 1 ) ;
232+ let totime: NaiveDateTime = row. get ( 2 ) ;
233+
234+ (
235+ row. get ( 0 ) ,
236+ OpenTimerange {
237+ from : Some ( fromtime. and_utc ( ) ) ,
238+ to : Some ( totime. and_utc ( ) ) ,
239+ } ,
240+ )
290241 } )
291242 . collect ( ) )
292243}
0 commit comments