mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 18:18:03 +00:00
Rough design for extension api/draft extension
This commit is contained in:
parent
0a10d893d9
commit
3412a3d4c2
18 changed files with 489 additions and 348 deletions
|
@ -1,68 +1,41 @@
|
|||
#[cfg(feature = "uuid")]
|
||||
mod uuid;
|
||||
use crate::{function::ExternalFunc, Database};
|
||||
use std::sync::Arc;
|
||||
use limbo_extension::{ExtensionApi, ResultCode, ScalarFunction, RESULT_ERROR, RESULT_OK};
|
||||
pub use limbo_extension::{Value as ExtValue, ValueType as ExtValueType};
|
||||
use std::{
|
||||
ffi::{c_char, c_void, CStr},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use extension_api::{AggregateFunction, ExtensionApi, Result, ScalarFunction, VirtualTable};
|
||||
#[cfg(feature = "uuid")]
|
||||
pub use uuid::{exec_ts_from_uuid7, exec_uuid, exec_uuidblob, exec_uuidstr, UuidFunc};
|
||||
|
||||
impl ExtensionApi for Database {
|
||||
fn register_scalar_function(
|
||||
&self,
|
||||
name: &str,
|
||||
func: Arc<dyn ScalarFunction>,
|
||||
) -> extension_api::Result<()> {
|
||||
let ext_func = ExternalFunc::new(name, func.clone());
|
||||
self.syms
|
||||
.borrow_mut()
|
||||
.functions
|
||||
.insert(name.to_string(), Arc::new(ext_func));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register_aggregate_function(
|
||||
&self,
|
||||
_name: &str,
|
||||
_func: Arc<dyn AggregateFunction>,
|
||||
) -> Result<()> {
|
||||
todo!("implement aggregate function registration");
|
||||
}
|
||||
|
||||
fn register_virtual_table(&self, _name: &str, _table: Arc<dyn VirtualTable>) -> Result<()> {
|
||||
todo!("implement virtual table registration");
|
||||
}
|
||||
extern "C" fn register_scalar_function(
|
||||
ctx: *mut c_void,
|
||||
name: *const c_char,
|
||||
func: ScalarFunction,
|
||||
) -> ResultCode {
|
||||
let c_str = unsafe { CStr::from_ptr(name) };
|
||||
let name_str = match c_str.to_str() {
|
||||
Ok(s) => s.to_string(),
|
||||
Err(_) => return RESULT_ERROR,
|
||||
};
|
||||
let db = unsafe { &*(ctx as *const Database) };
|
||||
db.register_scalar_function_impl(name_str, func)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum ExtFunc {
|
||||
#[cfg(feature = "uuid")]
|
||||
Uuid(UuidFunc),
|
||||
}
|
||||
impl Database {
|
||||
fn register_scalar_function_impl(&self, name: String, func: ScalarFunction) -> ResultCode {
|
||||
self.syms.borrow_mut().functions.insert(
|
||||
name.to_string(),
|
||||
Rc::new(ExternalFunc {
|
||||
name: name.to_string(),
|
||||
func,
|
||||
}),
|
||||
);
|
||||
RESULT_OK
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)] // TODO: remove when more extension funcs added
|
||||
impl std::fmt::Display for ExtFunc {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
#[cfg(feature = "uuid")]
|
||||
Self::Uuid(uuidfn) => write!(f, "{}", uuidfn),
|
||||
_ => write!(f, "unknown"),
|
||||
pub fn build_limbo_extension(&self) -> ExtensionApi {
|
||||
ExtensionApi {
|
||||
ctx: self as *const _ as *mut c_void,
|
||||
register_scalar_function,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
impl ExtFunc {
|
||||
pub fn resolve_function(name: &str, num_args: usize) -> Option<ExtFunc> {
|
||||
match name {
|
||||
#[cfg(feature = "uuid")]
|
||||
name => UuidFunc::resolve_function(name, num_args),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn init(db: &mut crate::Database) {
|
||||
// #[cfg(feature = "uuid")]
|
||||
// uuid::init(db);
|
||||
//}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue