2025-04-01 23:16:09 -04:00
use super ::* ;
use crate ::cache ::Cache ;
2025-04-02 11:39:51 -04:00
use crate ::model ::moderation ::AuditLogEntry ;
2025-04-01 23:16:09 -04:00
use crate ::model ::{ Error , Result , auth ::User , moderation ::Report , permissions ::FinePermission } ;
2025-04-03 15:07:57 -04:00
use crate ::{ auto_method , execute , get , query_row , query_rows , params } ;
2025-04-01 23:16:09 -04:00
#[ cfg(feature = " sqlite " ) ]
use rusqlite ::Row ;
#[ cfg(feature = " postgres " ) ]
use tokio_postgres ::Row ;
impl DataManager {
/// Get a [`Report`] from an SQL row.
pub ( crate ) fn get_report_from_row (
#[ cfg(feature = " sqlite " ) ] x : & Row < '_ > ,
#[ cfg(feature = " postgres " ) ] x : & Row ,
) -> Report {
Report {
2025-04-03 13:52:29 -04:00
id : get ! ( x ->0 ( i64 ) ) as usize ,
created : get ! ( x ->1 ( i64 ) ) as usize ,
owner : get ! ( x ->2 ( i64 ) ) as usize ,
2025-04-01 23:16:09 -04:00
content : get ! ( x ->3 ( String ) ) ,
2025-04-03 13:52:29 -04:00
asset : get ! ( x ->4 ( i64 ) ) as usize ,
2025-04-01 23:16:09 -04:00
asset_type : serde_json ::from_str ( & get! ( x ->5 ( String ) ) ) . unwrap ( ) ,
}
}
2025-04-03 15:07:57 -04:00
auto_method! ( get_report_by_id ( usize as i64 ) @ get_report_from_row -> " SELECT * FROM reports WHERE id = $1 " - - name = " report " - - returns = Report - - cache - key - tmpl = " atto.reports:{} " ) ;
2025-04-01 23:16:09 -04:00
2025-04-02 11:39:51 -04:00
/// Get all reports (paginated).
///
/// # Arguments
/// * `batch` - the limit of items in each page
/// * `page` - the page number
pub async fn get_reports ( & self , batch : usize , page : usize ) -> Result < Vec < Report > > {
let conn = match self . connect ( ) . await {
Ok ( c ) = > c ,
Err ( e ) = > return Err ( Error ::DatabaseConnection ( e . to_string ( ) ) ) ,
} ;
let res = query_rows! (
& conn ,
" SELECT * FROM reports ORDER BY created DESC LIMIT $1 OFFSET $2 " ,
2025-04-03 13:52:29 -04:00
& [ & ( batch as i64 ) , & ( ( page * batch ) as i64 ) ] ,
2025-04-02 11:39:51 -04:00
| x | { Self ::get_report_from_row ( x ) }
) ;
if res . is_err ( ) {
return Err ( Error ::GeneralNotFound ( " report " . to_string ( ) ) ) ;
}
Ok ( res . unwrap ( ) )
}
2025-04-01 23:16:09 -04:00
/// Create a new report in the database.
///
/// # Arguments
/// * `data` - a mock [`Report`] object to insert
pub async fn create_report ( & self , data : Report ) -> Result < ( ) > {
let conn = match self . connect ( ) . await {
Ok ( c ) = > c ,
Err ( e ) = > return Err ( Error ::DatabaseConnection ( e . to_string ( ) ) ) ,
} ;
let res = execute! (
& conn ,
" INSERT INTO reports VALUES ($1, $2, $3, $4, $5, $6) " ,
2025-04-03 15:07:57 -04:00
params! [
& ( data . id as i64 ) ,
& ( data . created as i64 ) ,
& ( data . owner as i64 ) ,
2025-04-01 23:16:09 -04:00
& data . content . as_str ( ) ,
2025-04-03 15:07:57 -04:00
& ( data . asset as i64 ) ,
2025-04-01 23:16:09 -04:00
& serde_json ::to_string ( & data . asset_type ) . unwrap ( ) . as_str ( ) ,
]
) ;
if let Err ( e ) = res {
return Err ( Error ::DatabaseError ( e . to_string ( ) ) ) ;
}
// return
Ok ( ( ) )
}
pub async fn delete_report ( & self , id : usize , user : User ) -> Result < ( ) > {
2025-05-22 00:36:35 -04:00
if let Err ( e ) = self . get_report_by_id ( id ) . await {
return Err ( e ) ;
}
2025-04-01 23:16:09 -04:00
if ! user . permissions . check ( FinePermission ::MANAGE_REPORTS ) {
return Err ( Error ::NotAllowed ) ;
}
let conn = match self . connect ( ) . await {
Ok ( c ) = > c ,
Err ( e ) = > return Err ( Error ::DatabaseConnection ( e . to_string ( ) ) ) ,
} ;
2025-04-03 15:07:57 -04:00
let res = execute! ( & conn , " DELETE FROM reports WHERE id = $1 " , & [ & ( id as i64 ) ] ) ;
2025-04-01 23:16:09 -04:00
if let Err ( e ) = res {
return Err ( Error ::DatabaseError ( e . to_string ( ) ) ) ;
}
self . 2. remove ( format! ( " atto.report: {} " , id ) ) . await ;
2025-04-02 11:39:51 -04:00
// create audit log entry
self . create_audit_log_entry ( AuditLogEntry ::new (
user . id ,
format! ( " invoked `delete_report` with x value ` {id} ` " ) ,
) )
. await ? ;
2025-04-01 23:16:09 -04:00
// return
Ok ( ( ) )
}
}