From d3d4f2a40540328f1d5777a5121862515ad64698 Mon Sep 17 00:00:00 2001 From: Zeph Levy <171337931+ZephLevy@users.noreply.github.com> Date: Mon, 1 Dec 2025 11:48:39 +0100 Subject: [PATCH] Add database and location query functionality --- Cargo.lock | 4 ++++ Cargo.toml | 8 +++++++- src/resolvers.rs | 47 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9554e50..2860d8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1838,6 +1838,7 @@ checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ "base64", "bytes", + "chrono", "crc", "crossbeam-queue", "either", @@ -1915,6 +1916,7 @@ dependencies = [ "bitflags", "byteorder", "bytes", + "chrono", "crc", "digest", "dotenvy", @@ -1956,6 +1958,7 @@ dependencies = [ "base64", "bitflags", "byteorder", + "chrono", "crc", "dotenvy", "etcetera", @@ -1990,6 +1993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", + "chrono", "flume", "futures-channel", "futures-core", diff --git a/Cargo.toml b/Cargo.toml index 5fb4b62..c4e527f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,13 @@ async-graphql = "7" async-graphql-axum = "7" serde = "1" serde_json = "1" -sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls-aws-lc-rs", "postgres"] } +sqlx = { version = "0.8", features = [ + "runtime-tokio", + "tls-rustls-aws-lc-rs", + "postgres", + "chrono", + "json" +] } chrono = "0.4" dotenv = "0.15.0" anyhow = "1.0" diff --git a/src/resolvers.rs b/src/resolvers.rs index 12bb8f9..5b4c0b7 100644 --- a/src/resolvers.rs +++ b/src/resolvers.rs @@ -4,22 +4,55 @@ use sqlx::PgPool; pub struct QueryRoot; +fn get_pg_pool<'a>(ctx: &'a Context<'_>) -> &'a PgPool { + ctx.data::() + .expect("A database connection does not exist") +} + #[Object] impl QueryRoot { pub async fn datasets(&self, ctx: &Context<'_>) -> anyhow::Result> { - let pool = ctx - .data::() - .expect("A database connection does not exist"); + let pool = get_pg_pool(ctx); let rows: Vec = sqlx::query_as("SELECT * FROM datasets") .fetch_all(pool) .await?; - let result = rows.into_iter().map(|r| Dataset::from(r)).collect(); - return Ok(result); + return Ok(rows.into_iter().map(|r| Dataset::from(r)).collect()); } - async fn query_dataset(&self, id: i32) -> anyhow::Result { - unimplemented!("This doesn't work yet"); + pub async fn query_dataset( + &self, + ctx: &Context<'_>, + id: i32, + ) -> anyhow::Result> { + let pool = get_pg_pool(ctx); + + let row: Option = sqlx::query_as( + r#"SELECT * FROM records + WHERE dataset_id = $1 + ORDER BY timestamp DESC + LIMIT 1;"#, + ) + .bind(id) + .fetch_optional(pool) + .await?; + + Ok(row.map(Into::into)) + } + + pub async fn get_location(&self, ctx: &Context<'_>, id: i32) -> anyhow::Result { + let pool = get_pg_pool(ctx); + + let row: LocationRow = sqlx::query_as( + r#"SELECT * FROM locations + WHERE id = $1 + LIMIT 1;"#, + ) + .bind(id) + .fetch_one(pool) + .await?; + + Ok(row.into()) } }