Skip to content

Commit

Permalink
fix rust bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
MarinPostma committed Nov 8, 2023
1 parent f0db07d commit 8d1e459
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 617 deletions.
3 changes: 1 addition & 2 deletions libsql-sys-tmp/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
pub mod types;

pub use rusqlite::ffi::{
libsql_wal_methods, libsql_wal_methods_find, libsql_wal_methods_register,
libsql_wal_methods_unregister, sqlite3, sqlite3_file, sqlite3_hard_heap_limit64,
libsql_wal_methods, sqlite3, sqlite3_file, sqlite3_hard_heap_limit64,
sqlite3_io_methods, sqlite3_soft_heap_limit64, sqlite3_vfs, WalIndexHdr, SQLITE_CANTOPEN,
SQLITE_CHECKPOINT_FULL, SQLITE_CHECKPOINT_TRUNCATE, SQLITE_IOERR_WRITE, SQLITE_OK,
};
Expand Down
77 changes: 25 additions & 52 deletions libsql-sys-tmp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,43 @@
#![allow(improper_ctypes)]

pub mod ffi;
// pub mod wal_hook;
pub mod wal;

use std::{ffi::{CString, c_int, c_void}, ops::Deref, time::Duration, ptr::slice_from_raw_parts_mut};
use std::marker::PhantomData;
use std::ops::Deref;

use crate::wal::BusyHandler;
pub use once_cell::sync::Lazy;
use rusqlite::ffi::{sqlite3, wal_impl, SQLITE_OK, WAL_SAVEPOINT_NDATA, PgHdr};
use rusqlite::ffi::sqlite3;

use self::{
ffi::{libsql_wal_methods, libsql_wal},
wal::{Wal, CreateWal},
};
use crate::wal::make_create_wal;

use self::wal::{Wal, CreateWal};


#[derive(Debug)]
pub struct Connection<W: WalHook> {
pub struct Connection<W> {
conn: rusqlite::Connection,
// Safety: _ctx MUST be dropped after the connection, because the connection has a pointer
// This pointer MUST NOT move out of the connection
_ctx: Box<W::Context>,
_pth: PhantomData<W>,
}

impl<W: WalHook> Deref for Connection<W> {
impl<W: Wal> Deref for Connection<W> {
type Target = rusqlite::Connection;

fn deref(&self) -> &Self::Target {
&self.conn
}
}

impl Connection<TransparentMethods> {
/// returns a dummy, in-memory connection. For testing purposes only
pub fn test() -> Self {
let conn = rusqlite::Connection::open_in_memory().unwrap();
Self {
conn,
_ctx: Box::new(()),
}
}
}
// impl Connection<Sqlite3> {
// /// returns a dummy, in-memory connection. For testing purposes only
// pub fn test() -> Self {
// let conn = rusqlite::Connection::open_in_memory().unwrap();
// Self {
// conn,
// _ctx: Box::new(()),
// }
// }
// }

impl<W: CreateWal> Connection<W> {
/// Opens a database with the regular wal methods in the directory pointed to by path
Expand All @@ -52,47 +48,24 @@ impl<W: CreateWal> Connection<W> {
auto_checkpoint: u32,
) -> Result<Self, rusqlite::Error> {
let path = path.as_ref().join("data");
let mut _ctx = Box::new(hook_ctx);
tracing::trace!(
"Opening a connection with regular WAL at {}",
path.display()
);

let conn_str = format!("file:{}?_journal_mode=WAL", path.display());
let filename = CString::new(conn_str).unwrap();
let mut db: *mut rusqlite::ffi::sqlite3 = std::ptr::null_mut();

let conn = rusqlite::Connection::open_with_flags_and_wal(conn_str, flags, make_create_wal(create_wal))?;
unsafe {
// We pass a pointer to the WAL methods data to the database connection. This means
// that the reference must outlive the connection. This is guaranteed by the marker in
// the returned connection.
let mut rc = rusqlite::ffi::libsql_open_v2(
filename.as_ptr(),
&mut db as *mut _,
flags.bits(),
std::ptr::null_mut(),
make_create_wal(Box::leak(Box::new(create_wal))),
);

if rc == 0 {
rc = rusqlite::ffi::sqlite3_wal_autocheckpoint(db, auto_checkpoint as _);
}

let rc = rusqlite::ffi::sqlite3_wal_autocheckpoint(conn.handle(), auto_checkpoint as _);
if rc != 0 {
rusqlite::ffi::sqlite3_close(db);
return Err(rusqlite::Error::SqliteFailure(
rusqlite::ffi::Error::new(rc),
None,
rusqlite::ffi::Error::new(rc),
Some("failed to set auto_checkpoint".into()),
));
}
}

assert!(!db.is_null());
};

let conn = unsafe { rusqlite::Connection::from_handle_owned(db)? };
conn.busy_timeout(Duration::from_millis(5000))?;

Ok(Connection { conn, _ctx })
Ok(Connection { conn, _pth: PhantomData })
}

/// Returns the raw sqlite handle
Expand Down
Loading

0 comments on commit 8d1e459

Please sign in to comment.