@@ -80,32 +80,69 @@ impl Storage {
8080 & self ,
8181 sensor_id : Option < & str > ,
8282 hours : u32 ,
83+ max_points : Option < u32 > ,
8384 ) -> rusqlite:: Result < Vec < SensorReading > > {
8485 let conn = self . conn . lock ( ) . await ;
8586 let cutoff = format ! ( "-{hours} hours" ) ;
8687
87- if let Some ( sid) = sensor_id {
88- let mut stmt = conn. prepare_cached (
89- "SELECT sensor_id, sensor_name, temperature, room_type, recorded_at
90- FROM sensor_readings
91- WHERE sensor_id = ?1 AND recorded_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', ?2)
92- ORDER BY recorded_at ASC" ,
93- ) ?;
94- let rows = stmt
95- . query_map ( rusqlite:: params![ sid, cutoff] , row_to_reading) ?
96- . collect :: < rusqlite:: Result < Vec < _ > > > ( ) ?;
97- Ok ( rows)
98- } else {
99- let mut stmt = conn. prepare_cached (
100- "SELECT sensor_id, sensor_name, temperature, room_type, recorded_at
101- FROM sensor_readings
102- WHERE recorded_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', ?1)
103- ORDER BY recorded_at ASC" ,
104- ) ?;
105- let rows = stmt
106- . query_map ( rusqlite:: params![ cutoff] , row_to_reading) ?
107- . collect :: < rusqlite:: Result < Vec < _ > > > ( ) ?;
108- Ok ( rows)
88+ match ( sensor_id, max_points) {
89+ ( Some ( sid) , Some ( max) ) => {
90+ let mut stmt = conn. prepare_cached (
91+ "SELECT sensor_id, sensor_name, temperature, room_type, recorded_at
92+ FROM (
93+ SELECT sensor_id, sensor_name, temperature, room_type, recorded_at,
94+ ROW_NUMBER() OVER (ORDER BY recorded_at) AS rn,
95+ COUNT(*) OVER () AS total
96+ FROM sensor_readings
97+ WHERE sensor_id = ?1
98+ AND recorded_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', ?2)
99+ )
100+ WHERE (rn - 1) % MAX(1, (total + ?3 - 1) / ?3) = 0
101+ ORDER BY recorded_at ASC" ,
102+ ) ?;
103+ let rows = stmt. query_map ( rusqlite:: params![ sid, cutoff, max] , row_to_reading) ?
104+ . collect :: < rusqlite:: Result < Vec < _ > > > ( ) ;
105+ rows
106+ }
107+ ( Some ( sid) , None ) => {
108+ let mut stmt = conn. prepare_cached (
109+ "SELECT sensor_id, sensor_name, temperature, room_type, recorded_at
110+ FROM sensor_readings
111+ WHERE sensor_id = ?1 AND recorded_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', ?2)
112+ ORDER BY recorded_at ASC" ,
113+ ) ?;
114+ let rows = stmt. query_map ( rusqlite:: params![ sid, cutoff] , row_to_reading) ?
115+ . collect :: < rusqlite:: Result < Vec < _ > > > ( ) ;
116+ rows
117+ }
118+ ( None , Some ( max) ) => {
119+ let mut stmt = conn. prepare_cached (
120+ "SELECT sensor_id, sensor_name, temperature, room_type, recorded_at
121+ FROM (
122+ SELECT sensor_id, sensor_name, temperature, room_type, recorded_at,
123+ ROW_NUMBER() OVER (PARTITION BY sensor_id ORDER BY recorded_at) AS rn,
124+ COUNT(*) OVER (PARTITION BY sensor_id) AS total
125+ FROM sensor_readings
126+ WHERE recorded_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', ?1)
127+ )
128+ WHERE (rn - 1) % MAX(1, (total + ?2 - 1) / ?2) = 0
129+ ORDER BY recorded_at ASC" ,
130+ ) ?;
131+ let rows = stmt. query_map ( rusqlite:: params![ cutoff, max] , row_to_reading) ?
132+ . collect :: < rusqlite:: Result < Vec < _ > > > ( ) ;
133+ rows
134+ }
135+ ( None , None ) => {
136+ let mut stmt = conn. prepare_cached (
137+ "SELECT sensor_id, sensor_name, temperature, room_type, recorded_at
138+ FROM sensor_readings
139+ WHERE recorded_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', ?1)
140+ ORDER BY recorded_at ASC" ,
141+ ) ?;
142+ let rows = stmt. query_map ( rusqlite:: params![ cutoff] , row_to_reading) ?
143+ . collect :: < rusqlite:: Result < Vec < _ > > > ( ) ;
144+ rows
145+ }
109146 }
110147 }
111148
0 commit comments