diff --git a/ahnlich/ai/src/engine/mod.rs b/ahnlich/ai/src/engine/mod.rs index 6f6c7b960..8e21cd42d 100644 --- a/ahnlich/ai/src/engine/mod.rs +++ b/ahnlich/ai/src/engine/mod.rs @@ -1,3 +1,4 @@ pub mod ai; pub mod operations; pub mod store; +pub mod versioned; diff --git a/ahnlich/ai/src/engine/operations.rs b/ahnlich/ai/src/engine/operations.rs index c1d27b777..37e861fae 100644 --- a/ahnlich/ai/src/engine/operations.rs +++ b/ahnlich/ai/src/engine/operations.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, sync::Arc}; use ahnlich_client_rs::db::DbClient; +use ahnlich_types::ai::query::DropSchema as AiDropSchema; use ahnlich_types::{ ai::{ models::AiModel, @@ -28,6 +29,7 @@ use ahnlich_types::{ In, Predicate, PredicateCondition, predicate::Kind as PredicateKind, predicate_condition::Kind, }, + schema::Schema, }; use itertools::Itertools; use rayon::prelude::*; @@ -90,6 +92,13 @@ pub async fn create_store( predicates.push(AHNLICH_AI_ONE_TO_MANY_INDEX_META_KEY.to_string()); } + let schema = match ¶ms.schema { + Some(s) => { + Schema::try_new(s.clone()).map_err(|e| AIProxyError::InvalidArgument(e.to_owned()))? + } + None => Schema::default(), + }; + require_db_client(db_client)? .create_store( DbCreateStore { @@ -98,6 +107,7 @@ pub async fn create_store( create_predicates: predicates, non_linear_indices: params.non_linear_indices, error_if_exists: params.error_if_exists, + schema: Some(schema.to_string()), }, parent_id, ) @@ -107,6 +117,7 @@ pub async fn create_store( StoreName { value: params.store, }, + &schema, query_model, index_model, params.error_if_exists, @@ -353,6 +364,12 @@ pub async fn drop_store( let store_name = StoreName { value: params.store, }; + let schema = match ¶ms.schema { + Some(s) => { + Schema::try_new(s.clone()).map_err(|e| AIProxyError::InvalidArgument(e.to_owned()))? + } + None => Schema::default(), + }; if store_handler.get(&store_name).is_ok() && let Some(db_client) = db_client @@ -362,13 +379,14 @@ pub async fn drop_store( DbDropStore { store: store_name.value.clone(), error_if_not_exists: params.error_if_not_exists, + schema: Some(schema.to_string()), }, parent_id, ) .await?; } - let dropped = store_handler.drop_store(store_name, params.error_if_not_exists)?; + let dropped = store_handler.drop_store(store_name, &schema, params.error_if_not_exists)?; Ok(Del { deleted_count: dropped as u64, }) @@ -380,19 +398,14 @@ pub async fn purge_stores( _params: PurgeStores, parent_id: Option, ) -> Result { - let store_names: Vec = store_handler - .list_stores() - .into_iter() - .map(|store| StoreName { value: store.name }) - .collect(); - if let Some(db_client) = db_client { - for store_name in &store_names { + for (schema, store_name) in store_handler.all_store_names_by_schema() { db_client .drop_store( DbDropStore { - store: store_name.value.clone(), + store: store_name.value, error_if_not_exists: false, + schema: Some(schema), }, parent_id.clone(), ) @@ -408,10 +421,19 @@ pub async fn purge_stores( pub async fn list_stores( store_handler: &AIStoreHandler, db_client: Option>, - _params: ListStores, + params: ListStores, parent_id: Option, ) -> Result { - let mut stores: Vec = store_handler.list_stores().into_iter().sorted().collect(); + let filter_schema = params + .schema + .as_ref() + .filter(|s| !s.is_empty()) + .map(|s| Schema::new(s.clone())); + let mut stores: Vec = store_handler + .list_stores(filter_schema.as_ref()) + .into_iter() + .sorted() + .collect(); if let Some(db_client) = db_client && let Ok(db_store_list) = db_client.list_stores(parent_id).await @@ -439,3 +461,18 @@ pub async fn list_stores( Ok(StoreList { stores }) } + +pub async fn drop_schema( + store_handler: &AIStoreHandler, + _db_client: Option>, + params: AiDropSchema, + _parent_id: Option, +) -> Result { + let schema = + Schema::try_new(params.schema).map_err(|e| AIProxyError::InvalidArgument(e.to_owned()))?; + + let dropped = store_handler.drop_schema(&schema)?; + Ok(Del { + deleted_count: dropped as u64, + }) +} diff --git a/ahnlich/ai/src/engine/store.rs b/ahnlich/ai/src/engine/store.rs index 458dc800f..b0a2bb111 100644 --- a/ahnlich/ai/src/engine/store.rs +++ b/ahnlich/ai/src/engine/store.rs @@ -16,6 +16,7 @@ use ahnlich_types::keyval::StoreName; use ahnlich_types::keyval::StoreValue; use ahnlich_types::metadata::MetadataValue; use ahnlich_types::metadata::metadata_value; +use ahnlich_types::schema::Schema; use fallible_collections::FallibleVec; use papaya::HashMap as ConcurrentHashMap; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; @@ -28,6 +29,7 @@ use std::sync::atomic::Ordering; use utils::fallible; use utils::parallel; use utils::persistence::AhnlichPersistenceUtils; +use utils::persistence::VersionedPersistence; use super::ai::models::ModelDetails; use super::ai::models::ModelResponse; @@ -38,10 +40,12 @@ pub struct AIStoreHandler { /// Making use of a concurrent hashmap, we should be able to create an engine that manages stores stores: AIStores, pub write_flag: Arc, + default_schema: Schema, supported_models: Vec, } -pub type AIStores = Arc>>; +pub type AIInnerStores = Arc>>; +pub type AIStores = Arc>; type StoreSetResponse = (Vec, Option>); type StoreValidateResponse = ( @@ -49,7 +53,7 @@ type StoreValidateResponse = ( Option>, ); impl AhnlichPersistenceUtils for AIStoreHandler { - type PersistenceObject = AIStores; + type PersistenceObject = super::versioned::VersionedAiStores; #[tracing::instrument(skip_all)] fn write_flag(&self) -> Arc { @@ -58,18 +62,19 @@ impl AhnlichPersistenceUtils for AIStoreHandler { #[tracing::instrument(skip(self))] fn get_snapshot(&self) -> Self::PersistenceObject { - self.stores.clone() + super::versioned::VersionedAiStores::current(self.stores.clone()) } } impl AIStoreHandler { pub fn new(write_flag: Arc, supported_models: Vec) -> Self { Self { - stores: Arc::new(fallible::try_new_hashmap().unwrap_or_else(|e| { + stores: fallible::try_new_arc_hashmap().unwrap_or_else(|e| { eprintln!("Fatal: Failed to create AIStoreHandler stores: {e}"); std::process::abort(); - })), + }), write_flag, + default_schema: Schema::default(), supported_models, } } @@ -86,10 +91,64 @@ impl AIStoreHandler { self.stores = stores_snapshot; } + /// Loads and migrates a persistence snapshot using the versioned format. + pub(crate) fn load_snapshot( + bytes: &[u8], + ) -> Result { + let versioned = super::versioned::VersionedAiStores::load_and_migrate(bytes)?; + versioned + .into_latest() + .map_err(utils::persistence::PersistenceTaskError::MigrationError) + } + + /// Returns the inner stores map for a given schema, creating it if it does not exist. + fn get_or_create_schema(&self, schema: &Schema) -> AIInnerStores { + let guard = self.stores.guard(); + if let Some(inner) = self.stores.get(schema, &guard) { + return AIInnerStores::clone(inner); + } + drop(guard); + let new_inner: AIInnerStores = fallible::try_new_arc_hashmap() + .expect("Failed to create inner AI stores map for schema"); + let guard = self.stores.guard(); + match self + .stores + .try_insert(schema.clone(), new_inner.clone(), &guard) + { + Ok(_) => new_inner, + Err(existing) => existing.current.clone(), + } + } + + /// Returns the inner stores map for a given schema, or `None` if the schema does not exist. + fn get_schema(&self, schema: &Schema) -> Option { + self.stores.get(schema, &self.stores.guard()).cloned() + } + + /// Returns a store using the store name and schema, else returns an error + #[tracing::instrument(skip(self))] + pub(crate) fn get(&self, store_name: &StoreName) -> Result, AIProxyError> { + let guard = self.stores.guard(); + if let Some(inner_stores) = self.stores.get(&self.default_schema, &guard) { + let inner_guard = inner_stores.guard(); + if let Some(store) = inner_stores.get(store_name, &inner_guard) { + return Ok(store.clone()); + } + } + for (_, inner_stores) in self.stores.iter(&guard) { + let inner_guard = inner_stores.guard(); + if let Some(store) = inner_stores.get(store_name, &inner_guard) { + return Ok(store.clone()); + } + } + Err(AIProxyError::StoreNotFound(store_name.clone())) + } + #[tracing::instrument(skip(self))] pub(crate) fn create_store( &self, store_name: StoreName, + schema: &Schema, query_model: AiModel, index_model: AiModel, error_if_exists: bool, @@ -111,8 +170,8 @@ impl AIStoreHandler { }); } - if self - .stores + let inner_stores = self.get_or_create_schema(schema); + if inner_stores .try_insert( store_name.clone(), Arc::new(AIStore::create( @@ -121,7 +180,7 @@ impl AIStoreHandler { index_model, store_original, )), - &self.stores.guard(), + &inner_stores.guard(), ) .is_err() && error_if_exists @@ -132,31 +191,56 @@ impl AIStoreHandler { Ok(()) } - /// matches LISTSTORES - to return statistics of all stores + /// matches LISTSTORES - to return statistics of all stores. + /// When schema is None, defaults to the public schema. #[tracing::instrument(skip(self))] - pub(crate) fn list_stores(&self) -> StdHashSet { - self.stores - .iter(&self.stores.guard()) - .map(|(store_name, store)| { - let model: ModelDetails = - SupportedModels::from(&store.index_model).to_model_details(); - - AiStoreInfo { - name: store_name.value.clone(), - query_model: store.query_model.into(), - index_model: store.index_model.into(), - embedding_size: model.embedding_size.get() as u64, - predicate_indices: vec![], - dimension: model.embedding_size.get() as u32, - db_info: None, - } - }) - .collect() + pub(crate) fn list_stores(&self, schema: Option<&Schema>) -> StdHashSet { + let guard = self.stores.guard(); + let mut result = StdHashSet::new(); + let schema = schema.unwrap_or(&self.default_schema); + let inner_stores = match self.stores.get(schema, &guard) { + Some(s) => s.clone(), + None => return result, + }; + let inner_guard = inner_stores.guard(); + for (store_name, store) in inner_stores.iter(&inner_guard) { + let model: ModelDetails = SupportedModels::from(&store.index_model).to_model_details(); + + result.insert(AiStoreInfo { + name: store_name.value.clone(), + query_model: store.query_model.into(), + index_model: store.index_model.into(), + embedding_size: model.embedding_size.get() as u64, + predicate_indices: vec![], + dimension: model.embedding_size.get() as u32, + db_info: None, + schema: Some(schema.to_string()), + }); + } + result + } + + /// Iterates all stores across every schema, returning (schema, store_name) pairs. + /// Used internally by purge_stores to clean up DB stores across all schemas. + pub(crate) fn all_store_names_by_schema(&self) -> Vec<(String, StoreName)> { + let guard = self.stores.guard(); + let mut result = Vec::new(); + for (schema, inner_stores) in self.stores.iter(&guard) { + let inner_guard = inner_stores.guard(); + for store_name in inner_stores.keys(&inner_guard) { + result.push((schema.to_string(), store_name.clone())); + } + } + result } /// matches GETSTORE - to return info for a single store #[tracing::instrument(skip(self))] - pub(crate) fn get_store(&self, store_name: &StoreName) -> Result { + pub(crate) fn get_store( + &self, + store_name: &StoreName, + schema: Option<&str>, + ) -> Result { let store = self.get(store_name)?; let model: ModelDetails = SupportedModels::from(&store.index_model).to_model_details(); Ok(AiStoreInfo { @@ -167,20 +251,10 @@ impl AIStoreHandler { predicate_indices: vec![], dimension: model.embedding_size.get() as u32, db_info: None, + schema: schema.map(|s| s.to_owned()), }) } - /// Returns a store using the store name, else returns an error - #[tracing::instrument(skip(self))] - pub(crate) fn get(&self, store_name: &StoreName) -> Result, AIProxyError> { - let store = self - .stores - .get(store_name, &self.stores.guard()) - .cloned() - .ok_or(AIProxyError::StoreNotFound(store_name.clone()))?; - Ok(store) - } - /// Validates storeinputs against a store and checks storevalue for reservedkey. #[tracing::instrument(skip(self, inputs), fields(input_length=inputs.len(), num_threads = rayon::current_num_threads()))] pub(crate) fn validate_and_prepare_store_data( @@ -422,9 +496,15 @@ impl AIStoreHandler { pub(crate) fn drop_store( &self, store_name: StoreName, + schema: &Schema, error_if_not_exists: bool, ) -> Result { - let pinned = self.stores.pin(); + let inner_stores = match self.get_schema(schema) { + Some(inner) => inner, + None if error_if_not_exists => return Err(AIProxyError::StoreNotFound(store_name)), + None => return Ok(0), + }; + let pinned = inner_stores.pin(); let removed = pinned.remove(&store_name).is_some(); if !removed && error_if_not_exists { return Err(AIProxyError::StoreNotFound(store_name)); @@ -438,6 +518,29 @@ impl AIStoreHandler { Ok(removed) } + /// Drops all stores within a schema and removes the schema. + /// Returns the number of stores dropped. + #[tracing::instrument(skip(self))] + pub(crate) fn drop_schema(&self, schema: &Schema) -> Result { + if schema.as_str() == Schema::DEFAULT_NAME { + return Err(AIProxyError::InvalidArgument(format!( + "Cannot drop the default '{}' schema", + Schema::DEFAULT_NAME + ))); + } + let pinned = self.stores.pin(); + let removed = pinned.remove(schema); + match removed { + Some(inner) => { + let pinned = inner.pin(); + let count = pinned.len(); + self.set_write_flag(); + Ok(count) + } + None => Ok(0), + } + } + #[tracing::instrument(skip(self))] pub(crate) fn store_original(&self, store_name: StoreName) -> Result { let store = self.get(&store_name)?; @@ -447,8 +550,12 @@ impl AIStoreHandler { /// Matches DestroyDatabase - Drops all the stores in the database #[tracing::instrument(skip(self))] pub(crate) fn purge_stores(&self) -> usize { - let store_length = self.stores.pin().len(); let guard = self.stores.guard(); + let store_length: usize = self + .stores + .iter(&guard) + .map(|(_, inner)| inner.pin().len()) + .sum(); self.stores.clear(&guard); if store_length > 0 { self.set_write_flag(); diff --git a/ahnlich/ai/src/engine/versioned.rs b/ahnlich/ai/src/engine/versioned.rs new file mode 100644 index 000000000..ec64df9e9 --- /dev/null +++ b/ahnlich/ai/src/engine/versioned.rs @@ -0,0 +1,139 @@ +use std::collections::HashMap; +use std::sync::Arc; + +use ahnlich_types::keyval::StoreName; +use ahnlich_types::schema::Schema; +use serde::{Deserialize, Serialize}; +use utils::fallible; +use utils::persistence::{PersistenceTaskError, VersionedPersistence}; + +use super::store::{AIStore, AIStores}; + +pub const AI_CURRENT_VERSION: u32 = 2; +pub const AI_MIN_VERSION: u32 = 1; + +type AiStoresV1 = HashMap; +type AiStoresV2 = HashMap; + +#[derive(Debug, Deserialize)] +struct TaggedAiStoresV1 { + stores: AiStoresV1, +} + +#[derive(Debug, Deserialize)] +struct TaggedAiStoresV2 { + stores: AiStoresV2, +} + +#[derive(Debug, Deserialize)] +struct AiVersionTag { + db_version: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(tag = "db_version")] +pub enum VersionedAiStores { + #[serde(rename = "1")] + V1 { stores: AiStoresV1 }, + + #[serde(rename = "2")] + V2 { stores: AIStores }, +} + +impl VersionedPersistence for VersionedAiStores { + const CURRENT_VERSION: u32 = AI_CURRENT_VERSION; + const MIN_VERSION: u32 = AI_MIN_VERSION; + + fn load_and_migrate(bytes: &[u8]) -> Result { + Self::validate_version(bytes)?; + + match Self::snapshot_version(bytes) { + Some(1) => { + let tagged: TaggedAiStoresV1 = serde_json::from_slice(bytes)?; + Ok(VersionedAiStores::V1 { + stores: tagged.stores, + }) + } + Some(2) => { + let tagged: TaggedAiStoresV2 = serde_json::from_slice(bytes)?; + let stores = Self::migrate_v1n_to_v2(tagged.stores) + .map_err(PersistenceTaskError::MigrationError)?; + Ok(VersionedAiStores::V2 { stores }) + } + _ => { + if let Ok(nested) = serde_json::from_slice::(bytes) { + log::warn!("No db_version tag, detected schema-nested (V1n) format"); + let stores = Self::migrate_v1n_to_v2(nested) + .map_err(PersistenceTaskError::MigrationError)?; + return Ok(VersionedAiStores::V2 { stores }); + } + log::warn!("No db_version tag, attempting bare V1 load"); + let v1_stores: AiStoresV1 = serde_json::from_slice(bytes)?; + Ok(VersionedAiStores::V1 { stores: v1_stores }) + } + } + } +} + +impl VersionedAiStores { + fn snapshot_version(bytes: &[u8]) -> Option { + serde_json::from_slice::(bytes) + .ok() + .and_then(|tag| tag.db_version) + .and_then(|version| version.parse::().ok()) + } + + fn migrate_v1n_to_v2(v1_nested: AiStoresV2) -> Result { + let stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + for (schema_name, inner) in v1_nested { + let inner_stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + { + let guard = inner_stores.pin(); + for (name, store) in inner { + guard.insert(name, Arc::new(store)); + } + } + { + let guard = stores.pin(); + guard.insert(schema_name, inner_stores); + } + } + Ok(stores) + } +} + +impl VersionedAiStores { + pub fn into_latest(self) -> Result { + match self { + VersionedAiStores::V1 { stores } => { + log::info!("Migrating AI stores V1 → V2"); + Self::migrate_v1_to_v2(stores) + } + VersionedAiStores::V2 { stores } => Ok(stores), + } + } + + pub fn current(stores: AIStores) -> Self { + VersionedAiStores::V2 { stores } + } + + fn migrate_v1_to_v2(v1_stores: AiStoresV1) -> Result { + let inner_stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + { + let guard = inner_stores.pin(); + for (name, store) in v1_stores { + guard.insert(name, Arc::new(store)); + } + } + let stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + { + let guard = stores.pin(); + guard.insert(Schema::default(), inner_stores); + } + Ok(stores) + } +} diff --git a/ahnlich/ai/src/error.rs b/ahnlich/ai/src/error.rs index 507a14839..ad5eacd71 100644 --- a/ahnlich/ai/src/error.rs +++ b/ahnlich/ai/src/error.rs @@ -182,6 +182,9 @@ pub enum AIProxyError { #[error("Cannot call DelKey on store with `store_original` as false")] DelKeyError, + #[error("Invalid argument: {0}")] + InvalidArgument(String), + #[error("Tokenizer for model failed to load: {message}")] ModelTokenizerLoadError { message: String }, @@ -234,6 +237,7 @@ impl From for Status { | AIProxyError::UnknownEnumValue(_) | AIProxyError::InputNotSpecified(_) | AIProxyError::MultipleEmbeddingsForQuery(_) => Code::InvalidArgument, + AIProxyError::InvalidArgument(_) => Code::InvalidArgument, AIProxyError::TokenExceededError { max_token_size: _, input_token_size: _, diff --git a/ahnlich/ai/src/server/handler.rs b/ahnlich/ai/src/server/handler.rs index 1e340006f..fbaddf716 100644 --- a/ahnlich/ai/src/server/handler.rs +++ b/ahnlich/ai/src/server/handler.rs @@ -26,6 +26,7 @@ use ahnlich_types::ai::query::DelKey; use ahnlich_types::ai::query::DelPred as AiDelPred; use ahnlich_types::ai::query::DropNonLinearAlgorithmIndex; use ahnlich_types::ai::query::DropPredIndex; +use ahnlich_types::ai::query::DropSchema as AiDropSchema; use ahnlich_types::ai::query::DropStore; use ahnlich_types::ai::query::GetKey; use ahnlich_types::ai::query::GetPred; @@ -473,6 +474,21 @@ impl AiService for AIProxyServer { Ok(tonic::Response::new(res)) } + #[tracing::instrument(skip_all)] + async fn drop_schema( + &self, + request: tonic::Request, + ) -> Result, tonic::Status> { + let res = operations::drop_schema( + self.store_handler.as_ref(), + self.db_client.clone(), + request.into_inner(), + tracer::span_to_trace_parent(tracing::Span::current()), + ) + .await?; + Ok(tonic::Response::new(res)) + } + #[tracing::instrument(skip_all)] async fn list_clients( &self, @@ -504,9 +520,12 @@ impl AiService for AIProxyServer { request: tonic::Request, ) -> Result, tonic::Status> { let params = request.into_inner(); - let mut store_info = self.store_handler.get_store(&StoreName { - value: params.store.clone(), - })?; + let mut store_info = self.store_handler.get_store( + &StoreName { + value: params.store.clone(), + }, + params.schema.as_deref(), + )?; // Enrich with predicate indices and db_info from DB, filtering out reserved keys if let Some(db_client) = &self.db_client { let parent_id = tracer::span_to_trace_parent(tracing::Span::current()); @@ -913,6 +932,20 @@ impl AiService for AIProxyServer { } } } + + Query::DropSchema(params) => { + match self.drop_schema(tonic::Request::new(params)).await { + Ok(res) => { + response_vec.push(ai_server_response::Response::Del(res.into_inner())) + } + Err(err) => { + response_vec.push(ai_server_response::Response::Error(ErrorResponse { + message: err.message().to_string(), + code: err.code().into(), + })); + } + } + } } } let response_vec = response_vec @@ -1009,7 +1042,11 @@ impl AIProxyServer { let mut store_handler = AIStoreHandler::new(write_flag.clone(), config.supported_models.clone()); if let Some(ref persist_location) = config.common.persist_location { - match Persistence::load_snapshot(persist_location, config.common.enable_mmap) { + match Persistence::load_snapshot_with_migration( + persist_location, + config.common.enable_mmap, + AIStoreHandler::load_snapshot, + ) { Err(e) => { log::error!("Failed to load snapshot from persist location {e}"); if config.common.fail_on_startup_if_persist_load_fails { diff --git a/ahnlich/ai/src/tests/aiproxy_test.rs b/ahnlich/ai/src/tests/aiproxy_test.rs index 5e2775f08..9bcc40981 100644 --- a/ahnlich/ai/src/tests/aiproxy_test.rs +++ b/ahnlich/ai/src/tests/aiproxy_test.rs @@ -151,6 +151,7 @@ async fn test_ai_proxy_create_store_success() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; let response = client .create_store(tonic::Request::new(create_store)) @@ -161,7 +162,7 @@ async fn test_ai_proxy_create_store_success() { assert_eq!(expected, response.into_inner()); // list stores to verify it's present. - let message = ahnlich_types::ai::query::ListStores {}; + let message = ahnlich_types::ai::query::ListStores { schema: None }; let response = client .list_stores(tonic::Request::new(message)) .await @@ -221,6 +222,7 @@ async fn test_ai_store_get_key_works() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -347,6 +349,7 @@ async fn test_ai_store_no_original() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -469,6 +472,7 @@ async fn test_ai_proxy_get_pred_succeeds() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -598,6 +602,7 @@ async fn test_ai_proxy_get_sim_n_succeeds() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -759,6 +764,7 @@ async fn test_convert_store_input_to_embeddings(index: usize, model: i32) { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -909,6 +915,7 @@ async fn test_convert_store_input_to_embeddings_without_db(index: usize, model: non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1005,6 +1012,7 @@ async fn test_ai_proxy_create_drop_pred_index() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1147,6 +1155,7 @@ async fn test_ai_proxy_del_key_drop_store() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1158,6 +1167,7 @@ async fn test_ai_proxy_del_key_drop_store() { non_linear_indices: vec![], error_if_exists: false, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1187,6 +1197,7 @@ async fn test_ai_proxy_del_key_drop_store() { query: Some(Query::DropStore(ai_query_types::DropStore { store: store_name.clone(), error_if_not_exists: true, + schema: None, })), }, ]; @@ -1284,16 +1295,20 @@ async fn test_ai_proxy_drop_store_cascades_to_db() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { query: Some(Query::DropStore(ai_query_types::DropStore { store: store_name.clone(), error_if_not_exists: true, + schema: None, })), }, ai_pipeline::AiQuery { - query: Some(Query::ListStores(ai_query_types::ListStores {})), + query: Some(Query::ListStores(ai_query_types::ListStores { + schema: None, + })), }, ], })) @@ -1318,7 +1333,9 @@ async fn test_ai_proxy_drop_store_cascades_to_db() { } let db_stores = db_client - .list_stores(tonic::Request::new(ahnlich_types::db::query::ListStores {})) + .list_stores(tonic::Request::new(ahnlich_types::db::query::ListStores { + schema: None, + })) .await .expect("Failed to list DB stores") .into_inner(); @@ -1394,6 +1411,7 @@ async fn test_ai_proxy_del_pred() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1460,6 +1478,8 @@ async fn test_ai_proxy_del_pred() { #[tokio::test] async fn test_ai_proxy_test_with_persistence() { + let _ = std::fs::remove_file(&*PERSISTENCE_FILE); + // Setup servers with persistence let server = Server::new(&CONFIG) .await @@ -1505,6 +1525,7 @@ async fn test_ai_proxy_test_with_persistence() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1516,12 +1537,14 @@ async fn test_ai_proxy_test_with_persistence() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { query: Some(Query::DropStore(ai_query_types::DropStore { store: store_name.clone(), error_if_not_exists: true, + schema: None, })), }, ]; @@ -1580,7 +1603,9 @@ async fn test_ai_proxy_test_with_persistence() { // Verify persisted data let list_response = persisted_client - .list_stores(tonic::Request::new(ai_query_types::ListStores {})) + .list_stores(tonic::Request::new(ai_query_types::ListStores { + schema: None, + })) .await .expect("Failed to list stores"); @@ -1628,16 +1653,21 @@ async fn test_ai_proxy_destroy_database() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { - query: Some(Query::ListStores(ai_query_types::ListStores {})), + query: Some(Query::ListStores(ai_query_types::ListStores { + schema: None, + })), }, ai_pipeline::AiQuery { query: Some(Query::PurgeStores(ai_query_types::PurgeStores {})), }, ai_pipeline::AiQuery { - query: Some(Query::ListStores(ai_query_types::ListStores {})), + query: Some(Query::ListStores(ai_query_types::ListStores { + schema: None, + })), }, ]; @@ -1730,6 +1760,7 @@ async fn test_ai_proxy_purge_stores_cascades_to_db() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1741,13 +1772,16 @@ async fn test_ai_proxy_purge_stores_cascades_to_db() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { query: Some(Query::PurgeStores(ai_query_types::PurgeStores {})), }, ai_pipeline::AiQuery { - query: Some(Query::ListStores(ai_query_types::ListStores {})), + query: Some(Query::ListStores(ai_query_types::ListStores { + schema: None, + })), }, ], })) @@ -1776,7 +1810,9 @@ async fn test_ai_proxy_purge_stores_cascades_to_db() { } let db_stores = db_client - .list_stores(tonic::Request::new(ahnlich_types::db::query::ListStores {})) + .list_stores(tonic::Request::new(ahnlich_types::db::query::ListStores { + schema: None, + })) .await .expect("Failed to list DB stores") .into_inner(); @@ -1875,10 +1911,13 @@ async fn test_ai_proxy_binary_store_actions() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { - query: Some(Query::ListStores(ai_query_types::ListStores {})), + query: Some(Query::ListStores(ai_query_types::ListStores { + schema: None, + })), }, ai_pipeline::AiQuery { query: Some(Query::CreatePredIndex(ai_query_types::CreatePredIndex { @@ -2060,6 +2099,7 @@ async fn test_ai_proxy_binary_store_set_text_and_binary_fails() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }, ai_pipeline::AiQuery { @@ -2141,6 +2181,7 @@ async fn test_ai_proxy_create_store_errors_unsupported_models() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }]; @@ -2191,6 +2232,7 @@ async fn test_ai_proxy_embedding_size_mismatch_error() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }]; @@ -2218,3 +2260,202 @@ async fn test_ai_proxy_embedding_size_mismatch_error() { assert_eq!(response.into_inner(), expected); } + +/// Helper: provisions DB + AI servers with only AllMiniLML6V2 model loaded +async fn provision_test_servers_limited() -> SocketAddr { + let server = Server::new(&CONFIG).await.expect("Failed to create server"); + let db_port = server.local_addr().unwrap().port(); + + tokio::spawn(async move { server.start().await }); + + let mut config = AI_CONFIG_LIMITED_MODELS.clone(); + config.db_port = db_port; + + let ai_server = AIProxyServer::new(config) + .await + .expect("Could not initialize ai proxy"); + + let ai_address = ai_server.local_addr().expect("Could not get local addr"); + + let _ = tokio::spawn(async move { ai_server.start().await }); + tokio::time::sleep(Duration::from_millis(200)).await; + + ai_address +} + +/// Test: Create stores in different schemas and list them via AI proxy +#[tokio::test] +async fn test_ai_schema_create_store_in_schema() { + let address = provision_test_servers_limited().await; + + let address = format!("http://{}", address); + + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + + let mut client = AiServiceClient::connect(channel).await.expect("Failure"); + + // Create a store in default schema + let create_store = ahnlich_types::ai::query::CreateStore { + store: "AiPublicStore".to_string(), + query_model: AiModel::AllMiniLmL6V2.into(), + index_model: AiModel::AllMiniLmL6V2.into(), + predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + store_original: true, + schema: None, + }; + client + .create_store(tonic::Request::new(create_store)) + .await + .expect("Failed to create store in default schema"); + + // Create a store in custom schema + let create_store = ahnlich_types::ai::query::CreateStore { + store: "AiCustomStore".to_string(), + query_model: AiModel::AllMiniLmL6V2.into(), + index_model: AiModel::AllMiniLmL6V2.into(), + predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + store_original: true, + schema: Some("ai_custom".to_string()), + }; + client + .create_store(tonic::Request::new(create_store)) + .await + .expect("Failed to create store in custom schema"); + + // List stores filtered by public schema + let message = ahnlich_types::ai::query::ListStores { + schema: Some("public".to_string()), + }; + let response = client + .list_stores(tonic::Request::new(message)) + .await + .expect("Failed to list stores") + .into_inner(); + assert_eq!(response.stores.len(), 1); + assert_eq!(response.stores[0].name, "AiPublicStore"); + + // List stores filtered by custom schema + let message = ahnlich_types::ai::query::ListStores { + schema: Some("ai_custom".to_string()), + }; + let response = client + .list_stores(tonic::Request::new(message)) + .await + .expect("Failed to list stores") + .into_inner(); + assert_eq!(response.stores.len(), 1); + assert_eq!(response.stores[0].name, "AiCustomStore"); + + // List stores with no filter - should default to public schema + let message = ahnlich_types::ai::query::ListStores { schema: None }; + let response = client + .list_stores(tonic::Request::new(message)) + .await + .expect("Failed to list stores without filter") + .into_inner(); + assert_eq!(response.stores.len(), 1); + assert_eq!(response.stores[0].name, "AiPublicStore"); +} + +/// Test: DropSchema through AI proxy +#[tokio::test] +async fn test_ai_schema_drop_schema() { + let address = provision_test_servers_limited().await; + + let address = format!("http://{}", address); + + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + + let mut client = AiServiceClient::connect(channel).await.expect("Failure"); + + // Create a store in a schema to drop + let create_store = ahnlich_types::ai::query::CreateStore { + store: "AiDropSchemaStore".to_string(), + query_model: AiModel::AllMiniLmL6V2.into(), + index_model: AiModel::AllMiniLmL6V2.into(), + predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + store_original: true, + schema: Some("ai_tobedropped".to_string()), + }; + client + .create_store(tonic::Request::new(create_store)) + .await + .expect("Failed to create store in schema to drop"); + + // Create another store in the same schema + let create_store = ahnlich_types::ai::query::CreateStore { + store: "AiDropSchemaStore2".to_string(), + query_model: AiModel::AllMiniLmL6V2.into(), + index_model: AiModel::AllMiniLmL6V2.into(), + predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + store_original: true, + schema: Some("ai_tobedropped".to_string()), + }; + client + .create_store(tonic::Request::new(create_store)) + .await + .expect("Failed to create second store in schema to drop"); + + // Drop the schema + let response = client + .drop_schema(tonic::Request::new(ahnlich_types::ai::query::DropSchema { + schema: "ai_tobedropped".to_string(), + })) + .await + .expect("DropSchema failed") + .into_inner(); + assert_eq!(response.deleted_count, 2); + + // Verify stores in dropped schema are gone by listing with schema filter + let message = ahnlich_types::ai::query::ListStores { + schema: Some("ai_tobedropped".to_string()), + }; + let response = client + .list_stores(tonic::Request::new(message)) + .await + .expect("Failed to list stores") + .into_inner(); + assert_eq!(response.stores.len(), 0); +} + +/// Test: Dropping the "public" schema through AI proxy should fail +#[tokio::test] +async fn test_ai_schema_drop_public_schema_fails() { + let address = provision_test_servers_limited().await; + + let address = format!("http://{}", address); + + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + + let mut client = AiServiceClient::connect(channel).await.expect("Failure"); + + // Attempt to drop "public" schema + let result = client + .drop_schema(tonic::Request::new(ahnlich_types::ai::query::DropSchema { + schema: "public".to_string(), + })) + .await; + + assert!( + result.is_err(), + "Dropping public schema should return an error" + ); + let status = result.unwrap_err(); + assert_eq!(status.code(), tonic::Code::InvalidArgument); + assert!( + status.message().contains("public"), + "Error message should reference 'public': {}", + status.message() + ); +} diff --git a/ahnlich/ai/src/tests/buffalo_l_test.rs b/ahnlich/ai/src/tests/buffalo_l_test.rs index cfb4c976f..0eeb0365d 100644 --- a/ahnlich/ai/src/tests/buffalo_l_test.rs +++ b/ahnlich/ai/src/tests/buffalo_l_test.rs @@ -91,6 +91,7 @@ async fn test_buffalo_l_face_detection() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -165,6 +166,7 @@ async fn test_buffalo_l_batch_multiple_images() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -259,6 +261,7 @@ async fn test_buffalo_l_no_faces() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -334,6 +337,7 @@ async fn test_buffalo_l_single_face() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -409,6 +413,7 @@ async fn test_buffalo_l_get_sim_n() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -603,6 +608,7 @@ async fn test_buffalo_l_get_sim_n_multi_face_query_errors() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -690,6 +696,7 @@ async fn test_buffalo_l_face_index_metadata() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, }; // Store the image @@ -847,6 +854,7 @@ async fn test_buffalo_l_mixed_batch_no_face_does_not_fail_batch() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -942,6 +950,7 @@ async fn test_buffalo_l_high_confidence_threshold() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -1002,6 +1011,7 @@ async fn test_buffalo_l_high_confidence_threshold() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -1102,6 +1112,7 @@ async fn test_buffalo_l_bounding_box_metadata() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1271,6 +1282,7 @@ async fn test_buffalo_l_gender_age_metadata() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1426,6 +1438,7 @@ async fn test_buffalo_l_gender_age_multi_face() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1620,6 +1633,7 @@ async fn test_buffalo_l_visualize_attributes() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1841,6 +1855,7 @@ async fn test_buffalo_l_without_genderage() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -1970,6 +1985,7 @@ async fn test_buffalo_l_genderage_opt_in() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { diff --git a/ahnlich/ai/src/tests/clap_test.rs b/ahnlich/ai/src/tests/clap_test.rs index 41e76833e..fdb884c30 100644 --- a/ahnlich/ai/src/tests/clap_test.rs +++ b/ahnlich/ai/src/tests/clap_test.rs @@ -128,6 +128,7 @@ async fn test_clap_cross_modal_audio_indexed_text_queried() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -217,6 +218,7 @@ async fn test_clap_audio_to_audio_retrieval() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -289,6 +291,7 @@ async fn test_clap_text_to_text_retrieval() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -402,6 +405,7 @@ async fn test_clap_audio_no_preprocessing_rejected() { non_linear_indices: vec![], error_if_exists: false, store_original: false, + schema: None, })), }], })) @@ -467,6 +471,7 @@ async fn test_clap_audio_too_long_rejected() { non_linear_indices: vec![], error_if_exists: false, store_original: false, + schema: None, })), }], })) @@ -533,6 +538,7 @@ async fn test_clap_short_audio_accepted() { non_linear_indices: vec![], error_if_exists: false, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { diff --git a/ahnlich/ai/src/tests/fixtures/ai_old_flat_snapshot.json b/ahnlich/ai/src/tests/fixtures/ai_old_flat_snapshot.json new file mode 100644 index 000000000..3774360d0 --- /dev/null +++ b/ahnlich/ai/src/tests/fixtures/ai_old_flat_snapshot.json @@ -0,0 +1,8 @@ +{ + "test_ai_store": { + "index_model": "AllMiniLmL6V2", + "name": "test_ai_store", + "query_model": "AllMiniLmL6V2", + "store_original": false + } +} \ No newline at end of file diff --git a/ahnlich/ai/src/tests/fixtures/ai_v2_snapshot.json b/ahnlich/ai/src/tests/fixtures/ai_v2_snapshot.json new file mode 100644 index 000000000..338e06688 --- /dev/null +++ b/ahnlich/ai/src/tests/fixtures/ai_v2_snapshot.json @@ -0,0 +1,13 @@ +{ + "db_version": "2", + "stores": { + "public": { + "test_ai_store": { + "name": "test_ai_store", + "index_model": "AllMiniLmL6V2", + "query_model": "AllMiniLmL6V2", + "store_original": false + } + } + } +} diff --git a/ahnlich/ai/src/tests/jina_code_test.rs b/ahnlich/ai/src/tests/jina_code_test.rs index 960a1da0e..8d3dd01b0 100644 --- a/ahnlich/ai/src/tests/jina_code_test.rs +++ b/ahnlich/ai/src/tests/jina_code_test.rs @@ -71,6 +71,7 @@ async fn test_jina_code_model_loads_and_produces_embeddings() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }; @@ -174,6 +175,7 @@ app.listen(3000);"#; non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }; @@ -342,6 +344,7 @@ async fn test_jina_code_natural_language_query() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }; @@ -467,6 +470,7 @@ async fn test_jina_code_embedding_dimensions() { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, })), }; @@ -490,7 +494,9 @@ async fn test_jina_code_embedding_dimensions() { // List stores to check dimensions let list_stores_query = ai_pipeline::AiQuery { - query: Some(Query::ListStores(ai_query_types::ListStores {})), + query: Some(Query::ListStores(ai_query_types::ListStores { + schema: None, + })), }; let pipelined_request = ai_pipeline::AiRequestPipeline { diff --git a/ahnlich/ai/src/tests/migration_test.rs b/ahnlich/ai/src/tests/migration_test.rs new file mode 100644 index 000000000..9ab55756c --- /dev/null +++ b/ahnlich/ai/src/tests/migration_test.rs @@ -0,0 +1,118 @@ +use crate::engine::store::{AIStoreHandler, AIStores}; +use ahnlich_types::schema::Schema; +use serde_json::json; + +#[test] +fn test_ai_migrate_old_flat_snapshot_via_json() { + // Construct old-format JSON: HashMap + // Where AIStore has name (serialized as string), query_model, index_model, store_original + let old_format = json!({ + "test_ai_store": { + "name": "test_ai_store", + "query_model": "AllMiniLmL6V2", + "index_model": "AllMiniLmL6V2", + "store_original": false + } + }); + + let json_bytes = serde_json::to_vec(&old_format).expect("Failed to serialize old format"); + + let migrated: AIStores = AIStoreHandler::load_snapshot(&json_bytes).expect("Migration failed"); + + let guard = migrated.guard(); + let inner = migrated + .get(&Schema::default(), &guard) + .expect("No public schema after migration"); + assert_eq!(inner.len(), 1, "Expected 1 AI store under public schema"); +} + +#[test] +fn test_ai_migrate_old_flat_snapshot_via_file() { + // Write fixture file + let old_format = json!({ + "test_ai_store": { + "name": "test_ai_store", + "query_model": "AllMiniLmL6V2", + "index_model": "AllMiniLmL6V2", + "store_original": false + } + }); + + let fixture_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures"); + std::fs::create_dir_all(&fixture_dir).expect("Failed to create fixtures dir"); + let fixture_path = fixture_dir.join("ai_old_flat_snapshot.json"); + let json_bytes = serde_json::to_vec_pretty(&old_format).expect("Failed to serialize"); + std::fs::write(&fixture_path, &json_bytes).expect("Failed to write fixture"); + + // Read back and migrate + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + let migrated: AIStores = + AIStoreHandler::load_snapshot(&read_bytes).expect("Migration of fixture failed"); + + let guard = migrated.guard(); + let inner = migrated + .get(&Schema::default(), &guard) + .expect("No public schema after migration"); + assert_eq!(inner.len(), 1, "Expected 1 AI store under public schema"); +} + +#[test] +fn test_ai_migrate_from_committed_fixture() { + let fixture_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures") + .join("ai_old_flat_snapshot.json"); + + assert!( + fixture_path.exists(), + "Committed fixture not found: {:?}", + fixture_path + ); + + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + + let migrated: AIStores = + AIStoreHandler::load_snapshot(&read_bytes).expect("Migration of fixture failed"); + + let guard = migrated.guard(); + let inner = migrated + .get(&Schema::default(), &guard) + .expect("No public schema after migration"); + assert_eq!(inner.len(), 1, "Expected 1 AI store under public schema"); + let pinned = inner.pin(); + let (key, _) = pinned.iter().next().expect("No store in result"); + assert_eq!( + key.value, "test_ai_store", + "Store name preserved after migration" + ); +} + +#[test] +fn test_ai_load_v2_snapshot() { + let fixture_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures") + .join("ai_v2_snapshot.json"); + + assert!( + fixture_path.exists(), + "V2 fixture not found: {:?}", + fixture_path + ); + + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + let loaded: AIStores = AIStoreHandler::load_snapshot(&read_bytes).expect("V2 load failed"); + let guard = loaded.guard(); + let inner = loaded + .get(&Schema::default(), &guard) + .expect("No public schema after V2 load"); + assert_eq!(inner.len(), 1, "Expected 1 AI store under public schema"); + let pinned = inner.pin(); + let (key, _) = pinned.iter().next().expect("No store in result"); + assert_eq!(key.value, "test_ai_store", "Store name preserved in V2"); +} diff --git a/ahnlich/ai/src/tests/mod.rs b/ahnlich/ai/src/tests/mod.rs index d5676cb23..705b25449 100644 --- a/ahnlich/ai/src/tests/mod.rs +++ b/ahnlich/ai/src/tests/mod.rs @@ -2,4 +2,5 @@ mod aiproxy_test; mod buffalo_l_test; mod clap_test; mod jina_code_test; +mod migration_test; mod sface_yunet_test; diff --git a/ahnlich/ai/src/tests/sface_yunet_test.rs b/ahnlich/ai/src/tests/sface_yunet_test.rs index fd66cfb32..8a87e7275 100644 --- a/ahnlich/ai/src/tests/sface_yunet_test.rs +++ b/ahnlich/ai/src/tests/sface_yunet_test.rs @@ -75,6 +75,7 @@ async fn test_sface_yunet_face_detection() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -154,6 +155,7 @@ async fn test_sface_yunet_single_face() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -227,6 +229,7 @@ async fn test_sface_yunet_no_faces() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -302,6 +305,7 @@ async fn test_sface_yunet_get_sim_n() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -420,6 +424,7 @@ async fn test_sface_yunet_multi_face_query_errors() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -508,6 +513,7 @@ async fn test_sface_yunet_mixed_batch_no_face_does_not_fail_batch() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { @@ -602,6 +608,7 @@ async fn test_sface_yunet_high_confidence_threshold() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -659,6 +666,7 @@ async fn test_sface_yunet_high_confidence_threshold() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }; @@ -759,6 +767,7 @@ async fn test_sface_yunet_bounding_box_metadata() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })), }, ai_pipeline::AiQuery { diff --git a/ahnlich/client/src/ai.rs b/ahnlich/client/src/ai.rs index 9563064f9..499251ce0 100644 --- a/ahnlich/client/src/ai.rs +++ b/ahnlich/client/src/ai.rs @@ -113,7 +113,8 @@ impl AiPipeline { } pub fn list_stores(&mut self) { - self.queries.push(Query::ListStores(ListStores {})); + self.queries + .push(Query::ListStores(ListStores { schema: None })); } pub fn list_clients(&mut self) { @@ -348,14 +349,17 @@ impl AiClient { store: String, tracing_id: Option, ) -> Result { - let mut req = tonic::Request::new(GetStore { store }); + let mut req = tonic::Request::new(GetStore { + store, + schema: None, + }); add_trace_parent(&mut req, tracing_id); add_auth_header(&mut req, &self.auth_token); Ok(self.client.clone().get_store(req).await?.into_inner()) } pub async fn list_stores(&self, tracing_id: Option) -> Result { - let mut req = tonic::Request::new(ListStores {}); + let mut req = tonic::Request::new(ListStores { schema: None }); add_trace_parent(&mut req, tracing_id); add_auth_header(&mut req, &self.auth_token); Ok(self.client.clone().list_stores(req).await?.into_inner()) @@ -544,6 +548,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; let create_store_params_2 = CreateStore { @@ -554,6 +559,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; let create_store_params_no_error = CreateStore { @@ -564,6 +570,7 @@ mod test { non_linear_indices: vec![], error_if_exists: false, store_original: true, + schema: None, }; pipeline.create_store(create_store_params); @@ -578,6 +585,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params); @@ -649,6 +657,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; assert!( @@ -715,6 +724,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params); @@ -726,6 +736,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params_2); @@ -737,6 +748,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params_3); @@ -745,6 +757,7 @@ mod test { let drop_store_params = DropStore { store: "Less".into(), error_if_not_exists: true, + schema: None, }; pipeline.drop_store(drop_store_params); @@ -820,6 +833,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params); @@ -1012,6 +1026,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params); @@ -1190,6 +1205,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; pipeline.create_store(create_store_params); @@ -1325,6 +1341,7 @@ mod test { non_linear_indices: vec![], error_if_exists: true, store_original: true, + schema: None, }; let mut pipeline = ai_client.pipeline(None); diff --git a/ahnlich/client/src/db.rs b/ahnlich/client/src/db.rs index 7765e3112..4d48ffc9c 100644 --- a/ahnlich/client/src/db.rs +++ b/ahnlich/client/src/db.rs @@ -104,7 +104,8 @@ impl DbPipeline { } pub fn list_stores(&mut self) { - self.queries.push(Query::ListStores(ListStores {})); + self.queries + .push(Query::ListStores(ListStores { schema: None })); } pub fn list_clients(&mut self) { @@ -347,14 +348,17 @@ impl DbClient { store: String, tracing_id: Option, ) -> Result { - let mut req = tonic::Request::new(GetStore { store }); + let mut req = tonic::Request::new(GetStore { + store, + schema: None, + }); add_trace_parent(&mut req, tracing_id); add_auth_header(&mut req, &self.auth_token); Ok(self.client.clone().get_store(req).await?.into_inner()) } pub async fn list_stores(&self, tracing_id: Option) -> Result { - let mut req = tonic::Request::new(ListStores {}); + let mut req = tonic::Request::new(ListStores { schema: None }); add_trace_parent(&mut req, tracing_id); add_auth_header(&mut req, &self.auth_token); Ok(self.client.clone().list_stores(req).await?.into_inner()) @@ -451,6 +455,7 @@ mod test { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, }); pipeline.create_store(CreateStore { store: "Main".to_string(), @@ -458,6 +463,7 @@ mod test { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, }); pipeline.create_store(CreateStore { store: "Main".to_string(), @@ -465,6 +471,7 @@ mod test { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: false, + schema: None, }); pipeline.list_stores(); @@ -525,6 +532,7 @@ mod test { dimension: 3, non_linear_indices: vec![], error_if_exists: true, + schema: None, }; assert!( @@ -720,6 +728,7 @@ mod test { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, }); pipeline.create_store(CreateStore { store: "Main".to_string(), @@ -727,6 +736,7 @@ mod test { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, }); pipeline.create_store(CreateStore { store: "Main".to_string(), @@ -734,6 +744,7 @@ mod test { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: false, + schema: None, }); pipeline.list_stores(); @@ -811,6 +822,7 @@ mod test { index: Some(non_linear_index::Index::Kdtree(KdTreeConfig {})), }], error_if_exists: true, + schema: None, }; assert!( @@ -931,6 +943,7 @@ mod test { dimension: 3, non_linear_indices: vec![], error_if_exists: true, + schema: None, }; assert!( diff --git a/ahnlich/db/benches/database.rs b/ahnlich/db/benches/database.rs index 22d9983bb..dbc88e332 100644 --- a/ahnlich/db/benches/database.rs +++ b/ahnlich/db/benches/database.rs @@ -6,6 +6,7 @@ use ahnlich_types::keyval::StoreName; use ahnlich_types::keyval::StoreValue; use ahnlich_types::metadata::MetadataValue; use ahnlich_types::predicates::{Predicate, PredicateCondition, predicate::Kind as PredicateKind}; +use ahnlich_types::schema::Schema; use criterion::{Criterion, criterion_group, criterion_main}; use rayon::iter::ParallelIterator; @@ -38,8 +39,7 @@ fn generate_storekey_store_value(size: usize, dimension: usize) -> Vec<(StoreKey fn initialize_store_handler() -> Arc { let write_flag = Arc::new(AtomicBool::new(false)); - let handler = Arc::new(StoreHandler::new(write_flag)); - handler + Arc::new(StoreHandler::new(write_flag)) } fn bench_retrieval(c: &mut Criterion) { @@ -67,6 +67,7 @@ fn bench_retrieval(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::new(), @@ -124,6 +125,7 @@ fn bench_retrieval(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::from_iter([non_linear_index::Index::Kdtree(KdTreeConfig {})]), @@ -181,6 +183,7 @@ fn bench_retrieval(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::from_iter([non_linear_index::Index::Hnsw(HnswConfig { @@ -252,6 +255,7 @@ fn bench_retrieval(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::new(), @@ -304,13 +308,13 @@ fn bench_insertion(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::new(), true, ) .unwrap(); - let dimension = dimension.clone(); let random_array = vec![( StoreKey { key: (0..dimension) @@ -351,6 +355,7 @@ fn bench_insertion(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::new(), @@ -389,6 +394,7 @@ fn bench_predicate_queries(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], // No predicate indices HashSet::new(), @@ -478,6 +484,7 @@ fn bench_predicate_queries(c: &mut Criterion) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec!["category".to_string()], // WITH predicate index HashSet::new(), diff --git a/ahnlich/db/benches/memory_profile.rs b/ahnlich/db/benches/memory_profile.rs index d3b36099a..d3c0cae03 100644 --- a/ahnlich/db/benches/memory_profile.rs +++ b/ahnlich/db/benches/memory_profile.rs @@ -5,6 +5,7 @@ use ahnlich_types::keyval::StoreName; use ahnlich_types::keyval::StoreValue; use ahnlich_types::metadata::MetadataValue; use ahnlich_types::predicates::{Predicate, PredicateCondition, predicate::Kind as PredicateKind}; +use ahnlich_types::schema::Schema; use std::collections::HashMap; use std::collections::HashSet; use std::num::NonZeroUsize; @@ -36,6 +37,7 @@ fn profile_batch_insertion(size: usize) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::new(), @@ -75,6 +77,7 @@ fn profile_similarity_queries(size: usize, num_queries: usize) { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], HashSet::new(), @@ -141,6 +144,7 @@ fn profile_predicate_queries(size: usize, num_queries: usize, with_index: bool) StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), predicate_indices, HashSet::new(), diff --git a/ahnlich/db/benches/persistence.rs b/ahnlich/db/benches/persistence.rs index f0f0b553f..458d7a367 100644 --- a/ahnlich/db/benches/persistence.rs +++ b/ahnlich/db/benches/persistence.rs @@ -3,7 +3,7 @@ use ahnlich_db::engine::store::StoreHandler; use ahnlich_types::algorithm::nonlinear::{HnswConfig, non_linear_index}; use ahnlich_types::keyval::{StoreKey, StoreName, StoreValue}; use ahnlich_types::metadata::MetadataValue; -use chrono; +use ahnlich_types::schema::Schema; use criterion::{Criterion, criterion_group, criterion_main}; use std::collections::HashMap; use std::collections::HashSet; @@ -98,6 +98,7 @@ fn create_test_store_with_data( handler .create_store( store_name.clone(), + &Schema::default(), NonZeroUsize::new(dimension).unwrap(), vec![], non_linear_indices, diff --git a/ahnlich/db/src/engine/mod.rs b/ahnlich/db/src/engine/mod.rs index 94a70afcf..ebfb475bf 100644 --- a/ahnlich/db/src/engine/mod.rs +++ b/ahnlich/db/src/engine/mod.rs @@ -1,3 +1,4 @@ pub mod operations; mod predicate; pub mod store; +pub mod versioned; diff --git a/ahnlich/db/src/engine/operations.rs b/ahnlich/db/src/engine/operations.rs index 7d518c921..2c8f0d7b1 100644 --- a/ahnlich/db/src/engine/operations.rs +++ b/ahnlich/db/src/engine/operations.rs @@ -1,10 +1,13 @@ use std::collections::HashMap; +use std::collections::HashSet as StdHashSet; use std::num::NonZeroUsize; use ahnlich_types::algorithm::nonlinear::NonLinearAlgorithm; +use ahnlich_types::algorithm::nonlinear::non_linear_index; use ahnlich_types::db::query; use ahnlich_types::db::server; use ahnlich_types::keyval::{StoreKey, StoreName, StoreValue}; +use ahnlich_types::schema::Schema; use ahnlich_types::shared::info::StoreUpsert; use itertools::Itertools; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -12,6 +15,15 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator}; use crate::engine::store::StoreHandler; use crate::errors::ServerError; +fn resolve_schema(schema: &Option) -> Result { + match schema { + Some(s) => { + Schema::try_new(s.clone()).map_err(|e| ServerError::InvalidArgument(e.to_owned())) + } + None => Ok(Schema::default()), + } +} + pub fn create_store( store_handler: &StoreHandler, params: query::CreateStore, @@ -20,16 +32,19 @@ pub fn create_store( ServerError::InvalidArgument("dimension must be greater than 0".to_owned()) })?; - let non_linear_indices = params + let non_linear_indices: StdHashSet = params .non_linear_indices .into_iter() .filter_map(|index| index.index) .collect(); + let schema = resolve_schema(¶ms.schema)?; + store_handler.create_store( StoreName { value: params.store, }, + &schema, dimensions, params.create_predicates, non_linear_indices, @@ -53,7 +68,7 @@ pub fn create_non_linear_algorithm_index( store_handler: &StoreHandler, params: query::CreateNonLinearAlgorithmIndex, ) -> Result { - let non_linear_indices = params + let non_linear_indices: StdHashSet = params .non_linear_indices .into_iter() .filter_map(|val| val.index) @@ -84,7 +99,7 @@ pub fn drop_non_linear_algorithm_index( store_handler: &StoreHandler, params: query::DropNonLinearAlgorithmIndex, ) -> Result { - let non_linear_indices = params + let non_linear_indices: StdHashSet = params .non_linear_indices .into_iter() .filter_map(|val| NonLinearAlgorithm::try_from(val).ok()) @@ -134,10 +149,12 @@ pub fn drop_store( store_handler: &StoreHandler, params: query::DropStore, ) -> Result { + let schema = resolve_schema(¶ms.schema)?; store_handler.drop_store( StoreName { value: params.store, }, + &schema, params.error_if_not_exists, ) } @@ -166,7 +183,26 @@ pub fn set(store_handler: &StoreHandler, params: query::Set) -> Result server::StoreList { - let stores = store_handler.list_stores().into_iter().sorted().collect(); +pub fn list_stores(store_handler: &StoreHandler, params: query::ListStores) -> server::StoreList { + let schema = params + .schema + .as_ref() + .filter(|s| !s.is_empty()) + .map(|s| Schema::new(s.clone())); + let stores = store_handler + .list_stores(schema.as_ref()) + .into_iter() + .sorted() + .collect(); server::StoreList { stores } } + +pub fn drop_schema( + store_handler: &StoreHandler, + params: query::DropSchema, +) -> Result { + let schema = + Schema::try_new(params.schema).map_err(|e| ServerError::InvalidArgument(e.to_owned()))?; + let dropped = store_handler.drop_schema(&schema)?; + Ok(dropped as u64) +} diff --git a/ahnlich/db/src/engine/store.rs b/ahnlich/db/src/engine/store.rs index b4c0e2f5e..1b90e92ca 100644 --- a/ahnlich/db/src/engine/store.rs +++ b/ahnlich/db/src/engine/store.rs @@ -14,6 +14,7 @@ use ahnlich_types::keyval::{StoreKey, StoreValue}; use ahnlich_types::predicates::{ self, Predicate, PredicateCondition, predicate::Kind as PredicateKind, }; +use ahnlich_types::schema::Schema; use ahnlich_types::shared::info::StoreUpsert; use ahnlich_types::similarity::Similarity; use papaya::HashMap as ConcurrentHashMap; @@ -28,6 +29,7 @@ use std::sync::atomic::Ordering; use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize}; use utils::fallible; use utils::persistence::AhnlichPersistenceUtils; +use utils::persistence::VersionedPersistence; type StoreEntry = (EmbeddingKey, Arc); type StoreEntryWithSimilarity = (EmbeddingKey, Arc, Similarity); @@ -82,10 +84,11 @@ pub struct StoreHandler { /// Making use of a concurrent hashmap, we should be able to create an engine that manages stores stores: Stores, pub write_flag: Arc, + default_schema: Schema, } impl AhnlichPersistenceUtils for StoreHandler { - type PersistenceObject = Stores; + type PersistenceObject = super::versioned::VersionedDbStores; #[tracing::instrument(skip_all)] fn write_flag(&self) -> Arc { @@ -94,38 +97,43 @@ impl AhnlichPersistenceUtils for StoreHandler { #[tracing::instrument(skip(self))] fn get_snapshot(&self) -> Self::PersistenceObject { - self.stores.clone() + super::versioned::VersionedDbStores::current(self.stores.clone()) } } impl utils::size_calculation::SizeCalculationHandler for StoresSnapshot { #[tracing::instrument(skip(self))] fn recalculate_all_sizes(&self) { - for (store_name, store) in self.0.iter(&self.0.guard()) { - // Only recalculate if this store has been modified - if store - .size_dirty - .compare_exchange(true, false, Ordering::Relaxed, Ordering::Relaxed) - .is_ok() - { - let len = store.len(); - let size = store.size(); - store.cached_len.store(len as u64, Ordering::Relaxed); - store - .cached_size_bytes - .store(size as u64, Ordering::Relaxed); - log::trace!( - "Recalculated size for store '{}': {} entries, {} bytes", - store_name.value, - len, - size - ); + let guard = self.0.guard(); + for (_schema, inner_stores) in self.0.iter(&guard) { + let inner_guard = inner_stores.guard(); + for (store_name, store) in inner_stores.iter(&inner_guard) { + // Only recalculate if this store has been modified + if store + .size_dirty + .compare_exchange(true, false, Ordering::Relaxed, Ordering::Relaxed) + .is_ok() + { + let len = store.len(); + let size = store.size(); + store.cached_len.store(len as u64, Ordering::Relaxed); + store + .cached_size_bytes + .store(size as u64, Ordering::Relaxed); + log::trace!( + "Recalculated size for store '{}': {} entries, {} bytes", + store_name.value, + len, + size + ); + } } } } } -pub type Stores = Arc>>; +pub type InnerStores = Arc>>; +pub type Stores = Arc>; /// Newtype wrapper around Stores to implement SizeCalculationHandler /// (orphan rule prevents implementing foreign traits on Arc directly) @@ -154,6 +162,7 @@ impl StoreHandler { std::process::abort(); }), write_flag, + default_schema: Schema::default(), } } @@ -179,15 +188,51 @@ impl StoreHandler { self.stores = stores_snapshot; } - /// Returns a store using the store name, else returns an error + /// Loads and migrates a persistence snapshot using the versioned format. + pub(crate) fn load_snapshot( + bytes: &[u8], + ) -> Result { + let versioned = super::versioned::VersionedDbStores::load_and_migrate(bytes)?; + versioned + .into_latest() + .map_err(utils::persistence::PersistenceTaskError::MigrationError) + } + + /// Returns the inner stores map for a given schema, creating it if it does not exist. + fn get_or_create_schema(&self, schema: &Schema) -> InnerStores { + let guard = self.stores.guard(); + if let Some(inner) = self.stores.get(schema, &guard) { + return inner.clone(); + } + drop(guard); + let new_inner: InnerStores = + fallible::try_new_arc_hashmap().expect("Failed to create inner stores map for schema"); + let guard = self.stores.guard(); + match self + .stores + .try_insert(schema.clone(), new_inner.clone(), &guard) + { + Ok(_) => new_inner, + Err(existing) => existing.current.clone(), + } + } + + /// Returns the inner stores map for a given schema, or `None` if the schema does not exist. + fn get_schema(&self, schema: &Schema) -> Option { + self.stores.get(schema, &self.stores.guard()).cloned() + } + + /// Returns a store using the store name and default schema, else returns an error #[tracing::instrument(skip(self))] fn get(&self, store_name: &StoreName) -> Result, ServerError> { - let store = self - .stores - .get(store_name, &self.stores.guard()) - .cloned() - .ok_or(ServerError::StoreNotFound(store_name.clone()))?; - Ok(store) + let guard = self.stores.guard(); + if let Some(inner_stores) = self.stores.get(&self.default_schema, &guard) { + let inner_guard = inner_stores.guard(); + if let Some(store) = inner_stores.get(store_name, &inner_guard) { + return Ok(store.clone()); + } + } + Err(ServerError::StoreNotFound(store_name.clone())) } /// Matches CREATEPREDINDEX - reindexes a store with some predicate values @@ -195,7 +240,6 @@ impl StoreHandler { pub(crate) fn create_pred_index( &self, store_name: &StoreName, - // TODO: create grpc datatype for metadata key predicates: Vec, ) -> Result { let store = self.get(store_name)?; @@ -363,10 +407,20 @@ impl StoreHandler { /// matches LISTSTORES - to return statistics of all stores #[tracing::instrument(skip(self))] - pub(crate) fn list_stores(&self) -> StdHashSet { - self.stores - .iter(&self.stores.guard()) - .map(|(store_name, store)| { + pub(crate) fn list_stores(&self, schema: Option<&Schema>) -> StdHashSet { + let guard = self.stores.guard(); + let mut result = StdHashSet::new(); + let schemas: Vec = if let Some(schema) = schema { + self.stores + .get(schema, &guard) + .map(|s| vec![s.clone()]) + .unwrap_or_default() + } else { + self.stores.iter(&guard).map(|(_, v)| v.clone()).collect() + }; + for inner_stores in schemas { + let inner_guard = inner_stores.guard(); + for (store_name, store) in inner_stores.iter(&inner_guard) { // Lazy initialization: if size is dirty (e.g., newly created store), // calculate it immediately. Background task will handle future updates. let (len, size_in_bytes) = if store.size_dirty.load(Ordering::Relaxed) { @@ -385,7 +439,7 @@ impl StoreHandler { ) }; - StoreInfo { + result.insert(StoreInfo { name: store_name.clone().value, len, size_in_bytes, @@ -397,15 +451,26 @@ impl StoreHandler { .sorted() .collect(), dimension: store.dimension.get() as u32, - } - }) - .collect() + }); + } + } + result } /// Matches GETSTORE - Returns detailed info for a single store by name #[tracing::instrument(skip(self))] - pub(crate) fn get_store(&self, store_name: &StoreName) -> Result { - let store = self.get(store_name)?; + pub(crate) fn get_store( + &self, + store_name: &StoreName, + schema: &Schema, + ) -> Result { + let inner_stores = self + .get_schema(schema) + .ok_or_else(|| ServerError::StoreNotFound(store_name.clone()))?; + let guard = inner_stores.guard(); + let store = inner_stores + .get(store_name, &guard) + .ok_or_else(|| ServerError::StoreNotFound(store_name.clone()))?; let (len, size_in_bytes) = if store.size_dirty.load(Ordering::Relaxed) { let len = store.len(); let size = store.size(); @@ -442,18 +507,18 @@ impl StoreHandler { pub fn create_store( &self, store_name: StoreName, + schema: &Schema, dimension: NonZeroUsize, - // FIXME: update metadata key with grpc type key predicates: Vec, non_linear_indices: StdHashSet, error_if_exists: bool, ) -> Result<(), ServerError> { - if self - .stores + let inner_stores = self.get_or_create_schema(schema); + if inner_stores .try_insert( store_name.clone(), Arc::new(Store::create(dimension, predicates, non_linear_indices)), - &self.stores.guard(), + &inner_stores.guard(), ) .is_err() && error_if_exists @@ -504,9 +569,15 @@ impl StoreHandler { pub(crate) fn drop_store( &self, store_name: StoreName, + schema: &Schema, error_if_not_exists: bool, ) -> Result { - let pinned = self.stores.pin(); + let inner_stores = match self.get_schema(schema) { + Some(inner) => inner, + None if error_if_not_exists => return Err(ServerError::StoreNotFound(store_name)), + None => return Ok(0), + }; + let pinned = inner_stores.pin(); let removed = pinned.remove(&store_name).is_some(); if !removed && error_if_not_exists { return Err(ServerError::StoreNotFound(store_name)); @@ -519,6 +590,29 @@ impl StoreHandler { }; Ok(removed) } + + /// Drops all stores within a schema and removes the schema. + /// Returns the number of stores dropped. + #[tracing::instrument(skip(self))] + pub(crate) fn drop_schema(&self, schema: &Schema) -> Result { + if schema.as_str() == Schema::DEFAULT_NAME { + return Err(ServerError::InvalidArgument(format!( + "Cannot drop the default '{}' schema", + Schema::DEFAULT_NAME + ))); + } + let pinned = self.stores.pin(); + let removed = pinned.remove(schema); + match removed { + Some(inner) => { + let pinned = inner.pin(); + let count = pinned.len(); + self.set_write_flag(); + Ok(count) + } + None => Ok(0), + } + } } /// A Store is a single database containing multiple N*1 arrays where N is the dimension of the @@ -1069,6 +1163,7 @@ mod tests { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(size).unwrap(), predicates, StdHashSet::new(), @@ -1101,6 +1196,7 @@ mod tests { StoreName { value: store_name.to_string(), }, + &Schema::default(), NonZeroUsize::new(size).unwrap(), predicates, StdHashSet::new(), @@ -1666,7 +1762,7 @@ mod tests { )], ) .unwrap(); - let stores = handler.list_stores(); + let stores = handler.list_stores(None); assert_eq!( stores, StdHashSet::from_iter([ diff --git a/ahnlich/db/src/engine/versioned.rs b/ahnlich/db/src/engine/versioned.rs new file mode 100644 index 000000000..e842c35c3 --- /dev/null +++ b/ahnlich/db/src/engine/versioned.rs @@ -0,0 +1,139 @@ +use std::collections::HashMap; +use std::sync::Arc; + +use ahnlich_types::keyval::StoreName; +use ahnlich_types::schema::Schema; +use serde::{Deserialize, Serialize}; +use utils::fallible; +use utils::persistence::{PersistenceTaskError, VersionedPersistence}; + +use super::store::{Store, Stores}; + +pub const DB_CURRENT_VERSION: u32 = 2; +pub const DB_MIN_VERSION: u32 = 1; + +type DbStoresV1 = HashMap; +type DbStoresV2 = HashMap; + +#[derive(Debug, Deserialize)] +struct TaggedDbStoresV1 { + stores: DbStoresV1, +} + +#[derive(Debug, Deserialize)] +struct TaggedDbStoresV2 { + stores: DbStoresV2, +} + +#[derive(Debug, Deserialize)] +struct DbVersionTag { + db_version: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(tag = "db_version")] +pub enum VersionedDbStores { + #[serde(rename = "1")] + V1 { stores: DbStoresV1 }, + + #[serde(rename = "2")] + V2 { stores: Stores }, +} + +impl VersionedPersistence for VersionedDbStores { + const CURRENT_VERSION: u32 = DB_CURRENT_VERSION; + const MIN_VERSION: u32 = DB_MIN_VERSION; + + fn load_and_migrate(bytes: &[u8]) -> Result { + Self::validate_version(bytes)?; + + match Self::snapshot_version(bytes) { + Some(1) => { + let tagged: TaggedDbStoresV1 = serde_json::from_slice(bytes)?; + Ok(VersionedDbStores::V1 { + stores: tagged.stores, + }) + } + Some(2) => { + let tagged: TaggedDbStoresV2 = serde_json::from_slice(bytes)?; + let stores = Self::migrate_v1n_to_v2(tagged.stores) + .map_err(PersistenceTaskError::MigrationError)?; + Ok(VersionedDbStores::V2 { stores }) + } + _ => { + if let Ok(nested) = serde_json::from_slice::(bytes) { + log::warn!("No db_version tag, detected schema-nested (V1n) format"); + let stores = Self::migrate_v1n_to_v2(nested) + .map_err(PersistenceTaskError::MigrationError)?; + return Ok(VersionedDbStores::V2 { stores }); + } + log::warn!("No db_version tag, attempting bare V1 load"); + let v1_stores: DbStoresV1 = serde_json::from_slice(bytes)?; + Ok(VersionedDbStores::V1 { stores: v1_stores }) + } + } + } +} + +impl VersionedDbStores { + fn snapshot_version(bytes: &[u8]) -> Option { + serde_json::from_slice::(bytes) + .ok() + .and_then(|tag| tag.db_version) + .and_then(|version| version.parse::().ok()) + } + + fn migrate_v1n_to_v2(v1_nested: DbStoresV2) -> Result { + let stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + for (schema_name, inner) in v1_nested { + let inner_stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + { + let guard = inner_stores.pin(); + for (name, store) in inner { + guard.insert(name, Arc::new(store)); + } + } + { + let guard = stores.pin(); + guard.insert(schema_name, inner_stores); + } + } + Ok(stores) + } +} + +impl VersionedDbStores { + pub fn into_latest(self) -> Result { + match self { + VersionedDbStores::V1 { stores } => { + log::info!("Migrating DB stores V1 → V2"); + Self::migrate_v1_to_v2(stores) + } + VersionedDbStores::V2 { stores } => Ok(stores), + } + } + + pub fn current(stores: Stores) -> Self { + VersionedDbStores::V2 { stores } + } + + fn migrate_v1_to_v2(v1_stores: DbStoresV1) -> Result { + let inner_stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + { + let guard = inner_stores.pin(); + for (name, store) in v1_stores { + guard.insert(name, Arc::new(store)); + } + } + let stores = + fallible::try_new_arc_hashmap().map_err(|e| format!("Migration failed: {e}"))?; + { + let guard = stores.pin(); + guard.insert(Schema::default(), inner_stores); + } + Ok(stores) + } +} diff --git a/ahnlich/db/src/replication/mod.rs b/ahnlich/db/src/replication/mod.rs index 550417cd3..4d7ca9d13 100644 --- a/ahnlich/db/src/replication/mod.rs +++ b/ahnlich/db/src/replication/mod.rs @@ -161,11 +161,21 @@ impl StateMachineHandler for DbStateMachine { encode_raw_result!(query::DropStore, &dropped) } + DbCommand::DropSchema(payload) => { + let params = decode_payload!(query::DropSchema, payload)?; + let dropped = operations::drop_schema(&self.store_handler, params) + .map_err(|err| operation_error!(query::DropSchema, err))?; + + encode_raw_result!(query::DropSchema, &dropped) + } } } fn get_snapshot(&self) -> Self::Snapshot { - self.store_handler.get_snapshot() + self.store_handler + .get_snapshot() + .into_latest() + .expect("snapshot should be at latest version") } fn restore_snapshot(&mut self, snapshot: Self::Snapshot) { @@ -204,6 +214,7 @@ mod tests { create_predicates: Vec::new(), non_linear_indices: Vec::new(), error_if_exists: true, + schema: None, } } @@ -223,6 +234,7 @@ mod tests { query::DropStore { store: store.to_owned(), error_if_not_exists: true, + schema: None, } } @@ -272,7 +284,10 @@ mod tests { } ); - let stores = operations::list_stores(state_machine.store_handler()); + let stores = operations::list_stores( + state_machine.store_handler(), + query::ListStores { schema: None }, + ); assert_eq!(stores.stores.len(), 1); assert_eq!(stores.stores[0].name, "products"); assert_eq!(stores.stores[0].len, 1); @@ -307,9 +322,12 @@ mod tests { let deleted_count = decode_count_response(response); assert_eq!(deleted_count, 1); assert!( - operations::list_stores(state_machine.store_handler()) - .stores - .is_empty() + operations::list_stores( + state_machine.store_handler(), + query::ListStores { schema: None } + ) + .stores + .is_empty() ); } @@ -323,9 +341,12 @@ mod tests { assert!(matches!(err, StorageError::IO { .. })); assert!( - operations::list_stores(state_machine.store_handler()) - .stores - .is_empty() + operations::list_stores( + state_machine.store_handler(), + query::ListStores { schema: None } + ) + .stores + .is_empty() ); assert!( !state_machine diff --git a/ahnlich/db/src/server/cluster_queries.rs b/ahnlich/db/src/server/cluster_queries.rs index 7cb00a3f4..33045d21d 100644 --- a/ahnlich/db/src/server/cluster_queries.rs +++ b/ahnlich/db/src/server/cluster_queries.rs @@ -4,7 +4,7 @@ use crate::errors::ServerError; use crate::server::store_runtime::StoreRuntime; use ahnlich_replication::cluster_info; use ahnlich_replication::node::ReplicationNode; -use ahnlich_types::db::server; +use ahnlich_types::db::{query, server}; use ahnlich_types::shared::cluster::{ ClusterInfoResponse, ClusterNode, NodeHealthStatus as PublicNodeHealthStatus, NodeRole as PublicNodeRole, @@ -55,6 +55,7 @@ pub(crate) fn read_store_handler( pub(crate) async fn list_stores_response( runtime: &StoreRuntime, + params: query::ListStores, ) -> Result { if let Some(cluster) = runtime.cluster() { cluster @@ -65,7 +66,7 @@ pub(crate) async fn list_stores_response( } read_store_handler(runtime, |store_handler| { - Ok(operations::list_stores(store_handler)) + Ok(operations::list_stores(store_handler, params)) }) } diff --git a/ahnlich/db/src/server/handler.rs b/ahnlich/db/src/server/handler.rs index 83e70fe4f..61e620db2 100644 --- a/ahnlich/db/src/server/handler.rs +++ b/ahnlich/db/src/server/handler.rs @@ -14,6 +14,7 @@ use ahnlich_replication::types::DbCommand; use ahnlich_types::db::pipeline::db_query::Query; use ahnlich_types::db::server::GetSimNEntry; use ahnlich_types::keyval::{DbStoreEntry, StoreKey, StoreName}; +use ahnlich_types::schema::Schema; use ahnlich_types::services::db_service::db_service_server::{DbService, DbServiceServer}; use ahnlich_types::shared::cluster::{ClusterInfoQuery, ClusterInfoResponse}; use ahnlich_types::shared::info::ErrorResponse; @@ -354,6 +355,33 @@ impl DbService for Server { Ok(tonic::Response::new(server::Del { deleted_count })) } + #[tracing::instrument(skip_all)] + async fn drop_schema( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + let params = request.into_inner(); + + let dropped = match &self.runtime { + StoreRuntime::Cluster(cluster) => { + submit_db_command!( + Some(cluster), + query::DropSchema, + params, + DbCommand::DropSchema + ) + .await? + } + StoreRuntime::Standalone(store_handler) => { + operations::drop_schema(store_handler, params)? + } + }; + + Ok(tonic::Response::new(server::Del { + deleted_count: dropped, + })) + } + #[tracing::instrument(skip_all)] async fn list_clients( &self, @@ -375,9 +403,9 @@ impl DbService for Server { #[tracing::instrument(skip_all)] async fn list_stores( &self, - _request: tonic::Request, + request: tonic::Request, ) -> std::result::Result, tonic::Status> { - let store_list = list_stores_response(&self.runtime).await?; + let store_list = list_stores_response(&self.runtime, request.into_inner()).await?; Ok(tonic::Response::new(store_list)) } @@ -387,10 +415,19 @@ impl DbService for Server { request: tonic::Request, ) -> std::result::Result, tonic::Status> { let params = request.into_inner(); + let schema = params + .schema + .map(Schema::try_new) + .transpose() + .map_err(tonic::Status::invalid_argument)? + .unwrap_or_default(); let store_info = read_store_handler(&self.runtime, |store_handler| { - store_handler.get_store(&StoreName { - value: params.store, - }) + store_handler.get_store( + &StoreName { + value: params.store, + }, + &schema, + ) })?; Ok(tonic::Response::new(store_info)) } @@ -750,6 +787,22 @@ impl DbService for Server { } } } + + Query::DropSchema(params) => { + match self.drop_schema(tonic::Request::new(params)).await { + Ok(res) => response_vec.push(pipeline::db_server_response::Response::Del( + res.into_inner(), + )), + Err(err) => { + response_vec.push(pipeline::db_server_response::Response::Error( + ErrorResponse { + message: err.message().to_string(), + code: err.code().into(), + }, + )); + } + } + } } } @@ -847,9 +900,14 @@ impl Server { build_cluster_runtime(config, service_addr, cluster_listener).await?, ) } else { - let mut store_handler = StoreHandler::new(Arc::new(AtomicBool::new(false))); + let write_flag = Arc::new(AtomicBool::new(false)); + let mut store_handler = StoreHandler::new(write_flag); if let Some(persist_location) = &config.common.persist_location { - match Persistence::load_snapshot(persist_location, config.common.enable_mmap) { + match Persistence::load_snapshot_with_migration( + persist_location, + config.common.enable_mmap, + StoreHandler::load_snapshot, + ) { Err(e) => { log::error!("Failed to load snapshot from persist location {e}"); if config.common.fail_on_startup_if_persist_load_fails { diff --git a/ahnlich/db/src/tests/cluster_tests.rs b/ahnlich/db/src/tests/cluster_tests.rs index dd0346688..32eae92b3 100644 --- a/ahnlich/db/src/tests/cluster_tests.rs +++ b/ahnlich/db/src/tests/cluster_tests.rs @@ -162,6 +162,7 @@ async fn test_single_node_clustered_pipeline_and_cluster_info() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, DbQuery { @@ -171,7 +172,9 @@ async fn test_single_node_clustered_pipeline_and_cluster_info() { })), }, DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, DbQuery { query: Some(Query::ClusterInfo(ClusterInfoQuery {})), @@ -275,6 +278,7 @@ async fn test_three_node_cluster_replication_and_follower_list_stores_error() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })) .await .expect("leader create_store should succeed"); @@ -306,7 +310,9 @@ async fn test_three_node_cluster_replication_and_follower_list_stores_error() { ); let leader_store_list = leader_client - .list_stores(tonic::Request::new(db_query_types::ListStores {})) + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: None, + })) .await .expect("leader ListStores should succeed") .into_inner(); @@ -321,13 +327,17 @@ async fn test_three_node_cluster_replication_and_follower_list_stores_error() { assert!(replicated_store.predicate_indices.is_empty()); let list_stores_error = follower_one_client - .list_stores(tonic::Request::new(db_query_types::ListStores {})) + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: None, + })) .await .expect_err("follower ListStores should error in M2"); assert_eq!(list_stores_error.code(), Code::FailedPrecondition); let second_list_stores_error = follower_two_client - .list_stores(tonic::Request::new(db_query_types::ListStores {})) + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: None, + })) .await .expect_err("second follower ListStores should error in M2"); assert_eq!(second_list_stores_error.code(), Code::FailedPrecondition); diff --git a/ahnlich/db/src/tests/fixtures/db_old_flat_snapshot.json b/ahnlich/db/src/tests/fixtures/db_old_flat_snapshot.json new file mode 100644 index 000000000..4114e152d --- /dev/null +++ b/ahnlich/db/src/tests/fixtures/db_old_flat_snapshot.json @@ -0,0 +1,16 @@ +{ + "fixture_store": { + "dimension": 3, + "id_to_value": {}, + "predicate_indices": { + "inner": {}, + "allowed_predicates": [] + }, + "non_linear_indices": { + "algorithm_to_index": {} + }, + "cached_len": 0, + "cached_size_bytes": 0, + "size_dirty": true + } +} \ No newline at end of file diff --git a/ahnlich/db/src/tests/fixtures/db_v2_snapshot.json b/ahnlich/db/src/tests/fixtures/db_v2_snapshot.json new file mode 100644 index 000000000..7cdf09b39 --- /dev/null +++ b/ahnlich/db/src/tests/fixtures/db_v2_snapshot.json @@ -0,0 +1,94 @@ +{ + "db_version": "2", + "stores": { + "public": { + "fixture_store": { + "dimension": 3, + "id_to_value": { + "15178017180037765037": [ + [ + 0.2, + 0.7, + 0.3 + ], + { + "value": { + "color": "str:green", + "category": "str:vegetable", + "name": "str:item2" + } + } + ], + "11596182387809500963": [ + [ + 0.5, + 0.1, + 0.8 + ], + { + "value": { + "color": "str:red", + "name": "str:item1", + "category": "str:fruit" + } + } + ] + }, + "predicate_indices": { + "inner": { + "category": { + "str:fruit": [ + 11596182387809500963 + ], + "str:vegetable": [ + 15178017180037765037 + ] + }, + "color": { + "str:green": [ + 15178017180037765037 + ], + "str:red": [ + 11596182387809500963 + ] + } + }, + "allowed_predicates": [ + "category", + "color" + ] + }, + "non_linear_indices": { + "algorithm_to_index": { + "KdTree": { + "KDTree": { + "root": { + "point": [ + 0.5, + 0.1, + 0.8 + ], + "left": { + "point": [ + 0.2, + 0.7, + 0.3 + ], + "left": null, + "right": null + }, + "right": null + }, + "dimension": 3, + "depth": 3 + } + } + } + }, + "cached_len": 0, + "cached_size_bytes": 0, + "size_dirty": true + } + } + } +} \ No newline at end of file diff --git a/ahnlich/db/src/tests/migration_test.rs b/ahnlich/db/src/tests/migration_test.rs new file mode 100644 index 000000000..c3c7bcabe --- /dev/null +++ b/ahnlich/db/src/tests/migration_test.rs @@ -0,0 +1,195 @@ +use crate::engine::store::StoreHandler; +use crate::engine::store::Stores; +use ahnlich_types::schema::Schema; +use serde_json::json; + +#[test] +fn test_db_migrate_old_flat_snapshot_via_json() { + let old_format = json!({ + "fixture_store": { + "dimension": 3, + "id_to_value": {}, + "predicate_indices": { + "inner": {}, + "allowed_predicates": [] + }, + "non_linear_indices": { + "algorithm_to_index": {} + }, + "cached_len": 0, + "cached_size_bytes": 0, + "size_dirty": true + } + }); + + let json_bytes = serde_json::to_vec(&old_format).expect("Failed to serialize old format"); + let migrated: Stores = StoreHandler::load_snapshot(&json_bytes).expect("Migration failed"); + let guard = migrated.guard(); + let inner = migrated + .get(&Schema::default(), &guard) + .expect("No public schema after migration"); + assert_eq!(inner.len(), 1, "Expected 1 DB store under public schema"); +} + +#[test] +fn test_db_migrate_from_committed_fixture() { + let fixture_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures") + .join("db_old_flat_snapshot.json"); + + assert!( + fixture_path.exists(), + "Committed fixture not found: {:?}", + fixture_path + ); + + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + let migrated: Stores = + StoreHandler::load_snapshot(&read_bytes).expect("Migration of fixture failed"); + let guard = migrated.guard(); + let inner = migrated + .get(&Schema::default(), &guard) + .expect("No public schema after migration"); + assert_eq!(inner.len(), 1, "Expected 1 DB store under public schema"); + let pinned = inner.pin(); + let (key, _) = pinned.iter().next().expect("No store in result"); + assert_eq!( + key.value, "fixture_store", + "Store name preserved after migration" + ); +} + +#[test] +#[ignore] +fn generate_db_v2_fixture() { + use crate::engine::store::StoreHandler; + use ahnlich_types::algorithm::nonlinear::KdTreeConfig; + use ahnlich_types::algorithm::nonlinear::non_linear_index; + use ahnlich_types::keyval::{StoreKey, StoreName, StoreValue}; + use ahnlich_types::metadata::{MetadataValue, metadata_value}; + use ahnlich_types::schema::Schema; + use std::collections::{HashMap, HashSet}; + use std::num::NonZeroUsize; + use std::sync::Arc; + use std::sync::atomic::AtomicBool; + use utils::persistence::AhnlichPersistenceUtils; + + let handler = StoreHandler::new(Arc::new(AtomicBool::new(false))); + let predicates = vec!["category".to_string(), "color".to_string()]; + let mut non_linear_indices: HashSet = HashSet::new(); + non_linear_indices.insert(non_linear_index::Index::Kdtree(KdTreeConfig {})); + handler + .create_store( + StoreName { + value: "fixture_store".to_string(), + }, + &Schema::default(), + NonZeroUsize::new(3).unwrap(), + predicates, + non_linear_indices, + false, + ) + .unwrap(); + + // Insert entry 1 + let key1 = StoreKey { + key: vec![0.5f32, 0.1, 0.8], + }; + let mut meta1 = HashMap::new(); + meta1.insert( + "name".to_string(), + MetadataValue { + value: Some(metadata_value::Value::RawString("item1".to_string())), + }, + ); + meta1.insert( + "category".to_string(), + MetadataValue { + value: Some(metadata_value::Value::RawString("fruit".to_string())), + }, + ); + meta1.insert( + "color".to_string(), + MetadataValue { + value: Some(metadata_value::Value::RawString("red".to_string())), + }, + ); + handler + .set_in_store( + &StoreName { + value: "fixture_store".to_string(), + }, + vec![(key1, StoreValue { value: meta1 })], + ) + .unwrap(); + + // Insert entry 2 + let key2 = StoreKey { + key: vec![0.2f32, 0.7, 0.3], + }; + let mut meta2 = HashMap::new(); + meta2.insert( + "name".to_string(), + MetadataValue { + value: Some(metadata_value::Value::RawString("item2".to_string())), + }, + ); + meta2.insert( + "category".to_string(), + MetadataValue { + value: Some(metadata_value::Value::RawString("vegetable".to_string())), + }, + ); + meta2.insert( + "color".to_string(), + MetadataValue { + value: Some(metadata_value::Value::RawString("green".to_string())), + }, + ); + handler + .set_in_store( + &StoreName { + value: "fixture_store".to_string(), + }, + vec![(key2, StoreValue { value: meta2 })], + ) + .unwrap(); + + let snapshot = handler.get_snapshot(); + let json = serde_json::to_string_pretty(&snapshot).expect("Serialization failed"); + let fixture_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures") + .join("db_v2_snapshot.json"); + std::fs::write(&fixture_path, &json).expect("Failed to write fixture"); + eprintln!("Generated fixture at: {:?}", fixture_path); +} + +#[test] +fn test_db_load_v2_snapshot() { + let fixture_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures") + .join("db_v2_snapshot.json"); + + assert!( + fixture_path.exists(), + "V2 fixture not found: {:?}", + fixture_path + ); + + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + let loaded: Stores = StoreHandler::load_snapshot(&read_bytes).expect("V2 load failed"); + let guard = loaded.guard(); + let inner = loaded + .get(&Schema::default(), &guard) + .expect("No public schema after V2 load"); + assert_eq!(inner.len(), 1, "Expected 1 DB store under public schema"); + let pinned = inner.pin(); + let (key, _store) = pinned.iter().next().expect("No store in result"); + assert_eq!(key.value, "fixture_store", "Store name preserved in V2"); +} diff --git a/ahnlich/db/src/tests/mod.rs b/ahnlich/db/src/tests/mod.rs index 56de61430..6671589b0 100644 --- a/ahnlich/db/src/tests/mod.rs +++ b/ahnlich/db/src/tests/mod.rs @@ -1,5 +1,6 @@ mod auth_tests; mod cluster_tests; +mod migration_test; mod replication_store_tests; mod server_tests; diff --git a/ahnlich/db/src/tests/replication_store_tests.rs b/ahnlich/db/src/tests/replication_store_tests.rs index 7a7fb94a0..67432b511 100644 --- a/ahnlich/db/src/tests/replication_store_tests.rs +++ b/ahnlich/db/src/tests/replication_store_tests.rs @@ -64,6 +64,7 @@ fn create_store_query(store: &str, dimension: u32) -> query::CreateStore { create_predicates: Vec::new(), non_linear_indices: Vec::new(), error_if_exists: true, + schema: None, } } @@ -83,6 +84,7 @@ fn drop_store_query(store: &str) -> query::DropStore { query::DropStore { store: store.to_owned(), error_if_not_exists: true, + schema: None, } } diff --git a/ahnlich/db/src/tests/server_tests.rs b/ahnlich/db/src/tests/server_tests.rs index 6340551b1..d4647828b 100644 --- a/ahnlich/db/src/tests/server_tests.rs +++ b/ahnlich/db/src/tests/server_tests.rs @@ -1,3 +1,4 @@ +use crate::engine::store::StoreHandler; use crate::server::handler::Server; use crate::{cli::ServerConfig, errors::ServerError}; use ahnlich_types::algorithm::algorithms::Algorithm; @@ -11,14 +12,17 @@ use ahnlich_types::predicates::{ self, Predicate, PredicateCondition, predicate::Kind as PredicateKind, predicate_condition::Kind as PredicateConditionKind, }; +use ahnlich_types::schema::Schema; use ahnlich_types::server_types::ServerType; use ahnlich_types::shared::info::StoreUpsert; use ahnlich_types::similarity::Similarity; use once_cell::sync::Lazy; use pretty_assertions::assert_eq; use std::collections::HashMap; +use std::num::NonZeroUsize; use std::path::PathBuf; -use std::sync::atomic::Ordering; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; use tokio::time::Duration; use utils::server::AhnlichServerUtils; @@ -191,7 +195,9 @@ async fn test_simple_stores_list() { let mut client = DbServiceClient::connect(channel).await.expect("Failure"); let response = client - .list_stores(tonic::Request::new(ahnlich_types::db::query::ListStores {})) + .list_stores(tonic::Request::new(ahnlich_types::db::query::ListStores { + schema: None, + })) .await .expect("Failed to get store's list"); @@ -222,6 +228,7 @@ async fn test_create_stores() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, db_pipeline::DbQuery { @@ -231,10 +238,13 @@ async fn test_create_stores() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -327,6 +337,7 @@ async fn test_del_pred() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Should not error as it is correct query @@ -384,7 +395,9 @@ async fn test_del_pred() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, db_pipeline::DbQuery { query: Some(Query::DelPred(db_query_types::DelPred { @@ -438,7 +451,9 @@ async fn test_del_pred() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -580,6 +595,7 @@ async fn test_del_key() { create_predicates: vec!["role".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Should not error but delete nothing (empty store) @@ -616,7 +632,9 @@ async fn test_del_key() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, // Should error due to dimension mismatch db_pipeline::DbQuery { @@ -637,7 +655,9 @@ async fn test_del_key() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -776,6 +796,7 @@ async fn test_server_with_persistence() { create_predicates: vec!["role".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Should not error but delete nothing @@ -817,7 +838,9 @@ async fn test_server_with_persistence() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, // Should error due to dimension mismatch db_pipeline::DbQuery { @@ -838,7 +861,9 @@ async fn test_server_with_persistence() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -976,6 +1001,7 @@ async fn test_server_with_persistence() { create_predicates: vec!["role".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Should not error as store exists @@ -1085,6 +1111,7 @@ async fn test_set_in_store() { create_predicates: vec!["role".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Valid set operation @@ -1145,7 +1172,9 @@ async fn test_set_in_store() { })), }, db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -1260,6 +1289,7 @@ async fn test_remove_non_linear_indices() { }], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -1507,6 +1537,7 @@ async fn test_get_sim_n_non_linear() { index: Some(non_linear_index::Index::Kdtree(KdTreeConfig {})), }], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -1717,6 +1748,7 @@ async fn test_get_sim_n() { create_predicates: vec!["medal".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -2085,6 +2117,7 @@ async fn test_get_pred() { create_predicates: vec!["medal".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -2292,6 +2325,7 @@ async fn test_get_key() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -2521,6 +2555,7 @@ async fn test_create_pred_index() { create_predicates: vec!["galaxy".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -2913,6 +2948,7 @@ async fn test_drop_pred_index() { create_predicates: vec!["galaxy".into()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Should not error (error_if_not_exists=false) @@ -3018,6 +3054,7 @@ async fn test_drop_stores() { query: Some(Query::DropStore(db_query_types::DropStore { store: "Main".to_string(), error_if_not_exists: false, + schema: None, })), }, // Create store @@ -3028,17 +3065,21 @@ async fn test_drop_stores() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // List stores db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, // Should succeed (store exists) db_pipeline::DbQuery { query: Some(Query::DropStore(db_query_types::DropStore { store: "Main".to_string(), error_if_not_exists: true, + schema: None, })), }, // Should error (store doesn't exist) @@ -3046,6 +3087,7 @@ async fn test_drop_stores() { query: Some(Query::DropStore(db_query_types::DropStore { store: "Main".to_string(), error_if_not_exists: true, + schema: None, })), }, ]; @@ -3142,6 +3184,7 @@ async fn test_server_persistence_with_hnsw_index() { index: Some(non_linear_index::Index::Hnsw(HnswConfig::default())), }], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -3271,6 +3314,7 @@ async fn test_server_persistence_with_hnsw_index() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // Should get persisted data @@ -3393,6 +3437,7 @@ async fn test_create_store_with_hnsw_configuration() { index: Some(non_linear_index::Index::Hnsw(hnsw_config)), }], error_if_exists: true, + schema: None, })), }, // Insert test data @@ -3456,7 +3501,9 @@ async fn test_create_store_with_hnsw_configuration() { }, // List stores to verify config is reflected db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -3575,6 +3622,7 @@ async fn test_duplicate_nonlinear_index_prevention() { index: Some(non_linear_index::Index::Hnsw(HnswConfig::default())), }], error_if_exists: true, + schema: None, })), }, // Try to create the same HNSW index again - should be idempotent, returns 0 @@ -3752,6 +3800,7 @@ async fn test_hnsw_recall_with_config_reconstruction() { index: Some(non_linear_index::Index::Hnsw(low_config)), }], error_if_exists: true, + schema: None, })), }], })) @@ -3981,6 +4030,7 @@ async fn test_list_stores_returns_nonlinear_config() { }, ], error_if_exists: true, + schema: None, })), }, // Create a store without nonlinear indices @@ -3991,11 +4041,14 @@ async fn test_list_stores_returns_nonlinear_config() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, // List stores db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }, ]; @@ -4133,6 +4186,7 @@ async fn test_get_store_not_found() { let result = client .get_store(tonic::Request::new(db_query_types::GetStore { store: "NonExistent".to_string(), + schema: None, })) .await; @@ -4174,6 +4228,7 @@ async fn test_get_store_success() { index: Some(non_linear_index::Index::Hnsw(hnsw_config)), }], error_if_exists: true, + schema: None, }; client @@ -4208,6 +4263,7 @@ async fn test_get_store_success() { let store_info = client .get_store(tonic::Request::new(db_query_types::GetStore { store: "TestGetStore".to_string(), + schema: None, })) .await .expect("GetStore failed") @@ -4247,17 +4303,20 @@ async fn test_get_store_in_pipeline() { create_predicates: vec!["tag".to_string()], non_linear_indices: vec![], error_if_exists: true, + schema: None, })), }, db_pipeline::DbQuery { query: Some(Query::GetStore(db_query_types::GetStore { store: "PipelineStore".to_string(), + schema: None, })), }, // GetStore on non-existent store should return error in pipeline db_pipeline::DbQuery { query: Some(Query::GetStore(db_query_types::GetStore { store: "DoesNotExist".to_string(), + schema: None, })), }, ]; @@ -4308,8 +4367,6 @@ async fn test_get_store_in_pipeline() { #[tokio::test] async fn test_mmap_persistence_performance() { - use std::time::Instant; - let mmap_file = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("ahnlich_mmap_test.dat"); let no_mmap_file = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("ahnlich_no_mmap_test.dat"); @@ -4350,6 +4407,7 @@ async fn test_mmap_persistence_performance() { create_predicates: vec![], non_linear_indices: vec![], error_if_exists: false, + schema: None, })), }; @@ -4399,10 +4457,9 @@ async fn test_mmap_persistence_performance() { // Verify the file was created and check its size let file_metadata = std::fs::metadata(&mmap_file).expect("Persistence file not created"); - let file_size_kb = file_metadata.len() / 1024; println!( "Persistence file size: {} KB ({} bytes)", - file_size_kb, + file_metadata.len() / 1024, file_metadata.len() ); @@ -4421,11 +4478,9 @@ async fn test_mmap_persistence_performance() { .os_select_port() .persist_location(mmap_file.clone()); - let start = Instant::now(); let server_mmap = Server::new(&config_with_mmap) .await .expect("Failed to create server with mmap"); - let mmap_duration = start.elapsed(); // Verify the store was loaded correctly let address = server_mmap.local_addr().expect("Could not get local addr"); @@ -4439,7 +4494,9 @@ async fn test_mmap_persistence_performance() { .expect("Failed to connect"); let list_query = db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }; let response = client_mmap @@ -4465,13 +4522,11 @@ async fn test_mmap_persistence_performance() { let config_no_mmap = ServerConfig::default() .os_select_port() .persist_location(no_mmap_file.clone()) - .disable_mmap(); // This is a new method we need to add + .disable_mmap(); - let start = Instant::now(); let server_no_mmap = Server::new(&config_no_mmap) .await .expect("Failed to create server without mmap"); - let no_mmap_duration = start.elapsed(); // Verify the store was loaded correctly let address = server_no_mmap @@ -4487,7 +4542,9 @@ async fn test_mmap_persistence_performance() { .expect("Failed to connect"); let list_query = db_pipeline::DbQuery { - query: Some(Query::ListStores(db_query_types::ListStores {})), + query: Some(Query::ListStores(db_query_types::ListStores { + schema: None, + })), }; let response = client_no_mmap @@ -4509,15 +4566,472 @@ async fn test_mmap_persistence_performance() { panic!("Expected StoreList response"); } - assert!( - mmap_duration < no_mmap_duration, - "Mmap should be strictly faster than buffered reading for large files. File: {} KB, mmap: {:?}, no mmap: {:?}", - file_size_kb, - mmap_duration, - no_mmap_duration - ); - // Clean up let _ = std::fs::remove_file(&mmap_file); let _ = std::fs::remove_file(&no_mmap_file); } + +/// Test: Create stores in different schemas and list them with schema filtering +#[tokio::test] +async fn test_schema_create_and_list_in_schema() { + let server = Server::new(&CONFIG).await.expect("Failed to create server"); + let address = server.local_addr().expect("Could not get local addr"); + + tokio::spawn(async move { server.start().await }); + + let address = format!("http://{}", address); + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + let mut client = DbServiceClient::connect(channel) + .await + .expect("Failed to connect"); + + // Create a store in default schema + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "PublicStore".to_string(), + dimension: 3, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: None, + })) + .await + .expect("CreateStore in default schema failed"); + + // Create a store in custom schema + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "CustomStore".to_string(), + dimension: 5, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: Some("custom".to_string()), + })) + .await + .expect("CreateStore in custom schema failed"); + + // Create another store in custom schema + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "CustomStore2".to_string(), + dimension: 7, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: Some("custom".to_string()), + })) + .await + .expect("Create second store in custom schema failed"); + + // List stores filtered by public schema + let response = client + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: Some("public".to_string()), + })) + .await + .expect("ListStores with public schema failed") + .into_inner(); + assert_eq!(response.stores.len(), 1); + assert_eq!(response.stores[0].name, "PublicStore"); + + // List stores filtered by custom schema + let response = client + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: Some("custom".to_string()), + })) + .await + .expect("ListStores with custom schema failed") + .into_inner(); + assert_eq!(response.stores.len(), 2); + let names: Vec<&str> = response.stores.iter().map(|s| s.name.as_str()).collect(); + assert!(names.contains(&"CustomStore")); + assert!(names.contains(&"CustomStore2")); + + // List stores with no schema filter - should return all 3 stores + let response = client + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: None, + })) + .await + .expect("ListStores without schema filter failed") + .into_inner(); + assert_eq!(response.stores.len(), 3); +} + +/// Test: GetStore with schema parameter +#[tokio::test] +async fn test_schema_get_store_in_schema() { + let server = Server::new(&CONFIG).await.expect("Failed to create server"); + let address = server.local_addr().expect("Could not get local addr"); + + tokio::spawn(async move { server.start().await }); + + let address = format!("http://{}", address); + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + let mut client = DbServiceClient::connect(channel) + .await + .expect("Failed to connect"); + + // Create store in custom schema + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "SchemaGetStore".to_string(), + dimension: 4, + create_predicates: vec!["tag".to_string()], + non_linear_indices: vec![], + error_if_exists: true, + schema: Some("myschema".to_string()), + })) + .await + .expect("CreateStore failed"); + + // GetStore with schema specified + let store_info = client + .get_store(tonic::Request::new(db_query_types::GetStore { + store: "SchemaGetStore".to_string(), + schema: Some("myschema".to_string()), + })) + .await + .expect("GetStore with schema failed") + .into_inner(); + + assert_eq!(store_info.name, "SchemaGetStore"); + assert_eq!(store_info.dimension, 4); + assert_eq!(store_info.predicate_indices, vec!["tag".to_string()]); + + // GetStore without schema should NOT find it (defaults to public schema only) + let result = client + .get_store(tonic::Request::new(db_query_types::GetStore { + store: "SchemaGetStore".to_string(), + schema: None, + })) + .await; + assert!( + result.is_err(), + "GetStore without schema should fail for stores in non-public schema" + ); + + assert_eq!(store_info.name, "SchemaGetStore"); + assert_eq!(store_info.dimension, 4); +} + +/// Test: DropStore with schema parameter +#[tokio::test] +async fn test_schema_drop_store_in_schema() { + let server = Server::new(&CONFIG).await.expect("Failed to create server"); + let address = server.local_addr().expect("Could not get local addr"); + + tokio::spawn(async move { server.start().await }); + + let address = format!("http://{}", address); + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + let mut client = DbServiceClient::connect(channel) + .await + .expect("Failed to connect"); + + // Create store in custom schema + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "DropInSchema".to_string(), + dimension: 3, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: Some("dropschema".to_string()), + })) + .await + .expect("CreateStore failed"); + + // Verify store exists via GetStore + client + .get_store(tonic::Request::new(db_query_types::GetStore { + store: "DropInSchema".to_string(), + schema: Some("dropschema".to_string()), + })) + .await + .expect("GetStore should succeed before drop"); + + // Drop store with schema specified + client + .drop_store(tonic::Request::new(db_query_types::DropStore { + store: "DropInSchema".to_string(), + error_if_not_exists: true, + schema: Some("dropschema".to_string()), + })) + .await + .expect("DropStore failed"); + + // Verify store is gone + let result = client + .get_store(tonic::Request::new(db_query_types::GetStore { + store: "DropInSchema".to_string(), + schema: Some("dropschema".to_string()), + })) + .await; + + assert!(result.is_err(), "GetStore should fail after drop"); +} + +/// Test: DropSchema to remove an entire non-public schema +#[tokio::test] +async fn test_schema_drop_schema() { + let server = Server::new(&CONFIG).await.expect("Failed to create server"); + let address = server.local_addr().expect("Could not get local addr"); + + tokio::spawn(async move { server.start().await }); + + let address = format!("http://{}", address); + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + let mut client = DbServiceClient::connect(channel) + .await + .expect("Failed to connect"); + + // Create two stores in a schema to drop + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "DropSchemaStore1".to_string(), + dimension: 3, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: Some("tobedropped".to_string()), + })) + .await + .expect("CreateStore 1 failed"); + + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "DropSchemaStore2".to_string(), + dimension: 5, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: Some("tobedropped".to_string()), + })) + .await + .expect("CreateStore 2 failed"); + + // Also create a store in public schema to verify isolation + client + .create_store(tonic::Request::new(db_query_types::CreateStore { + store: "PublicSurvivor".to_string(), + dimension: 2, + create_predicates: vec![], + non_linear_indices: vec![], + error_if_exists: true, + schema: None, + })) + .await + .expect("CreateStore in public failed"); + + // Drop the schema + let response = client + .drop_schema(tonic::Request::new(db_query_types::DropSchema { + schema: "tobedropped".to_string(), + })) + .await + .expect("DropSchema failed") + .into_inner(); + assert_eq!(response.deleted_count, 2); + + // Verify stores in dropped schema are gone + let result = client + .get_store(tonic::Request::new(db_query_types::GetStore { + store: "DropSchemaStore1".to_string(), + schema: Some("tobedropped".to_string()), + })) + .await; + assert!(result.is_err(), "Store in dropped schema should be gone"); + + // Verify public schema store still exists + let pub_store = client + .get_store(tonic::Request::new(db_query_types::GetStore { + store: "PublicSurvivor".to_string(), + schema: None, + })) + .await + .expect("Public store should still exist") + .into_inner(); + assert_eq!(pub_store.name, "PublicSurvivor"); + + // Verify list stores filtered by public schema shows only the survivor + let response = client + .list_stores(tonic::Request::new(db_query_types::ListStores { + schema: Some("public".to_string()), + })) + .await + .expect("ListStores failed") + .into_inner(); + assert_eq!(response.stores.len(), 1); + assert_eq!(response.stores[0].name, "PublicSurvivor"); +} + +/// Test: Dropping the "public" schema should fail +#[tokio::test] +async fn test_schema_drop_public_schema_fails() { + let server = Server::new(&CONFIG).await.expect("Failed to create server"); + let address = server.local_addr().expect("Could not get local addr"); + + tokio::spawn(async move { server.start().await }); + + let address = format!("http://{}", address); + tokio::time::sleep(Duration::from_millis(100)).await; + let channel = Channel::from_shared(address).expect("Failed to get channel"); + let mut client = DbServiceClient::connect(channel) + .await + .expect("Failed to connect"); + + // Attempt to drop "public" schema + let result = client + .drop_schema(tonic::Request::new(db_query_types::DropSchema { + schema: "public".to_string(), + })) + .await; + + assert!( + result.is_err(), + "Dropping public schema should return an error" + ); + let status = result.unwrap_err(); + assert_eq!(status.code(), tonic::Code::InvalidArgument); + assert!( + status.message().contains("public"), + "Error message should reference 'public': {}", + status.message() + ); +} + +#[test] +fn test_migrate_old_flat_snapshot() { + // Create a store handler and populate a store under "public" + let handler = StoreHandler::new(Arc::new(AtomicBool::new(false))); + let store_name = StoreName { + value: "test_store".to_string(), + }; + handler + .create_store( + store_name.clone(), + &Schema::default(), + NonZeroUsize::new(3).unwrap(), + vec![], + std::collections::HashSet::new(), + true, + ) + .expect("Failed to create store"); + + // Serialize the inner stores (under "public") as the old flat format + let stores = handler.get_stores(); + let guard = stores.guard(); + let inner = stores + .get(&Schema::default(), &guard) + .expect("No public schema"); + let pinned = inner.pin(); + let old_format_bytes = serde_json::to_vec(&pinned).expect("Failed to serialize old format"); + + // Now simulate loading this old-format snapshot via migration + let migrated = StoreHandler::load_snapshot(&old_format_bytes).expect("Migration failed"); + + // Verify: migrated stores should contain the store under "public" + let migrated_guard = migrated.guard(); + let migrated_inner = migrated + .get(&Schema::default(), &migrated_guard) + .expect("No public schema after migration"); + assert_eq!( + migrated_inner.len(), + 1, + "Expected 1 store under public schema" + ); + let migrated_pinned = migrated_inner.pin(); + let (_key, _store) = migrated_pinned.iter().next().expect("No store in result"); +} + +#[test] +fn test_migrate_old_flat_snapshot_json_file() { + // Create a real store handler and serialize its inner public stores as old-format JSON + let handler = StoreHandler::new(Arc::new(AtomicBool::new(false))); + let store_name = StoreName { + value: "fixture_store".to_string(), + }; + handler + .create_store( + store_name.clone(), + &Schema::default(), + NonZeroUsize::new(3).unwrap(), + vec![], + std::collections::HashSet::new(), + true, + ) + .expect("Failed to create store"); + + // Get the flat (old-format) JSON: the inner HashMap under "public" + let stores = handler.get_stores(); + let guard = stores.guard(); + let inner = stores + .get(&Schema::default(), &guard) + .expect("No public schema"); + let pinned = inner.pin(); + let json_bytes = serde_json::to_vec_pretty(&pinned).expect("Failed to serialize"); + + // Write to fixture file in tests/fixtures/ + let fixture_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures"); + std::fs::create_dir_all(&fixture_dir).expect("Failed to create fixtures dir"); + let fixture_path = fixture_dir.join("db_old_flat_snapshot.json"); + std::fs::write(&fixture_path, &json_bytes).expect("Failed to write fixture"); + + // Now read it back and verify it migrates correctly + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + let migrated = StoreHandler::load_snapshot(&read_bytes).expect("Migration of fixture failed"); + + let migrated_guard = migrated.guard(); + let migrated_inner = migrated + .get(&Schema::default(), &migrated_guard) + .expect("No public schema after migration"); + assert_eq!( + migrated_inner.len(), + 1, + "Expected 1 store under public schema" + ); +} + +#[test] +fn test_migrate_from_committed_db_fixture() { + let fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("tests") + .join("fixtures") + .join("db_old_flat_snapshot.json"); + + assert!( + fixture_path.exists(), + "Committed fixture not found: {:?}", + fixture_path + ); + + let read_bytes = std::fs::read(&fixture_path).expect("Failed to read fixture"); + + let migrated = StoreHandler::load_snapshot(&read_bytes).expect("Migration of fixture failed"); + + let migrated_guard = migrated.guard(); + let migrated_inner = migrated + .get(&Schema::default(), &migrated_guard) + .expect("No public schema after migration"); + assert_eq!( + migrated_inner.len(), + 1, + "Expected 1 store under public schema" + ); + let pinned = migrated_inner.pin(); + let (key, _) = pinned.iter().next().expect("No store in result"); + assert_eq!( + key.value, "fixture_store", + "Store name preserved after migration" + ); +} diff --git a/ahnlich/dsl/src/ai.rs b/ahnlich/dsl/src/ai.rs index b08a13c21..e5d687fed 100644 --- a/ahnlich/dsl/src/ai.rs +++ b/ahnlich/dsl/src/ai.rs @@ -85,7 +85,7 @@ pub fn parse_ai_query(input: &str) -> Result, DslError> { let end_pos = statement.as_span().end_pos().pos(); let query = match statement.as_rule() { Rule::ping => AiQuery::Ping(Ping {}), - Rule::list_stores => AiQuery::ListStores(ListStores {}), + Rule::list_stores => AiQuery::ListStores(ListStores { schema: None }), Rule::info_server => AiQuery::InfoServer(InfoServer {}), Rule::purge_stores => AiQuery::PurgeStores(PurgeStores {}), Rule::ai_set_in_store => { @@ -192,6 +192,7 @@ pub fn parse_ai_query(input: &str) -> Result, DslError> { non_linear_indices, error_if_exists, store_original, + schema: None, }) } Rule::ai_get_sim_n => { @@ -323,6 +324,7 @@ pub fn parse_ai_query(input: &str) -> Result, DslError> { AiQuery::DropStore(DropStore { store, error_if_not_exists, + schema: None, }) } Rule::get_store => { @@ -332,7 +334,10 @@ pub fn parse_ai_query(input: &str) -> Result, DslError> { .ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))? .as_str() .to_string(); - AiQuery::GetStore(GetStore { store }) + AiQuery::GetStore(GetStore { + store, + schema: None, + }) } _ => return Err(DslError::UnexpectedSpan((start_pos, end_pos))), }; diff --git a/ahnlich/dsl/src/db.rs b/ahnlich/dsl/src/db.rs index 85ef6ab10..47760045d 100644 --- a/ahnlich/dsl/src/db.rs +++ b/ahnlich/dsl/src/db.rs @@ -53,7 +53,7 @@ pub fn parse_db_query(input: &str) -> Result, DslError> { let query = match statement.as_rule() { Rule::ping => DBQuery::Ping(Ping {}), Rule::list_clients => DBQuery::ListClients(ListClients {}), - Rule::list_stores => DBQuery::ListStores(ListStores {}), + Rule::list_stores => DBQuery::ListStores(ListStores { schema: None }), Rule::info_server => DBQuery::InfoServer(InfoServer {}), Rule::get_store => { let mut inner_pairs = statement.into_inner(); @@ -62,7 +62,10 @@ pub fn parse_db_query(input: &str) -> Result, DslError> { .ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))? .as_str() .to_string(); - DBQuery::GetStore(GetStore { store }) + DBQuery::GetStore(GetStore { + store, + schema: None, + }) } Rule::set_in_store => { let mut inner_pairs = statement.into_inner(); @@ -131,6 +134,7 @@ pub fn parse_db_query(input: &str) -> Result, DslError> { create_predicates, non_linear_indices, error_if_exists, + schema: None, }) } Rule::get_sim_n => { @@ -249,6 +253,7 @@ pub fn parse_db_query(input: &str) -> Result, DslError> { DBQuery::DropStore(DropStore { store, error_if_not_exists, + schema: None, }) } _ => return Err(DslError::UnexpectedSpan((start_pos, end_pos))), diff --git a/ahnlich/dsl/src/tests/ai.rs b/ahnlich/dsl/src/tests/ai.rs index 3e9980cf2..1b85ac6d6 100644 --- a/ahnlich/dsl/src/tests/ai.rs +++ b/ahnlich/dsl/src/tests/ai.rs @@ -55,7 +55,7 @@ fn test_multi_query_parse() { parse_ai_query(input).expect("Could not parse query input"), vec![ AiQuery::InfoServer(InfoServer {}), - AiQuery::ListStores(ListStores {}) + AiQuery::ListStores(ListStores { schema: None }) ] ); } @@ -81,6 +81,7 @@ fn test_get_store_parse() { parse_ai_query(input).expect("Could not parse query input"), vec![AiQuery::GetStore(GetStore { store: "my_store".to_string(), + schema: None, })] ); let input = r#"getstore test-store-1"#; @@ -88,6 +89,7 @@ fn test_get_store_parse() { parse_ai_query(input).expect("Could not parse query input"), vec![AiQuery::GetStore(GetStore { store: "test-store-1".to_string(), + schema: None, })] ); } @@ -99,7 +101,8 @@ fn test_drop_store_parse() { parse_ai_query(input).expect("Could not parse query input"), vec![AiQuery::DropStore(DropStore { store: "random".to_string(), - error_if_not_exists: true + error_if_not_exists: true, + schema: None, })] ); let input = r#"dropstore yeezy_store IF exists"#; @@ -108,6 +111,7 @@ fn test_drop_store_parse() { vec![AiQuery::DropStore(DropStore { store: "yeezy_store".to_string(), error_if_not_exists: false, + schema: None, })] ); let input = r#"dropstore yeezy IF NOT exists"#; @@ -166,6 +170,7 @@ fn test_create_store_parse() { non_linear_indices: vec![], error_if_exists: true, store_original: false, + schema: None, })] ); let input = r#"CREATEstore IF NOT EXISTS storename QUERYMODEL resnet-50 INDEXMODEL all-minilm-l6-v2 PREDICATES (department, faculty) STOREORIGINAL"#; @@ -179,6 +184,7 @@ fn test_create_store_parse() { non_linear_indices: vec![], error_if_exists: false, store_original: true, + schema: None, })] ); let input = r#"createstore school QUERYMODEL all-minilm-l6-v2 INDEXMODEL resnet-50 NONLINEARALGORITHMINDEX (kdtree) STOREORIGINAL"#; @@ -194,6 +200,7 @@ fn test_create_store_parse() { }], error_if_exists: true, store_original: true, + schema: None, })] ); } diff --git a/ahnlich/dsl/src/tests/db.rs b/ahnlich/dsl/src/tests/db.rs index 4cd15df9b..e32468961 100644 --- a/ahnlich/dsl/src/tests/db.rs +++ b/ahnlich/dsl/src/tests/db.rs @@ -50,7 +50,7 @@ fn test_multi_query_parse() { parse_db_query(input).expect("Could not parse query input"), vec![ DBQuery::InfoServer(InfoServer {}), - DBQuery::ListStores(ListStores {}) + DBQuery::ListStores(ListStores { schema: None }) ] ); } @@ -80,7 +80,8 @@ fn test_create_store_parse() { dimension: 23, create_predicates: vec![], non_linear_indices: vec![], - error_if_exists: true + error_if_exists: true, + schema: None, })] ); let input = r#"CREATEstore IF NOT EXISTS testing DIMENSION 43"#; @@ -91,7 +92,8 @@ fn test_create_store_parse() { dimension: 43, create_predicates: vec![], non_linear_indices: vec![], - error_if_exists: false + error_if_exists: false, + schema: None, })] ); let input = r#"CREATEstore IF NOT EXISTS school DIMENSION 39 PREDICATES (department, faculty)"#; @@ -102,7 +104,8 @@ fn test_create_store_parse() { dimension: 39, create_predicates: vec!["department".to_string(), "faculty".to_string()], non_linear_indices: vec![], - error_if_exists: false + error_if_exists: false, + schema: None, })] ); let input = r#"CREATEstore school DIMENSION 39 NONLINEARALGORITHMINDEX (kdtree)"#; @@ -115,7 +118,8 @@ fn test_create_store_parse() { non_linear_indices: vec![NonLinearIndex { index: Some(non_linear_index::Index::Kdtree(KdTreeConfig {})), }], - error_if_exists: true + error_if_exists: true, + schema: None, })] ); let input = r#"CREATEstore school DIMENSION 77 PREDICATES(name, surname) NONLINEARALGORITHMINDEX (kdtree)"#; @@ -128,7 +132,8 @@ fn test_create_store_parse() { non_linear_indices: vec![NonLinearIndex { index: Some(non_linear_index::Index::Kdtree(KdTreeConfig {})), }], - error_if_exists: true + error_if_exists: true, + schema: None, })] ); } @@ -140,7 +145,8 @@ fn test_drop_store_parse() { parse_db_query(input).expect("Could not parse query input"), vec![DBQuery::DropStore(DropStore { store: "random".to_string(), - error_if_not_exists: true + error_if_not_exists: true, + schema: None, })] ); let input = r#"dropstore yeezy_store IF exists"#; @@ -149,6 +155,7 @@ fn test_drop_store_parse() { vec![DBQuery::DropStore(DropStore { store: "yeezy_store".to_string(), error_if_not_exists: false, + schema: None, })] ); let input = r#"dropstore yeezy IF NOT exists"#; @@ -448,6 +455,7 @@ fn test_get_pred_parse() { parse_db_query(input).expect("Could not parse query input"), vec![DBQuery::GetStore(GetStore { store: "my_store".to_string(), + schema: None, })] ); let input = r#"GETSTORE TestStore123"#; @@ -455,6 +463,7 @@ fn test_get_pred_parse() { parse_db_query(input).expect("Could not parse query input"), vec![DBQuery::GetStore(GetStore { store: "TestStore123".to_string(), + schema: None, })] ); let input = r#"GETPRED ((pages in (0, 1, 2)) AND (author != dickens) OR (author NOT in (jk-rowlins, rick-riodan)) ) in bookshelf"#; diff --git a/ahnlich/replication/src/types.rs b/ahnlich/replication/src/types.rs index 119dc67d8..9973340bc 100644 --- a/ahnlich/replication/src/types.rs +++ b/ahnlich/replication/src/types.rs @@ -32,6 +32,7 @@ pub enum DbCommand { DropPredIndex(Vec), DropNonLinearAlgorithmIndex(Vec), DropStore(Vec), + DropSchema(Vec), } /// AI Raft commands. Only operations that mutate AI-local state diff --git a/ahnlich/similarity/src/hnsw/mod.rs b/ahnlich/similarity/src/hnsw/mod.rs index 3d5150d09..c3213d1fa 100644 --- a/ahnlich/similarity/src/hnsw/mod.rs +++ b/ahnlich/similarity/src/hnsw/mod.rs @@ -42,6 +42,7 @@ pub(crate) type NodeIdHashSet = std::collections::HashSet Result<()> { if let Ok(entries) = std::fs::read_dir(out_dir) { for entry in entries.filter_map(Result::ok) { let path = entry.path(); - if path.file_name().is_some_and(|name| name != "utils") { + let preserve = ["utils", "schema.rs"]; + if path + .file_name() + .is_some_and(|name| !preserve.contains(&name.to_str().unwrap_or(""))) + { if path.is_dir() { std::fs::remove_dir_all(&path).expect("Failed to remove directory"); } else { @@ -172,6 +176,7 @@ fn restructure_generated_code(out_dir: &PathBuf, file: &mut std::fs::File) { } module_names.insert("utils"); + module_names.insert("schema"); let buffer = module_names .into_iter() diff --git a/ahnlich/types/src/ai/pipeline.rs b/ahnlich/types/src/ai/pipeline.rs index 2d6f7e4ba..073e45199 100644 --- a/ahnlich/types/src/ai/pipeline.rs +++ b/ahnlich/types/src/ai/pipeline.rs @@ -3,7 +3,7 @@ pub struct AiQuery { #[prost( oneof = "ai_query::Query", - tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19" + tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20" )] pub query: ::core::option::Option, } @@ -49,6 +49,8 @@ pub mod ai_query { DelPred(super::super::query::DelPred), #[prost(message, tag = "19")] GetStore(super::super::query::GetStore), + #[prost(message, tag = "20")] + DropSchema(super::super::query::DropSchema), } } #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/ahnlich/types/src/ai/query.rs b/ahnlich/types/src/ai/query.rs index cc7e62f1f..80f64c8da 100644 --- a/ahnlich/types/src/ai/query.rs +++ b/ahnlich/types/src/ai/query.rs @@ -30,6 +30,9 @@ pub struct CreateStore { /// Flag to store original data. Used if you wanna keep the original(image or text) input sent #[prost(bool, tag = "7")] pub store_original: bool, + /// Optional schema/namespace for the store. Defaults to "public". + #[prost(string, optional, tag = "8")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetPred { @@ -173,6 +176,9 @@ pub struct DropStore { /// Flag to throw an error if the store does not exist #[prost(bool, tag = "2")] pub error_if_not_exists: bool, + /// Optional schema/namespace for the store. Defaults to "public". + #[prost(string, optional, tag = "3")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetKey { @@ -191,9 +197,14 @@ pub struct InfoServer {} /// Lists all clients currently connected to the server #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListClients {} -/// Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. -#[derive(Clone, Copy, PartialEq, ::prost::Message)] -pub struct ListStores {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListStores { + /// Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. + /// + /// Optional schema/namespace to filter stores. If unset, lists all schemas. + #[prost(string, optional, tag = "1")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, +} #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetStore { /// Gets detailed information about a specific store by name. Returns an error if the store does not exist. @@ -201,6 +212,17 @@ pub struct GetStore { /// Store name #[prost(string, tag = "1")] pub store: ::prost::alloc::string::String, + /// Optional schema/namespace for the store. Defaults to "public". + #[prost(string, optional, tag = "2")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DropSchema { + /// Drops an entire schema and all stores within it. Cannot drop the "public" default schema. + /// + /// The name of the schema to drop. + #[prost(string, tag = "1")] + pub schema: ::prost::alloc::string::String, } /// Purges (deletes) all stores on the server, effectively destroying all stored data #[derive(Clone, Copy, PartialEq, ::prost::Message)] diff --git a/ahnlich/types/src/ai/server.rs b/ahnlich/types/src/ai/server.rs index 2539184b3..682fc567b 100644 --- a/ahnlich/types/src/ai/server.rs +++ b/ahnlich/types/src/ai/server.rs @@ -75,6 +75,8 @@ pub struct AiStoreInfo { pub dimension: u32, #[prost(message, optional, tag = "7")] pub db_info: ::core::option::Option, + #[prost(string, optional, tag = "8")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct EmbeddingWithMetadata { diff --git a/ahnlich/types/src/db/pipeline.rs b/ahnlich/types/src/db/pipeline.rs index f98cab8d6..302d704a2 100644 --- a/ahnlich/types/src/db/pipeline.rs +++ b/ahnlich/types/src/db/pipeline.rs @@ -3,7 +3,7 @@ pub struct DbQuery { #[prost( oneof = "db_query::Query", - tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18" + tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19" )] pub query: ::core::option::Option, } @@ -47,6 +47,8 @@ pub mod db_query { GetStore(super::super::query::GetStore), #[prost(message, tag = "18")] ClusterInfo(super::super::super::shared::cluster::ClusterInfoQuery), + #[prost(message, tag = "19")] + DropSchema(super::super::query::DropSchema), } } #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/ahnlich/types/src/db/query.rs b/ahnlich/types/src/db/query.rs index e7f7a8efe..8d5828253 100644 --- a/ahnlich/types/src/db/query.rs +++ b/ahnlich/types/src/db/query.rs @@ -19,6 +19,9 @@ pub struct CreateStore { /// Flag indicating whether to error if store already exists. #[prost(bool, tag = "5")] pub error_if_exists: bool, + /// Optional schema/namespace for the store. Defaults to "public". + #[prost(string, optional, tag = "6")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, } /// Retrieves values from the store based on provided keys. #[derive(Clone, PartialEq, ::prost::Message)] @@ -151,13 +154,20 @@ pub struct DropStore { /// Flag indicating whether to error if store does not exist. #[prost(bool, tag = "2")] pub error_if_not_exists: bool, + /// Optional schema/namespace for the store. Defaults to "public". + #[prost(string, optional, tag = "3")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, } /// A request to get server information such as host, port, and version. #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct InfoServer {} /// A request to list all the stores on the server, along with their size or length. -#[derive(Clone, Copy, PartialEq, ::prost::Message)] -pub struct ListStores {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListStores { + /// Optional schema/namespace to filter stores. If unset, lists all schemas. + #[prost(string, optional, tag = "1")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, +} /// A request to list all the clients currently connected to the server. #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct ListClients {} @@ -170,6 +180,17 @@ pub struct GetStore { /// The name of the store. #[prost(string, tag = "1")] pub store: ::prost::alloc::string::String, + /// Optional schema/namespace for the store. Defaults to "public". + #[prost(string, optional, tag = "2")] + pub schema: ::core::option::Option<::prost::alloc::string::String>, +} +/// Drops an entire schema and all stores within it. +/// Cannot drop the "public" default schema. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DropSchema { + /// The name of the schema to drop. + #[prost(string, tag = "1")] + pub schema: ::prost::alloc::string::String, } /// A request to set multiple key-value entries in the store. /// Validation is done for each vector before updating the store. diff --git a/ahnlich/types/src/lib.rs b/ahnlich/types/src/lib.rs index f84880258..61dd745cb 100644 --- a/ahnlich/types/src/lib.rs +++ b/ahnlich/types/src/lib.rs @@ -5,6 +5,7 @@ pub mod db; pub mod keyval; pub mod metadata; pub mod predicates; +pub mod schema; pub mod server_types; pub mod services; pub mod shared; diff --git a/ahnlich/types/src/schema.rs b/ahnlich/types/src/schema.rs new file mode 100644 index 000000000..abdfc29b1 --- /dev/null +++ b/ahnlich/types/src/schema.rs @@ -0,0 +1,80 @@ +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A logical namespace for grouping stores within ahnlich. +/// +/// Schemas provide multi-tenant isolation and organizational hierarchy +/// on top of the flat store namespace. Every store belongs to exactly +/// one schema. The schema `"public"` is the default used when none is +/// specified, preserving backward compatibility with existing stores. +/// +/// Schema names are case-sensitive, so `"Public"` and `"public"` are +/// treated as distinct schemas. +#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +pub struct Schema(String); + +impl Schema { + /// The default schema name used when no schema is specified. + pub const DEFAULT_NAME: &'static str = "public"; + + /// Creates a new `Schema` with the given name. + /// + /// # Panics + /// + /// Panics if `name` is empty. + pub fn new(name: impl Into) -> Self { + let name = name.into(); + assert!(!name.is_empty(), "Schema name cannot be empty"); + Self(name) + } + + /// Creates a new `Schema` with the given name, returning an error if `name` is empty. + pub fn try_new(name: impl Into) -> Result { + let name = name.into(); + if name.is_empty() { + Err("Schema name cannot be empty") + } else { + Ok(Self(name)) + } + } + + /// Returns the schema name as a string slice. + pub fn as_str(&self) -> &str { + &self.0 + } + + /// Consumes the schema, returning the inner string. + pub fn into_inner(self) -> String { + self.0 + } +} + +impl Default for Schema { + fn default() -> Self { + Self(Self::DEFAULT_NAME.to_string()) + } +} + +impl fmt::Display for Schema { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&self.0) + } +} + +impl From for Schema { + fn from(s: String) -> Self { + Self::new(s) + } +} + +impl From<&str> for Schema { + fn from(s: &str) -> Self { + Self::new(s) + } +} + +impl AsRef for Schema { + fn as_ref(&self) -> &str { + &self.0 + } +} diff --git a/ahnlich/types/src/services/ai_service.rs b/ahnlich/types/src/services/ai_service.rs index 63699c6af..d825b06a7 100644 --- a/ahnlich/types/src/services/ai_service.rs +++ b/ahnlich/types/src/services/ai_service.rs @@ -330,6 +330,24 @@ pub mod ai_service_client { )); self.inner.unary(req, path, codec).await } + pub async fn drop_schema( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = + http::uri::PathAndQuery::from_static("/services.ai_service.AIService/DropSchema"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new( + "services.ai_service.AIService", + "DropSchema", + )); + self.inner.unary(req, path, codec).await + } /// * Ancillary info methods * pub async fn list_clients( &mut self, @@ -554,6 +572,10 @@ pub mod ai_service_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; + async fn drop_schema( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// * Ancillary info methods * async fn list_clients( &self, @@ -1223,6 +1245,47 @@ pub mod ai_service_server { }; Box::pin(fut) } + "/services.ai_service.AIService/DropSchema" => { + #[allow(non_camel_case_types)] + struct DropSchemaSvc(pub Arc); + impl + tonic::server::UnaryService + for DropSchemaSvc + { + type Response = super::super::super::ai::server::Del; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = + async move { ::drop_schema(&inner, request).await }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = DropSchemaSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/services.ai_service.AIService/ListClients" => { #[allow(non_camel_case_types)] struct ListClientsSvc(pub Arc); diff --git a/ahnlich/types/src/services/db_service.rs b/ahnlich/types/src/services/db_service.rs index c73d1ecf5..69ceede44 100644 --- a/ahnlich/types/src/services/db_service.rs +++ b/ahnlich/types/src/services/db_service.rs @@ -330,6 +330,24 @@ pub mod db_service_client { )); self.inner.unary(req, path, codec).await } + pub async fn drop_schema( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = + http::uri::PathAndQuery::from_static("/services.db_service.DBService/DropSchema"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new( + "services.db_service.DBService", + "DropSchema", + )); + self.inner.unary(req, path, codec).await + } /// * Ancillary info methods * pub async fn list_clients( &mut self, @@ -533,6 +551,10 @@ pub mod db_service_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; + async fn drop_schema( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// * Ancillary info methods * async fn list_clients( &self, @@ -1198,6 +1220,47 @@ pub mod db_service_server { }; Box::pin(fut) } + "/services.db_service.DBService/DropSchema" => { + #[allow(non_camel_case_types)] + struct DropSchemaSvc(pub Arc); + impl + tonic::server::UnaryService + for DropSchemaSvc + { + type Response = super::super::super::db::server::Del; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = + async move { ::drop_schema(&inner, request).await }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = DropSchemaSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/services.db_service.DBService/ListClients" => { #[allow(non_camel_case_types)] struct ListClientsSvc(pub Arc); diff --git a/ahnlich/utils/src/persistence.rs b/ahnlich/utils/src/persistence.rs index 996209adb..2b11f644a 100644 --- a/ahnlich/utils/src/persistence.rs +++ b/ahnlich/utils/src/persistence.rs @@ -1,4 +1,5 @@ use memmap2::Mmap; +use serde::Deserialize; use serde::Serialize; use serde::de::DeserializeOwned; use std::fmt::Debug; @@ -20,6 +21,64 @@ use tokio::time::sleep; const MMAP_THRESHOLD: u64 = 64 * 1024; // 64KB +#[derive(Error, Debug)] +pub enum VersionError { + #[error( + "Persistence file version {file_version} is too new for this ahnlich binary (max supported: {max_version}). Please upgrade ahnlich." + )] + VersionTooNew { file_version: u32, max_version: u32 }, + + #[error( + "Persistence file version {file_version} is too old (minimum supported: {min_version}). Migration path removed." + )] + VersionTooOld { file_version: u32, min_version: u32 }, +} + +/// Trait for versioned persistence types. +pub trait VersionedPersistence: Sized + Serialize + for<'de> Deserialize<'de> { + /// The current version this binary writes. + const CURRENT_VERSION: u32; + + /// The minimum version this binary can read. + const MIN_VERSION: u32; + + /// Validate version compatibility from raw bytes. + fn validate_version(bytes: &[u8]) -> Result<(), VersionError> { + #[derive(Deserialize)] + struct VersionOnly { + #[serde(rename = "db_version")] + db_version: Option, + } + + let version = match serde_json::from_slice::(bytes) { + Ok(v) => v + .db_version + .and_then(|s| s.parse::().ok()) + .unwrap_or(1), + Err(_) => 1, + }; + + if version > Self::CURRENT_VERSION { + return Err(VersionError::VersionTooNew { + file_version: version, + max_version: Self::CURRENT_VERSION, + }); + } + + if version < Self::MIN_VERSION { + return Err(VersionError::VersionTooOld { + file_version: version, + min_version: Self::MIN_VERSION, + }); + } + + Ok(()) + } + + /// Load from bytes with automatic migration from older formats. + fn load_and_migrate(bytes: &[u8]) -> Result; +} + pub trait AhnlichPersistenceUtils { type PersistenceObject: Serialize + DeserializeOwned + Send + Sync + 'static + Debug; @@ -40,6 +99,10 @@ pub enum PersistenceTaskError { FileError(#[from] std::io::Error), #[error("SerdeError {0}")] SerdeError(#[from] serde_json::error::Error), + #[error("MigrationError {0}")] + MigrationError(String), + #[error("VersionError {0}")] + Version(#[from] VersionError), } #[derive(Debug, Clone)] @@ -96,6 +159,14 @@ impl Persistence { persist_location: &std::path::PathBuf, enable_mmap: bool, ) -> Result { + let bytes = Self::read_snapshot_raw(persist_location, enable_mmap)?; + Ok(serde_json::from_slice(&bytes)?) + } + + pub fn read_snapshot_raw( + persist_location: &std::path::PathBuf, + enable_mmap: bool, + ) -> Result, PersistenceTaskError> { let file = File::open(persist_location)?; let file_size = file.metadata()?.len(); @@ -105,17 +176,37 @@ impl Persistence { file_size ); let mmap = unsafe { Mmap::map(&file)? }; - serde_json::from_slice(&mmap)? + mmap.to_vec() } else { log::debug!( "Using buffered reader to load persistence file (size: {} bytes)", file_size ); let reader = BufReader::new(file); - serde_json::from_reader(reader)? + let mut bytes = Vec::with_capacity(file_size as usize); + use std::io::Read; + reader.take(file_size).read_to_end(&mut bytes)?; + bytes }) } + pub fn load_snapshot_with_migration( + persist_location: &std::path::PathBuf, + enable_mmap: bool, + migrate: F, + ) -> Result + where + F: FnOnce(&[u8]) -> Result, + { + match Self::load_snapshot(persist_location, enable_mmap) { + Ok(snapshot) => Ok(snapshot), + Err(_) => { + let bytes = Self::read_snapshot_raw(persist_location, enable_mmap)?; + migrate(&bytes) + } + } + } + pub fn task( write_flag: Arc, persistence_interval: u64, diff --git a/docs/schema.md b/docs/schema.md new file mode 100644 index 000000000..7cb46353e --- /dev/null +++ b/docs/schema.md @@ -0,0 +1,79 @@ +# Multi-Schema + +Stores in ahnlich can be organized into named schemas, providing lightweight namespacing. Every store belongs to exactly one schema. + +## Default Schema + +When a store is created without specifying a schema, it is placed into the `"public"` schema. The `"public"` schema is always available and cannot be dropped. + +## Operations + +### CreateStore + +Takes an optional `schema` field. If omitted (or set to `None`), the store is created in the `"public"` schema: + +``` +CREATESTORE my_store DIMENSION 2 PREDICATES (author, country) +``` + +To create in a custom schema, use the `SCHEMA` keyword: + +``` +CREATESTORE my_store DIMENSION 2 PREDICATES (author, country) SCHEMA my_schema +``` + +### GetStore + +Takes an optional `schema` field: + +- If `schema` is provided, the store is looked up within that schema only. +- If `schema` is `None`, the server searches all schemas in an arbitrary order and returns the first match. An exact-match lookup (where the store is in `"public"` and `schema` is `None`) takes priority. + +### DropStore + +Takes an optional `schema` field. If `None`, the search logic follows the same rules as GetStore. + +### ListStores + +Takes an optional `schema` field: + +- If `schema` is provided, only stores within that schema are returned. +- If `schema` is `None`, all stores across all schemas are returned. + +### DropSchema *(new RPC)* + +Drops all stores within a schema and removes the schema itself. + +- Dropping `"public"` returns an `InvalidArgument` error. +- Dropping a non-existent schema returns an error. +- Dropping a schema cascades: all stores in that schema are removed from both the AI proxy and the underlying DB. + +## Protobuf + +The `schema` field and `DropSchema` RPC were added to all relevant messages in the protobuf definitions under `protos/`: + +**`protos/db/query.proto`** and **`protos/ai/query.proto`**: +- `CreateStore`, `GetStore`, `DropStore`, `ListStores` — each got an optional `string schema = ...` field (the field number varies by message). +- `DropSchema` — new message with a `string schema` field. + +**`protos/services/db_service.proto`** and **`protos/services/ai_service.proto`**: +- New `rpc DropSchema(DropSchema) returns (DropSchemaResponse);` on both services. + +## Architecture + +- The DB engine stores stores as `HashMap>` — the schema is the outer key. +- The AI proxy mirrors this structure: `ConcurrentHashMap>`. +- When `DropSchema` is called on the AI proxy, it cascades to the DB by both dropping the schema remotely and clearing all stores in that schema locally. +- `purge_stores` (DestroyDatabase) clears all schemas and all stores across all schemas. + +## CLI + +The CLI DSL supports the `SCHEMA` keyword in `CREATESTORE`, `GETSTORE`, `DROPSTORE`, and `LISTSTORES`. It also supports `DROPSCHEMA` as a new top-level command: + +``` +DROPSCHEMA my_schema +``` + +## SDK + +All SDKs (Go, Python, Node.js) have regenerated protobuf stubs that include the `schema` field and `DropSchema` RPC. The hand-written client wrappers have not been modified — usage requires constructing the protobuf messages directly or using the generated service stubs. diff --git a/examples/rust/image-search/Cargo.lock b/examples/rust/image-search/Cargo.lock index bd890ef3c..45953fa4e 100644 --- a/examples/rust/image-search/Cargo.lock +++ b/examples/rust/image-search/Cargo.lock @@ -31,11 +31,10 @@ dependencies = [ [[package]] name = "ahnlich_client_rs" -version = "0.1.0" +version = "0.3.0" dependencies = [ "ahnlich_types", "async-trait", - "bincode", "fallible_collections", "http", "once_cell", @@ -46,7 +45,7 @@ dependencies = [ [[package]] name = "ahnlich_types" -version = "0.1.0" +version = "0.3.0" dependencies = [ "ascii85", "prost", @@ -302,15 +301,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bit_field" version = "0.10.2" diff --git a/examples/rust/image-search/src/main.rs b/examples/rust/image-search/src/main.rs index 3dc38e4c7..cdb71c649 100644 --- a/examples/rust/image-search/src/main.rs +++ b/examples/rust/image-search/src/main.rs @@ -8,10 +8,10 @@ use ahnlich_client_rs::ai::AiClient; use ahnlich_types::{ ai::query::{CreateStore, GetSimN, Set}, algorithm::algorithms::Algorithm, - keyval::{store_input::Value, AiStoreEntry, StoreInput, StoreValue}, + keyval::{AiStoreEntry, StoreInput, StoreValue, store_input::Value}, }; -use ahnlich_types::metadata::{metadata_value::Value as MValue, MetadataValue}; +use ahnlich_types::metadata::{MetadataValue, metadata_value::Value as MValue}; use clap::{Parser, Subcommand}; use tokio; @@ -68,6 +68,7 @@ async fn index_mode() { non_linear_indices: vec![], error_if_exists: false, store_original: true, + schema: None, }; client diff --git a/protos/ai/pipeline.proto b/protos/ai/pipeline.proto index d253fa665..3227503eb 100644 --- a/protos/ai/pipeline.proto +++ b/protos/ai/pipeline.proto @@ -29,6 +29,7 @@ message AIQuery { ai.query.ConvertStoreInputToEmbeddings convert_store_input_to_embeddings = 17; ai.query.DelPred del_pred = 18; ai.query.GetStore get_store = 19; + ai.query.DropSchema drop_schema = 20; } } diff --git a/protos/ai/query.proto b/protos/ai/query.proto index d0eb48063..d4d4c183f 100644 --- a/protos/ai/query.proto +++ b/protos/ai/query.proto @@ -30,6 +30,7 @@ message CreateStore { repeated algorithm.nonlinear.NonLinearIndex non_linear_indices = 5; // Optional non-linear indices bool error_if_exists = 6; // Whether to throw an error if the store already exists bool store_original = 7; // Flag to store original data. Used if you wanna keep the original(image or text) input sent + optional string schema = 8; // Optional schema/namespace for the store. Defaults to "public". } message GetPred { @@ -99,6 +100,7 @@ message DropStore { // Destroys the store, and updates indices accordingly string store = 1; // Store name bool error_if_not_exists = 2; // Flag to throw an error if the store does not exist + optional string schema = 3; // Optional schema/namespace for the store. Defaults to "public". } message GetKey { @@ -117,11 +119,18 @@ message ListClients { message ListStores { // Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. + optional string schema = 1; // Optional schema/namespace to filter stores. If unset, lists all schemas. } message GetStore { // Gets detailed information about a specific store by name. Returns an error if the store does not exist. string store = 1; // Store name + optional string schema = 2; // Optional schema/namespace for the store. Defaults to "public". +} + +message DropSchema { + // Drops an entire schema and all stores within it. Cannot drop the "public" default schema. + string schema = 1; // The name of the schema to drop. } message PurgeStores { diff --git a/protos/ai/server.proto b/protos/ai/server.proto index 2492427e1..a941689ce 100644 --- a/protos/ai/server.proto +++ b/protos/ai/server.proto @@ -67,6 +67,7 @@ message AIStoreInfo { repeated string predicate_indices = 5; uint32 dimension = 6; optional db.server.StoreInfo db_info = 7; + optional string schema = 8; } message EmbeddingWithMetadata { diff --git a/protos/db/pipeline.proto b/protos/db/pipeline.proto index 49bc3a332..9959db9e8 100644 --- a/protos/db/pipeline.proto +++ b/protos/db/pipeline.proto @@ -33,6 +33,7 @@ message DBQuery { db.query.Ping ping = 16; db.query.GetStore get_store = 17; shared.cluster.ClusterInfoQuery cluster_info = 18; + db.query.DropSchema drop_schema = 19; } } diff --git a/protos/db/query.proto b/protos/db/query.proto index be53e0a92..a08d9fd71 100644 --- a/protos/db/query.proto +++ b/protos/db/query.proto @@ -21,6 +21,7 @@ message CreateStore { repeated string create_predicates = 3; // Predicates used for querying. repeated algorithm.nonlinear.NonLinearIndex non_linear_indices = 4; // Non-linear algorithms for indexing. bool error_if_exists = 5; // Flag indicating whether to error if store already exists. + optional string schema = 6; // Optional schema/namespace for the store. Defaults to "public". } // Retrieves values from the store based on provided keys. @@ -95,13 +96,16 @@ message DelPred { message DropStore { string store = 1; // The name of the store. bool error_if_not_exists = 2; // Flag indicating whether to error if store does not exist. + optional string schema = 3; // Optional schema/namespace for the store. Defaults to "public". } // A request to get server information such as host, port, and version. message InfoServer {} // A request to list all the stores on the server, along with their size or length. -message ListStores {} +message ListStores { + optional string schema = 1; // Optional schema/namespace to filter stores. If unset, lists all schemas. +} // A request to list all the clients currently connected to the server. message ListClients {} @@ -112,6 +116,13 @@ message Ping {} // A request to get detailed information about a specific store by name. message GetStore { string store = 1; // The name of the store. + optional string schema = 2; // Optional schema/namespace for the store. Defaults to "public". +} + +// Drops an entire schema and all stores within it. +// Cannot drop the "public" default schema. +message DropSchema { + string schema = 1; // The name of the schema to drop. } // A request to set multiple key-value entries in the store. diff --git a/protos/services/ai_service.proto b/protos/services/ai_service.proto index 93cdf48ac..8aee77f6e 100644 --- a/protos/services/ai_service.proto +++ b/protos/services/ai_service.proto @@ -29,6 +29,7 @@ service AIService { rpc DelKey(ai.query.DelKey) returns (ai.server.Del); rpc DelPred(ai.query.DelPred) returns (ai.server.Del); rpc DropStore(ai.query.DropStore) returns (ai.server.Del); + rpc DropSchema(ai.query.DropSchema) returns (ai.server.Del); /** Ancillary info methods **/ rpc ListClients(ai.query.ListClients) returns (ai.server.ClientList); diff --git a/protos/services/db_service.proto b/protos/services/db_service.proto index de83615ac..27dbe62ac 100644 --- a/protos/services/db_service.proto +++ b/protos/services/db_service.proto @@ -30,6 +30,7 @@ service DBService { rpc DelKey(db.query.DelKey) returns (db.server.Del); rpc DelPred(db.query.DelPred) returns (db.server.Del); rpc DropStore(db.query.DropStore) returns (db.server.Del); + rpc DropSchema(db.query.DropSchema) returns (db.server.Del); /** Ancillary info methods **/ rpc ListClients(db.query.ListClients) returns (db.server.ClientList); diff --git a/sdk/ahnlich-client-go/grpc/ai/pipeline/pipeline.pb.go b/sdk/ahnlich-client-go/grpc/ai/pipeline/pipeline.pb.go index 0018e5bb4..a14bc4cfd 100644 --- a/sdk/ahnlich-client-go/grpc/ai/pipeline/pipeline.pb.go +++ b/sdk/ahnlich-client-go/grpc/ai/pipeline/pipeline.pb.go @@ -51,6 +51,7 @@ type AIQuery struct { // *AIQuery_ConvertStoreInputToEmbeddings // *AIQuery_DelPred // *AIQuery_GetStore + // *AIQuery_DropSchema Query isAIQuery_Query `protobuf_oneof:"query"` } @@ -226,6 +227,13 @@ func (x *AIQuery) GetGetStore() *query.GetStore { return nil } +func (x *AIQuery) GetDropSchema() *query.DropSchema { + if x, ok := x.GetQuery().(*AIQuery_DropSchema); ok { + return x.DropSchema + } + return nil +} + type isAIQuery_Query interface { isAIQuery_Query() } @@ -306,6 +314,10 @@ type AIQuery_GetStore struct { GetStore *query.GetStore `protobuf:"bytes,19,opt,name=get_store,json=getStore,proto3,oneof"` } +type AIQuery_DropSchema struct { + DropSchema *query.DropSchema `protobuf:"bytes,20,opt,name=drop_schema,json=dropSchema,proto3,oneof"` +} + func (*AIQuery_CreateStore) isAIQuery_Query() {} func (*AIQuery_GetPred) isAIQuery_Query() {} @@ -344,6 +356,8 @@ func (*AIQuery_DelPred) isAIQuery_Query() {} func (*AIQuery_GetStore) isAIQuery_Query() {} +func (*AIQuery_DropSchema) isAIQuery_Query() {} + type AIRequestPipeline struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -681,7 +695,7 @@ var file_ai_pipeline_proto_rawDesc = []byte{ 0x1a, 0x0e, 0x61, 0x69, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x61, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, 0x09, 0x0a, 0x07, 0x41, 0x49, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x09, 0x0a, 0x07, 0x41, 0x49, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x00, 0x52, @@ -756,67 +770,71 @@ var file_ai_pipeline_proto_rawDesc = []byte{ 0x6c, 0x50, 0x72, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x48, 0x00, 0x52, 0x08, - 0x67, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x22, 0x43, 0x0a, 0x11, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x69, - 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, 0x71, - 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xcc, 0x05, 0x0a, 0x10, 0x41, 0x49, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x75, - 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x69, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x75, 0x6e, - 0x69, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, - 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, - 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6e, - 0x66, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x66, 0x6f, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x66, 0x6f, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, - 0x74, 0x48, 0x00, 0x52, 0x03, 0x73, 0x65, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x30, 0x0a, 0x09, - 0x67, 0x65, 0x74, 0x5f, 0x73, 0x69, 0x6d, 0x5f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x69, 0x6d, 0x4e, 0x48, 0x00, 0x52, 0x07, 0x67, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x12, 0x22, - 0x0a, 0x03, 0x64, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x69, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x03, 0x64, - 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x48, 0x00, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x32, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x6b, 0x0a, 0x1e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x69, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, - 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, - 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x41, 0x49, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x09, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x12, 0x41, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, - 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, - 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, - 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2f, 0x61, 0x69, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x70, 0x69, - 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x67, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x72, 0x6f, 0x70, + 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x42, 0x07, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x43, 0x0a, 0x11, 0x41, 0x49, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, + 0x2e, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x41, + 0x49, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, + 0xcc, 0x05, 0x0a, 0x10, 0x41, 0x49, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, + 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x70, + 0x6f, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x69, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, + 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0a, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, + 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x22, 0x0a, + 0x03, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x69, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x73, 0x65, + 0x74, 0x12, 0x22, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x00, + 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x30, 0x0a, 0x09, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x69, 0x6d, + 0x5f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x48, 0x00, 0x52, 0x07, + 0x67, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x12, 0x22, 0x0a, 0x03, 0x64, 0x65, 0x6c, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x44, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x03, 0x64, 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0c, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x32, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, + 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x6b, 0x0a, 0x1e, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x65, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, + 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x49, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, + 0x0a, 0x12, 0x41, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x73, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, + 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x69, 0x2f, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -856,19 +874,20 @@ var file_ai_pipeline_proto_goTypes = []any{ (*query.ConvertStoreInputToEmbeddings)(nil), // 20: ai.query.ConvertStoreInputToEmbeddings (*query.DelPred)(nil), // 21: ai.query.DelPred (*query.GetStore)(nil), // 22: ai.query.GetStore - (*server.Unit)(nil), // 23: ai.server.Unit - (*server.Pong)(nil), // 24: ai.server.Pong - (*server.ClientList)(nil), // 25: ai.server.ClientList - (*server.StoreList)(nil), // 26: ai.server.StoreList - (*server.InfoServer)(nil), // 27: ai.server.InfoServer - (*server.Set)(nil), // 28: ai.server.Set - (*server.Get)(nil), // 29: ai.server.Get - (*server.GetSimN)(nil), // 30: ai.server.GetSimN - (*server.Del)(nil), // 31: ai.server.Del - (*server.CreateIndex)(nil), // 32: ai.server.CreateIndex - (*info.ErrorResponse)(nil), // 33: shared.info.ErrorResponse - (*server.StoreInputToEmbeddingsList)(nil), // 34: ai.server.StoreInputToEmbeddingsList - (*server.AIStoreInfo)(nil), // 35: ai.server.AIStoreInfo + (*query.DropSchema)(nil), // 23: ai.query.DropSchema + (*server.Unit)(nil), // 24: ai.server.Unit + (*server.Pong)(nil), // 25: ai.server.Pong + (*server.ClientList)(nil), // 26: ai.server.ClientList + (*server.StoreList)(nil), // 27: ai.server.StoreList + (*server.InfoServer)(nil), // 28: ai.server.InfoServer + (*server.Set)(nil), // 29: ai.server.Set + (*server.Get)(nil), // 30: ai.server.Get + (*server.GetSimN)(nil), // 31: ai.server.GetSimN + (*server.Del)(nil), // 32: ai.server.Del + (*server.CreateIndex)(nil), // 33: ai.server.CreateIndex + (*info.ErrorResponse)(nil), // 34: shared.info.ErrorResponse + (*server.StoreInputToEmbeddingsList)(nil), // 35: ai.server.StoreInputToEmbeddingsList + (*server.AIStoreInfo)(nil), // 36: ai.server.AIStoreInfo } var file_ai_pipeline_proto_depIdxs = []int32{ 4, // 0: ai.pipeline.AIQuery.create_store:type_name -> ai.query.CreateStore @@ -890,26 +909,27 @@ var file_ai_pipeline_proto_depIdxs = []int32{ 20, // 16: ai.pipeline.AIQuery.convert_store_input_to_embeddings:type_name -> ai.query.ConvertStoreInputToEmbeddings 21, // 17: ai.pipeline.AIQuery.del_pred:type_name -> ai.query.DelPred 22, // 18: ai.pipeline.AIQuery.get_store:type_name -> ai.query.GetStore - 0, // 19: ai.pipeline.AIRequestPipeline.queries:type_name -> ai.pipeline.AIQuery - 23, // 20: ai.pipeline.AIServerResponse.unit:type_name -> ai.server.Unit - 24, // 21: ai.pipeline.AIServerResponse.pong:type_name -> ai.server.Pong - 25, // 22: ai.pipeline.AIServerResponse.client_list:type_name -> ai.server.ClientList - 26, // 23: ai.pipeline.AIServerResponse.store_list:type_name -> ai.server.StoreList - 27, // 24: ai.pipeline.AIServerResponse.info_server:type_name -> ai.server.InfoServer - 28, // 25: ai.pipeline.AIServerResponse.set:type_name -> ai.server.Set - 29, // 26: ai.pipeline.AIServerResponse.get:type_name -> ai.server.Get - 30, // 27: ai.pipeline.AIServerResponse.get_sim_n:type_name -> ai.server.GetSimN - 31, // 28: ai.pipeline.AIServerResponse.del:type_name -> ai.server.Del - 32, // 29: ai.pipeline.AIServerResponse.create_index:type_name -> ai.server.CreateIndex - 33, // 30: ai.pipeline.AIServerResponse.error:type_name -> shared.info.ErrorResponse - 34, // 31: ai.pipeline.AIServerResponse.store_input_to_embeddings_list:type_name -> ai.server.StoreInputToEmbeddingsList - 35, // 32: ai.pipeline.AIServerResponse.store_info:type_name -> ai.server.AIStoreInfo - 2, // 33: ai.pipeline.AIResponsePipeline.responses:type_name -> ai.pipeline.AIServerResponse - 34, // [34:34] is the sub-list for method output_type - 34, // [34:34] is the sub-list for method input_type - 34, // [34:34] is the sub-list for extension type_name - 34, // [34:34] is the sub-list for extension extendee - 0, // [0:34] is the sub-list for field type_name + 23, // 19: ai.pipeline.AIQuery.drop_schema:type_name -> ai.query.DropSchema + 0, // 20: ai.pipeline.AIRequestPipeline.queries:type_name -> ai.pipeline.AIQuery + 24, // 21: ai.pipeline.AIServerResponse.unit:type_name -> ai.server.Unit + 25, // 22: ai.pipeline.AIServerResponse.pong:type_name -> ai.server.Pong + 26, // 23: ai.pipeline.AIServerResponse.client_list:type_name -> ai.server.ClientList + 27, // 24: ai.pipeline.AIServerResponse.store_list:type_name -> ai.server.StoreList + 28, // 25: ai.pipeline.AIServerResponse.info_server:type_name -> ai.server.InfoServer + 29, // 26: ai.pipeline.AIServerResponse.set:type_name -> ai.server.Set + 30, // 27: ai.pipeline.AIServerResponse.get:type_name -> ai.server.Get + 31, // 28: ai.pipeline.AIServerResponse.get_sim_n:type_name -> ai.server.GetSimN + 32, // 29: ai.pipeline.AIServerResponse.del:type_name -> ai.server.Del + 33, // 30: ai.pipeline.AIServerResponse.create_index:type_name -> ai.server.CreateIndex + 34, // 31: ai.pipeline.AIServerResponse.error:type_name -> shared.info.ErrorResponse + 35, // 32: ai.pipeline.AIServerResponse.store_input_to_embeddings_list:type_name -> ai.server.StoreInputToEmbeddingsList + 36, // 33: ai.pipeline.AIServerResponse.store_info:type_name -> ai.server.AIStoreInfo + 2, // 34: ai.pipeline.AIResponsePipeline.responses:type_name -> ai.pipeline.AIServerResponse + 35, // [35:35] is the sub-list for method output_type + 35, // [35:35] is the sub-list for method input_type + 35, // [35:35] is the sub-list for extension type_name + 35, // [35:35] is the sub-list for extension extendee + 0, // [0:35] is the sub-list for field type_name } func init() { file_ai_pipeline_proto_init() } @@ -987,6 +1007,7 @@ func file_ai_pipeline_proto_init() { (*AIQuery_ConvertStoreInputToEmbeddings)(nil), (*AIQuery_DelPred)(nil), (*AIQuery_GetStore)(nil), + (*AIQuery_DropSchema)(nil), } file_ai_pipeline_proto_msgTypes[2].OneofWrappers = []any{ (*AIServerResponse_Unit)(nil), diff --git a/sdk/ahnlich-client-go/grpc/ai/query/query.pb.go b/sdk/ahnlich-client-go/grpc/ai/query/query.pb.go index 79eb9c7a1..6437b74f0 100644 --- a/sdk/ahnlich-client-go/grpc/ai/query/query.pb.go +++ b/sdk/ahnlich-client-go/grpc/ai/query/query.pb.go @@ -47,6 +47,7 @@ type CreateStore struct { NonLinearIndices []*nonlinear.NonLinearIndex `protobuf:"bytes,5,rep,name=non_linear_indices,json=nonLinearIndices,proto3" json:"non_linear_indices,omitempty"` // Optional non-linear indices ErrorIfExists bool `protobuf:"varint,6,opt,name=error_if_exists,json=errorIfExists,proto3" json:"error_if_exists,omitempty"` // Whether to throw an error if the store already exists StoreOriginal bool `protobuf:"varint,7,opt,name=store_original,json=storeOriginal,proto3" json:"store_original,omitempty"` // Flag to store original data. Used if you wanna keep the original(image or text) input sent + Schema *string `protobuf:"bytes,8,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace for the store. Defaults to "public". } func (x *CreateStore) Reset() { @@ -130,6 +131,13 @@ func (x *CreateStore) GetStoreOriginal() bool { return false } +func (x *CreateStore) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + type GetPred struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -655,8 +663,9 @@ type DropStore struct { // Deletes the entire store and removes all associated data // Destroys the store, and updates indices accordingly - Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // Store name - ErrorIfNotExists bool `protobuf:"varint,2,opt,name=error_if_not_exists,json=errorIfNotExists,proto3" json:"error_if_not_exists,omitempty"` // Flag to throw an error if the store does not exist + Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // Store name + ErrorIfNotExists bool `protobuf:"varint,2,opt,name=error_if_not_exists,json=errorIfNotExists,proto3" json:"error_if_not_exists,omitempty"` // Flag to throw an error if the store does not exist + Schema *string `protobuf:"bytes,3,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace for the store. Defaults to "public". } func (x *DropStore) Reset() { @@ -705,6 +714,13 @@ func (x *DropStore) GetErrorIfNotExists() bool { return false } +func (x *DropStore) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + type GetKey struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -841,6 +857,9 @@ type ListStores struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. + Schema *string `protobuf:"bytes,1,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace to filter stores. If unset, lists all schemas. } func (x *ListStores) Reset() { @@ -875,13 +894,21 @@ func (*ListStores) Descriptor() ([]byte, []int) { return file_ai_query_proto_rawDescGZIP(), []int{13} } +func (x *ListStores) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + type GetStore struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Gets detailed information about a specific store by name. Returns an error if the store does not exist. - Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // Store name + Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // Store name + Schema *string `protobuf:"bytes,2,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace for the store. Defaults to "public". } func (x *GetStore) Reset() { @@ -923,6 +950,61 @@ func (x *GetStore) GetStore() string { return "" } +func (x *GetStore) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + +type DropSchema struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Drops an entire schema and all stores within it. Cannot drop the "public" default schema. + Schema string `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` // The name of the schema to drop. +} + +func (x *DropSchema) Reset() { + *x = DropSchema{} + if protoimpl.UnsafeEnabled { + mi := &file_ai_query_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DropSchema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DropSchema) ProtoMessage() {} + +func (x *DropSchema) ProtoReflect() protoreflect.Message { + mi := &file_ai_query_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DropSchema.ProtoReflect.Descriptor instead. +func (*DropSchema) Descriptor() ([]byte, []int) { + return file_ai_query_proto_rawDescGZIP(), []int{15} +} + +func (x *DropSchema) GetSchema() string { + if x != nil { + return x.Schema + } + return "" +} + type PurgeStores struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -932,7 +1014,7 @@ type PurgeStores struct { func (x *PurgeStores) Reset() { *x = PurgeStores{} if protoimpl.UnsafeEnabled { - mi := &file_ai_query_proto_msgTypes[15] + mi := &file_ai_query_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -945,7 +1027,7 @@ func (x *PurgeStores) String() string { func (*PurgeStores) ProtoMessage() {} func (x *PurgeStores) ProtoReflect() protoreflect.Message { - mi := &file_ai_query_proto_msgTypes[15] + mi := &file_ai_query_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -958,7 +1040,7 @@ func (x *PurgeStores) ProtoReflect() protoreflect.Message { // Deprecated: Use PurgeStores.ProtoReflect.Descriptor instead. func (*PurgeStores) Descriptor() ([]byte, []int) { - return file_ai_query_proto_rawDescGZIP(), []int{15} + return file_ai_query_proto_rawDescGZIP(), []int{16} } type Ping struct { @@ -970,7 +1052,7 @@ type Ping struct { func (x *Ping) Reset() { *x = Ping{} if protoimpl.UnsafeEnabled { - mi := &file_ai_query_proto_msgTypes[16] + mi := &file_ai_query_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -983,7 +1065,7 @@ func (x *Ping) String() string { func (*Ping) ProtoMessage() {} func (x *Ping) ProtoReflect() protoreflect.Message { - mi := &file_ai_query_proto_msgTypes[16] + mi := &file_ai_query_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -996,7 +1078,7 @@ func (x *Ping) ProtoReflect() protoreflect.Message { // Deprecated: Use Ping.ProtoReflect.Descriptor instead. func (*Ping) Descriptor() ([]byte, []int) { - return file_ai_query_proto_rawDescGZIP(), []int{16} + return file_ai_query_proto_rawDescGZIP(), []int{17} } type Set struct { @@ -1016,7 +1098,7 @@ type Set struct { func (x *Set) Reset() { *x = Set{} if protoimpl.UnsafeEnabled { - mi := &file_ai_query_proto_msgTypes[17] + mi := &file_ai_query_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1029,7 +1111,7 @@ func (x *Set) String() string { func (*Set) ProtoMessage() {} func (x *Set) ProtoReflect() protoreflect.Message { - mi := &file_ai_query_proto_msgTypes[17] + mi := &file_ai_query_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1042,7 +1124,7 @@ func (x *Set) ProtoReflect() protoreflect.Message { // Deprecated: Use Set.ProtoReflect.Descriptor instead. func (*Set) Descriptor() ([]byte, []int) { - return file_ai_query_proto_rawDescGZIP(), []int{17} + return file_ai_query_proto_rawDescGZIP(), []int{18} } func (x *Set) GetStore() string { @@ -1095,7 +1177,7 @@ type ConvertStoreInputToEmbeddings struct { func (x *ConvertStoreInputToEmbeddings) Reset() { *x = ConvertStoreInputToEmbeddings{} if protoimpl.UnsafeEnabled { - mi := &file_ai_query_proto_msgTypes[18] + mi := &file_ai_query_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1108,7 +1190,7 @@ func (x *ConvertStoreInputToEmbeddings) String() string { func (*ConvertStoreInputToEmbeddings) ProtoMessage() {} func (x *ConvertStoreInputToEmbeddings) ProtoReflect() protoreflect.Message { - mi := &file_ai_query_proto_msgTypes[18] + mi := &file_ai_query_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1121,7 +1203,7 @@ func (x *ConvertStoreInputToEmbeddings) ProtoReflect() protoreflect.Message { // Deprecated: Use ConvertStoreInputToEmbeddings.ProtoReflect.Descriptor instead. func (*ConvertStoreInputToEmbeddings) Descriptor() ([]byte, []int) { - return file_ai_query_proto_rawDescGZIP(), []int{18} + return file_ai_query_proto_rawDescGZIP(), []int{19} } func (x *ConvertStoreInputToEmbeddings) GetStoreInputs() []*keyval.StoreInput { @@ -1166,7 +1248,7 @@ var file_ai_query_proto_rawDesc = []byte{ 0x74, 0x68, 0x6d, 0x2f, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xcf, 0x02, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, + 0x74, 0x6f, 0x22, 0xf7, 0x02, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, @@ -1187,163 +1269,175 @@ var file_ai_query_proto_rawDesc = []byte{ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x5d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xcd, 0x04, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, - 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, - 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x41, 0x0a, 0x09, - 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x4e, 0x12, 0x3d, 0x0a, 0x09, - 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1f, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x61, 0x6c, 0x67, 0x6f, - 0x72, 0x69, 0x74, 0x68, 0x6d, 0x73, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, - 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x4c, 0x0a, 0x11, 0x70, - 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x72, 0x65, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x12, 0x65, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x61, 0x69, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x48, - 0x01, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, - 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x3e, - 0x0a, 0x10, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, - 0x0a, 0x0a, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x15, 0x0a, 0x13, - 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, - 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, - 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, - 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, - 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, + 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, + 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x5d, 0x0a, 0x07, + 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, + 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xcd, 0x04, 0x0a, 0x07, + 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35, 0x0a, + 0x0c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x12, 0x41, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x73, 0x74, 0x4e, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, + 0x74, 0x68, 0x6d, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x73, 0x2e, 0x41, + 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, + 0x74, 0x68, 0x6d, 0x12, 0x4c, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, + 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, + 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x10, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x5c, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, + 0x61, 0x69, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x48, 0x01, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, + 0x45, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x0f, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x12, 0x51, 0x0a, 0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, - 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x23, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, - 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, - 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x22, 0x74, 0x0a, 0x0d, 0x44, 0x72, 0x6f, 0x70, 0x50, - 0x72, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2d, - 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, - 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0xb9, 0x01, - 0x0a, 0x1b, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, - 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, - 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x27, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, - 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, - 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, - 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, - 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x46, 0x0a, 0x06, 0x44, 0x65, 0x6c, - 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, - 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x04, 0x6b, 0x65, 0x79, - 0x73, 0x22, 0x5d, 0x0a, 0x07, 0x44, 0x65, 0x6c, 0x50, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x50, 0x0a, 0x09, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, - 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, - 0x74, 0x73, 0x22, 0x46, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, + 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x51, 0x0a, 0x12, + 0x6e, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, + 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x10, 0x6e, + 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x22, + 0x74, 0x0a, 0x0d, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x72, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, + 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x1b, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x6f, + 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x6e, + 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, + 0x74, 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, + 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, + 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, + 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, + 0x73, 0x22, 0x46, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x5d, 0x0a, 0x07, 0x44, 0x65, 0x6c, + 0x50, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x78, 0x0a, 0x09, 0x44, 0x72, 0x6f, 0x70, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2d, 0x0a, 0x13, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, + 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, + 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x22, 0x46, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x73, 0x22, 0x20, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x75, 0x72, 0x67, 0x65, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x22, 0x8f, - 0x03, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x06, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6b, - 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x41, 0x69, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x4c, 0x0a, 0x11, 0x70, 0x72, - 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x72, 0x65, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x61, 0x69, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x48, 0x00, - 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, - 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x65, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x34, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, + 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x48, 0x0a, + 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, + 0x1b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, + 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x24, 0x0a, 0x0a, 0x44, 0x72, 0x6f, 0x70, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x0d, 0x0a, + 0x0b, 0x50, 0x75, 0x72, 0x67, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x22, 0x06, 0x0a, 0x04, + 0x50, 0x69, 0x6e, 0x67, 0x22, 0x8f, 0x03, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x41, 0x69, 0x53, 0x74, + 0x6f, 0x72, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, + 0x12, 0x4c, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x69, + 0x2e, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x70, 0x72, + 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, + 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x61, 0x69, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x65, + 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, + 0x3e, 0x0a, 0x10, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, + 0x15, 0x0a, 0x13, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x86, 0x03, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, + 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, + 0x75, 0x74, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, + 0x51, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x69, 0x2e, + 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x70, + 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, + 0x01, 0x01, 0x12, 0x28, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x12, 0x2e, 0x61, 0x69, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x41, 0x49, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x5b, 0x0a, 0x0c, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, + 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x22, 0x86, 0x03, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, - 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, - 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x0b, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x51, 0x0a, 0x11, 0x70, 0x72, 0x65, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x05, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x61, 0x69, - 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x41, 0x49, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, - 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x5b, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x61, - 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, - 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, - 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, - 0x70, 0x63, 0x2f, 0x61, 0x69, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x3b, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x70, 0x72, + 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, + 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, + 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x69, 0x2f, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x3b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1358,7 +1452,7 @@ func file_ai_query_proto_rawDescGZIP() []byte { return file_ai_query_proto_rawDescData } -var file_ai_query_proto_msgTypes = make([]protoimpl.MessageInfo, 22) +var file_ai_query_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_ai_query_proto_goTypes = []any{ (*CreateStore)(nil), // 0: ai.query.CreateStore (*GetPred)(nil), // 1: ai.query.GetPred @@ -1375,47 +1469,48 @@ var file_ai_query_proto_goTypes = []any{ (*ListClients)(nil), // 12: ai.query.ListClients (*ListStores)(nil), // 13: ai.query.ListStores (*GetStore)(nil), // 14: ai.query.GetStore - (*PurgeStores)(nil), // 15: ai.query.PurgeStores - (*Ping)(nil), // 16: ai.query.Ping - (*Set)(nil), // 17: ai.query.Set - (*ConvertStoreInputToEmbeddings)(nil), // 18: ai.query.ConvertStoreInputToEmbeddings - nil, // 19: ai.query.GetSimN.ModelParamsEntry - nil, // 20: ai.query.Set.ModelParamsEntry - nil, // 21: ai.query.ConvertStoreInputToEmbeddings.ModelParamsEntry - (models.AIModel)(0), // 22: ai.models.AIModel - (*nonlinear.NonLinearIndex)(nil), // 23: algorithm.nonlinear.NonLinearIndex - (*predicates.PredicateCondition)(nil), // 24: predicates.PredicateCondition - (*keyval.StoreInput)(nil), // 25: keyval.StoreInput - (algorithms.Algorithm)(0), // 26: algorithm.algorithms.Algorithm - (preprocess.PreprocessAction)(0), // 27: ai.preprocess.PreprocessAction - (execution_provider.ExecutionProvider)(0), // 28: ai.execution_provider.ExecutionProvider - (nonlinear.NonLinearAlgorithm)(0), // 29: algorithm.nonlinear.NonLinearAlgorithm - (*keyval.AiStoreEntry)(nil), // 30: keyval.AiStoreEntry + (*DropSchema)(nil), // 15: ai.query.DropSchema + (*PurgeStores)(nil), // 16: ai.query.PurgeStores + (*Ping)(nil), // 17: ai.query.Ping + (*Set)(nil), // 18: ai.query.Set + (*ConvertStoreInputToEmbeddings)(nil), // 19: ai.query.ConvertStoreInputToEmbeddings + nil, // 20: ai.query.GetSimN.ModelParamsEntry + nil, // 21: ai.query.Set.ModelParamsEntry + nil, // 22: ai.query.ConvertStoreInputToEmbeddings.ModelParamsEntry + (models.AIModel)(0), // 23: ai.models.AIModel + (*nonlinear.NonLinearIndex)(nil), // 24: algorithm.nonlinear.NonLinearIndex + (*predicates.PredicateCondition)(nil), // 25: predicates.PredicateCondition + (*keyval.StoreInput)(nil), // 26: keyval.StoreInput + (algorithms.Algorithm)(0), // 27: algorithm.algorithms.Algorithm + (preprocess.PreprocessAction)(0), // 28: ai.preprocess.PreprocessAction + (execution_provider.ExecutionProvider)(0), // 29: ai.execution_provider.ExecutionProvider + (nonlinear.NonLinearAlgorithm)(0), // 30: algorithm.nonlinear.NonLinearAlgorithm + (*keyval.AiStoreEntry)(nil), // 31: keyval.AiStoreEntry } var file_ai_query_proto_depIdxs = []int32{ - 22, // 0: ai.query.CreateStore.query_model:type_name -> ai.models.AIModel - 22, // 1: ai.query.CreateStore.index_model:type_name -> ai.models.AIModel - 23, // 2: ai.query.CreateStore.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex - 24, // 3: ai.query.GetPred.condition:type_name -> predicates.PredicateCondition - 25, // 4: ai.query.GetSimN.search_input:type_name -> keyval.StoreInput - 24, // 5: ai.query.GetSimN.condition:type_name -> predicates.PredicateCondition - 26, // 6: ai.query.GetSimN.algorithm:type_name -> algorithm.algorithms.Algorithm - 27, // 7: ai.query.GetSimN.preprocess_action:type_name -> ai.preprocess.PreprocessAction - 28, // 8: ai.query.GetSimN.execution_provider:type_name -> ai.execution_provider.ExecutionProvider - 19, // 9: ai.query.GetSimN.model_params:type_name -> ai.query.GetSimN.ModelParamsEntry - 23, // 10: ai.query.CreateNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex - 29, // 11: ai.query.DropNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearAlgorithm - 25, // 12: ai.query.DelKey.keys:type_name -> keyval.StoreInput - 24, // 13: ai.query.DelPred.condition:type_name -> predicates.PredicateCondition - 25, // 14: ai.query.GetKey.keys:type_name -> keyval.StoreInput - 30, // 15: ai.query.Set.inputs:type_name -> keyval.AiStoreEntry - 27, // 16: ai.query.Set.preprocess_action:type_name -> ai.preprocess.PreprocessAction - 28, // 17: ai.query.Set.execution_provider:type_name -> ai.execution_provider.ExecutionProvider - 20, // 18: ai.query.Set.model_params:type_name -> ai.query.Set.ModelParamsEntry - 25, // 19: ai.query.ConvertStoreInputToEmbeddings.store_inputs:type_name -> keyval.StoreInput - 27, // 20: ai.query.ConvertStoreInputToEmbeddings.preprocess_action:type_name -> ai.preprocess.PreprocessAction - 22, // 21: ai.query.ConvertStoreInputToEmbeddings.model:type_name -> ai.models.AIModel - 21, // 22: ai.query.ConvertStoreInputToEmbeddings.model_params:type_name -> ai.query.ConvertStoreInputToEmbeddings.ModelParamsEntry + 23, // 0: ai.query.CreateStore.query_model:type_name -> ai.models.AIModel + 23, // 1: ai.query.CreateStore.index_model:type_name -> ai.models.AIModel + 24, // 2: ai.query.CreateStore.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex + 25, // 3: ai.query.GetPred.condition:type_name -> predicates.PredicateCondition + 26, // 4: ai.query.GetSimN.search_input:type_name -> keyval.StoreInput + 25, // 5: ai.query.GetSimN.condition:type_name -> predicates.PredicateCondition + 27, // 6: ai.query.GetSimN.algorithm:type_name -> algorithm.algorithms.Algorithm + 28, // 7: ai.query.GetSimN.preprocess_action:type_name -> ai.preprocess.PreprocessAction + 29, // 8: ai.query.GetSimN.execution_provider:type_name -> ai.execution_provider.ExecutionProvider + 20, // 9: ai.query.GetSimN.model_params:type_name -> ai.query.GetSimN.ModelParamsEntry + 24, // 10: ai.query.CreateNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex + 30, // 11: ai.query.DropNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearAlgorithm + 26, // 12: ai.query.DelKey.keys:type_name -> keyval.StoreInput + 25, // 13: ai.query.DelPred.condition:type_name -> predicates.PredicateCondition + 26, // 14: ai.query.GetKey.keys:type_name -> keyval.StoreInput + 31, // 15: ai.query.Set.inputs:type_name -> keyval.AiStoreEntry + 28, // 16: ai.query.Set.preprocess_action:type_name -> ai.preprocess.PreprocessAction + 29, // 17: ai.query.Set.execution_provider:type_name -> ai.execution_provider.ExecutionProvider + 21, // 18: ai.query.Set.model_params:type_name -> ai.query.Set.ModelParamsEntry + 26, // 19: ai.query.ConvertStoreInputToEmbeddings.store_inputs:type_name -> keyval.StoreInput + 28, // 20: ai.query.ConvertStoreInputToEmbeddings.preprocess_action:type_name -> ai.preprocess.PreprocessAction + 23, // 21: ai.query.ConvertStoreInputToEmbeddings.model:type_name -> ai.models.AIModel + 22, // 22: ai.query.ConvertStoreInputToEmbeddings.model_params:type_name -> ai.query.ConvertStoreInputToEmbeddings.ModelParamsEntry 23, // [23:23] is the sub-list for method output_type 23, // [23:23] is the sub-list for method input_type 23, // [23:23] is the sub-list for extension type_name @@ -1610,7 +1705,7 @@ func file_ai_query_proto_init() { } } file_ai_query_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*PurgeStores); i { + switch v := v.(*DropSchema); i { case 0: return &v.state case 1: @@ -1622,7 +1717,7 @@ func file_ai_query_proto_init() { } } file_ai_query_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*Ping); i { + switch v := v.(*PurgeStores); i { case 0: return &v.state case 1: @@ -1634,7 +1729,7 @@ func file_ai_query_proto_init() { } } file_ai_query_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*Set); i { + switch v := v.(*Ping); i { case 0: return &v.state case 1: @@ -1646,6 +1741,18 @@ func file_ai_query_proto_init() { } } file_ai_query_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*Set); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ai_query_proto_msgTypes[19].Exporter = func(v any, i int) any { switch v := v.(*ConvertStoreInputToEmbeddings); i { case 0: return &v.state @@ -1658,16 +1765,20 @@ func file_ai_query_proto_init() { } } } + file_ai_query_proto_msgTypes[0].OneofWrappers = []any{} file_ai_query_proto_msgTypes[2].OneofWrappers = []any{} - file_ai_query_proto_msgTypes[17].OneofWrappers = []any{} + file_ai_query_proto_msgTypes[9].OneofWrappers = []any{} + file_ai_query_proto_msgTypes[13].OneofWrappers = []any{} + file_ai_query_proto_msgTypes[14].OneofWrappers = []any{} file_ai_query_proto_msgTypes[18].OneofWrappers = []any{} + file_ai_query_proto_msgTypes[19].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ai_query_proto_rawDesc, NumEnums: 0, - NumMessages: 22, + NumMessages: 23, NumExtensions: 0, NumServices: 0, }, diff --git a/sdk/ahnlich-client-go/grpc/ai/server/server.pb.go b/sdk/ahnlich-client-go/grpc/ai/server/server.pb.go index 64ea1dabf..d404ca099 100644 --- a/sdk/ahnlich-client-go/grpc/ai/server/server.pb.go +++ b/sdk/ahnlich-client-go/grpc/ai/server/server.pb.go @@ -611,6 +611,7 @@ type AIStoreInfo struct { PredicateIndices []string `protobuf:"bytes,5,rep,name=predicate_indices,json=predicateIndices,proto3" json:"predicate_indices,omitempty"` Dimension uint32 `protobuf:"varint,6,opt,name=dimension,proto3" json:"dimension,omitempty"` DbInfo *server.StoreInfo `protobuf:"bytes,7,opt,name=db_info,json=dbInfo,proto3,oneof" json:"db_info,omitempty"` + Schema *string `protobuf:"bytes,8,opt,name=schema,proto3,oneof" json:"schema,omitempty"` } func (x *AIStoreInfo) Reset() { @@ -694,6 +695,13 @@ func (x *AIStoreInfo) GetDbInfo() *server.StoreInfo { return nil } +func (x *AIStoreInfo) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + type EmbeddingWithMetadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -989,7 +997,7 @@ var file_ai_server_proto_rawDesc = []byte{ 0x75, 0x6e, 0x74, 0x22, 0x36, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x22, 0xbd, 0x02, 0x0a, 0x0b, + 0x61, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x22, 0xe5, 0x02, 0x0a, 0x0b, 0x41, 0x49, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, @@ -1008,46 +1016,48 @@ var file_ai_server_proto_rawDesc = []byte{ 0x52, 0x09, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x64, 0x62, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, - 0x66, 0x6f, 0x48, 0x00, 0x52, 0x06, 0x64, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01, 0x42, - 0x0a, 0x0a, 0x08, 0x5f, 0x64, 0x62, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x89, 0x01, 0x0a, 0x15, - 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x09, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, - 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x65, 0x6d, 0x62, 0x65, - 0x64, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, - 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x55, 0x0a, 0x11, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x70, 0x6c, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x40, 0x0a, 0x0a, - 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x62, - 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xc5, - 0x01, 0x0a, 0x16, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, - 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x05, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, - 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x05, 0x69, 0x6e, - 0x70, 0x75, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x12, - 0x3a, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x62, 0x65, - 0x64, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x76, - 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x57, 0x0a, 0x1a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, - 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, - 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, - 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, - 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, - 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x66, 0x6f, 0x48, 0x00, 0x52, 0x06, 0x64, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01, 0x12, + 0x1b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x01, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, + 0x5f, 0x64, 0x62, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x22, 0x89, 0x01, 0x0a, 0x15, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, + 0x09, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, + 0x65, 0x79, 0x52, 0x09, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, + 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x55, 0x0a, 0x11, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x12, 0x40, 0x0a, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, + 0x74, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x16, 0x53, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x12, 0x28, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, + 0x6c, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x08, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, + 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x57, + 0x0a, 0x1a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, + 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x06, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, + 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x52, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, + 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, + 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, + 0x2f, 0x61, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/sdk/ahnlich-client-go/grpc/db/pipeline/pipeline.pb.go b/sdk/ahnlich-client-go/grpc/db/pipeline/pipeline.pb.go index 10f681e68..eb2ace05d 100644 --- a/sdk/ahnlich-client-go/grpc/db/pipeline/pipeline.pb.go +++ b/sdk/ahnlich-client-go/grpc/db/pipeline/pipeline.pb.go @@ -51,6 +51,7 @@ type DBQuery struct { // *DBQuery_Ping // *DBQuery_GetStore // *DBQuery_ClusterInfo + // *DBQuery_DropSchema Query isDBQuery_Query `protobuf_oneof:"query"` } @@ -219,6 +220,13 @@ func (x *DBQuery) GetClusterInfo() *cluster.ClusterInfoQuery { return nil } +func (x *DBQuery) GetDropSchema() *query.DropSchema { + if x, ok := x.GetQuery().(*DBQuery_DropSchema); ok { + return x.DropSchema + } + return nil +} + type isDBQuery_Query interface { isDBQuery_Query() } @@ -295,6 +303,10 @@ type DBQuery_ClusterInfo struct { ClusterInfo *cluster.ClusterInfoQuery `protobuf:"bytes,18,opt,name=cluster_info,json=clusterInfo,proto3,oneof"` } +type DBQuery_DropSchema struct { + DropSchema *query.DropSchema `protobuf:"bytes,19,opt,name=drop_schema,json=dropSchema,proto3,oneof"` +} + func (*DBQuery_CreateStore) isDBQuery_Query() {} func (*DBQuery_GetKey) isDBQuery_Query() {} @@ -331,6 +343,8 @@ func (*DBQuery_GetStore) isDBQuery_Query() {} func (*DBQuery_ClusterInfo) isDBQuery_Query() {} +func (*DBQuery_DropSchema) isDBQuery_Query() {} + type DBRequestPipeline struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -669,7 +683,7 @@ var file_db_pipeline_proto_rawDesc = []byte{ 0x1a, 0x0f, 0x64, 0x62, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, - 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd0, 0x08, 0x0a, 0x07, 0x44, + 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x89, 0x09, 0x0a, 0x07, 0x44, 0x42, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, @@ -738,65 +752,68 @@ var file_db_pipeline_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x07, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x43, 0x0a, - 0x11, 0x44, 0x42, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x2e, 0x44, 0x42, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x22, 0xa7, 0x05, 0x0a, 0x10, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x25, - 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, - 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x48, 0x00, 0x52, - 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x62, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, - 0x74, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, - 0x35, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x62, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x12, 0x22, 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x03, 0x73, 0x65, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, - 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x30, 0x0a, 0x09, 0x67, 0x65, 0x74, 0x5f, - 0x73, 0x69, 0x6d, 0x5f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, 0x62, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x48, - 0x00, 0x52, 0x07, 0x67, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x12, 0x22, 0x0a, 0x03, 0x64, 0x65, - 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x03, 0x64, 0x65, 0x6c, 0x12, 0x3b, - 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x48, 0x00, 0x52, 0x0b, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x32, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x68, 0x61, - 0x72, 0x65, 0x64, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x35, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, - 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, - 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x12, - 0x44, 0x42, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x62, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x42, - 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, - 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, - 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x62, 0x2f, 0x70, 0x69, 0x70, 0x65, - 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x48, + 0x00, 0x52, 0x0a, 0x64, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x42, 0x07, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x43, 0x0a, 0x11, 0x44, 0x42, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x71, + 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, + 0x62, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa7, 0x05, 0x0a, 0x10, + 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x25, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x48, + 0x00, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x38, + 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, + 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0b, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x69, + 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x03, 0x73, 0x65, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x73, 0x65, 0x74, 0x12, 0x22, 0x0a, + 0x03, 0x67, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x62, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, + 0x74, 0x12, 0x30, 0x0a, 0x09, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x69, 0x6d, 0x5f, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x48, 0x00, 0x52, 0x07, 0x67, 0x65, 0x74, 0x53, + 0x69, 0x6d, 0x4e, 0x12, 0x22, 0x0a, 0x03, 0x64, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, + 0x48, 0x00, 0x52, 0x03, 0x64, 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x12, 0x32, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x69, 0x6e, 0x66, + 0x6f, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, + 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, + 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x48, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x12, 0x44, 0x42, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x64, 0x62, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, + 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, + 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, + 0x63, 0x2f, 0x64, 0x62, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -835,19 +852,20 @@ var file_db_pipeline_proto_goTypes = []any{ (*query.Ping)(nil), // 19: db.query.Ping (*query.GetStore)(nil), // 20: db.query.GetStore (*cluster.ClusterInfoQuery)(nil), // 21: shared.cluster.ClusterInfoQuery - (*server.Unit)(nil), // 22: db.server.Unit - (*server.Pong)(nil), // 23: db.server.Pong - (*server.ClientList)(nil), // 24: db.server.ClientList - (*server.StoreList)(nil), // 25: db.server.StoreList - (*server.InfoServer)(nil), // 26: db.server.InfoServer - (*server.Set)(nil), // 27: db.server.Set - (*server.Get)(nil), // 28: db.server.Get - (*server.GetSimN)(nil), // 29: db.server.GetSimN - (*server.Del)(nil), // 30: db.server.Del - (*server.CreateIndex)(nil), // 31: db.server.CreateIndex - (*info.ErrorResponse)(nil), // 32: shared.info.ErrorResponse - (*server.StoreInfo)(nil), // 33: db.server.StoreInfo - (*cluster.ClusterInfoResponse)(nil), // 34: shared.cluster.ClusterInfoResponse + (*query.DropSchema)(nil), // 22: db.query.DropSchema + (*server.Unit)(nil), // 23: db.server.Unit + (*server.Pong)(nil), // 24: db.server.Pong + (*server.ClientList)(nil), // 25: db.server.ClientList + (*server.StoreList)(nil), // 26: db.server.StoreList + (*server.InfoServer)(nil), // 27: db.server.InfoServer + (*server.Set)(nil), // 28: db.server.Set + (*server.Get)(nil), // 29: db.server.Get + (*server.GetSimN)(nil), // 30: db.server.GetSimN + (*server.Del)(nil), // 31: db.server.Del + (*server.CreateIndex)(nil), // 32: db.server.CreateIndex + (*info.ErrorResponse)(nil), // 33: shared.info.ErrorResponse + (*server.StoreInfo)(nil), // 34: db.server.StoreInfo + (*cluster.ClusterInfoResponse)(nil), // 35: shared.cluster.ClusterInfoResponse } var file_db_pipeline_proto_depIdxs = []int32{ 4, // 0: db.pipeline.DBQuery.create_store:type_name -> db.query.CreateStore @@ -868,26 +886,27 @@ var file_db_pipeline_proto_depIdxs = []int32{ 19, // 15: db.pipeline.DBQuery.ping:type_name -> db.query.Ping 20, // 16: db.pipeline.DBQuery.get_store:type_name -> db.query.GetStore 21, // 17: db.pipeline.DBQuery.cluster_info:type_name -> shared.cluster.ClusterInfoQuery - 0, // 18: db.pipeline.DBRequestPipeline.queries:type_name -> db.pipeline.DBQuery - 22, // 19: db.pipeline.DBServerResponse.unit:type_name -> db.server.Unit - 23, // 20: db.pipeline.DBServerResponse.pong:type_name -> db.server.Pong - 24, // 21: db.pipeline.DBServerResponse.client_list:type_name -> db.server.ClientList - 25, // 22: db.pipeline.DBServerResponse.store_list:type_name -> db.server.StoreList - 26, // 23: db.pipeline.DBServerResponse.info_server:type_name -> db.server.InfoServer - 27, // 24: db.pipeline.DBServerResponse.set:type_name -> db.server.Set - 28, // 25: db.pipeline.DBServerResponse.get:type_name -> db.server.Get - 29, // 26: db.pipeline.DBServerResponse.get_sim_n:type_name -> db.server.GetSimN - 30, // 27: db.pipeline.DBServerResponse.del:type_name -> db.server.Del - 31, // 28: db.pipeline.DBServerResponse.create_index:type_name -> db.server.CreateIndex - 32, // 29: db.pipeline.DBServerResponse.error:type_name -> shared.info.ErrorResponse - 33, // 30: db.pipeline.DBServerResponse.store_info:type_name -> db.server.StoreInfo - 34, // 31: db.pipeline.DBServerResponse.cluster_info:type_name -> shared.cluster.ClusterInfoResponse - 2, // 32: db.pipeline.DBResponsePipeline.responses:type_name -> db.pipeline.DBServerResponse - 33, // [33:33] is the sub-list for method output_type - 33, // [33:33] is the sub-list for method input_type - 33, // [33:33] is the sub-list for extension type_name - 33, // [33:33] is the sub-list for extension extendee - 0, // [0:33] is the sub-list for field type_name + 22, // 18: db.pipeline.DBQuery.drop_schema:type_name -> db.query.DropSchema + 0, // 19: db.pipeline.DBRequestPipeline.queries:type_name -> db.pipeline.DBQuery + 23, // 20: db.pipeline.DBServerResponse.unit:type_name -> db.server.Unit + 24, // 21: db.pipeline.DBServerResponse.pong:type_name -> db.server.Pong + 25, // 22: db.pipeline.DBServerResponse.client_list:type_name -> db.server.ClientList + 26, // 23: db.pipeline.DBServerResponse.store_list:type_name -> db.server.StoreList + 27, // 24: db.pipeline.DBServerResponse.info_server:type_name -> db.server.InfoServer + 28, // 25: db.pipeline.DBServerResponse.set:type_name -> db.server.Set + 29, // 26: db.pipeline.DBServerResponse.get:type_name -> db.server.Get + 30, // 27: db.pipeline.DBServerResponse.get_sim_n:type_name -> db.server.GetSimN + 31, // 28: db.pipeline.DBServerResponse.del:type_name -> db.server.Del + 32, // 29: db.pipeline.DBServerResponse.create_index:type_name -> db.server.CreateIndex + 33, // 30: db.pipeline.DBServerResponse.error:type_name -> shared.info.ErrorResponse + 34, // 31: db.pipeline.DBServerResponse.store_info:type_name -> db.server.StoreInfo + 35, // 32: db.pipeline.DBServerResponse.cluster_info:type_name -> shared.cluster.ClusterInfoResponse + 2, // 33: db.pipeline.DBResponsePipeline.responses:type_name -> db.pipeline.DBServerResponse + 34, // [34:34] is the sub-list for method output_type + 34, // [34:34] is the sub-list for method input_type + 34, // [34:34] is the sub-list for extension type_name + 34, // [34:34] is the sub-list for extension extendee + 0, // [0:34] is the sub-list for field type_name } func init() { file_db_pipeline_proto_init() } @@ -964,6 +983,7 @@ func file_db_pipeline_proto_init() { (*DBQuery_Ping)(nil), (*DBQuery_GetStore)(nil), (*DBQuery_ClusterInfo)(nil), + (*DBQuery_DropSchema)(nil), } file_db_pipeline_proto_msgTypes[2].OneofWrappers = []any{ (*DBServerResponse_Unit)(nil), diff --git a/sdk/ahnlich-client-go/grpc/db/query/query.pb.go b/sdk/ahnlich-client-go/grpc/db/query/query.pb.go index 797850019..51ce5ae88 100644 --- a/sdk/ahnlich-client-go/grpc/db/query/query.pb.go +++ b/sdk/ahnlich-client-go/grpc/db/query/query.pb.go @@ -38,6 +38,7 @@ type CreateStore struct { CreatePredicates []string `protobuf:"bytes,3,rep,name=create_predicates,json=createPredicates,proto3" json:"create_predicates,omitempty"` // Predicates used for querying. NonLinearIndices []*nonlinear.NonLinearIndex `protobuf:"bytes,4,rep,name=non_linear_indices,json=nonLinearIndices,proto3" json:"non_linear_indices,omitempty"` // Non-linear algorithms for indexing. ErrorIfExists bool `protobuf:"varint,5,opt,name=error_if_exists,json=errorIfExists,proto3" json:"error_if_exists,omitempty"` // Flag indicating whether to error if store already exists. + Schema *string `protobuf:"bytes,6,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace for the store. Defaults to "public". } func (x *CreateStore) Reset() { @@ -107,6 +108,13 @@ func (x *CreateStore) GetErrorIfExists() bool { return false } +func (x *CreateStore) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + // Retrieves values from the store based on provided keys. type GetKey struct { state protoimpl.MessageState @@ -666,8 +674,9 @@ type DropStore struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // The name of the store. - ErrorIfNotExists bool `protobuf:"varint,2,opt,name=error_if_not_exists,json=errorIfNotExists,proto3" json:"error_if_not_exists,omitempty"` // Flag indicating whether to error if store does not exist. + Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // The name of the store. + ErrorIfNotExists bool `protobuf:"varint,2,opt,name=error_if_not_exists,json=errorIfNotExists,proto3" json:"error_if_not_exists,omitempty"` // Flag indicating whether to error if store does not exist. + Schema *string `protobuf:"bytes,3,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace for the store. Defaults to "public". } func (x *DropStore) Reset() { @@ -716,6 +725,13 @@ func (x *DropStore) GetErrorIfNotExists() bool { return false } +func (x *DropStore) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + // A request to get server information such as host, port, and version. type InfoServer struct { state protoimpl.MessageState @@ -760,6 +776,8 @@ type ListStores struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Schema *string `protobuf:"bytes,1,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace to filter stores. If unset, lists all schemas. } func (x *ListStores) Reset() { @@ -794,6 +812,13 @@ func (*ListStores) Descriptor() ([]byte, []int) { return file_db_query_proto_rawDescGZIP(), []int{12} } +func (x *ListStores) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + // A request to list all the clients currently connected to the server. type ListClients struct { state protoimpl.MessageState @@ -878,7 +903,8 @@ type GetStore struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // The name of the store. + Store string `protobuf:"bytes,1,opt,name=store,proto3" json:"store,omitempty"` // The name of the store. + Schema *string `protobuf:"bytes,2,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // Optional schema/namespace for the store. Defaults to "public". } func (x *GetStore) Reset() { @@ -920,6 +946,62 @@ func (x *GetStore) GetStore() string { return "" } +func (x *GetStore) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + +// Drops an entire schema and all stores within it. +// Cannot drop the "public" default schema. +type DropSchema struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Schema string `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` // The name of the schema to drop. +} + +func (x *DropSchema) Reset() { + *x = DropSchema{} + if protoimpl.UnsafeEnabled { + mi := &file_db_query_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DropSchema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DropSchema) ProtoMessage() {} + +func (x *DropSchema) ProtoReflect() protoreflect.Message { + mi := &file_db_query_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DropSchema.ProtoReflect.Descriptor instead. +func (*DropSchema) Descriptor() ([]byte, []int) { + return file_db_query_proto_rawDescGZIP(), []int{16} +} + +func (x *DropSchema) GetSchema() string { + if x != nil { + return x.Schema + } + return "" +} + // A request to set multiple key-value entries in the store. // Validation is done for each vector before updating the store. type Set struct { @@ -934,7 +1016,7 @@ type Set struct { func (x *Set) Reset() { *x = Set{} if protoimpl.UnsafeEnabled { - mi := &file_db_query_proto_msgTypes[16] + mi := &file_db_query_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -947,7 +1029,7 @@ func (x *Set) String() string { func (*Set) ProtoMessage() {} func (x *Set) ProtoReflect() protoreflect.Message { - mi := &file_db_query_proto_msgTypes[16] + mi := &file_db_query_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -960,7 +1042,7 @@ func (x *Set) ProtoReflect() protoreflect.Message { // Deprecated: Use Set.ProtoReflect.Descriptor instead. func (*Set) Descriptor() ([]byte, []int) { - return file_db_query_proto_rawDescGZIP(), []int{16} + return file_db_query_proto_rawDescGZIP(), []int{17} } func (x *Set) GetStore() string { @@ -987,7 +1069,7 @@ var file_db_query_proto_rawDesc = []byte{ 0x2f, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xe9, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, + 0x91, 0x02, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, @@ -1001,95 +1083,108 @@ var file_db_query_proto_rawDesc = []byte{ 0x78, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x49, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x44, 0x0a, 0x06, 0x47, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x6b, - 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, - 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, - 0x73, 0x22, 0x5d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0xee, 0x01, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x53, 0x69, 0x6d, 0x4e, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x6f, 0x72, 0x49, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x22, 0x44, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x5d, 0x0a, 0x07, 0x47, 0x65, 0x74, + 0x50, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xee, 0x01, 0x0a, 0x07, 0x47, 0x65, 0x74, + 0x53, 0x69, 0x6d, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x33, 0x0a, 0x0c, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, + 0x65, 0x79, 0x52, 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x4e, 0x12, 0x3d, 0x0a, 0x09, + 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1f, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x73, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x3c, 0x0a, 0x09, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, + 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0x0a, 0x0f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x12, 0x33, 0x0a, 0x0c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, - 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0b, 0x73, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, - 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, - 0x65, 0x73, 0x74, 0x4e, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, - 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, - 0x74, 0x68, 0x6d, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x73, 0x2e, 0x41, - 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, - 0x74, 0x68, 0x6d, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x47, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x64, 0x49, + 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x6e, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, - 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x1d, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x12, 0x51, 0x0a, 0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, - 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, - 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, - 0x64, 0x69, 0x63, 0x65, 0x73, 0x22, 0x74, 0x0a, 0x0d, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x72, 0x65, - 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, - 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x13, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, - 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x1b, - 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, - 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x12, 0x55, 0x0a, 0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x5f, - 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x27, 0x2e, - 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, - 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, - 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, - 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, - 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x44, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x4b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x5d, 0x0a, - 0x07, 0x44, 0x65, 0x6c, 0x50, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3c, - 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, - 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x09, - 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x51, 0x0a, 0x12, 0x6e, 0x6f, + 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, + 0x68, 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x10, 0x6e, 0x6f, 0x6e, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x22, 0x74, 0x0a, + 0x0d, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x72, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, + 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, + 0x73, 0x74, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x1b, 0x44, 0x72, 0x6f, 0x70, 0x4e, 0x6f, 0x6e, 0x4c, + 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x6e, 0x6f, 0x6e, + 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x2e, 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2e, 0x4e, 0x6f, 0x6e, 0x4c, + 0x69, 0x6e, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x10, + 0x6e, 0x6f, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, + 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, + 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, + 0x44, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, - 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, - 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x0c, - 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x0c, 0x0a, 0x0a, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x22, 0x20, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x22, 0x49, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x12, 0x2c, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x44, 0x62, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x46, - 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, - 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, - 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, - 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x62, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x3b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x24, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x52, + 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x5d, 0x0a, 0x07, 0x44, 0x65, 0x6c, 0x50, 0x72, 0x65, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x64, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x78, 0x0a, 0x09, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2d, 0x0a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x66, 0x4e, 0x6f, 0x74, + 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x0c, + 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x34, 0x0a, 0x0a, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x22, 0x48, 0x0a, 0x08, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x22, 0x24, 0x0a, 0x0a, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x49, 0x0a, 0x03, 0x53, 0x65, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x2e, + 0x44, 0x62, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x73, 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, + 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x62, + 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x3b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1104,7 +1199,7 @@ func file_db_query_proto_rawDescGZIP() []byte { return file_db_query_proto_rawDescData } -var file_db_query_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_db_query_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_db_query_proto_goTypes = []any{ (*CreateStore)(nil), // 0: db.query.CreateStore (*GetKey)(nil), // 1: db.query.GetKey @@ -1122,26 +1217,27 @@ var file_db_query_proto_goTypes = []any{ (*ListClients)(nil), // 13: db.query.ListClients (*Ping)(nil), // 14: db.query.Ping (*GetStore)(nil), // 15: db.query.GetStore - (*Set)(nil), // 16: db.query.Set - (*nonlinear.NonLinearIndex)(nil), // 17: algorithm.nonlinear.NonLinearIndex - (*keyval.StoreKey)(nil), // 18: keyval.StoreKey - (*predicates.PredicateCondition)(nil), // 19: predicates.PredicateCondition - (algorithms.Algorithm)(0), // 20: algorithm.algorithms.Algorithm - (nonlinear.NonLinearAlgorithm)(0), // 21: algorithm.nonlinear.NonLinearAlgorithm - (*keyval.DbStoreEntry)(nil), // 22: keyval.DbStoreEntry + (*DropSchema)(nil), // 16: db.query.DropSchema + (*Set)(nil), // 17: db.query.Set + (*nonlinear.NonLinearIndex)(nil), // 18: algorithm.nonlinear.NonLinearIndex + (*keyval.StoreKey)(nil), // 19: keyval.StoreKey + (*predicates.PredicateCondition)(nil), // 20: predicates.PredicateCondition + (algorithms.Algorithm)(0), // 21: algorithm.algorithms.Algorithm + (nonlinear.NonLinearAlgorithm)(0), // 22: algorithm.nonlinear.NonLinearAlgorithm + (*keyval.DbStoreEntry)(nil), // 23: keyval.DbStoreEntry } var file_db_query_proto_depIdxs = []int32{ - 17, // 0: db.query.CreateStore.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex - 18, // 1: db.query.GetKey.keys:type_name -> keyval.StoreKey - 19, // 2: db.query.GetPred.condition:type_name -> predicates.PredicateCondition - 18, // 3: db.query.GetSimN.search_input:type_name -> keyval.StoreKey - 20, // 4: db.query.GetSimN.algorithm:type_name -> algorithm.algorithms.Algorithm - 19, // 5: db.query.GetSimN.condition:type_name -> predicates.PredicateCondition - 17, // 6: db.query.CreateNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex - 21, // 7: db.query.DropNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearAlgorithm - 18, // 8: db.query.DelKey.keys:type_name -> keyval.StoreKey - 19, // 9: db.query.DelPred.condition:type_name -> predicates.PredicateCondition - 22, // 10: db.query.Set.inputs:type_name -> keyval.DbStoreEntry + 18, // 0: db.query.CreateStore.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex + 19, // 1: db.query.GetKey.keys:type_name -> keyval.StoreKey + 20, // 2: db.query.GetPred.condition:type_name -> predicates.PredicateCondition + 19, // 3: db.query.GetSimN.search_input:type_name -> keyval.StoreKey + 21, // 4: db.query.GetSimN.algorithm:type_name -> algorithm.algorithms.Algorithm + 20, // 5: db.query.GetSimN.condition:type_name -> predicates.PredicateCondition + 18, // 6: db.query.CreateNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearIndex + 22, // 7: db.query.DropNonLinearAlgorithmIndex.non_linear_indices:type_name -> algorithm.nonlinear.NonLinearAlgorithm + 19, // 8: db.query.DelKey.keys:type_name -> keyval.StoreKey + 20, // 9: db.query.DelPred.condition:type_name -> predicates.PredicateCondition + 23, // 10: db.query.Set.inputs:type_name -> keyval.DbStoreEntry 11, // [11:11] is the sub-list for method output_type 11, // [11:11] is the sub-list for method input_type 11, // [11:11] is the sub-list for extension type_name @@ -1348,6 +1444,18 @@ func file_db_query_proto_init() { } } file_db_query_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*DropSchema); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_db_query_proto_msgTypes[17].Exporter = func(v any, i int) any { switch v := v.(*Set); i { case 0: return &v.state @@ -1360,13 +1468,17 @@ func file_db_query_proto_init() { } } } + file_db_query_proto_msgTypes[0].OneofWrappers = []any{} + file_db_query_proto_msgTypes[10].OneofWrappers = []any{} + file_db_query_proto_msgTypes[12].OneofWrappers = []any{} + file_db_query_proto_msgTypes[15].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_db_query_proto_rawDesc, NumEnums: 0, - NumMessages: 17, + NumMessages: 18, NumExtensions: 0, NumServices: 0, }, diff --git a/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service.pb.go b/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service.pb.go index 7adb42165..b130cfc8c 100644 --- a/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service.pb.go +++ b/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service.pb.go @@ -33,7 +33,7 @@ var file_services_ai_service_proto_rawDesc = []byte{ 0x1a, 0x11, 0x61, 0x69, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0e, 0x61, 0x69, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x61, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xbf, 0x09, 0x0a, 0x09, 0x41, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xf3, 0x09, 0x0a, 0x09, 0x41, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0f, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, @@ -80,42 +80,45 @@ var file_services_ai_service_proto_rawDesc = []byte{ 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x30, 0x0a, 0x09, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x15, 0x2e, - 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x1a, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x39, - 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x61, - 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x1a, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x49, - 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0b, 0x50, 0x75, 0x72, - 0x67, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x1a, - 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, - 0x27, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a, 0x0f, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x6f, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, - 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x27, 0x2e, 0x61, 0x69, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, - 0x67, 0x73, 0x1a, 0x25, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x08, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x69, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x1a, 0x1f, 0x2e, 0x61, 0x69, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x69, - 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, - 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, - 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x3b, 0x61, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x32, 0x0a, 0x0a, 0x44, 0x72, 0x6f, 0x70, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x0e, 0x2e, 0x61, 0x69, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x15, 0x2e, 0x61, 0x69, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x1a, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x1a, 0x14, 0x2e, 0x61, + 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x14, 0x2e, 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x66, 0x6f, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x1a, 0x15, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x34, 0x0a, + 0x0b, 0x50, 0x75, 0x72, 0x67, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x61, + 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x1a, 0x0e, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x44, 0x65, 0x6c, 0x12, 0x27, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x2e, 0x61, 0x69, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a, 0x0f, 0x2e, 0x61, 0x69, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x6f, 0x0a, 0x1d, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x27, 0x2e, + 0x61, 0x69, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x25, 0x2e, 0x61, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x45, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x4b, 0x0a, + 0x08, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x61, 0x69, 0x2e, 0x70, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x1a, 0x1f, 0x2e, 0x61, 0x69, 0x2e, 0x70, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x41, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, + 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, + 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, + 0x72, 0x70, 0x63, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x69, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x61, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_services_ai_service_proto_goTypes = []any{ @@ -132,26 +135,27 @@ var file_services_ai_service_proto_goTypes = []any{ (*query.DelKey)(nil), // 10: ai.query.DelKey (*query.DelPred)(nil), // 11: ai.query.DelPred (*query.DropStore)(nil), // 12: ai.query.DropStore - (*query.ListClients)(nil), // 13: ai.query.ListClients - (*query.ListStores)(nil), // 14: ai.query.ListStores - (*query.InfoServer)(nil), // 15: ai.query.InfoServer - (*query.PurgeStores)(nil), // 16: ai.query.PurgeStores - (*query.Ping)(nil), // 17: ai.query.Ping - (*query.ConvertStoreInputToEmbeddings)(nil), // 18: ai.query.ConvertStoreInputToEmbeddings - (*pipeline.AIRequestPipeline)(nil), // 19: ai.pipeline.AIRequestPipeline - (*server.Unit)(nil), // 20: ai.server.Unit - (*server.CreateIndex)(nil), // 21: ai.server.CreateIndex - (*server.Get)(nil), // 22: ai.server.Get - (*server.GetSimN)(nil), // 23: ai.server.GetSimN - (*server.AIStoreInfo)(nil), // 24: ai.server.AIStoreInfo - (*server.Set)(nil), // 25: ai.server.Set - (*server.Del)(nil), // 26: ai.server.Del - (*server.ClientList)(nil), // 27: ai.server.ClientList - (*server.StoreList)(nil), // 28: ai.server.StoreList - (*server.InfoServer)(nil), // 29: ai.server.InfoServer - (*server.Pong)(nil), // 30: ai.server.Pong - (*server.StoreInputToEmbeddingsList)(nil), // 31: ai.server.StoreInputToEmbeddingsList - (*pipeline.AIResponsePipeline)(nil), // 32: ai.pipeline.AIResponsePipeline + (*query.DropSchema)(nil), // 13: ai.query.DropSchema + (*query.ListClients)(nil), // 14: ai.query.ListClients + (*query.ListStores)(nil), // 15: ai.query.ListStores + (*query.InfoServer)(nil), // 16: ai.query.InfoServer + (*query.PurgeStores)(nil), // 17: ai.query.PurgeStores + (*query.Ping)(nil), // 18: ai.query.Ping + (*query.ConvertStoreInputToEmbeddings)(nil), // 19: ai.query.ConvertStoreInputToEmbeddings + (*pipeline.AIRequestPipeline)(nil), // 20: ai.pipeline.AIRequestPipeline + (*server.Unit)(nil), // 21: ai.server.Unit + (*server.CreateIndex)(nil), // 22: ai.server.CreateIndex + (*server.Get)(nil), // 23: ai.server.Get + (*server.GetSimN)(nil), // 24: ai.server.GetSimN + (*server.AIStoreInfo)(nil), // 25: ai.server.AIStoreInfo + (*server.Set)(nil), // 26: ai.server.Set + (*server.Del)(nil), // 27: ai.server.Del + (*server.ClientList)(nil), // 28: ai.server.ClientList + (*server.StoreList)(nil), // 29: ai.server.StoreList + (*server.InfoServer)(nil), // 30: ai.server.InfoServer + (*server.Pong)(nil), // 31: ai.server.Pong + (*server.StoreInputToEmbeddingsList)(nil), // 32: ai.server.StoreInputToEmbeddingsList + (*pipeline.AIResponsePipeline)(nil), // 33: ai.pipeline.AIResponsePipeline } var file_services_ai_service_proto_depIdxs = []int32{ 0, // 0: services.ai_service.AIService.CreateStore:input_type -> ai.query.CreateStore @@ -167,35 +171,37 @@ var file_services_ai_service_proto_depIdxs = []int32{ 10, // 10: services.ai_service.AIService.DelKey:input_type -> ai.query.DelKey 11, // 11: services.ai_service.AIService.DelPred:input_type -> ai.query.DelPred 12, // 12: services.ai_service.AIService.DropStore:input_type -> ai.query.DropStore - 13, // 13: services.ai_service.AIService.ListClients:input_type -> ai.query.ListClients - 14, // 14: services.ai_service.AIService.ListStores:input_type -> ai.query.ListStores - 15, // 15: services.ai_service.AIService.InfoServer:input_type -> ai.query.InfoServer - 16, // 16: services.ai_service.AIService.PurgeStores:input_type -> ai.query.PurgeStores - 17, // 17: services.ai_service.AIService.Ping:input_type -> ai.query.Ping - 18, // 18: services.ai_service.AIService.ConvertStoreInputToEmbeddings:input_type -> ai.query.ConvertStoreInputToEmbeddings - 19, // 19: services.ai_service.AIService.Pipeline:input_type -> ai.pipeline.AIRequestPipeline - 20, // 20: services.ai_service.AIService.CreateStore:output_type -> ai.server.Unit - 21, // 21: services.ai_service.AIService.CreatePredIndex:output_type -> ai.server.CreateIndex - 21, // 22: services.ai_service.AIService.CreateNonLinearAlgorithmIndex:output_type -> ai.server.CreateIndex - 22, // 23: services.ai_service.AIService.GetKey:output_type -> ai.server.Get - 22, // 24: services.ai_service.AIService.GetPred:output_type -> ai.server.Get - 23, // 25: services.ai_service.AIService.GetSimN:output_type -> ai.server.GetSimN - 24, // 26: services.ai_service.AIService.GetStore:output_type -> ai.server.AIStoreInfo - 25, // 27: services.ai_service.AIService.Set:output_type -> ai.server.Set - 26, // 28: services.ai_service.AIService.DropPredIndex:output_type -> ai.server.Del - 26, // 29: services.ai_service.AIService.DropNonLinearAlgorithmIndex:output_type -> ai.server.Del - 26, // 30: services.ai_service.AIService.DelKey:output_type -> ai.server.Del - 26, // 31: services.ai_service.AIService.DelPred:output_type -> ai.server.Del - 26, // 32: services.ai_service.AIService.DropStore:output_type -> ai.server.Del - 27, // 33: services.ai_service.AIService.ListClients:output_type -> ai.server.ClientList - 28, // 34: services.ai_service.AIService.ListStores:output_type -> ai.server.StoreList - 29, // 35: services.ai_service.AIService.InfoServer:output_type -> ai.server.InfoServer - 26, // 36: services.ai_service.AIService.PurgeStores:output_type -> ai.server.Del - 30, // 37: services.ai_service.AIService.Ping:output_type -> ai.server.Pong - 31, // 38: services.ai_service.AIService.ConvertStoreInputToEmbeddings:output_type -> ai.server.StoreInputToEmbeddingsList - 32, // 39: services.ai_service.AIService.Pipeline:output_type -> ai.pipeline.AIResponsePipeline - 20, // [20:40] is the sub-list for method output_type - 0, // [0:20] is the sub-list for method input_type + 13, // 13: services.ai_service.AIService.DropSchema:input_type -> ai.query.DropSchema + 14, // 14: services.ai_service.AIService.ListClients:input_type -> ai.query.ListClients + 15, // 15: services.ai_service.AIService.ListStores:input_type -> ai.query.ListStores + 16, // 16: services.ai_service.AIService.InfoServer:input_type -> ai.query.InfoServer + 17, // 17: services.ai_service.AIService.PurgeStores:input_type -> ai.query.PurgeStores + 18, // 18: services.ai_service.AIService.Ping:input_type -> ai.query.Ping + 19, // 19: services.ai_service.AIService.ConvertStoreInputToEmbeddings:input_type -> ai.query.ConvertStoreInputToEmbeddings + 20, // 20: services.ai_service.AIService.Pipeline:input_type -> ai.pipeline.AIRequestPipeline + 21, // 21: services.ai_service.AIService.CreateStore:output_type -> ai.server.Unit + 22, // 22: services.ai_service.AIService.CreatePredIndex:output_type -> ai.server.CreateIndex + 22, // 23: services.ai_service.AIService.CreateNonLinearAlgorithmIndex:output_type -> ai.server.CreateIndex + 23, // 24: services.ai_service.AIService.GetKey:output_type -> ai.server.Get + 23, // 25: services.ai_service.AIService.GetPred:output_type -> ai.server.Get + 24, // 26: services.ai_service.AIService.GetSimN:output_type -> ai.server.GetSimN + 25, // 27: services.ai_service.AIService.GetStore:output_type -> ai.server.AIStoreInfo + 26, // 28: services.ai_service.AIService.Set:output_type -> ai.server.Set + 27, // 29: services.ai_service.AIService.DropPredIndex:output_type -> ai.server.Del + 27, // 30: services.ai_service.AIService.DropNonLinearAlgorithmIndex:output_type -> ai.server.Del + 27, // 31: services.ai_service.AIService.DelKey:output_type -> ai.server.Del + 27, // 32: services.ai_service.AIService.DelPred:output_type -> ai.server.Del + 27, // 33: services.ai_service.AIService.DropStore:output_type -> ai.server.Del + 27, // 34: services.ai_service.AIService.DropSchema:output_type -> ai.server.Del + 28, // 35: services.ai_service.AIService.ListClients:output_type -> ai.server.ClientList + 29, // 36: services.ai_service.AIService.ListStores:output_type -> ai.server.StoreList + 30, // 37: services.ai_service.AIService.InfoServer:output_type -> ai.server.InfoServer + 27, // 38: services.ai_service.AIService.PurgeStores:output_type -> ai.server.Del + 31, // 39: services.ai_service.AIService.Ping:output_type -> ai.server.Pong + 32, // 40: services.ai_service.AIService.ConvertStoreInputToEmbeddings:output_type -> ai.server.StoreInputToEmbeddingsList + 33, // 41: services.ai_service.AIService.Pipeline:output_type -> ai.pipeline.AIResponsePipeline + 21, // [21:42] is the sub-list for method output_type + 0, // [0:21] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service_grpc.pb.go b/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service_grpc.pb.go index 97ed8d7c6..70554e958 100644 --- a/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service_grpc.pb.go +++ b/sdk/ahnlich-client-go/grpc/services/ai_service/ai_service_grpc.pb.go @@ -37,6 +37,7 @@ const ( AIService_DelKey_FullMethodName = "/services.ai_service.AIService/DelKey" AIService_DelPred_FullMethodName = "/services.ai_service.AIService/DelPred" AIService_DropStore_FullMethodName = "/services.ai_service.AIService/DropStore" + AIService_DropSchema_FullMethodName = "/services.ai_service.AIService/DropSchema" AIService_ListClients_FullMethodName = "/services.ai_service.AIService/ListClients" AIService_ListStores_FullMethodName = "/services.ai_service.AIService/ListStores" AIService_InfoServer_FullMethodName = "/services.ai_service.AIService/InfoServer" @@ -67,6 +68,7 @@ type AIServiceClient interface { DelKey(ctx context.Context, in *query.DelKey, opts ...grpc.CallOption) (*server.Del, error) DelPred(ctx context.Context, in *query.DelPred, opts ...grpc.CallOption) (*server.Del, error) DropStore(ctx context.Context, in *query.DropStore, opts ...grpc.CallOption) (*server.Del, error) + DropSchema(ctx context.Context, in *query.DropSchema, opts ...grpc.CallOption) (*server.Del, error) // * Ancillary info methods * ListClients(ctx context.Context, in *query.ListClients, opts ...grpc.CallOption) (*server.ClientList, error) ListStores(ctx context.Context, in *query.ListStores, opts ...grpc.CallOption) (*server.StoreList, error) @@ -216,6 +218,16 @@ func (c *aIServiceClient) DropStore(ctx context.Context, in *query.DropStore, op return out, nil } +func (c *aIServiceClient) DropSchema(ctx context.Context, in *query.DropSchema, opts ...grpc.CallOption) (*server.Del, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(server.Del) + err := c.cc.Invoke(ctx, AIService_DropSchema_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *aIServiceClient) ListClients(ctx context.Context, in *query.ListClients, opts ...grpc.CallOption) (*server.ClientList, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(server.ClientList) @@ -307,6 +319,7 @@ type AIServiceServer interface { DelKey(context.Context, *query.DelKey) (*server.Del, error) DelPred(context.Context, *query.DelPred) (*server.Del, error) DropStore(context.Context, *query.DropStore) (*server.Del, error) + DropSchema(context.Context, *query.DropSchema) (*server.Del, error) // * Ancillary info methods * ListClients(context.Context, *query.ListClients) (*server.ClientList, error) ListStores(context.Context, *query.ListStores) (*server.StoreList, error) @@ -365,6 +378,9 @@ func (UnimplementedAIServiceServer) DelPred(context.Context, *query.DelPred) (*s func (UnimplementedAIServiceServer) DropStore(context.Context, *query.DropStore) (*server.Del, error) { return nil, status.Errorf(codes.Unimplemented, "method DropStore not implemented") } +func (UnimplementedAIServiceServer) DropSchema(context.Context, *query.DropSchema) (*server.Del, error) { + return nil, status.Errorf(codes.Unimplemented, "method DropSchema not implemented") +} func (UnimplementedAIServiceServer) ListClients(context.Context, *query.ListClients) (*server.ClientList, error) { return nil, status.Errorf(codes.Unimplemented, "method ListClients not implemented") } @@ -641,6 +657,24 @@ func _AIService_DropStore_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _AIService_DropSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(query.DropSchema) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AIServiceServer).DropSchema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AIService_DropSchema_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AIServiceServer).DropSchema(ctx, req.(*query.DropSchema)) + } + return interceptor(ctx, in, info, handler) +} + func _AIService_ListClients_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(query.ListClients) if err := dec(in); err != nil { @@ -826,6 +860,10 @@ var AIService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DropStore", Handler: _AIService_DropStore_Handler, }, + { + MethodName: "DropSchema", + Handler: _AIService_DropSchema_Handler, + }, { MethodName: "ListClients", Handler: _AIService_ListClients_Handler, diff --git a/sdk/ahnlich-client-go/grpc/services/db_service/db_service.pb.go b/sdk/ahnlich-client-go/grpc/services/db_service/db_service.pb.go index 1248b6836..27d7f2e5b 100644 --- a/sdk/ahnlich-client-go/grpc/services/db_service/db_service.pb.go +++ b/sdk/ahnlich-client-go/grpc/services/db_service/db_service.pb.go @@ -35,7 +35,7 @@ var file_services_db_service_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x1a, 0x0e, 0x64, 0x62, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x64, 0x62, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xec, 0x08, 0x0a, 0x09, 0x44, + 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xa0, 0x09, 0x0a, 0x09, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0f, @@ -82,37 +82,40 @@ var file_services_db_service_proto_rawDesc = []byte{ 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x30, 0x0a, 0x09, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x1a, 0x0e, 0x2e, 0x64, 0x62, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x4c, - 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x15, 0x2e, 0x64, 0x62, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x73, 0x1a, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x1a, 0x14, 0x2e, 0x64, - 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x12, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x66, 0x6f, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x1a, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x54, 0x0a, - 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x73, - 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x23, - 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x2e, 0x64, 0x62, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a, 0x0f, 0x2e, 0x64, 0x62, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x4b, 0x0a, 0x08, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x64, 0x62, 0x2e, 0x70, 0x69, - 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x2e, 0x70, 0x69, - 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x39, 0x36, 0x2f, - 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x68, 0x6e, 0x6c, - 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x72, - 0x70, 0x63, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x64, 0x62, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x64, 0x62, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, 0x32, 0x0a, 0x0a, 0x44, + 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, + 0x0e, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x12, + 0x3b, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x15, + 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x15, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x64, 0x62, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x1a, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x1a, 0x15, 0x2e, 0x64, 0x62, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x54, 0x0a, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x20, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x1a, 0x23, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, + 0x0e, 0x2e, 0x64, 0x62, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a, + 0x0f, 0x2e, 0x64, 0x62, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, + 0x12, 0x4b, 0x0a, 0x08, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x64, + 0x62, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x1a, 0x1f, 0x2e, 0x64, + 0x62, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x42, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x56, 0x5a, + 0x54, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x65, + 0x6e, 0x39, 0x36, 0x2f, 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2f, 0x73, 0x64, 0x6b, 0x2f, + 0x61, 0x68, 0x6e, 0x6c, 0x69, 0x63, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, + 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x64, 0x62, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x64, 0x62, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_services_db_service_proto_goTypes = []any{ @@ -129,25 +132,26 @@ var file_services_db_service_proto_goTypes = []any{ (*query.DelKey)(nil), // 10: db.query.DelKey (*query.DelPred)(nil), // 11: db.query.DelPred (*query.DropStore)(nil), // 12: db.query.DropStore - (*query.ListClients)(nil), // 13: db.query.ListClients - (*query.ListStores)(nil), // 14: db.query.ListStores - (*query.InfoServer)(nil), // 15: db.query.InfoServer - (*cluster.ClusterInfoQuery)(nil), // 16: shared.cluster.ClusterInfoQuery - (*query.Ping)(nil), // 17: db.query.Ping - (*pipeline.DBRequestPipeline)(nil), // 18: db.pipeline.DBRequestPipeline - (*server.Unit)(nil), // 19: db.server.Unit - (*server.CreateIndex)(nil), // 20: db.server.CreateIndex - (*server.Get)(nil), // 21: db.server.Get - (*server.GetSimN)(nil), // 22: db.server.GetSimN - (*server.StoreInfo)(nil), // 23: db.server.StoreInfo - (*server.Set)(nil), // 24: db.server.Set - (*server.Del)(nil), // 25: db.server.Del - (*server.ClientList)(nil), // 26: db.server.ClientList - (*server.StoreList)(nil), // 27: db.server.StoreList - (*server.InfoServer)(nil), // 28: db.server.InfoServer - (*cluster.ClusterInfoResponse)(nil), // 29: shared.cluster.ClusterInfoResponse - (*server.Pong)(nil), // 30: db.server.Pong - (*pipeline.DBResponsePipeline)(nil), // 31: db.pipeline.DBResponsePipeline + (*query.DropSchema)(nil), // 13: db.query.DropSchema + (*query.ListClients)(nil), // 14: db.query.ListClients + (*query.ListStores)(nil), // 15: db.query.ListStores + (*query.InfoServer)(nil), // 16: db.query.InfoServer + (*cluster.ClusterInfoQuery)(nil), // 17: shared.cluster.ClusterInfoQuery + (*query.Ping)(nil), // 18: db.query.Ping + (*pipeline.DBRequestPipeline)(nil), // 19: db.pipeline.DBRequestPipeline + (*server.Unit)(nil), // 20: db.server.Unit + (*server.CreateIndex)(nil), // 21: db.server.CreateIndex + (*server.Get)(nil), // 22: db.server.Get + (*server.GetSimN)(nil), // 23: db.server.GetSimN + (*server.StoreInfo)(nil), // 24: db.server.StoreInfo + (*server.Set)(nil), // 25: db.server.Set + (*server.Del)(nil), // 26: db.server.Del + (*server.ClientList)(nil), // 27: db.server.ClientList + (*server.StoreList)(nil), // 28: db.server.StoreList + (*server.InfoServer)(nil), // 29: db.server.InfoServer + (*cluster.ClusterInfoResponse)(nil), // 30: shared.cluster.ClusterInfoResponse + (*server.Pong)(nil), // 31: db.server.Pong + (*pipeline.DBResponsePipeline)(nil), // 32: db.pipeline.DBResponsePipeline } var file_services_db_service_proto_depIdxs = []int32{ 0, // 0: services.db_service.DBService.CreateStore:input_type -> db.query.CreateStore @@ -163,33 +167,35 @@ var file_services_db_service_proto_depIdxs = []int32{ 10, // 10: services.db_service.DBService.DelKey:input_type -> db.query.DelKey 11, // 11: services.db_service.DBService.DelPred:input_type -> db.query.DelPred 12, // 12: services.db_service.DBService.DropStore:input_type -> db.query.DropStore - 13, // 13: services.db_service.DBService.ListClients:input_type -> db.query.ListClients - 14, // 14: services.db_service.DBService.ListStores:input_type -> db.query.ListStores - 15, // 15: services.db_service.DBService.InfoServer:input_type -> db.query.InfoServer - 16, // 16: services.db_service.DBService.ClusterInfo:input_type -> shared.cluster.ClusterInfoQuery - 17, // 17: services.db_service.DBService.Ping:input_type -> db.query.Ping - 18, // 18: services.db_service.DBService.Pipeline:input_type -> db.pipeline.DBRequestPipeline - 19, // 19: services.db_service.DBService.CreateStore:output_type -> db.server.Unit - 20, // 20: services.db_service.DBService.CreatePredIndex:output_type -> db.server.CreateIndex - 20, // 21: services.db_service.DBService.CreateNonLinearAlgorithmIndex:output_type -> db.server.CreateIndex - 21, // 22: services.db_service.DBService.GetKey:output_type -> db.server.Get - 21, // 23: services.db_service.DBService.GetPred:output_type -> db.server.Get - 22, // 24: services.db_service.DBService.GetSimN:output_type -> db.server.GetSimN - 23, // 25: services.db_service.DBService.GetStore:output_type -> db.server.StoreInfo - 24, // 26: services.db_service.DBService.Set:output_type -> db.server.Set - 25, // 27: services.db_service.DBService.DropPredIndex:output_type -> db.server.Del - 25, // 28: services.db_service.DBService.DropNonLinearAlgorithmIndex:output_type -> db.server.Del - 25, // 29: services.db_service.DBService.DelKey:output_type -> db.server.Del - 25, // 30: services.db_service.DBService.DelPred:output_type -> db.server.Del - 25, // 31: services.db_service.DBService.DropStore:output_type -> db.server.Del - 26, // 32: services.db_service.DBService.ListClients:output_type -> db.server.ClientList - 27, // 33: services.db_service.DBService.ListStores:output_type -> db.server.StoreList - 28, // 34: services.db_service.DBService.InfoServer:output_type -> db.server.InfoServer - 29, // 35: services.db_service.DBService.ClusterInfo:output_type -> shared.cluster.ClusterInfoResponse - 30, // 36: services.db_service.DBService.Ping:output_type -> db.server.Pong - 31, // 37: services.db_service.DBService.Pipeline:output_type -> db.pipeline.DBResponsePipeline - 19, // [19:38] is the sub-list for method output_type - 0, // [0:19] is the sub-list for method input_type + 13, // 13: services.db_service.DBService.DropSchema:input_type -> db.query.DropSchema + 14, // 14: services.db_service.DBService.ListClients:input_type -> db.query.ListClients + 15, // 15: services.db_service.DBService.ListStores:input_type -> db.query.ListStores + 16, // 16: services.db_service.DBService.InfoServer:input_type -> db.query.InfoServer + 17, // 17: services.db_service.DBService.ClusterInfo:input_type -> shared.cluster.ClusterInfoQuery + 18, // 18: services.db_service.DBService.Ping:input_type -> db.query.Ping + 19, // 19: services.db_service.DBService.Pipeline:input_type -> db.pipeline.DBRequestPipeline + 20, // 20: services.db_service.DBService.CreateStore:output_type -> db.server.Unit + 21, // 21: services.db_service.DBService.CreatePredIndex:output_type -> db.server.CreateIndex + 21, // 22: services.db_service.DBService.CreateNonLinearAlgorithmIndex:output_type -> db.server.CreateIndex + 22, // 23: services.db_service.DBService.GetKey:output_type -> db.server.Get + 22, // 24: services.db_service.DBService.GetPred:output_type -> db.server.Get + 23, // 25: services.db_service.DBService.GetSimN:output_type -> db.server.GetSimN + 24, // 26: services.db_service.DBService.GetStore:output_type -> db.server.StoreInfo + 25, // 27: services.db_service.DBService.Set:output_type -> db.server.Set + 26, // 28: services.db_service.DBService.DropPredIndex:output_type -> db.server.Del + 26, // 29: services.db_service.DBService.DropNonLinearAlgorithmIndex:output_type -> db.server.Del + 26, // 30: services.db_service.DBService.DelKey:output_type -> db.server.Del + 26, // 31: services.db_service.DBService.DelPred:output_type -> db.server.Del + 26, // 32: services.db_service.DBService.DropStore:output_type -> db.server.Del + 26, // 33: services.db_service.DBService.DropSchema:output_type -> db.server.Del + 27, // 34: services.db_service.DBService.ListClients:output_type -> db.server.ClientList + 28, // 35: services.db_service.DBService.ListStores:output_type -> db.server.StoreList + 29, // 36: services.db_service.DBService.InfoServer:output_type -> db.server.InfoServer + 30, // 37: services.db_service.DBService.ClusterInfo:output_type -> shared.cluster.ClusterInfoResponse + 31, // 38: services.db_service.DBService.Ping:output_type -> db.server.Pong + 32, // 39: services.db_service.DBService.Pipeline:output_type -> db.pipeline.DBResponsePipeline + 20, // [20:40] is the sub-list for method output_type + 0, // [0:20] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/sdk/ahnlich-client-go/grpc/services/db_service/db_service_grpc.pb.go b/sdk/ahnlich-client-go/grpc/services/db_service/db_service_grpc.pb.go index ce4b12bea..36ff36bd1 100644 --- a/sdk/ahnlich-client-go/grpc/services/db_service/db_service_grpc.pb.go +++ b/sdk/ahnlich-client-go/grpc/services/db_service/db_service_grpc.pb.go @@ -38,6 +38,7 @@ const ( DBService_DelKey_FullMethodName = "/services.db_service.DBService/DelKey" DBService_DelPred_FullMethodName = "/services.db_service.DBService/DelPred" DBService_DropStore_FullMethodName = "/services.db_service.DBService/DropStore" + DBService_DropSchema_FullMethodName = "/services.db_service.DBService/DropSchema" DBService_ListClients_FullMethodName = "/services.db_service.DBService/ListClients" DBService_ListStores_FullMethodName = "/services.db_service.DBService/ListStores" DBService_InfoServer_FullMethodName = "/services.db_service.DBService/InfoServer" @@ -67,6 +68,7 @@ type DBServiceClient interface { DelKey(ctx context.Context, in *query.DelKey, opts ...grpc.CallOption) (*server.Del, error) DelPred(ctx context.Context, in *query.DelPred, opts ...grpc.CallOption) (*server.Del, error) DropStore(ctx context.Context, in *query.DropStore, opts ...grpc.CallOption) (*server.Del, error) + DropSchema(ctx context.Context, in *query.DropSchema, opts ...grpc.CallOption) (*server.Del, error) // * Ancillary info methods * ListClients(ctx context.Context, in *query.ListClients, opts ...grpc.CallOption) (*server.ClientList, error) ListStores(ctx context.Context, in *query.ListStores, opts ...grpc.CallOption) (*server.StoreList, error) @@ -215,6 +217,16 @@ func (c *dBServiceClient) DropStore(ctx context.Context, in *query.DropStore, op return out, nil } +func (c *dBServiceClient) DropSchema(ctx context.Context, in *query.DropSchema, opts ...grpc.CallOption) (*server.Del, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(server.Del) + err := c.cc.Invoke(ctx, DBService_DropSchema_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *dBServiceClient) ListClients(ctx context.Context, in *query.ListClients, opts ...grpc.CallOption) (*server.ClientList, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(server.ClientList) @@ -296,6 +308,7 @@ type DBServiceServer interface { DelKey(context.Context, *query.DelKey) (*server.Del, error) DelPred(context.Context, *query.DelPred) (*server.Del, error) DropStore(context.Context, *query.DropStore) (*server.Del, error) + DropSchema(context.Context, *query.DropSchema) (*server.Del, error) // * Ancillary info methods * ListClients(context.Context, *query.ListClients) (*server.ClientList, error) ListStores(context.Context, *query.ListStores) (*server.StoreList, error) @@ -353,6 +366,9 @@ func (UnimplementedDBServiceServer) DelPred(context.Context, *query.DelPred) (*s func (UnimplementedDBServiceServer) DropStore(context.Context, *query.DropStore) (*server.Del, error) { return nil, status.Errorf(codes.Unimplemented, "method DropStore not implemented") } +func (UnimplementedDBServiceServer) DropSchema(context.Context, *query.DropSchema) (*server.Del, error) { + return nil, status.Errorf(codes.Unimplemented, "method DropSchema not implemented") +} func (UnimplementedDBServiceServer) ListClients(context.Context, *query.ListClients) (*server.ClientList, error) { return nil, status.Errorf(codes.Unimplemented, "method ListClients not implemented") } @@ -626,6 +642,24 @@ func _DBService_DropStore_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _DBService_DropSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(query.DropSchema) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DBServiceServer).DropSchema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DBService_DropSchema_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DBServiceServer).DropSchema(ctx, req.(*query.DropSchema)) + } + return interceptor(ctx, in, info, handler) +} + func _DBService_ListClients_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(query.ListClients) if err := dec(in); err != nil { @@ -793,6 +827,10 @@ var DBService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DropStore", Handler: _DBService_DropStore_Handler, }, + { + MethodName: "DropSchema", + Handler: _DBService_DropSchema_Handler, + }, { MethodName: "ListClients", Handler: _DBService_ListClients_Handler, diff --git a/sdk/ahnlich-client-go/tests/ai/ai_test.go b/sdk/ahnlich-client-go/tests/ai/ai_test.go index d7425109e..61d18b363 100644 --- a/sdk/ahnlich-client-go/tests/ai/ai_test.go +++ b/sdk/ahnlich-client-go/tests/ai/ai_test.go @@ -1,3 +1,4 @@ +// Package ai_test contains integration tests for AI proxy operations. package ai_test import ( diff --git a/sdk/ahnlich-client-go/tests/ai/auth_test.go b/sdk/ahnlich-client-go/tests/ai/auth_test.go index fa7a67ccb..e070815ee 100644 --- a/sdk/ahnlich-client-go/tests/ai/auth_test.go +++ b/sdk/ahnlich-client-go/tests/ai/auth_test.go @@ -1,3 +1,4 @@ +// Package ai_test contains integration tests for AI proxy operations. package ai_test import ( diff --git a/sdk/ahnlich-client-go/tests/auth_utils.go b/sdk/ahnlich-client-go/tests/auth_utils.go index c895c20a7..b7206b3b7 100644 --- a/sdk/ahnlich-client-go/tests/auth_utils.go +++ b/sdk/ahnlich-client-go/tests/auth_utils.go @@ -1,3 +1,4 @@ +// Package ahnlichgotest provides test utilities for ahnlich Go SDK tests. package ahnlichgotest import ( diff --git a/sdk/ahnlich-client-go/tests/db/auth_test.go b/sdk/ahnlich-client-go/tests/db/auth_test.go index abcac00ca..e19c81dde 100644 --- a/sdk/ahnlich-client-go/tests/db/auth_test.go +++ b/sdk/ahnlich-client-go/tests/db/auth_test.go @@ -1,3 +1,4 @@ +// Package db_test contains integration tests for DB operations. package db_test import ( diff --git a/sdk/ahnlich-client-go/tests/db/db_test.go b/sdk/ahnlich-client-go/tests/db/db_test.go index 84f5628e5..fe3ca9c1b 100644 --- a/sdk/ahnlich-client-go/tests/db/db_test.go +++ b/sdk/ahnlich-client-go/tests/db/db_test.go @@ -1,3 +1,4 @@ +// Package db_test contains integration tests for DB operations. package db_test import ( diff --git a/sdk/ahnlich-client-go/tests/utils.go b/sdk/ahnlich-client-go/tests/utils.go index 7a274e5a4..d9b23e1ec 100644 --- a/sdk/ahnlich-client-go/tests/utils.go +++ b/sdk/ahnlich-client-go/tests/utils.go @@ -26,9 +26,11 @@ import ( dbsvc "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/services/db_service" ) +// MaxRetries is the maximum number of retries to check if the Ahnlich process is running. +// RetryInterval is the interval between retries to check if the Ahnlich process is running. const ( - MaxRetries = 120 // MaxRetries ... Maximum number of retries to check if the Ahnlich process is running - RetryInterval = 1 * time.Second // RetryInterval ... Interval between retries to check if the Ahnlich process is running + MaxRetries = 120 + RetryInterval = 1 * time.Second ) // AhnlichProcess ... A struct to hold the Ahnlich process information diff --git a/sdk/ahnlich-client-node/grpc/ai/pipeline_pb.ts b/sdk/ahnlich-client-node/grpc/ai/pipeline_pb.ts index 7741b427b..84f736f25 100644 --- a/sdk/ahnlich-client-node/grpc/ai/pipeline_pb.ts +++ b/sdk/ahnlich-client-node/grpc/ai/pipeline_pb.ts @@ -21,6 +21,7 @@ import { DelPred, DropNonLinearAlgorithmIndex, DropPredIndex, + DropSchema, DropStore, GetKey, GetPred, @@ -190,6 +191,13 @@ export class AIQuery extends Message { value: GetStore; case: "getStore"; } + | { + /** + * @generated from field: ai.query.DropSchema drop_schema = 20; + */ + value: DropSchema; + case: "dropSchema"; + } | { case: undefined; value?: undefined } = { case: undefined }; constructor(data?: PartialMessage) { @@ -237,6 +245,7 @@ export class AIQuery extends Message { }, { no: 18, name: "del_pred", kind: "message", T: DelPred, oneof: "query" }, { no: 19, name: "get_store", kind: "message", T: GetStore, oneof: "query" }, + { no: 20, name: "drop_schema", kind: "message", T: DropSchema, oneof: "query" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): AIQuery { diff --git a/sdk/ahnlich-client-node/grpc/ai/query_pb.ts b/sdk/ahnlich-client-node/grpc/ai/query_pb.ts index c291c2f43..cad629d2e 100644 --- a/sdk/ahnlich-client-node/grpc/ai/query_pb.ts +++ b/sdk/ahnlich-client-node/grpc/ai/query_pb.ts @@ -80,6 +80,13 @@ export class CreateStore extends Message { */ storeOriginal = false; + /** + * Optional schema/namespace for the store. Defaults to "public". + * + * @generated from field: optional string schema = 8; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -95,6 +102,7 @@ export class CreateStore extends Message { { no: 5, name: "non_linear_indices", kind: "message", T: NonLinearIndex, repeated: true }, { no: 6, name: "error_if_exists", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, { no: 7, name: "store_original", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 8, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): CreateStore { @@ -660,6 +668,13 @@ export class DropStore extends Message { */ errorIfNotExists = false; + /** + * Optional schema/namespace for the store. Defaults to "public". + * + * @generated from field: optional string schema = 3; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -670,6 +685,7 @@ export class DropStore extends Message { static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "store", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 2, name: "error_if_not_exists", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 3, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): DropStore { @@ -815,11 +831,18 @@ export class ListClients extends Message { } /** - * Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. - * * @generated from message ai.query.ListStores */ export class ListStores extends Message { + /** + * Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. + * + * Optional schema/namespace to filter stores. If unset, lists all schemas. + * + * @generated from field: optional string schema = 1; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -827,7 +850,9 @@ export class ListStores extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "ai.query.ListStores"; - static readonly fields: FieldList = proto3.util.newFieldList(() => []); + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + ]); static fromBinary(bytes: Uint8Array, options?: Partial): ListStores { return new ListStores().fromBinary(bytes, options); @@ -862,6 +887,13 @@ export class GetStore extends Message { */ store = ""; + /** + * Optional schema/namespace for the store. Defaults to "public". + * + * @generated from field: optional string schema = 2; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -871,6 +903,7 @@ export class GetStore extends Message { static readonly typeName = "ai.query.GetStore"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "store", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetStore { @@ -893,6 +926,50 @@ export class GetStore extends Message { } } +/** + * @generated from message ai.query.DropSchema + */ +export class DropSchema extends Message { + /** + * Drops an entire schema and all stores within it. Cannot drop the "public" default schema. + * + * The name of the schema to drop. + * + * @generated from field: string schema = 1; + */ + schema = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "ai.query.DropSchema"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): DropSchema { + return new DropSchema().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): DropSchema { + return new DropSchema().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): DropSchema { + return new DropSchema().fromJsonString(jsonString, options); + } + + static equals( + a: DropSchema | PlainMessage | undefined, + b: DropSchema | PlainMessage | undefined, + ): boolean { + return proto3.util.equals(DropSchema, a, b); + } +} + /** * Purges (deletes) all stores on the server, effectively destroying all stored data * diff --git a/sdk/ahnlich-client-node/grpc/ai/server_pb.ts b/sdk/ahnlich-client-node/grpc/ai/server_pb.ts index 35eb22f0e..5f8385e31 100644 --- a/sdk/ahnlich-client-node/grpc/ai/server_pb.ts +++ b/sdk/ahnlich-client-node/grpc/ai/server_pb.ts @@ -542,6 +542,11 @@ export class AIStoreInfo extends Message { */ dbInfo?: StoreInfo; + /** + * @generated from field: optional string schema = 8; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -563,6 +568,7 @@ export class AIStoreInfo extends Message { }, { no: 6, name: "dimension", kind: "scalar", T: 13 /* ScalarType.UINT32 */ }, { no: 7, name: "db_info", kind: "message", T: StoreInfo, opt: true }, + { no: 8, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): AIStoreInfo { diff --git a/sdk/ahnlich-client-node/grpc/db/pipeline_pb.ts b/sdk/ahnlich-client-node/grpc/db/pipeline_pb.ts index 77685eee3..75588b49f 100644 --- a/sdk/ahnlich-client-node/grpc/db/pipeline_pb.ts +++ b/sdk/ahnlich-client-node/grpc/db/pipeline_pb.ts @@ -20,6 +20,7 @@ import { DelPred, DropNonLinearAlgorithmIndex, DropPredIndex, + DropSchema, DropStore, GetKey, GetPred, @@ -181,6 +182,13 @@ export class DBQuery extends Message { value: ClusterInfoQuery; case: "clusterInfo"; } + | { + /** + * @generated from field: db.query.DropSchema drop_schema = 19; + */ + value: DropSchema; + case: "dropSchema"; + } | { case: undefined; value?: undefined } = { case: undefined }; constructor(data?: PartialMessage) { @@ -221,6 +229,7 @@ export class DBQuery extends Message { { no: 16, name: "ping", kind: "message", T: Ping, oneof: "query" }, { no: 17, name: "get_store", kind: "message", T: GetStore, oneof: "query" }, { no: 18, name: "cluster_info", kind: "message", T: ClusterInfoQuery, oneof: "query" }, + { no: 19, name: "drop_schema", kind: "message", T: DropSchema, oneof: "query" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): DBQuery { diff --git a/sdk/ahnlich-client-node/grpc/db/query_pb.ts b/sdk/ahnlich-client-node/grpc/db/query_pb.ts index e996b0eba..00a82d351 100644 --- a/sdk/ahnlich-client-node/grpc/db/query_pb.ts +++ b/sdk/ahnlich-client-node/grpc/db/query_pb.ts @@ -59,6 +59,13 @@ export class CreateStore extends Message { */ errorIfExists = false; + /** + * Optional schema/namespace for the store. Defaults to "public". + * + * @generated from field: optional string schema = 6; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -78,6 +85,7 @@ export class CreateStore extends Message { }, { no: 4, name: "non_linear_indices", kind: "message", T: NonLinearIndex, repeated: true }, { no: 5, name: "error_if_exists", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 6, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): CreateStore { @@ -661,6 +669,13 @@ export class DropStore extends Message { */ errorIfNotExists = false; + /** + * Optional schema/namespace for the store. Defaults to "public". + * + * @generated from field: optional string schema = 3; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -671,6 +686,7 @@ export class DropStore extends Message { static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "store", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 2, name: "error_if_not_exists", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 3, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): DropStore { @@ -734,6 +750,13 @@ export class InfoServer extends Message { * @generated from message db.query.ListStores */ export class ListStores extends Message { + /** + * Optional schema/namespace to filter stores. If unset, lists all schemas. + * + * @generated from field: optional string schema = 1; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -741,7 +764,9 @@ export class ListStores extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "db.query.ListStores"; - static readonly fields: FieldList = proto3.util.newFieldList(() => []); + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + ]); static fromBinary(bytes: Uint8Array, options?: Partial): ListStores { return new ListStores().fromBinary(bytes, options); @@ -846,6 +871,13 @@ export class GetStore extends Message { */ store = ""; + /** + * Optional schema/namespace for the store. Defaults to "public". + * + * @generated from field: optional string schema = 2; + */ + schema?: string; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -855,6 +887,7 @@ export class GetStore extends Message { static readonly typeName = "db.query.GetStore"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "store", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetStore { @@ -877,6 +910,51 @@ export class GetStore extends Message { } } +/** + * Drops an entire schema and all stores within it. + * Cannot drop the "public" default schema. + * + * @generated from message db.query.DropSchema + */ +export class DropSchema extends Message { + /** + * The name of the schema to drop. + * + * @generated from field: string schema = 1; + */ + schema = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "db.query.DropSchema"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "schema", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): DropSchema { + return new DropSchema().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): DropSchema { + return new DropSchema().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): DropSchema { + return new DropSchema().fromJsonString(jsonString, options); + } + + static equals( + a: DropSchema | PlainMessage | undefined, + b: DropSchema | PlainMessage | undefined, + ): boolean { + return proto3.util.equals(DropSchema, a, b); + } +} + /** * A request to set multiple key-value entries in the store. * Validation is done for each vector before updating the store. diff --git a/sdk/ahnlich-client-node/grpc/services/ai_service_connect.ts b/sdk/ahnlich-client-node/grpc/services/ai_service_connect.ts index 2910499ee..d8369120a 100644 --- a/sdk/ahnlich-client-node/grpc/services/ai_service_connect.ts +++ b/sdk/ahnlich-client-node/grpc/services/ai_service_connect.ts @@ -12,6 +12,7 @@ import { DelPred, DropNonLinearAlgorithmIndex, DropPredIndex, + DropSchema, DropStore, GetKey, GetPred, @@ -172,6 +173,15 @@ export const AIService = { O: Del, kind: MethodKind.Unary, }, + /** + * @generated from rpc services.ai_service.AIService.DropSchema + */ + dropSchema: { + name: "DropSchema", + I: DropSchema, + O: Del, + kind: MethodKind.Unary, + }, /** * * Ancillary info methods * * diff --git a/sdk/ahnlich-client-node/grpc/services/db_service_connect.ts b/sdk/ahnlich-client-node/grpc/services/db_service_connect.ts index 358a86e0b..1cb8b3eb5 100644 --- a/sdk/ahnlich-client-node/grpc/services/db_service_connect.ts +++ b/sdk/ahnlich-client-node/grpc/services/db_service_connect.ts @@ -11,6 +11,7 @@ import { DelPred, DropNonLinearAlgorithmIndex, DropPredIndex, + DropSchema, DropStore, GetKey, GetPred, @@ -170,6 +171,15 @@ export const DBService = { O: Del, kind: MethodKind.Unary, }, + /** + * @generated from rpc services.db_service.DBService.DropSchema + */ + dropSchema: { + name: "DropSchema", + I: DropSchema, + O: Del, + kind: MethodKind.Unary, + }, /** * * Ancillary info methods * * diff --git a/sdk/ahnlich-client-node/package-lock.json b/sdk/ahnlich-client-node/package-lock.json index 539dc3bc9..e1522b19f 100644 --- a/sdk/ahnlich-client-node/package-lock.json +++ b/sdk/ahnlich-client-node/package-lock.json @@ -1,12 +1,12 @@ { "name": "@deven96/ahnlich-client-node", - "version": "0.0.1", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@deven96/ahnlich-client-node", - "version": "0.0.1", + "version": "0.3.0", "dependencies": { "@connectrpc/connect": "^1.7.0", "@connectrpc/connect-node": "^1.7.0" diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/pipeline/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/pipeline/__init__.py index 0e7bdce31..ad4fa8c37 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/pipeline/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/pipeline/__init__.py @@ -44,6 +44,7 @@ class AiQuery(betterproto.Message): ) del_pred: "_query__.DelPred" = betterproto.message_field(18, group="query") get_store: "_query__.GetStore" = betterproto.message_field(19, group="query") + drop_schema: "_query__.DropSchema" = betterproto.message_field(20, group="query") @dataclass(eq=False, repr=False) diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/query/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/query/__init__.py index 588c93f9a..5de7cd195 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/query/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/query/__init__.py @@ -37,6 +37,7 @@ class CreateStore(betterproto.Message): ) error_if_exists: bool = betterproto.bool_field(6) store_original: bool = betterproto.bool_field(7) + schema: Optional[str] = betterproto.string_field(8, optional=True) @dataclass(eq=False, repr=False) @@ -152,6 +153,7 @@ class DropStore(betterproto.Message): """ error_if_not_exists: bool = betterproto.bool_field(2) + schema: Optional[str] = betterproto.string_field(3, optional=True) @dataclass(eq=False, repr=False) @@ -176,7 +178,10 @@ class ListClients(betterproto.Message): @dataclass(eq=False, repr=False) class ListStores(betterproto.Message): - pass + schema: Optional[str] = betterproto.string_field(1, optional=True) + """ + Lists all stores on the server along with details like store size, embedding dimensions, AI models, etc. + """ @dataclass(eq=False, repr=False) @@ -186,6 +191,16 @@ class GetStore(betterproto.Message): Gets detailed information about a specific store by name. Returns an error if the store does not exist. """ + schema: Optional[str] = betterproto.string_field(2, optional=True) + + +@dataclass(eq=False, repr=False) +class DropSchema(betterproto.Message): + schema: str = betterproto.string_field(1) + """ + Drops an entire schema and all stores within it. Cannot drop the "public" default schema. + """ + @dataclass(eq=False, repr=False) class PurgeStores(betterproto.Message): diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/server/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/server/__init__.py index 3a127c314..7e0eb8961 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/server/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/ai/server/__init__.py @@ -90,6 +90,7 @@ class AiStoreInfo(betterproto.Message): db_info: Optional["__db_server__.StoreInfo"] = betterproto.message_field( 7, optional=True ) + schema: Optional[str] = betterproto.string_field(8, optional=True) @dataclass(eq=False, repr=False) diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/pipeline/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/pipeline/__init__.py index 51a8d190d..63392e964 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/pipeline/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/pipeline/__init__.py @@ -44,6 +44,7 @@ class DbQuery(betterproto.Message): cluster_info: "__shared_cluster__.ClusterInfoQuery" = betterproto.message_field( 18, group="query" ) + drop_schema: "_query__.DropSchema" = betterproto.message_field(19, group="query") @dataclass(eq=False, repr=False) diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/query/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/query/__init__.py index 4ac775b4e..9ded6c902 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/query/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/db/query/__init__.py @@ -4,7 +4,7 @@ # This file has been @generated from dataclasses import dataclass -from typing import List +from typing import List, Optional import betterproto @@ -28,6 +28,7 @@ class CreateStore(betterproto.Message): betterproto.message_field(4) ) error_if_exists: bool = betterproto.bool_field(5) + schema: Optional[str] = betterproto.string_field(6, optional=True) @dataclass(eq=False, repr=False) @@ -144,6 +145,7 @@ class DropStore(betterproto.Message): store: str = betterproto.string_field(1) error_if_not_exists: bool = betterproto.bool_field(2) + schema: Optional[str] = betterproto.string_field(3, optional=True) @dataclass(eq=False, repr=False) @@ -159,7 +161,7 @@ class ListStores(betterproto.Message): A request to list all the stores on the server, along with their size or length. """ - pass + schema: Optional[str] = betterproto.string_field(1, optional=True) @dataclass(eq=False, repr=False) @@ -183,6 +185,17 @@ class GetStore(betterproto.Message): """ store: str = betterproto.string_field(1) + schema: Optional[str] = betterproto.string_field(2, optional=True) + + +@dataclass(eq=False, repr=False) +class DropSchema(betterproto.Message): + """ + Drops an entire schema and all stores within it. + Cannot drop the "public" default schema. + """ + + schema: str = betterproto.string_field(1) @dataclass(eq=False, repr=False) diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/ai_service/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/ai_service/__init__.py index b47828b65..14b9bc124 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/ai_service/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/ai_service/__init__.py @@ -242,6 +242,23 @@ async def drop_store( metadata=metadata, ) + async def drop_schema( + self, + ai_query_drop_schema: "__ai_query__.DropSchema", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "__ai_server__.Del": + return await self._unary_unary( + "/services.ai_service.AIService/DropSchema", + ai_query_drop_schema, + __ai_server__.Del, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + async def list_clients( self, ai_query_list_clients: "__ai_query__.ListClients", @@ -429,6 +446,11 @@ async def drop_store( ) -> "__ai_server__.Del": raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + async def drop_schema( + self, ai_query_drop_schema: "__ai_query__.DropSchema" + ) -> "__ai_server__.Del": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + async def list_clients( self, ai_query_list_clients: "__ai_query__.ListClients" ) -> "__ai_server__.ClientList": @@ -561,6 +583,14 @@ async def __rpc_drop_store( response = await self.drop_store(request) await stream.send_message(response) + async def __rpc_drop_schema( + self, + stream: "grpclib.server.Stream[__ai_query__.DropSchema, __ai_server__.Del]", + ) -> None: + request = await stream.recv_message() + response = await self.drop_schema(request) + await stream.send_message(response) + async def __rpc_list_clients( self, stream: "grpclib.server.Stream[__ai_query__.ListClients, __ai_server__.ClientList]", @@ -696,6 +726,12 @@ def __mapping__(self) -> Dict[str, grpclib.const.Handler]: __ai_query__.DropStore, __ai_server__.Del, ), + "/services.ai_service.AIService/DropSchema": grpclib.const.Handler( + self.__rpc_drop_schema, + grpclib.const.Cardinality.UNARY_UNARY, + __ai_query__.DropSchema, + __ai_server__.Del, + ), "/services.ai_service.AIService/ListClients": grpclib.const.Handler( self.__rpc_list_clients, grpclib.const.Cardinality.UNARY_UNARY, diff --git a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/db_service/__init__.py b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/db_service/__init__.py index cc8a071fc..d788d34dc 100644 --- a/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/db_service/__init__.py +++ b/sdk/ahnlich-client-py/ahnlich_client_py/grpc/services/db_service/__init__.py @@ -243,6 +243,23 @@ async def drop_store( metadata=metadata, ) + async def drop_schema( + self, + db_query_drop_schema: "__db_query__.DropSchema", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "__db_server__.Del": + return await self._unary_unary( + "/services.db_service.DBService/DropSchema", + db_query_drop_schema, + __db_server__.Del, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + async def list_clients( self, db_query_list_clients: "__db_query__.ListClients", @@ -413,6 +430,11 @@ async def drop_store( ) -> "__db_server__.Del": raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + async def drop_schema( + self, db_query_drop_schema: "__db_query__.DropSchema" + ) -> "__db_server__.Del": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + async def list_clients( self, db_query_list_clients: "__db_query__.ListClients" ) -> "__db_server__.ClientList": @@ -539,6 +561,14 @@ async def __rpc_drop_store( response = await self.drop_store(request) await stream.send_message(response) + async def __rpc_drop_schema( + self, + stream: "grpclib.server.Stream[__db_query__.DropSchema, __db_server__.Del]", + ) -> None: + request = await stream.recv_message() + response = await self.drop_schema(request) + await stream.send_message(response) + async def __rpc_list_clients( self, stream: "grpclib.server.Stream[__db_query__.ListClients, __db_server__.ClientList]", @@ -666,6 +696,12 @@ def __mapping__(self) -> Dict[str, grpclib.const.Handler]: __db_query__.DropStore, __db_server__.Del, ), + "/services.db_service.DBService/DropSchema": grpclib.const.Handler( + self.__rpc_drop_schema, + grpclib.const.Cardinality.UNARY_UNARY, + __db_query__.DropSchema, + __db_server__.Del, + ), "/services.db_service.DBService/ListClients": grpclib.const.Handler( self.__rpc_list_clients, grpclib.const.Cardinality.UNARY_UNARY, diff --git a/web/ahnlich-web/docusaurus.config.ts b/web/ahnlich-web/docusaurus.config.ts index d1a765ed7..d87fc112a 100644 --- a/web/ahnlich-web/docusaurus.config.ts +++ b/web/ahnlich-web/docusaurus.config.ts @@ -95,10 +95,14 @@ const config: Config = { theme: { customCss: './src/css/custom.css', }, - gtag: { - trackingID: process.env.G_TRACKING_ID, - anonymizeIP: true, - }, + ...(process.env.G_TRACKING_ID + ? { + gtag: { + trackingID: process.env.G_TRACKING_ID, + anonymizeIP: true, + }, + } + : {}), } satisfies Preset.Options, ], ],