summaryrefslogtreecommitdiff
path: root/src/handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/handlers.rs')
-rw-r--r--src/handlers.rs38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/handlers.rs b/src/handlers.rs
index 5d31600..7067f3a 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -21,6 +21,40 @@ pub async fn list_measurements(
State(pool): State<PgPool>,
AppQuery(query): AppQuery<ListQuery>,
) -> Result<Json<Vec<MeasurementView>>, AppError> {
+ Ok(Json(fetch_measurements(&pool, &query).await?))
+}
+
+pub async fn export_measurements(
+ State(pool): State<PgPool>,
+ AppQuery(query): AppQuery<ListQuery>,
+) -> Result<([(HeaderName, &'static str); 2], Vec<u8>), AppError> {
+ let rows = fetch_measurements(&pool, &query).await?;
+ let mut writer = csv::WriterBuilder::new()
+ .has_headers(false)
+ .from_writer(Vec::new());
+ writer.write_record(["id", "measured_at", "metric_type", "value", "unit"])?;
+ for row in &rows {
+ writer.serialize(row)?;
+ }
+ let csv = writer
+ .into_inner()
+ .map_err(|e| csv::Error::from(e.into_error()))?;
+ Ok((
+ [
+ (header::CONTENT_TYPE, "text/csv; charset=utf-8"),
+ (
+ header::CONTENT_DISPOSITION,
+ "attachment; filename=\"measurements.csv\"",
+ ),
+ ],
+ csv,
+ ))
+}
+
+async fn fetch_measurements(
+ pool: &PgPool,
+ query: &ListQuery,
+) -> Result<Vec<MeasurementView>, AppError> {
let limit = match query.limit {
Some(x) if (x > 0) => Some(x),
None => None,
@@ -52,9 +86,9 @@ pub async fn list_measurements(
matches!(query.order, Order::Desc),
query.metric_type
)
- .fetch_all(&pool)
+ .fetch_all(pool)
.await?;
- Ok(Json(rows))
+ Ok(rows)
}
pub async fn create_measurement(