ruvector_server/routes/
collections.rs1use crate::{error::Error, state::AppState, Result};
4use axum::{
5 extract::{Path, State},
6 http::StatusCode,
7 response::IntoResponse,
8 routing::{get, post},
9 Json, Router,
10};
11use ruvector_core::{types::DbOptions, DistanceMetric, VectorDB};
12use serde::{Deserialize, Serialize};
13use std::sync::Arc;
14
15#[derive(Debug, Deserialize)]
17pub struct CreateCollectionRequest {
18 pub name: String,
20 pub dimension: usize,
22 pub metric: Option<DistanceMetric>,
24}
25
26#[derive(Debug, Serialize)]
28pub struct CollectionInfo {
29 pub name: String,
31 pub dimension: usize,
33 pub metric: DistanceMetric,
35}
36
37#[derive(Debug, Serialize)]
39pub struct CollectionsList {
40 pub collections: Vec<String>,
42}
43
44pub fn routes() -> Router<AppState> {
46 Router::new()
47 .route("/", post(create_collection).get(list_collections))
48 .route("/:name", get(get_collection).delete(delete_collection))
49}
50
51async fn create_collection(
55 State(state): State<AppState>,
56 Json(req): Json<CreateCollectionRequest>,
57) -> Result<impl IntoResponse> {
58 if state.contains_collection(&req.name) {
59 return Err(Error::CollectionExists(req.name));
60 }
61
62 let mut options = DbOptions::default();
63 options.dimensions = req.dimension;
64 options.distance_metric = req.metric.unwrap_or(DistanceMetric::Cosine);
65 options.storage_path = format!("memory://{}", req.name);
67
68 let db = VectorDB::new(options.clone()).map_err(Error::Core)?;
69 state.insert_collection(req.name.clone(), Arc::new(db));
70
71 let info = CollectionInfo {
72 name: req.name,
73 dimension: req.dimension,
74 metric: options.distance_metric,
75 };
76
77 Ok((StatusCode::CREATED, Json(info)))
78}
79
80async fn list_collections(State(state): State<AppState>) -> Result<impl IntoResponse> {
84 let collections = state.collection_names();
85 Ok(Json(CollectionsList { collections }))
86}
87
88async fn get_collection(
92 State(state): State<AppState>,
93 Path(name): Path<String>,
94) -> Result<impl IntoResponse> {
95 let _db = state
96 .get_collection(&name)
97 .ok_or_else(|| Error::CollectionNotFound(name.clone()))?;
98
99 let info = CollectionInfo {
101 name,
102 dimension: 0, metric: DistanceMetric::Cosine, };
105
106 Ok(Json(info))
107}
108
109async fn delete_collection(
113 State(state): State<AppState>,
114 Path(name): Path<String>,
115) -> Result<impl IntoResponse> {
116 state
117 .remove_collection(&name)
118 .ok_or_else(|| Error::CollectionNotFound(name))?;
119
120 Ok(StatusCode::NO_CONTENT)
121}