Spaces:
Build error
Build error
use actix_web::rt::time::Instant; | |
use actix_web::{delete, post, put, web, Responder}; | |
use actix_web_validator::{Json, Path, Query}; | |
use api::rest::schema::PointInsertOperations; | |
use api::rest::UpdateVectors; | |
use collection::operations::payload_ops::{DeletePayload, SetPayload}; | |
use collection::operations::point_ops::{PointsSelector, WriteOrdering}; | |
use collection::operations::types::UpdateResult; | |
use collection::operations::vector_ops::DeleteVectors; | |
use collection::operations::verification::new_unchecked_verification_pass; | |
use schemars::JsonSchema; | |
use segment::json_path::JsonPath; | |
use serde::{Deserialize, Serialize}; | |
use storage::content_manager::collection_verification::check_strict_mode; | |
use storage::dispatcher::Dispatcher; | |
use validator::Validate; | |
use super::CollectionPath; | |
use crate::actix::auth::ActixAccess; | |
use crate::actix::helpers::{self, process_response, process_response_error}; | |
use crate::common::points::{ | |
do_batch_update_points, do_clear_payload, do_create_index, do_delete_index, do_delete_payload, | |
do_delete_points, do_delete_vectors, do_overwrite_payload, do_set_payload, do_update_vectors, | |
do_upsert_points, CreateFieldIndex, UpdateOperations, | |
}; | |
struct FieldPath { | |
name: JsonPath, | |
} | |
pub struct UpdateParam { | |
pub wait: Option<bool>, | |
pub ordering: Option<WriteOrdering>, | |
} | |
async fn upsert_points( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<PointInsertOperations>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
// nothing to verify. | |
let pass = new_unchecked_verification_pass(); | |
let operation = operation.into_inner(); | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_upsert_points( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn delete_points( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<PointsSelector>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let operation = operation.into_inner(); | |
let pass = | |
match check_strict_mode(&operation, None, &collection.name, &dispatcher, &access).await { | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, Instant::now(), None), | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_delete_points( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn update_vectors( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<UpdateVectors>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
// Nothing to verify here. | |
let pass = new_unchecked_verification_pass(); | |
let operation = operation.into_inner(); | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_update_vectors( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn delete_vectors( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<DeleteVectors>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let timing = Instant::now(); | |
let operation = operation.into_inner(); | |
let pass = | |
match check_strict_mode(&operation, None, &collection.name, &dispatcher, &access).await { | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, timing, None), | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
let response = do_delete_vectors( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
) | |
.await; | |
process_response(response, timing, None) | |
} | |
async fn set_payload( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<SetPayload>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let operation = operation.into_inner(); | |
let pass = | |
match check_strict_mode(&operation, None, &collection.name, &dispatcher, &access).await { | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, Instant::now(), None), | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_set_payload( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn overwrite_payload( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<SetPayload>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let operation = operation.into_inner(); | |
let pass = | |
match check_strict_mode(&operation, None, &collection.name, &dispatcher, &access).await { | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, Instant::now(), None), | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_overwrite_payload( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn delete_payload( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<DeletePayload>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let operation = operation.into_inner(); | |
let pass = | |
match check_strict_mode(&operation, None, &collection.name, &dispatcher, &access).await { | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, Instant::now(), None), | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_delete_payload( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn clear_payload( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<PointsSelector>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let operation = operation.into_inner(); | |
let pass = | |
match check_strict_mode(&operation, None, &collection.name, &dispatcher, &access).await { | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, Instant::now(), None), | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
helpers::time(do_clear_payload( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
)) | |
.await | |
} | |
async fn update_batch( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operations: Json<UpdateOperations>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let timing = Instant::now(); | |
let operations = operations.into_inner(); | |
let mut vpass = None; | |
for operation in operations.operations.iter() { | |
let pass = match check_strict_mode(operation, None, &collection.name, &dispatcher, &access) | |
.await | |
{ | |
Ok(pass) => pass, | |
Err(err) => return process_response_error(err, Instant::now(), None), | |
}; | |
vpass = Some(pass); | |
} | |
// vpass == None => No update operation available | |
let Some(pass) = vpass else { | |
return process_response::<Vec<UpdateResult>>(Ok(vec![]), timing, None); | |
}; | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
let response = do_batch_update_points( | |
dispatcher.toc(&access, &pass).clone(), | |
collection.into_inner().name, | |
operations.operations, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
) | |
.await; | |
process_response(response, timing, None) | |
} | |
async fn create_field_index( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
operation: Json<CreateFieldIndex>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let timing = Instant::now(); | |
let operation = operation.into_inner(); | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
let response = do_create_index( | |
dispatcher.into_inner(), | |
collection.into_inner().name, | |
operation, | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
) | |
.await; | |
process_response(response, timing, None) | |
} | |
async fn delete_field_index( | |
dispatcher: web::Data<Dispatcher>, | |
collection: Path<CollectionPath>, | |
field: Path<FieldPath>, | |
params: Query<UpdateParam>, | |
ActixAccess(access): ActixAccess, | |
) -> impl Responder { | |
let timing = Instant::now(); | |
let wait = params.wait.unwrap_or(false); | |
let ordering = params.ordering.unwrap_or_default(); | |
let response = do_delete_index( | |
dispatcher.into_inner(), | |
collection.into_inner().name, | |
field.name.clone(), | |
None, | |
None, | |
wait, | |
ordering, | |
access, | |
) | |
.await; | |
process_response(response, timing, None) | |
} | |
// Configure services | |
pub fn config_update_api(cfg: &mut web::ServiceConfig) { | |
cfg.service(upsert_points) | |
.service(delete_points) | |
.service(update_vectors) | |
.service(delete_vectors) | |
.service(set_payload) | |
.service(overwrite_payload) | |
.service(delete_payload) | |
.service(clear_payload) | |
.service(create_field_index) | |
.service(delete_field_index) | |
.service(update_batch); | |
} | |