@@ -6,14 +6,16 @@ use crate::{
6
6
} ;
7
7
8
8
use axum:: { extract:: State , Json } ;
9
- use chrono:: { Local , Duration } ;
9
+ use chrono:: { Duration , Local } ;
10
+ use migration:: Expr ;
10
11
use reqwest:: StatusCode ;
11
- use serde:: { Serialize } ;
12
12
use 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 ,
16
17
} ;
18
+ use serde:: Serialize ;
17
19
use tower_sessions:: Session ;
18
20
19
21
use super :: util:: {
@@ -113,19 +115,31 @@ pub struct RecentScanItem {
113
115
114
116
pub async fn recent ( state : State < AppState > ) -> ResponseResult < Json < Vec < RecentScanItem > > > {
115
117
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
+ ) ) ?;
129
143
130
144
Ok ( Json ( scans) )
131
145
}
0 commit comments