use super::Session;
use crate::api_core::{CoreError, CoreResult};
use linkrs_query::executor::expression::functions::registry::DynamicUdfInfo;
use linkrs_query::executor::expression::functions::{CustomFunction, FunctionRegistry};
use linkrs_query::parser::ast::stmt::ExtensionAction;
use linkrs_query::parser::ast::stmt::ExtensionStmt;
use linkrs_storage::StorageClient;
use std::path::Path;
impl<S: StorageClient + Clone + Send + Sync + 'static + linkrs_storage::UndoTarget> Session<S> {
pub fn register_custom_function(&self, function: CustomFunction) -> CoreResult<()> {
let mut registry = self.function_registry.write();
registry.register_custom_full(function);
Ok(())
}
pub fn load_extension(&self, path: &Path) -> CoreResult<String> {
let mut registry = self.function_registry.write();
registry
.load_dynamic_udf(path)
.map_err(|e| CoreError::InvalidParameter(e.to_string()))
}
pub fn unload_extension(&self, name: &str) -> CoreResult<()> {
let mut registry = self.function_registry.write();
registry
.unload_dynamic_udf(name)
.map_err(|e| CoreError::InvalidParameter(e.to_string()))
}
pub fn reload_extension(&self, name: &str) -> CoreResult<bool> {
let mut registry = self.function_registry.write();
registry
.reload_dynamic_udf(name)
.map_err(|e| CoreError::InvalidParameter(e.to_string()))
}
pub fn install_extension(&self, source: &str) -> CoreResult<String> {
let mut registry = self.function_registry.write();
registry
.install_dynamic_udf(source)
.map_err(|e| CoreError::InvalidParameter(e.to_string()))
}
pub fn list_extensions(&self) -> Vec<DynamicUdfInfo> {
self.function_registry.read().list_dynamic_udfs()
}
pub(crate) fn execute_extension(
&self,
extension: &ExtensionStmt,
) -> CoreResult<crate::embedded::result::QueryResult> {
let message = match extension.action {
ExtensionAction::Load => {
let name = self.load_extension(Path::new(&extension.name))?;
format!("Loaded extension '{name}' from '{}'", extension.name)
}
ExtensionAction::Uninstall => {
self.unload_extension(&extension.name)?;
format!("Uninstalled extension '{}'", extension.name)
}
ExtensionAction::Install => {
let source = extension.source.clone().unwrap_or_default();
let name = self.install_extension(&source)?;
format!("Installed extension '{name}' from '{source}'")
}
ExtensionAction::Update => {
let reloaded = self.reload_extension(&extension.name)?;
if reloaded {
format!("Updated extension '{}'", extension.name)
} else {
format!("Extension '{}' is already up to date", extension.name)
}
}
};
Ok(Self::single_message_result(message))
}
}