2021-07-06 11:54:37 +02:00
|
|
|
use std::{
|
2022-07-04 12:00:03 +02:00
|
|
|
fmt::Write,
|
2021-07-06 11:54:37 +02:00
|
|
|
panic::{catch_unwind, resume_unwind, UnwindSafe},
|
|
|
|
time::Duration,
|
|
|
|
};
|
2021-02-18 22:10:50 +01:00
|
|
|
|
2021-02-18 19:50:52 +01:00
|
|
|
use actix_web::http::StatusCode;
|
|
|
|
use serde_json::{json, Value};
|
2021-03-10 14:47:04 +01:00
|
|
|
use tokio::time::sleep;
|
2022-10-09 19:43:51 +02:00
|
|
|
use urlencoding::encode as urlencode;
|
2021-02-18 19:50:52 +01:00
|
|
|
|
|
|
|
use super::service::Service;
|
|
|
|
|
2022-10-09 19:43:51 +02:00
|
|
|
use super::encoder::Encoder;
|
|
|
|
|
2021-02-18 19:50:52 +01:00
|
|
|
pub struct Index<'a> {
|
|
|
|
pub uid: String,
|
|
|
|
pub service: &'a Service,
|
2022-10-09 19:43:51 +02:00
|
|
|
pub encoder: Encoder,
|
2021-02-18 19:50:52 +01:00
|
|
|
}
|
|
|
|
|
2021-04-20 12:07:22 +02:00
|
|
|
#[allow(dead_code)]
|
2021-02-18 19:50:52 +01:00
|
|
|
impl Index<'_> {
|
|
|
|
pub async fn get(&self) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}", urlencode(self.uid.as_ref()));
|
2021-02-18 19:50:52 +01:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
|
|
|
|
2021-02-19 19:55:00 +01:00
|
|
|
pub async fn load_test_set(&self) -> u64 {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/documents", urlencode(self.uid.as_ref()));
|
2021-03-15 18:11:10 +01:00
|
|
|
let (response, code) = self
|
|
|
|
.service
|
|
|
|
.post_str(url, include_str!("../assets/test_set.json"))
|
|
|
|
.await;
|
2021-03-17 13:54:17 +01:00
|
|
|
assert_eq!(code, 202);
|
2022-05-17 11:17:32 +02:00
|
|
|
let update_id = response["taskUid"].as_i64().unwrap();
|
2021-12-02 16:03:26 +01:00
|
|
|
self.wait_task(update_id as u64).await;
|
2021-02-19 19:55:00 +01:00
|
|
|
update_id as u64
|
|
|
|
}
|
|
|
|
|
2021-05-31 16:03:39 +02:00
|
|
|
pub async fn create(&self, primary_key: Option<&str>) -> (Value, StatusCode) {
|
2021-02-18 19:50:52 +01:00
|
|
|
let body = json!({
|
|
|
|
"uid": self.uid,
|
|
|
|
"primaryKey": primary_key,
|
|
|
|
});
|
2022-10-09 19:43:51 +02:00
|
|
|
self.service
|
|
|
|
.post_encoded("/indexes", body, self.encoder)
|
|
|
|
.await
|
2021-02-18 19:50:52 +01:00
|
|
|
}
|
2021-02-18 20:28:10 +01:00
|
|
|
|
|
|
|
pub async fn update(&self, primary_key: Option<&str>) -> (Value, StatusCode) {
|
|
|
|
let body = json!({
|
|
|
|
"primaryKey": primary_key,
|
|
|
|
});
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}", urlencode(self.uid.as_ref()));
|
2021-02-18 20:28:10 +01:00
|
|
|
|
2022-10-09 19:43:51 +02:00
|
|
|
self.service.patch_encoded(url, body, self.encoder).await
|
2021-02-18 20:28:10 +01:00
|
|
|
}
|
2021-02-18 20:44:33 +01:00
|
|
|
|
|
|
|
pub async fn delete(&self) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}", urlencode(self.uid.as_ref()));
|
2021-02-18 20:44:33 +01:00
|
|
|
self.service.delete(url).await
|
|
|
|
}
|
2021-02-18 22:10:50 +01:00
|
|
|
|
|
|
|
pub async fn add_documents(
|
|
|
|
&self,
|
|
|
|
documents: Value,
|
|
|
|
primary_key: Option<&str>,
|
|
|
|
) -> (Value, StatusCode) {
|
|
|
|
let url = match primary_key {
|
2021-11-03 14:25:49 +01:00
|
|
|
Some(key) => format!(
|
|
|
|
"/indexes/{}/documents?primaryKey={}",
|
2022-10-09 19:43:51 +02:00
|
|
|
urlencode(self.uid.as_ref()),
|
2021-11-03 14:25:49 +01:00
|
|
|
key
|
|
|
|
),
|
2022-10-09 19:43:51 +02:00
|
|
|
None => format!("/indexes/{}/documents", urlencode(self.uid.as_ref())),
|
2021-02-18 22:10:50 +01:00
|
|
|
};
|
2022-10-09 19:43:51 +02:00
|
|
|
self.service
|
|
|
|
.post_encoded(url, documents, self.encoder)
|
|
|
|
.await
|
2021-02-18 22:10:50 +01:00
|
|
|
}
|
|
|
|
|
2021-03-15 18:11:10 +01:00
|
|
|
pub async fn update_documents(
|
|
|
|
&self,
|
|
|
|
documents: Value,
|
|
|
|
primary_key: Option<&str>,
|
|
|
|
) -> (Value, StatusCode) {
|
2021-02-19 19:55:00 +01:00
|
|
|
let url = match primary_key {
|
2021-11-03 14:25:49 +01:00
|
|
|
Some(key) => format!(
|
|
|
|
"/indexes/{}/documents?primaryKey={}",
|
2022-10-09 19:43:51 +02:00
|
|
|
urlencode(self.uid.as_ref()),
|
2021-11-03 14:25:49 +01:00
|
|
|
key
|
|
|
|
),
|
2022-10-09 19:43:51 +02:00
|
|
|
None => format!("/indexes/{}/documents", urlencode(self.uid.as_ref())),
|
2021-02-19 19:55:00 +01:00
|
|
|
};
|
2022-10-09 19:43:51 +02:00
|
|
|
self.service.put_encoded(url, documents, self.encoder).await
|
2021-02-19 19:55:00 +01:00
|
|
|
}
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
pub async fn wait_task(&self, update_id: u64) -> Value {
|
2022-06-08 12:11:35 +02:00
|
|
|
// try several times to get status, or panic to not wait forever
|
2021-12-02 16:03:26 +01:00
|
|
|
let url = format!("/tasks/{}", update_id);
|
2022-06-08 12:11:35 +02:00
|
|
|
for _ in 0..100 {
|
2021-02-18 22:10:50 +01:00
|
|
|
let (response, status_code) = self.service.get(&url).await;
|
2022-05-23 17:03:28 +02:00
|
|
|
assert_eq!(200, status_code, "response: {}", response);
|
2021-02-18 22:10:50 +01:00
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
if response["status"] == "succeeded" || response["status"] == "failed" {
|
2021-02-22 16:03:17 +01:00
|
|
|
return response;
|
2021-02-18 22:10:50 +01:00
|
|
|
}
|
|
|
|
|
2022-06-08 12:11:35 +02:00
|
|
|
// wait 0.5 second.
|
|
|
|
sleep(Duration::from_millis(500)).await;
|
2021-02-18 22:10:50 +01:00
|
|
|
}
|
|
|
|
panic!("Timeout waiting for update id");
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
pub async fn get_task(&self, update_id: u64) -> (Value, StatusCode) {
|
2022-05-17 16:08:23 +02:00
|
|
|
let url = format!("/tasks/{}", update_id);
|
2021-02-18 22:10:50 +01:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
pub async fn list_tasks(&self) -> (Value, StatusCode) {
|
2022-05-17 16:08:23 +02:00
|
|
|
let url = format!("/tasks?indexUid={}", self.uid);
|
2021-02-18 22:10:50 +01:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
2021-02-19 19:55:00 +01:00
|
|
|
|
2022-05-18 12:07:06 +02:00
|
|
|
pub async fn filtered_tasks(&self, type_: &[&str], status: &[&str]) -> (Value, StatusCode) {
|
|
|
|
let mut url = format!("/tasks?indexUid={}", self.uid);
|
|
|
|
if !type_.is_empty() {
|
2022-07-04 12:00:03 +02:00
|
|
|
let _ = write!(url, "&type={}", type_.join(","));
|
2022-05-18 12:07:06 +02:00
|
|
|
}
|
|
|
|
if !status.is_empty() {
|
2022-07-04 12:00:03 +02:00
|
|
|
let _ = write!(url, "&status={}", status.join(","));
|
2022-05-18 12:07:06 +02:00
|
|
|
}
|
|
|
|
self.service.get(url).await
|
|
|
|
}
|
|
|
|
|
2021-03-15 18:11:10 +01:00
|
|
|
pub async fn get_document(
|
|
|
|
&self,
|
|
|
|
id: u64,
|
2022-05-25 11:51:26 +02:00
|
|
|
options: Option<GetDocumentOptions>,
|
2021-03-15 18:11:10 +01:00
|
|
|
) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let mut url = format!("/indexes/{}/documents/{}", urlencode(self.uid.as_ref()), id);
|
2022-05-25 11:51:26 +02:00
|
|
|
if let Some(fields) = options.and_then(|o| o.fields) {
|
2022-07-04 12:00:03 +02:00
|
|
|
let _ = write!(url, "?fields={}", fields.join(","));
|
2022-05-25 11:51:26 +02:00
|
|
|
}
|
2021-02-19 19:55:00 +01:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
|
|
|
|
2021-02-22 14:23:17 +01:00
|
|
|
pub async fn get_all_documents(&self, options: GetAllDocumentsOptions) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let mut url = format!("/indexes/{}/documents?", urlencode(self.uid.as_ref()));
|
2021-02-22 14:23:17 +01:00
|
|
|
if let Some(limit) = options.limit {
|
2022-07-04 12:00:03 +02:00
|
|
|
let _ = write!(url, "limit={}&", limit);
|
2021-02-22 14:23:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(offset) = options.offset {
|
2022-07-04 12:00:03 +02:00
|
|
|
let _ = write!(url, "offset={}&", offset);
|
2021-02-22 14:23:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(attributes_to_retrieve) = options.attributes_to_retrieve {
|
2022-07-04 12:00:03 +02:00
|
|
|
let _ = write!(url, "fields={}&", attributes_to_retrieve.join(","));
|
2021-02-22 14:23:17 +01:00
|
|
|
}
|
|
|
|
|
2021-02-19 19:55:00 +01:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
2021-02-22 16:03:17 +01:00
|
|
|
|
|
|
|
pub async fn delete_document(&self, id: u64) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/documents/{}", urlencode(self.uid.as_ref()), id);
|
2021-02-22 16:03:17 +01:00
|
|
|
self.service.delete(url).await
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn clear_all_documents(&self) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/documents", urlencode(self.uid.as_ref()));
|
2021-02-22 16:03:17 +01:00
|
|
|
self.service.delete(url).await
|
|
|
|
}
|
2021-02-23 14:13:43 +01:00
|
|
|
|
|
|
|
pub async fn delete_batch(&self, ids: Vec<u64>) -> (Value, StatusCode) {
|
2021-11-03 14:25:49 +01:00
|
|
|
let url = format!(
|
|
|
|
"/indexes/{}/documents/delete-batch",
|
2022-10-09 19:43:51 +02:00
|
|
|
urlencode(self.uid.as_ref())
|
2021-11-03 14:25:49 +01:00
|
|
|
);
|
2021-03-15 18:11:10 +01:00
|
|
|
self.service
|
2022-10-09 19:43:51 +02:00
|
|
|
.post_encoded(url, serde_json::to_value(&ids).unwrap(), self.encoder)
|
2021-03-15 18:11:10 +01:00
|
|
|
.await
|
2021-02-23 14:13:43 +01:00
|
|
|
}
|
2021-02-24 09:30:51 +01:00
|
|
|
|
|
|
|
pub async fn settings(&self) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/settings", urlencode(self.uid.as_ref()));
|
2021-02-24 09:30:51 +01:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn update_settings(&self, settings: Value) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/settings", urlencode(self.uid.as_ref()));
|
2022-10-10 11:04:46 +02:00
|
|
|
self.service
|
|
|
|
.patch_encoded(url, settings, self.encoder)
|
|
|
|
.await
|
2021-02-24 09:30:51 +01:00
|
|
|
}
|
2021-02-24 10:14:36 +01:00
|
|
|
|
|
|
|
pub async fn delete_settings(&self) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/settings", urlencode(self.uid.as_ref()));
|
2021-02-24 10:14:36 +01:00
|
|
|
self.service.delete(url).await
|
|
|
|
}
|
2021-04-01 20:54:37 +02:00
|
|
|
|
|
|
|
pub async fn stats(&self) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/stats", urlencode(self.uid.as_ref()));
|
2021-04-01 20:54:37 +02:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
2021-04-20 12:07:22 +02:00
|
|
|
|
2021-07-06 11:54:37 +02:00
|
|
|
/// Performs both GET and POST search queries
|
|
|
|
pub async fn search(
|
|
|
|
&self,
|
|
|
|
query: Value,
|
|
|
|
test: impl Fn(Value, StatusCode) + UnwindSafe + Clone,
|
|
|
|
) {
|
2021-07-06 11:54:09 +02:00
|
|
|
let (response, code) = self.search_post(query.clone()).await;
|
|
|
|
let t = test.clone();
|
|
|
|
if let Err(e) = catch_unwind(move || t(response, code)) {
|
|
|
|
eprintln!("Error with post search");
|
|
|
|
resume_unwind(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
let (response, code) = self.search_get(query).await;
|
|
|
|
if let Err(e) = catch_unwind(move || test(response, code)) {
|
|
|
|
eprintln!("Error with get search");
|
|
|
|
resume_unwind(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn search_post(&self, query: Value) -> (Value, StatusCode) {
|
2022-10-09 19:43:51 +02:00
|
|
|
let url = format!("/indexes/{}/search", urlencode(self.uid.as_ref()));
|
|
|
|
self.service.post_encoded(url, query, self.encoder).await
|
2021-07-06 11:54:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn search_get(&self, query: Value) -> (Value, StatusCode) {
|
2022-06-22 12:33:15 +02:00
|
|
|
let params = yaup::to_string(&query).unwrap();
|
2022-10-10 11:04:46 +02:00
|
|
|
let url = format!(
|
|
|
|
"/indexes/{}/search?{}",
|
|
|
|
urlencode(self.uid.as_ref()),
|
|
|
|
params
|
|
|
|
);
|
2021-07-06 11:54:09 +02:00
|
|
|
self.service.get(url).await
|
|
|
|
}
|
|
|
|
|
2022-06-02 12:16:46 +02:00
|
|
|
pub async fn update_distinct_attribute(&self, value: Value) -> (Value, StatusCode) {
|
|
|
|
let url = format!(
|
|
|
|
"/indexes/{}/settings/{}",
|
2022-10-09 19:43:51 +02:00
|
|
|
urlencode(self.uid.as_ref()),
|
2022-06-02 12:16:46 +02:00
|
|
|
"distinct-attribute"
|
|
|
|
);
|
2022-10-09 19:43:51 +02:00
|
|
|
self.service.put_encoded(url, value, self.encoder).await
|
2022-06-02 12:16:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_distinct_attribute(&self) -> (Value, StatusCode) {
|
|
|
|
let url = format!(
|
|
|
|
"/indexes/{}/settings/{}",
|
2022-10-09 19:43:51 +02:00
|
|
|
urlencode(self.uid.as_ref()),
|
2022-06-02 12:16:46 +02:00
|
|
|
"distinct-attribute"
|
|
|
|
);
|
|
|
|
self.service.get(url).await
|
|
|
|
}
|
2021-02-18 19:50:52 +01:00
|
|
|
}
|
2021-02-19 19:55:00 +01:00
|
|
|
|
2022-05-25 11:51:26 +02:00
|
|
|
pub struct GetDocumentOptions {
|
|
|
|
pub fields: Option<Vec<&'static str>>,
|
|
|
|
}
|
2021-02-19 19:55:00 +01:00
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
2021-02-22 14:23:17 +01:00
|
|
|
pub struct GetAllDocumentsOptions {
|
|
|
|
pub limit: Option<usize>,
|
|
|
|
pub offset: Option<usize>,
|
|
|
|
pub attributes_to_retrieve: Option<Vec<&'static str>>,
|
|
|
|
}
|