38 lines
1.3 KiB
Rust
38 lines
1.3 KiB
Rust
use scylla::Session;
|
|
use std::sync::Arc;
|
|
use crate::domain::node::MapNode;
|
|
use std::error::Error;
|
|
|
|
#[cfg_attr(test, mockall::automock)]
|
|
#[async_trait::async_trait]
|
|
pub trait NodeRepositoryTrait: Send + Sync {
|
|
async fn find_nodes_in_tile(&self, z: i32, x: i32, y: i32) -> Result<Vec<MapNode>, Box<dyn Error + Send + Sync>>;
|
|
}
|
|
|
|
pub struct NodeRepository {
|
|
session: Arc<Session>,
|
|
}
|
|
|
|
impl NodeRepository {
|
|
pub fn new(session: Arc<Session>) -> Self {
|
|
Self { session }
|
|
}
|
|
}
|
|
|
|
#[async_trait::async_trait]
|
|
impl NodeRepositoryTrait for NodeRepository {
|
|
async fn find_nodes_in_tile(&self, z: i32, x: i32, y: i32) -> Result<Vec<MapNode>, Box<dyn Error + Send + Sync>> {
|
|
let query = "SELECT id, lat, lon, tags FROM map_data.nodes WHERE zoom = ? AND tile_x = ? AND tile_y = ?";
|
|
let rows = self.session.query(query, (z, x, y)).await?.rows.unwrap_or_default();
|
|
|
|
let mut nodes = Vec::with_capacity(rows.len());
|
|
for row in rows {
|
|
let (id, lat, lon, tags) = row.into_typed::<(i64, f64, f64, std::collections::HashMap<String, String>)>()
|
|
.map_err(|e| Box::<dyn Error + Send + Sync>::from(format!("Serialization error: {}", e)))?;
|
|
|
|
nodes.push(MapNode { id, lat, lon, tags });
|
|
}
|
|
Ok(nodes)
|
|
}
|
|
}
|