Skip to content

Commit d3bf87e

Browse files
bors[bot]psarna
andauthored
Merge #81
81: Switch to a fork of libsqlite3-sys in order to statically link libSQL r=MarinPostma a=psarna Until (if?) we get official libSQL support from the great libsqlite3-sys crate, we can instead switch to a git dependency. What it provides is as follows: - statically links libSQL, compiled from sqlite3.c and sqlite3.h amalgamation files - adds custom libSQL helper functions, like automatic initialization of the WebAssembly function table and opening a connection with virtual WAL It also lets us drop the libsql git submodule, because we now only rely on the libsqlite3-sys crate to provide the library for us. Ref: rusqlite/rusqlite#1283 Co-authored-by: Piotr Sarna <sarna@chiselstrike.com>
2 parents 25e174f + 8d0e869 commit d3bf87e

10 files changed

Lines changed: 32 additions & 112 deletions

File tree

libsql-server/.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

libsql-server/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# install dependencies
22
FROM rust:slim-bullseye AS compiler
3-
RUN apt update && apt install -y libclang-dev clang libsqlite3-dev \
3+
RUN apt update && apt install -y libclang-dev clang \
44
build-essential tcl protobuf-compiler file
55
RUN cargo install cargo-chef
66
WORKDIR /sqld

libsql-server/libsql

Lines changed: 0 additions & 1 deletion
This file was deleted.

libsql-server/sqld/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fallible-iterator = "0.2.0"
1717
futures = "0.3.25"
1818
hex = "0.4.3"
1919
hyper = { version = "0.14.23", features = ["http2"] }
20+
libsql-wasmtime-bindings = "0"
2021
# Regular mvfs prevents users from enabling WAL mode
2122
mvfs = { git = "https://github.com/psarna/mvsqlite", branch = "mwal", optional = true }
2223
mwal = { git = "https://github.com/psarna/mvsqlite", branch = "mwal", optional = true }
@@ -27,7 +28,10 @@ pin-project-lite = "0.2.9"
2728
postgres-protocol = "0.6.4"
2829
prost = "0.11.3"
2930
regex = "1.7.0"
30-
rusqlite = { version = "0.28.0", features = [ "buildtime_bindgen", "column_decltype" ] }
31+
rusqlite = { git = "https://github.com/psarna/rusqlite", branch = "libsql-dev", default-features = false, features = [
32+
"bundled-libsql",
33+
"column_decltype"
34+
] }
3135
serde = { version = "1.0.149", features = ["derive"] }
3236
serde_json = "1.0.91"
3337
smallvec = "1.10.0"

libsql-server/sqld/build.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,6 @@
1-
use std::env;
2-
use std::fs;
3-
use std::process::Command;
4-
51
use prost_build::Config;
62

73
fn main() -> Result<(), Box<dyn std::error::Error>> {
8-
let mut pwd = env::current_dir().unwrap();
9-
pwd.push("../libsql");
10-
let libsql_dir = fs::canonicalize(pwd.as_path()).unwrap();
11-
let mut bindings = Command::new("./configure");
12-
let configure = bindings.current_dir(libsql_dir.as_path()).arg("--with-pic");
13-
let profile = std::env::var("PROFILE").unwrap();
14-
if profile.as_str() == "release" {
15-
configure.arg("--enable-releasemode");
16-
}
17-
let output = configure.output().unwrap();
18-
if !output.status.success() {
19-
println!("{}", std::str::from_utf8(&output.stderr).unwrap());
20-
panic!("failed to configure");
21-
}
22-
23-
if !Command::new("make")
24-
.current_dir(libsql_dir.as_path())
25-
.status()
26-
.unwrap()
27-
.success()
28-
{
29-
panic!("failed to compile");
30-
}
31-
324
let mut config = Config::new();
335
config.bytes([".wal_log"]);
346
tonic_build::configure()
@@ -41,9 +13,5 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
4113

4214
println!("cargo:rerun-if-changed=proto");
4315

44-
println!("cargo:rustc-link-search=native=libsql/.libs");
45-
println!("cargo:rustc-link-lib=static=sqlite3");
46-
println!("cargo:rerun-if-changed=../libsql/src");
47-
4816
Ok(())
4917
}

libsql-server/sqld/src/database/libsql.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use tokio::sync::oneshot;
1010
use tracing::warn;
1111

1212
use crate::libsql::wal_hook::WalHook;
13-
use crate::libsql::WalConnection;
1413
use crate::query::{
1514
Column, ErrorCode, Params, Queries, Query, QueryError, QueryResponse, QueryResult, ResultSet,
1615
Row,
@@ -136,7 +135,7 @@ fn open_db(
136135
Arc<Mutex<mwal::ffi::libsql_wal_methods>>,
137136
>,
138137
wal_hook: impl WalHook + Send + Clone + 'static,
139-
) -> anyhow::Result<WalConnection> {
138+
) -> anyhow::Result<rusqlite::Connection> {
140139
let mut retries = 0;
141140
loop {
142141
#[cfg(feature = "mwal_backend")]

libsql-server/sqld/src/database/write_proxy/replication.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ use tokio::runtime::Handle;
3131
use tonic::transport::Channel;
3232

3333
use crate::libsql::ffi::{types::XWalFrameFn, PgHdr, Wal};
34+
use crate::libsql::open_with_regular_wal;
3435
use crate::libsql::wal_hook::WalHook;
35-
use crate::libsql::{open_with_regular_wal, WalConnection};
3636
use crate::rpc::wal_log::wal_log_rpc::wal_log_entry::Payload;
3737
use crate::rpc::wal_log::wal_log_rpc::{wal_log_client::WalLogClient, LogOffset, WalLogEntry};
3838
use crate::rpc::wal_log::wal_log_rpc::{Commit, Frame};
3939

4040
pub struct PeriodicDbUpdater {
4141
interval: Duration,
42-
db: WalConnection,
42+
db: rusqlite::Connection,
4343
}
4444

4545
/// The `PeriodicUpdater` role is to periodically trigger a dummy write that will be intercepted by

libsql-server/sqld/src/libsql/mod.rs

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ pub mod ffi;
55
pub mod mwal;
66
pub mod wal_hook;
77

8+
pub use wblibsql::{
9+
libsql_compile_wasm_module, libsql_free_wasm_module, libsql_run_wasm, libsql_wasm_engine_new,
10+
};
11+
812
use anyhow::ensure;
913
use rusqlite::Connection;
10-
use std::os::unix::ffi::OsStrExt;
1114

1215
use crate::libsql::{ffi::libsql_wal_methods_register, wal_hook::WalMethodsHook};
1316

@@ -16,37 +19,6 @@ use self::{
1619
wal_hook::WalHook,
1720
};
1821

19-
pub struct WalConnection {
20-
inner: rusqlite::Connection,
21-
}
22-
23-
impl std::ops::Deref for WalConnection {
24-
type Target = rusqlite::Connection;
25-
26-
fn deref(&self) -> &Self::Target {
27-
&self.inner
28-
}
29-
}
30-
31-
impl std::ops::Drop for WalConnection {
32-
fn drop(&mut self) {
33-
unsafe {
34-
rusqlite::ffi::sqlite3_close(self.inner.handle());
35-
}
36-
let _ = self.inner;
37-
}
38-
}
39-
40-
extern "C" {
41-
fn libsql_open(
42-
filename: *const u8,
43-
ppdb: *mut *mut rusqlite::ffi::sqlite3,
44-
flags: std::ffi::c_int,
45-
vfs: *const u8,
46-
wal: *const u8,
47-
) -> i32;
48-
}
49-
5022
fn get_orig_wal_methods() -> anyhow::Result<*mut libsql_wal_methods> {
5123
let orig: *mut libsql_wal_methods = unsafe { libsql_wal_methods_find(0) };
5224
if orig.is_null() {
@@ -60,29 +32,17 @@ pub(crate) fn open_with_regular_wal(
6032
path: impl AsRef<std::path::Path>,
6133
flags: rusqlite::OpenFlags,
6234
wal_hook: impl WalHook + 'static,
63-
) -> anyhow::Result<WalConnection> {
35+
) -> anyhow::Result<Connection> {
6436
unsafe {
65-
let mut pdb: *mut rusqlite::ffi::sqlite3 = std::ptr::null_mut();
66-
let ppdb: *mut *mut rusqlite::ffi::sqlite3 = &mut pdb;
6737
let orig = get_orig_wal_methods()?;
6838
let wrapped = WalMethodsHook::wrap(orig, wal_hook);
6939
let res = libsql_wal_methods_register(wrapped);
7040
ensure!(res == 0, "failed to register WAL methods");
71-
72-
let open_err = libsql_open(
73-
path.as_ref().as_os_str().as_bytes().as_ptr(),
74-
ppdb,
75-
flags.bits(),
76-
std::ptr::null(),
77-
WalMethodsHook::METHODS_NAME.as_ptr(),
78-
);
79-
assert_eq!(open_err, 0);
80-
let conn = Connection::from_handle(pdb)?;
81-
conn.pragma_update(None, "journal_mode", "wal")?;
82-
tracing::trace!(
83-
"Opening a connection with regular WAL at {}",
84-
path.as_ref().display()
85-
);
86-
Ok(WalConnection { inner: conn })
8741
}
42+
tracing::trace!(
43+
"Opening a connection with regular WAL at {}",
44+
path.as_ref().display()
45+
);
46+
let conn = Connection::open_with_flags_and_wal(path, flags, WalMethodsHook::METHODS_NAME_STR)?;
47+
Ok(conn)
8848
}

libsql-server/sqld/src/libsql/mwal/mod.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,22 @@ pub(crate) fn open_with_virtual_wal(
66
path: impl AsRef<std::path::Path>,
77
flags: rusqlite::OpenFlags,
88
vwal_methods: Arc<Mutex<mwal::ffi::libsql_wal_methods>>,
9-
) -> anyhow::Result<super::WalConnection> {
10-
use std::os::unix::ffi::OsStrExt;
9+
) -> anyhow::Result<rusqlite::Connection> {
1110
let mut vwal_methods = vwal_methods.lock().map_err(|e| anyhow::anyhow!("{}", e))?;
1211
unsafe {
13-
let mut pdb: *mut rusqlite::ffi::sqlite3 = std::ptr::null_mut();
14-
let ppdb: *mut *mut rusqlite::ffi::sqlite3 = &mut pdb;
1512
let register_err = super::ffi::libsql_wal_methods_register(
1613
&mut *vwal_methods as *const mwal::ffi::libsql_wal_methods as _,
1714
);
1815
assert_eq!(register_err, 0);
19-
let open_err = super::libsql_open(
20-
path.as_ref().as_os_str().as_bytes().as_ptr(),
21-
ppdb,
22-
flags.bits(),
23-
std::ptr::null(),
24-
vwal_methods.name,
25-
);
26-
assert_eq!(open_err, 0);
27-
let conn = super::Connection::from_handle(pdb)?;
28-
conn.pragma_update(None, "journal_mode", "wal")?;
29-
tracing::trace!(
30-
"Opening a connection with virtual WAL at {}",
31-
path.as_ref().display()
32-
);
33-
Ok(super::WalConnection { inner: conn })
3416
}
17+
tracing::trace!(
18+
"Opening a connection with virtual WAL at {}",
19+
path.as_ref().display()
20+
);
21+
let conn = rusqlite::Connection::open_with_flags_and_wal(path, flags, unsafe {
22+
std::ffi::CStr::from_ptr(vwal_methods.name as *const _)
23+
.to_str()
24+
.unwrap()
25+
})?;
26+
Ok(conn)
3527
}

libsql-server/sqld/src/libsql/wal_hook.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub unsafe trait WalHook {
5353
unsafe impl WalHook for () {}
5454

5555
impl WalMethodsHook {
56+
pub const METHODS_NAME_STR: &'static str = "wal_hook";
5657
pub const METHODS_NAME: &'static [u8] = b"wal_hook\0";
5758

5859
pub fn wrap(

0 commit comments

Comments
 (0)