fix(structure): load dynamic data type options
This commit is contained in:
1 parent
5ffac129e0
commit
cdfe576024
24 files changed
+380
-3
No files matched your search
@@ -120,6 +120,7 @@ pub enum AgentMethod {
|
||||
ListSchemas,
|
||||
ListTables,
|
||||
ListObjects,
|
||||
ListDataTypes,
|
||||
CompletionAssistantSearchV1,
|
||||
GetObjectSource,
|
||||
GetColumns,
|
||||
@@ -141,7 +142,7 @@ pub enum AgentMethod {
|
||||
}
|
||||
|
||||
impl AgentMethod {
|
||||
pub const ALL: [Self; 26] = [
|
||||
pub const ALL: [Self; 27] = [
|
||||
Self::Handshake,
|
||||
Self::Connect,
|
||||
Self::TestConnection,
|
||||
@@ -150,6 +151,7 @@ impl AgentMethod {
|
||||
Self::ListSchemas,
|
||||
Self::ListTables,
|
||||
Self::ListObjects,
|
||||
Self::ListDataTypes,
|
||||
Self::CompletionAssistantSearchV1,
|
||||
Self::GetObjectSource,
|
||||
Self::GetTableDdl,
|
||||
@@ -180,6 +182,7 @@ impl AgentMethod {
|
||||
Self::ListSchemas => "list_schemas",
|
||||
Self::ListTables => "list_tables",
|
||||
Self::ListObjects => "list_objects",
|
||||
Self::ListDataTypes => "list_data_types",
|
||||
Self::CompletionAssistantSearchV1 => "completion_assistant_search_v1",
|
||||
Self::GetObjectSource => "get_object_source",
|
||||
Self::GetTableDdl => "get_table_ddl",
|
||||
@@ -616,6 +619,19 @@ impl AgentDriverClient {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_data_types<T: DeserializeOwned + Send + 'static>(
|
||||
&mut self,
|
||||
database: &str,
|
||||
timeout_duration: Option<Duration>,
|
||||
) -> Result<T, String> {
|
||||
self.call_method_with_timeout(
|
||||
AgentMethod::ListDataTypes,
|
||||
serde_json::json!({ "database": database }),
|
||||
timeout_duration,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn completion_assistant_search<T: DeserializeOwned + Send + 'static>(
|
||||
&mut self,
|
||||
request: &crate::types::CompletionAssistantRequest,
|
||||
@@ -1338,6 +1354,7 @@ mod tests {
|
||||
assert_eq!(AgentMethod::ListSchemas.as_str(), "list_schemas");
|
||||
assert_eq!(AgentMethod::ListTables.as_str(), "list_tables");
|
||||
assert_eq!(AgentMethod::ListObjects.as_str(), "list_objects");
|
||||
assert_eq!(AgentMethod::ListDataTypes.as_str(), "list_data_types");
|
||||
assert_eq!(AgentMethod::CompletionAssistantSearchV1.as_str(), "completion_assistant_search_v1");
|
||||
assert_eq!(AgentMethod::GetObjectSource.as_str(), "get_object_source");
|
||||
assert_eq!(AgentMethod::GetColumns.as_str(), "get_columns");
|
||||
|
||||
@@ -627,6 +627,56 @@ async fn list_schema_infos_once(
|
||||
Ok(schemas.into_iter().map(|name| db::SchemaInfo { name, comment: None }).collect())
|
||||
}
|
||||
|
||||
pub async fn list_data_types_core(
|
||||
state: &AppState,
|
||||
connection_id: &str,
|
||||
database: &str,
|
||||
) -> Result<Vec<String>, String> {
|
||||
retry_metadata_connection(state, connection_id, Some(database), || async {
|
||||
let pool_key = state.get_or_create_pool(connection_id, Some(database)).await?;
|
||||
let db_config = connection_config(state, connection_id).await;
|
||||
let connections = state.connections.read().await;
|
||||
if let Some(PoolKind::ExternalDriver { config, session, .. }) = connections.get(&pool_key) {
|
||||
let config = config.clone();
|
||||
let session = session.clone();
|
||||
drop(connections);
|
||||
return session
|
||||
.invoke::<Vec<String>>(
|
||||
"listDataTypes",
|
||||
serde_json::json!({ "connection": config.as_ref(), "database": database }),
|
||||
)
|
||||
.await
|
||||
.map(deduplicate_data_type_names);
|
||||
}
|
||||
if let Some(client) = extract_pool!(&connections, &pool_key, Agent) {
|
||||
drop(connections);
|
||||
let mut client = client.lock().await;
|
||||
return client
|
||||
.list_data_types::<Vec<String>>(database, agent_metadata_timeout(db_config.as_ref()))
|
||||
.await
|
||||
.map(deduplicate_data_type_names);
|
||||
}
|
||||
Ok(Vec::new())
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
fn deduplicate_data_type_names(names: Vec<String>) -> Vec<String> {
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
let mut result = Vec::new();
|
||||
for name in names {
|
||||
let trimmed = name.trim();
|
||||
if trimmed.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let key = trimmed.to_ascii_lowercase();
|
||||
if seen.insert(key) {
|
||||
result.push(trimmed.to_string());
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
async fn list_schemas_once(
|
||||
state: &AppState,
|
||||
connection_id: &str,
|
||||
|
||||
Reference in new issue
Block a user