@@ -6,14 +6,16 @@ use crate::{
66} ;
77
88use axum:: { extract:: State , Json } ;
9- use chrono:: { Local , Duration } ;
9+ use chrono:: { Duration , Local } ;
10+ use migration:: Expr ;
1011use reqwest:: StatusCode ;
11- use serde:: { Serialize } ;
1212use sea_orm:: {
13- ActiveModelTrait , ColumnTrait , EntityTrait , JoinType :: InnerJoin , QueryFilter , QuerySelect ,
14- RelationTrait , Set , FromQueryResult , entity:: prelude:: DateTimeWithTimeZone , Statement , DbBackend ,
15- Value
13+ entity:: prelude:: DateTimeWithTimeZone ,
14+ ActiveModelTrait , ColumnTrait , EntityTrait , FromQueryResult , IdenStatic ,
15+ JoinType :: { self , InnerJoin } ,
16+ QueryFilter , QueryOrder , QuerySelect , RelationTrait , Set ,
1617} ;
18+ use serde:: Serialize ;
1719use tower_sessions:: Session ;
1820
1921use super :: util:: {
@@ -113,19 +115,31 @@ pub struct RecentScanItem {
113115
114116pub async fn recent ( state : State < AppState > ) -> ResponseResult < Json < Vec < RecentScanItem > > > {
115117 let fourteen_days_ago = ( Local :: now ( ) - Duration :: days ( 14 ) ) . naive_local ( ) ;
116- let scans = RecentScanItem :: find_by_statement ( Statement :: from_sql_and_values ( DbBackend :: Postgres , "
117- SELECT DISTINCT ON (s.user_id, DATE(s.scan_time)) s.id, s.scan_time
118- FROM (
119- SELECT scan.id, scan.scan_time, \" user\" .id as user_id
120- FROM scan
121- INNER JOIN card ON card.serial = scan.card_serial
122- INNER JOIN \" user\" ON \" user\" .id = card.user_id
123- WHERE scan.scan_time > $1
124- ) s
125- ORDER BY s.user_id, DATE(s.scan_time), s.id;" , [ Value :: ChronoDateTime ( Some ( Box :: new ( fourteen_days_ago) ) ) ] ) )
126- . all ( & state. db )
127- . await
128- . or_log ( ( StatusCode :: INTERNAL_SERVER_ERROR , "could not get all recent scans" ) ) ?;
118+ let scans = Scan :: find ( )
119+ . select_only ( )
120+ . expr ( Expr :: cust ( format ! (
121+ "DISTINCT ON ({}, DATE({})) scan.{}, scan.{}" , //NOTE: this is a pain
122+ card:: Column :: UserId . as_str( ) ,
123+ scan:: Column :: ScanTime . as_str( ) ,
124+ scan:: Column :: Id . as_str( ) ,
125+ scan:: Column :: ScanTime . as_str( ) ,
126+ ) ) )
127+ . join ( JoinType :: InnerJoin , scan:: Relation :: Card . def ( ) )
128+ . join ( JoinType :: InnerJoin , card:: Relation :: User . def ( ) )
129+ . filter ( scan:: Column :: ScanTime . gt ( fourteen_days_ago) )
130+ . order_by_asc ( card:: Column :: UserId )
131+ . order_by_asc ( Expr :: cust ( format ! (
132+ "DATE({})" ,
133+ scan:: Column :: ScanTime . as_str( )
134+ ) ) )
135+ . order_by_asc ( scan:: Column :: Id )
136+ . into_model :: < RecentScanItem > ( )
137+ . all ( & state. db )
138+ . await
139+ . or_log ( (
140+ StatusCode :: INTERNAL_SERVER_ERROR ,
141+ "could not get all recent scans" ,
142+ ) ) ?;
129143
130144 Ok ( Json ( scans) )
131145}
0 commit comments