diff --git a/src/database.rs b/src/database.rs index ee24c2a..859c251 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,7 +1,8 @@ use crate::check; use crate::database::DatabaseOwnership::{Borrowed, Owned}; use crate::duckly::{ - duckdb_close, duckdb_connect, duckdb_connection, duckdb_database, duckdb_open, + duckdb_add_replacement_scan, duckdb_close, duckdb_connect, duckdb_connection, duckdb_database, + duckdb_delete_callback_t, duckdb_open, duckdb_replacement_callback_t, }; use crate::Connection; use std::error::Error; @@ -42,10 +43,7 @@ impl Database { pub fn connect(&self) -> Result> { let mut connection: duckdb_connection = null_mut(); - let db = match &self.0 { - Borrowed(wrapper) => addr_of!(wrapper) as duckdb_database, - Owned(ptr) => *ptr, - }; + let db = self.get_ptr(); unsafe { check!(duckdb_connect(db, &mut connection)); @@ -53,6 +51,31 @@ impl Database { Ok(Connection::from(connection)) } + + fn get_ptr(&self) -> duckdb_database { + match &self.0 { + Borrowed(wrapper) => addr_of!(wrapper) as duckdb_database, + Owned(ptr) => *ptr, + } + } + + /// Add a replacement scan definition to the specified database + /// + /// # Safety + /// The `extra_data` arg should live as long as the database + /// + /// # Arguments + /// * `replacement`: The replacement scan callback + /// * `extra_data`: Extra data that is passed back into the specified callback + /// * `delete_callback`: The delete callback to call on the extra data, if any + pub unsafe fn add_replacement_scan( + &self, + replacement: duckdb_replacement_callback_t, + extra_data: *mut c_void, + delete_callback: duckdb_delete_callback_t, + ) { + duckdb_add_replacement_scan(self.get_ptr(), replacement, extra_data, delete_callback); + } } impl Drop for Database { diff --git a/src/lib.rs b/src/lib.rs index 92251c0..ff3d087 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ mod error; mod function_info; mod init_info; mod logical_type; +mod replacement_scan; mod table_function; #[cfg(test)] mod test_integration; @@ -33,6 +34,7 @@ pub use crate::database::Database; pub use crate::function_info::FunctionInfo; pub use crate::init_info::InitInfo; pub use crate::logical_type::LogicalType; +pub use crate::replacement_scan::ReplacementScanInfo; pub use crate::table_function::TableFunction; pub use crate::value::Value; pub use crate::vector::Vector; diff --git a/src/replacement_scan.rs b/src/replacement_scan.rs new file mode 100644 index 0000000..a5b52fc --- /dev/null +++ b/src/replacement_scan.rs @@ -0,0 +1,32 @@ +use crate::{ + duckly::{ + duckdb_replacement_scan_add_parameter, duckdb_replacement_scan_info, + duckdb_replacement_scan_set_error, duckdb_replacement_scan_set_function_name, + }, + Value, +}; +use std::ffi::CString; +pub struct ReplacementScanInfo(pub(crate) duckdb_replacement_scan_info); + +impl ReplacementScanInfo { + /// Sets the replacement function name to use. If this function is called in the replacement callback, the replacement scan is performed. If it is not called, the replacement callback is not performed. + pub fn set_function_name(&mut self, function_name: &str) { + unsafe { + let function_name = CString::new(function_name).unwrap(); + duckdb_replacement_scan_set_function_name(self.0, function_name.as_ptr()); + } + } + /// Adds a parameter to the replacement scan function. + pub fn add_parameter(&mut self, parameter: Value) { + unsafe { + duckdb_replacement_scan_add_parameter(self.0, parameter.0); + } + } + /// Report that an error has occurred while executing the replacement scan. + pub fn set_error(&mut self, error: &str) { + unsafe { + let error = CString::new(error).unwrap(); + duckdb_replacement_scan_set_error(self.0, error.as_ptr()); + } + } +} diff --git a/src/value.rs b/src/value.rs index a2c04ac..5f55b58 100644 --- a/src/value.rs +++ b/src/value.rs @@ -4,7 +4,7 @@ use std::ffi::CString; /// The Value object holds a single arbitrary value of any type that can be /// stored in the database. #[derive(Debug)] -pub struct Value(duckdb_value); +pub struct Value(pub(crate) duckdb_value); impl Value { /// Obtains a string representation of the given value