Limbo extension API
The limbo_ext crate simplifies the creation and registration of libraries meant to extend the functionality of Limbo, that can be loaded
like traditional sqlite3 extensions, but are able to be written in much more ergonomic Rust.
Currently supported features
- [ x ] Scalar Functions: Create scalar functions using the
scalarmacro. - [ x ] Aggregate Functions: Define aggregate functions with
AggregateDerivemacro andAggFunctrait. - [ x ] Virtual tables: Create a module for a virtual table with the
VTabModuleDerivemacro andVTabCursortrait. - [] VFS Modules
Installation
On the root of the workspace run:
Add the crate to your extensions/your_crate_name/Cargo.toml:
[]
= ["limbo_ext/static"]
[]
= { = "path/to/limbo/extensions/core", = ["static"] } # temporary until crate is published
# mimalloc is required if you intend on linking dynamically. It is imported for you by the register_extension
# macro, so no configuration is needed. But it must be added to your Cargo.toml
[]
= { = "0.1", = false }
# NOTE: Crate must be of type `cdylib` if you wish to link dynamically
[]
= ["cdylib", "lib"]
cargo build will output a shared library that can be loaded by the following options:
CLI:
`.load target/debug/libyour_crate_name`
SQL:
SELECT load_extension('target/debug/libyour_crate_name')
Extensions can be registered with the register_extension! macro:
register_extension!
Scalar Example:
use ;
/// Annotate each with the scalar macro, specifying the name you would like to call it with
/// and optionally, an alias.. e.g. SELECT double(4); or SELECT twice(4);
Aggregates Example:
use ;
/// annotate your struct with the AggregateDerive macro, and it must implement the below AggFunc trait
;
Virtual Table Example:
/// Example: A virtual table that operates on a CSV file as a database table.
/// This example assumes that the CSV file is located at "data.csv" in the current directory.
;
/// The cursor for iterating over CSV rows.
/// Implement the VTabCursor trait for your cursor type
Cargo.toml Config
Edit the workspace Cargo.toml to include your extension as a workspace dependency, e.g:
[workspace.dependencies]
limbo_core = { path = "core", version = "0.0.16" }
limbo_crypto = { path = "extensions/crypto", version = "0.0.16" }
limbo_ext = { path = "extensions/core", version = "0.0.16" }
limbo_macros = { path = "macros", version = "0.0.16" }
limbo_uuid = { path = "extensions/uuid", version = "0.0.16" }
...
+limbo_csv = { path = "extensions/csv", version = "0.0.16" }
And add your extension as a feature in core/Cargo.toml:
[features]
default = ["fs", "json", "uuid", "time"]
fs = []
json = ["dep:jsonb", "dep:pest", "dep:pest_derive", "dep:serde", "dep:indexmap"]
uuid = ["limbo_uuid/static"]
...
+csv = ["limbo_csv/static"]
Register Extension in Core
Lastly, you have to register your extension statically in the core crate:
pub fn register_builtins(&self) -> Result<(), String> {
#[allow(unused_variables)]
let ext_api = self.build_limbo_ext();
#[cfg(feature = "uuid")]
if unsafe { !limbo_uuid::register_extension_static(&ext_api).is_ok() } {
return Err("Failed to register uuid extension".to_string());
}
+ #[cfg(feature = "csv")]
+ if unsafe { !limbo_csv::register_extension_static(&ext_api).is_ok() } {
+ return Err("Failed to register csv extension".to_string());
+ }
Ok(())
}