mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-30 14:34:22 +01:00
124 lines
3.5 KiB
Rust
124 lines
3.5 KiB
Rust
mod types;
|
|
pub use limbo_macros::{register_extension, scalar, AggregateDerive, VTabModuleDerive};
|
|
use std::os::raw::{c_char, c_void};
|
|
pub use types::{ResultCode, Value, ValueType};
|
|
|
|
#[repr(C)]
|
|
pub struct ExtensionApi {
|
|
pub ctx: *mut c_void,
|
|
|
|
pub register_scalar_function: unsafe extern "C" fn(
|
|
ctx: *mut c_void,
|
|
name: *const c_char,
|
|
func: ScalarFunction,
|
|
) -> ResultCode,
|
|
|
|
pub register_aggregate_function: unsafe extern "C" fn(
|
|
ctx: *mut c_void,
|
|
name: *const c_char,
|
|
args: i32,
|
|
init_func: InitAggFunction,
|
|
step_func: StepFunction,
|
|
finalize_func: FinalizeFunction,
|
|
) -> ResultCode,
|
|
|
|
pub register_module: unsafe extern "C" fn(
|
|
ctx: *mut c_void,
|
|
name: *const c_char,
|
|
module: VTabModuleImpl,
|
|
) -> ResultCode,
|
|
|
|
pub declare_vtab: unsafe extern "C" fn(
|
|
ctx: *mut c_void,
|
|
name: *const c_char,
|
|
sql: *const c_char,
|
|
) -> ResultCode,
|
|
}
|
|
|
|
impl ExtensionApi {
|
|
pub fn declare_virtual_table(&self, name: &str, sql: &str) -> ResultCode {
|
|
let Ok(name) = std::ffi::CString::new(name) else {
|
|
return ResultCode::Error;
|
|
};
|
|
let Ok(sql) = std::ffi::CString::new(sql) else {
|
|
return ResultCode::Error;
|
|
};
|
|
unsafe { (self.declare_vtab)(self.ctx, name.as_ptr(), sql.as_ptr()) }
|
|
}
|
|
}
|
|
|
|
pub type ExtensionEntryPoint = unsafe extern "C" fn(api: *const ExtensionApi) -> ResultCode;
|
|
pub type ScalarFunction = unsafe extern "C" fn(argc: i32, *const Value) -> Value;
|
|
|
|
pub type InitAggFunction = unsafe extern "C" fn() -> *mut AggCtx;
|
|
pub type StepFunction = unsafe extern "C" fn(ctx: *mut AggCtx, argc: i32, argv: *const Value);
|
|
pub type FinalizeFunction = unsafe extern "C" fn(ctx: *mut AggCtx) -> Value;
|
|
|
|
pub trait Scalar {
|
|
fn call(&self, args: &[Value]) -> Value;
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct AggCtx {
|
|
pub state: *mut c_void,
|
|
}
|
|
|
|
pub trait AggFunc {
|
|
type State: Default;
|
|
const NAME: &'static str;
|
|
const ARGS: i32;
|
|
|
|
fn step(state: &mut Self::State, args: &[Value]);
|
|
fn finalize(state: Self::State) -> Value;
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Debug)]
|
|
pub struct VTabModuleImpl {
|
|
pub name: *const c_char,
|
|
pub connect: VtabFnConnect,
|
|
pub open: VtabFnOpen,
|
|
pub filter: VtabFnFilter,
|
|
pub column: VtabFnColumn,
|
|
pub next: VtabFnNext,
|
|
pub eof: VtabFnEof,
|
|
}
|
|
|
|
pub type VtabFnConnect = unsafe extern "C" fn(api: *const c_void) -> ResultCode;
|
|
|
|
pub type VtabFnOpen = unsafe extern "C" fn() -> *mut c_void;
|
|
|
|
pub type VtabFnFilter =
|
|
unsafe extern "C" fn(cursor: *mut c_void, argc: i32, argv: *const Value) -> ResultCode;
|
|
|
|
pub type VtabFnColumn = unsafe extern "C" fn(cursor: *mut c_void, idx: u32) -> Value;
|
|
|
|
pub type VtabFnNext = unsafe extern "C" fn(cursor: *mut c_void) -> ResultCode;
|
|
|
|
pub type VtabFnEof = unsafe extern "C" fn(cursor: *mut c_void) -> bool;
|
|
|
|
pub trait VTabModule: 'static {
|
|
type VCursor: VTabCursor;
|
|
const NAME: &'static str;
|
|
|
|
fn connect(api: &ExtensionApi) -> ResultCode;
|
|
fn open() -> Self::VCursor;
|
|
fn filter(cursor: &mut Self::VCursor, arg_count: i32, args: &[Value]) -> ResultCode;
|
|
fn column(cursor: &Self::VCursor, idx: u32) -> Value;
|
|
fn next(cursor: &mut Self::VCursor) -> ResultCode;
|
|
fn eof(cursor: &Self::VCursor) -> bool;
|
|
}
|
|
|
|
pub trait VTabCursor: Sized {
|
|
type Error: std::fmt::Display;
|
|
fn rowid(&self) -> i64;
|
|
fn column(&self, idx: u32) -> Value;
|
|
fn eof(&self) -> bool;
|
|
fn next(&mut self) -> ResultCode;
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct VTabImpl {
|
|
pub module: VTabModuleImpl,
|
|
}
|