90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
use crate::model::responses::{NearestTileResponse, TileResponse};
|
|
use axum::Error;
|
|
use chrono::{DateTime, Utc};
|
|
use sqlx::PgPool;
|
|
|
|
#[derive(Clone)]
|
|
pub struct Service {
|
|
pub pool: PgPool,
|
|
}
|
|
|
|
impl Service {
|
|
pub fn new(pool: PgPool) -> Self {
|
|
Self { pool }
|
|
}
|
|
|
|
pub async fn get_tile_data(
|
|
&self,
|
|
datetime: DateTime<Utc>,
|
|
area: &str,
|
|
) -> Result<TileResponse, Error> {
|
|
let primitive_datetime = datetime.format("%Y%m%d%H%M%S").to_string();
|
|
|
|
let record = sqlx::query!(
|
|
r#"
|
|
SELECT
|
|
id,
|
|
ingestion_time,
|
|
data_time,
|
|
source,
|
|
storage_url
|
|
FROM data_ingestion
|
|
WHERE data_time = $1 AND source = $2
|
|
"#,
|
|
datetime.naive_utc(),
|
|
area
|
|
)
|
|
.fetch_optional(&self.pool)
|
|
.await
|
|
.map_err(|e| Error::new(format!("Database error: {}", e)))?;
|
|
|
|
match record {
|
|
Some(row) => Ok(TileResponse {
|
|
id: row.id,
|
|
ingestion_time: row.ingestion_time.and_utc(),
|
|
data_time: row.data_time.and_utc(),
|
|
source: row.source,
|
|
storage_url: row.storage_url,
|
|
}),
|
|
None => Err(Error::new(format!(
|
|
"No tile data found for datetime: {} and area: {}",
|
|
primitive_datetime, area
|
|
))),
|
|
}
|
|
}
|
|
|
|
pub async fn get_nearest_tile_data(
|
|
&self,
|
|
datetime: DateTime<Utc>,
|
|
area: &str,
|
|
) -> Result<NearestTileResponse, Error> {
|
|
let primitive_datetime = datetime.format("%Y%m%d%H%M%S").to_string();
|
|
|
|
// 查找距离指定 datetime 最近的数据
|
|
let record = sqlx::query!(
|
|
r#"
|
|
SELECT
|
|
id,
|
|
data_time
|
|
FROM data_ingestion
|
|
WHERE source = $1
|
|
ORDER BY ABS(EXTRACT(EPOCH FROM (data_time - $2)))
|
|
LIMIT 1
|
|
"#,
|
|
area,
|
|
datetime.naive_utc()
|
|
)
|
|
.fetch_optional(&self.pool)
|
|
.await
|
|
.map_err(|e| Error::new(format!("Database error: {}", e)))?;
|
|
|
|
match record {
|
|
Some(row) => Ok(NearestTileResponse {
|
|
id: row.id,
|
|
nearest_data_time: row.data_time.and_utc(),
|
|
}),
|
|
None => Err(Error::new(format!("No tile data found for area: {}", area))),
|
|
}
|
|
}
|
|
}
|