From 8ffcc3c87b6ace7f153457e01fe8b34b6913cb83 Mon Sep 17 00:00:00 2001 From: "Levy A." Date: Fri, 3 Oct 2025 21:55:16 -0300 Subject: [PATCH 1/3] feat: expose set/get reserved bytes to public API --- libsql/src/connection.rs | 16 ++++++++++++++++ libsql/src/errors.rs | 2 ++ libsql/src/local/impls.rs | 8 ++++++++ libsql/src/replication/connection.rs | 8 ++++++++ libsql/src/sync/connection.rs | 8 ++++++++ 5 files changed, 42 insertions(+) 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() + } } From 54df763c511112c70e839687137bde482842c3ef Mon Sep 17 00:00:00 2001 From: "Levy A." Date: Fri, 3 Oct 2025 22:22:04 -0300 Subject: [PATCH 2/3] feat: add get/set reserved bytes to c api --- bindings/c/include/libsql.h | 4 ++++ bindings/c/src/lib.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) 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..52aa104ed3 100644 --- a/bindings/c/src/lib.rs +++ b/bindings/c/src/lib.rs @@ -549,6 +549,41 @@ 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); + } + 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), + } + 0 +} + #[no_mangle] pub unsafe extern "C" fn libsql_reset( conn: libsql_connection_t, From 5cfbbd5588ed76383defc2d4af8b21609ead27fd Mon Sep 17 00:00:00 2001 From: "Levy A." Date: Sat, 4 Oct 2025 08:17:39 -0300 Subject: [PATCH 3/3] fix(c-bindings): return 1 on error --- bindings/c/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bindings/c/src/lib.rs b/bindings/c/src/lib.rs index 52aa104ed3..ea02fcf966 100644 --- a/bindings/c/src/lib.rs +++ b/bindings/c/src/lib.rs @@ -562,6 +562,7 @@ pub unsafe extern "C" fn libsql_set_reserved_bytes( 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 } @@ -579,7 +580,10 @@ pub unsafe extern "C" fn libsql_get_reserved_bytes( 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), + Err(err) => { + set_err_msg(err.to_string(), out_err_msg); + return 1; + } } 0 }