diff --git a/bindings/c/include/libsql.h b/bindings/c/include/libsql.h index eec2d5b4d9..b14c7b5ad9 100644 --- a/bindings/c/include/libsql.h +++ b/bindings/c/include/libsql.h @@ -107,6 +107,10 @@ int libsql_load_extension(libsql_connection_t conn, const char *entry_point, const char **out_err_msg); +int libsql_set_reserved_bytes(libsql_connection_t conn, int32_t reserved_bytes, const char **out_err_msg); + +int libsql_get_reserved_bytes(libsql_connection_t conn, int32_t *reserved_bytes, const char **out_err_msg); + int libsql_reset(libsql_connection_t conn, const char **out_err_msg); void libsql_disconnect(libsql_connection_t conn); diff --git a/bindings/c/src/lib.rs b/bindings/c/src/lib.rs index cb369b1d22..ea02fcf966 100644 --- a/bindings/c/src/lib.rs +++ b/bindings/c/src/lib.rs @@ -549,6 +549,45 @@ pub unsafe extern "C" fn libsql_load_extension( 0 } +#[no_mangle] +pub unsafe extern "C" fn libsql_set_reserved_bytes( + conn: libsql_connection_t, + reserved_bytes: i32, + out_err_msg: *mut *const std::ffi::c_char, +) -> std::ffi::c_int { + if conn.is_null() { + set_err_msg("Null connection".to_string(), out_err_msg); + return 1; + } + let conn = conn.get_ref(); + if let Err(err) = conn.set_reserved_bytes(reserved_bytes) { + set_err_msg(err.to_string(), out_err_msg); + return 1; + } + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn libsql_get_reserved_bytes( + conn: libsql_connection_t, + reserved_bytes: *mut i32, + out_err_msg: *mut *const std::ffi::c_char, +) -> std::ffi::c_int { + if conn.is_null() { + set_err_msg("Null connection".to_string(), out_err_msg); + return 1; + } + let conn = conn.get_ref(); + match conn.get_reserved_bytes() { + Ok(v) => *reserved_bytes = v, + Err(err) => { + set_err_msg(err.to_string(), out_err_msg); + return 1; + } + } + 0 +} + #[no_mangle] pub unsafe extern "C" fn libsql_reset( conn: libsql_connection_t, diff --git a/libsql/src/connection.rs b/libsql/src/connection.rs index e9831411d6..2bca312500 100644 --- a/libsql/src/connection.rs +++ b/libsql/src/connection.rs @@ -39,6 +39,14 @@ pub(crate) trait Conn { async fn reset(&self); + fn set_reserved_bytes(&self, _reserved_bytes: i32) -> Result<()> { + Err(crate::Error::ReservedBytesNotSupported) + } + + fn get_reserved_bytes(&self) -> Result { + Err(crate::Error::ReservedBytesNotSupported) + } + fn enable_load_extension(&self, _onoff: bool) -> Result<()> { Err(crate::Error::LoadExtensionNotSupported) } @@ -230,6 +238,14 @@ impl Connection { self.conn.reset().await } + pub fn set_reserved_bytes(&self, reserved_bytes: i32) -> Result<()> { + self.conn.set_reserved_bytes(reserved_bytes) + } + + pub fn get_reserved_bytes(&self) -> Result { + self.conn.get_reserved_bytes() + } + /// Enable loading SQLite extensions from SQL queries and Rust API. /// /// See [`load_extension`](Connection::load_extension) documentation for more details. diff --git a/libsql/src/errors.rs b/libsql/src/errors.rs index ad230039c5..069e5fd5cd 100644 --- a/libsql/src/errors.rs +++ b/libsql/src/errors.rs @@ -61,6 +61,8 @@ pub enum Error { Sync(crate::BoxError), #[error("WAL frame insert conflict")] WalConflict, + #[error("Reserved bytes not supported")] + ReservedBytesNotSupported, } #[cfg(feature = "hrana")] diff --git a/libsql/src/local/impls.rs b/libsql/src/local/impls.rs index 0445e8c94b..26b8cd0575 100644 --- a/libsql/src/local/impls.rs +++ b/libsql/src/local/impls.rs @@ -81,6 +81,14 @@ impl Conn for LibsqlConnection { async fn reset(&self) {} + fn set_reserved_bytes(&self, reserved_bytes: i32) -> Result<()> { + self.conn.set_reserved_bytes(reserved_bytes) + } + + fn get_reserved_bytes(&self) -> Result { + self.conn.get_reserved_bytes() + } + fn enable_load_extension(&self, onoff: bool) -> Result<()> { self.conn.enable_load_extension(onoff) } diff --git a/libsql/src/replication/connection.rs b/libsql/src/replication/connection.rs index 50fd4dd939..418ae03465 100644 --- a/libsql/src/replication/connection.rs +++ b/libsql/src/replication/connection.rs @@ -542,6 +542,14 @@ impl Conn for RemoteConnection { } async fn reset(&self) {} + + fn set_reserved_bytes(&self, reserved_bytes: i32) -> Result<()> { + self.local.set_reserved_bytes(reserved_bytes) + } + + fn get_reserved_bytes(&self) -> Result { + self.local.get_reserved_bytes() + } } pub struct ColumnMeta { diff --git a/libsql/src/sync/connection.rs b/libsql/src/sync/connection.rs index 5c48e788d1..4337361c4f 100644 --- a/libsql/src/sync/connection.rs +++ b/libsql/src/sync/connection.rs @@ -189,4 +189,12 @@ impl Conn for SyncedConnection { } async fn reset(&self) {} + + fn set_reserved_bytes(&self, reserved_bytes: i32) -> Result<()> { + self.local.set_reserved_bytes(reserved_bytes) + } + + fn get_reserved_bytes(&self) -> Result { + self.local.get_reserved_bytes() + } }