diff --git a/Cargo.lock b/Cargo.lock index f48df72..499386f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,6 +271,7 @@ checksum = "e8496eeb328dce26ee9d9b73275d396d9bddb433fa30106cf6056dd8c3c2764c" dependencies = [ "bitflags", "byteorder", + "chrono", "diesel_derives", "downcast-rs", "itoa", diff --git a/Cargo.toml b/Cargo.toml index f88f542..2038aaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,5 @@ rocket = { version = "0.5.1", features = ["json"] } serde = { version = "1.0.228", features = ["derive"] } dotenv = "0.15.0" uuid = { version = "1.18.1", features = ["v4", "serde"] } -diesel = { version = "2.3.2", features = ["postgres", "uuid"] } +diesel = { version = "2.3.2", features = ["postgres", "uuid", "chrono"] } chrono = "0.4.42" diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..e660e7e --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1 @@ +pub mod tracker; diff --git a/src/api/tracker.rs b/src/api/tracker.rs new file mode 100644 index 0000000..2d6cc4f --- /dev/null +++ b/src/api/tracker.rs @@ -0,0 +1,29 @@ +use crate::dtos::TrackerDTO; +use crate::models::{AppState, Tracker}; +use crate::schema::trackers::dsl::trackers; +use diesel::{QueryDsl, RunQueryDsl, SelectableHelper}; +use rocket::State; +use rocket::serde::json::Json; + +#[get("/?&")] +pub fn index( + offset: Option, + limit: Option, + data: &State, +) -> Json> { + let mut db = data.db.lock().unwrap(); + + let offset = offset.unwrap_or(0); + let limit = limit.unwrap_or(10); + + println!("hey"); + let results = trackers + .offset(offset) + .limit(limit) + .select(Tracker::as_select()) + .load(&mut *db) + .expect("Error loading trackers"); + + println!("hi"); + Json(results.iter().map(TrackerDTO::from).collect()) +} diff --git a/src/dtos.rs b/src/dtos.rs new file mode 100644 index 0000000..43e3c02 --- /dev/null +++ b/src/dtos.rs @@ -0,0 +1,41 @@ +use chrono::{DateTime, Utc}; +use crate::models::{Hit, Tracker}; +use serde::Serialize; + +#[derive(Serialize)] +pub struct TrackerDTO { + pub id: String, + pub created_at: String, +} + +impl TrackerDTO { + pub fn from(tracker: &Tracker) -> TrackerDTO { + TrackerDTO { + id: tracker.id.to_string(), + created_at: tracker.created_at.to_string(), + } + } +} + +#[derive(Serialize)] +pub struct HitDTO { + pub id: String, + pub tracker_id: String, + pub ip: String, + pub agent: Option, + pub language: Option, + pub created_at: String, +} + +impl HitDTO { + pub fn from(hit: &Hit) -> HitDTO { + HitDTO { + id: hit.id.to_string(), + tracker_id: hit.tracker_id.to_string(), + ip: hit.ip.clone(), + agent: hit.agent.clone(), + language: hit.language.clone(), + created_at: hit.created_at.to_string(), + } + } +} diff --git a/src/main.rs b/src/main.rs index b184eb7..a72880b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,9 @@ +mod api; mod models; mod schema; -mod tracker; +mod dtos; +use crate::api::tracker; use crate::models::Hit; use crate::schema::hits::dsl::*; use diesel::{Connection, PgConnection, QueryDsl, RunQueryDsl, SelectableHelper}; @@ -30,7 +32,9 @@ fn rocket() -> _ { .expect("Error loading hits"); println!("results: {}", results.len()); + let app_data = models::AppState::new(db); rocket::build() + .manage(app_data) .mount("/", routes![index]) .mount("/tracker", routes![tracker::index]) } diff --git a/src/models.rs b/src/models.rs index c72a5f4..cd99ede 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,16 +1,17 @@ -use diesel::{Insertable, Queryable, Selectable}; -use diesel::data_types::PgTimestamp; +use chrono::NaiveDateTime; +use diesel::{PgConnection, Queryable, Selectable}; +use std::sync::{Arc, Mutex}; use uuid::Uuid; -#[derive(Queryable, Selectable, Insertable, Clone)] +#[derive(Queryable, Selectable, Clone)] #[diesel(table_name = crate::schema::trackers)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct Tracker { pub id: Uuid, - pub created_at: PgTimestamp, + pub created_at: NaiveDateTime, } -#[derive(Queryable, Selectable, Insertable, Clone)] +#[derive(Queryable, Selectable, Clone)] #[diesel(table_name = crate::schema::hits)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct Hit { @@ -19,5 +20,17 @@ pub struct Hit { pub ip: String, pub agent: Option, pub language: Option, - pub created_at: PgTimestamp, + pub created_at: NaiveDateTime, +} + +pub struct AppState { + pub db: Arc>, +} + +impl AppState { + pub fn new(db: PgConnection) -> Self { + AppState { + db: Arc::new(Mutex::new(db)), + } + } } diff --git a/src/tracker.rs b/src/tracker.rs deleted file mode 100644 index d84f098..0000000 --- a/src/tracker.rs +++ /dev/null @@ -1,13 +0,0 @@ -use serde::Serialize; -use uuid::Uuid; - -#[derive(Serialize)] -pub struct Tracker { - pub id: Uuid, - pub created_at: String, -} - -#[get("/")] -pub fn index() -> &'static str { - "Tracker" -}