Skip to main content

oramacore_client/
manager.rs

1//! Orama Core Manager for collection management operations.
2
3use std::sync::Arc;
4
5use reqwest::Client;
6use serde::{Deserialize, Serialize};
7
8use crate::auth::{ApiKeyAuth, Auth, AuthConfig, Target};
9use crate::client::{ApiKeyPosition, ClientRequest, OramaClient};
10use crate::error::Result;
11use crate::types::*;
12use crate::utils::create_random_string;
13
14/// Configuration for OramaCoreManager
15#[derive(Debug, Clone)]
16pub struct OramaCoreManagerConfig {
17    pub url: String,
18    pub master_api_key: String,
19}
20
21/// Parameters for creating a collection
22#[derive(Debug, Clone, Serialize)]
23pub struct CreateCollectionParams {
24    pub id: String,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub description: Option<String>,
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub write_api_key: Option<String>,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub read_api_key: Option<String>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub language: Option<Language>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub embeddings_model: Option<EmbeddingsModel>,
35}
36
37/// Response from creating a new collection
38#[derive(Debug, Clone, Deserialize)]
39pub struct NewCollectionResponse {
40    pub id: String,
41    pub description: Option<String>,
42    #[serde(rename = "writeAPIKey")]
43    pub write_api_key: String,
44    #[serde(rename = "readonlyAPIKey")]
45    pub readonly_api_key: String,
46}
47
48/// Collection index field information
49#[derive(Debug, Clone, Deserialize)]
50pub struct CollectionIndexField {
51    pub field_id: String,
52    pub field_path: String,
53    pub is_array: bool,
54    pub field_type: serde_json::Value,
55}
56
57/// Collection index information
58#[derive(Debug, Clone, Deserialize)]
59pub struct CollectionIndex {
60    pub id: String,
61    pub document_count: u32,
62    pub fields: Vec<CollectionIndexField>,
63    pub automatically_chosen_properties: serde_json::Value,
64}
65
66/// Response from getting collections
67#[derive(Debug, Clone, Deserialize)]
68pub struct GetCollectionsResponse {
69    pub id: String,
70    pub description: Option<String>,
71    pub document_count: u32,
72    pub indexes: Vec<CollectionIndex>,
73}
74
75/// Collection management namespace
76#[derive(Debug, Clone)]
77pub struct CollectionNamespace {
78    client: OramaClient,
79}
80
81impl CollectionNamespace {
82    /// Create a new collection namespace
83    pub(crate) fn new(client: OramaClient) -> Self {
84        Self { client }
85    }
86
87    /// Create a new collection
88    pub async fn create(&self, config: CreateCollectionParams) -> Result<NewCollectionResponse> {
89        let mut body = serde_json::json!({
90            "id": config.id,
91            "description": config.description,
92            "write_api_key": config.write_api_key.unwrap_or_else(|| create_random_string(32)),
93            "read_api_key": config.read_api_key.unwrap_or_else(|| create_random_string(32)),
94        });
95
96        if let Some(embeddings_model) = config.embeddings_model {
97            body["embeddings_model"] = serde_json::to_value(embeddings_model)?;
98        }
99
100        let request = ClientRequest::post(
101            "/v1/collections/create".to_string(),
102            Target::Writer,
103            ApiKeyPosition::Header,
104            body,
105        );
106
107        let response: serde_json::Value = self.client.request(request).await?;
108
109        // Convert response to NewCollectionResponse
110        Ok(NewCollectionResponse {
111            id: response["id"].as_str().unwrap_or_default().to_string(),
112            description: response["description"].as_str().map(|s| s.to_string()),
113            write_api_key: response["write_api_key"]
114                .as_str()
115                .unwrap_or_default()
116                .to_string(),
117            readonly_api_key: response["read_api_key"]
118                .as_str()
119                .unwrap_or_default()
120                .to_string(),
121        })
122    }
123
124    /// List all collections
125    pub async fn list(&self) -> Result<Vec<GetCollectionsResponse>> {
126        let request = ClientRequest::<()>::get(
127            "/v1/collections".to_string(),
128            Target::Writer,
129            ApiKeyPosition::Header,
130        );
131
132        self.client.request(request).await
133    }
134
135    /// Get a specific collection
136    pub async fn get(&self, collection_id: &str) -> Result<GetCollectionsResponse> {
137        let request = ClientRequest::<()>::get(
138            format!("/v1/collections/{collection_id}"),
139            Target::Writer,
140            ApiKeyPosition::Header,
141        );
142
143        self.client.request(request).await
144    }
145
146    /// Delete a collection
147    pub async fn delete(&self, collection_id: &str) -> Result<()> {
148        let body = serde_json::json!({
149            "collection_id_to_delete": collection_id
150        });
151
152        let request = ClientRequest::post(
153            "/v1/collections/delete".to_string(),
154            Target::Writer,
155            ApiKeyPosition::Header,
156            body,
157        );
158
159        let _: serde_json::Value = self.client.request(request).await?;
160        Ok(())
161    }
162}
163
164/// Main manager class for Orama Core operations
165#[derive(Debug, Clone)]
166pub struct OramaCoreManager {
167    pub collection: CollectionNamespace,
168}
169
170impl OramaCoreManager {
171    /// Create a new OramaCoreManager
172    pub async fn new(config: OramaCoreManagerConfig) -> Result<Self> {
173        let auth_config =
174            AuthConfig::ApiKey(ApiKeyAuth::new(config.master_api_key).with_writer_url(config.url));
175
176        let client = Client::new();
177        let auth = Auth::new(auth_config, Arc::new(client));
178        let orama_client = OramaClient::new(auth)?;
179
180        Ok(Self {
181            collection: CollectionNamespace::new(orama_client),
182        })
183    }
184}
185
186impl CreateCollectionParams {
187    /// Create a new CreateCollectionParams
188    pub fn new<S: Into<String>>(id: S) -> Self {
189        Self {
190            id: id.into(),
191            description: None,
192            write_api_key: None,
193            read_api_key: None,
194            language: None,
195            embeddings_model: None,
196        }
197    }
198
199    /// Set the description
200    pub fn with_description<S: Into<String>>(mut self, description: S) -> Self {
201        self.description = Some(description.into());
202        self
203    }
204
205    /// Set the write API key
206    pub fn with_write_api_key<S: Into<String>>(mut self, key: S) -> Self {
207        self.write_api_key = Some(key.into());
208        self
209    }
210
211    /// Set the read API key
212    pub fn with_read_api_key<S: Into<String>>(mut self, key: S) -> Self {
213        self.read_api_key = Some(key.into());
214        self
215    }
216
217    /// Set the language
218    pub fn with_language(mut self, language: Language) -> Self {
219        self.language = Some(language);
220        self
221    }
222
223    /// Set the embeddings model
224    pub fn with_embeddings_model(mut self, model: EmbeddingsModel) -> Self {
225        self.embeddings_model = Some(model);
226        self
227    }
228}