Skip to content

Instantly share code, notes, and snippets.

@BrendanThompson
Last active January 20, 2026 05:35
Show Gist options
  • Select an option

  • Save BrendanThompson/373026b909b918c4f6a013f415a1a88f to your computer and use it in GitHub Desktop.

Select an option

Save BrendanThompson/373026b909b918c4f6a013f415a1a88f to your computer and use it in GitHub Desktop.
Libsql why you no webpki
public class Database {
var inner: libsql_database_t
deinit {
libsql_database_deinit(self.inner)
}
public func sync() throws {
let sync = libsql_database_sync(self.inner)
try errIf(sync.err)
}
public func connect() throws -> Connection {
let conn = libsql_database_connect(self.inner)
try errIf(conn.err)
return Connection(from: conn)
}
public init(
path: String,
url: String,
authToken: String,
readYourWrites: Bool = true,
encryptionKey: String? = nil,
syncInterval: UInt64 = 0,
withWebpki: Bool = false
) throws {
self.inner = try path.withCString { path in
try url.withCString { url in
try authToken.withCString { authToken in
try encryptionKey.withCString { encryptionKey in
var desc = libsql_database_desc_t()
desc.path = path
desc.url = url
desc.auth_token = authToken
desc.encryption_key = encryptionKey
desc.disable_read_your_writes = !readYourWrites
desc.sync_interval = syncInterval
desc.webpki = withWebpki
let db = libsql_database_init(desc)
try errIf(db.err)
return db
}
}
}
}
}
}
typedef struct {
libsql_error_t *err;
void *inner;
} libsql_database_t;
typedef struct {
/** The url to the primary database */
const char *url;
/** Path to the database file or `:memory:` */
const char *path;
/** Auth token to access the primary */
const char *auth_token;
/** Encryption key to encrypt and decrypt the database in `path` */
const char *encryption_key;
/** Interval to periodicaly sync with primary */
uint64_t sync_interval;
/** Cypher to be used with `encryption_key` */
libsql_cypher_t cypher;
/** If set, disable `read_your_writes`. To mantain consistency. */
bool disable_read_your_writes;
/** Enable Webpki connector */
bool webpki;
/** Offline writes */
bool synced;
/** Safety assert */
bool disable_safety_assert;
} libsql_database_desc_t;
libsql_database_t libsql_database_init(libsql_database_desc_t desc);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct libsql_database_t {
pub err: *mut libsql_error_t,
pub inner: *mut ::std::os::raw::c_void,
}
#[no_mangle]
#[signature(c)]
pub extern "C" fn libsql_database_init(desc: c::libsql_database_desc_t) -> c::libsql_database_t {
match (|| -> anyhow::Result<Database> {
let path = desc
.path
.is_null()
.not()
.then(|| unsafe { CStr::from_ptr(desc.path) });
let url = desc
.url
.is_null()
.not()
.then(|| unsafe { CStr::from_ptr(desc.url) });
let auth_token = desc
.auth_token
.is_null()
.not()
.then(|| unsafe { CStr::from_ptr(desc.auth_token) });
let encryption_key = desc
.encryption_key
.is_null()
.not()
.then(|| unsafe { CStr::from_ptr(desc.encryption_key) });
let db = match (path, url, auth_token, desc.synced) {
(None, None, None, _) => {
let db = libsql::Builder::new_local(":memory:");
let db = unsafe { db.skip_safety_assert(desc.disable_safety_assert) };
RT.block_on(db.build())
}
(Some(path), None, None, _) => {
let db = libsql::Builder::new_local(path.to_str()?);
let db = unsafe { db.skip_safety_assert(desc.disable_safety_assert) };
let db = match (desc.cypher, encryption_key) {
(
c::libsql_cypher_t::LIBSQL_CYPHER_AES256
| c::libsql_cypher_t::LIBSQL_CYPHER_DEFAULT,
Some(key),
) => db.encryption_config(libsql::EncryptionConfig {
cipher: libsql::Cipher::Aes256Cbc,
encryption_key: key.to_bytes().into(),
}),
_ => db,
};
RT.block_on(async {
let db = db.build().await?;
let conn = db.connect()?;
conn.query("PRAGMA journal_mode=WAL", ()).await?;
Ok(db)
})
}
(None, Some(url), auth_token, _) => {
let mut db = libsql::Builder::new_remote(
url.to_str()?.to_string(),
match auth_token {
Some(auth_token) => auth_token.to_str()?.to_string(),
None => "".to_string(),
},
);
if desc.webpki {
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_webpki_roots()
.https_or_http()
.enable_http1()
.build();
db = db.connector(connector)
};
let namespace = desc
.namespace
.is_null()
.not()
.then(|| unsafe { CStr::from_ptr(desc.namespace) });
if let Some(ns) = namespace {
db = db.namespace(ns.to_str()?.to_string());
}
RT.block_on(async {
let version = VERSION.read().await;
let db = if let Some(ref version) = *version {
db.version(version.to_owned())
} else {
db
};
db.build().await
})
}
(Some(path), Some(url), auth_token, true) => {
let db = libsql::Builder::new_synced_database(
path.to_str()?,
url.to_str()?.to_string(),
match auth_token {
Some(s) => s.to_str()?.to_string(),
None => "".to_string(),
},
);
let db = if desc.webpki {
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_webpki_roots()
.https_or_http()
.enable_http1()
.build();
db.connector(connector)
} else {
db
};
RT.block_on(async {
let version = VERSION.read().await;
let db = if let Some(ref version) = *version {
db.version(version.to_owned())
} else {
db
};
db.build().await
})
}
(Some(path), Some(url), auth_token, false) => {
let db = libsql::Builder::new_remote_replica(
path.to_str()?,
url.to_str()?.to_string(),
match auth_token {
Some(s) => s.to_str()?.to_string(),
None => "".to_string(),
},
);
// NOTE: This is done so that the default zero initialization respects that
// read_your_writes is true by default.
let db = db.read_your_writes(desc.disable_read_your_writes.not());
let db = unsafe { db.skip_safety_assert(desc.disable_safety_assert) };
let db = match (desc.cypher, encryption_key) {
(
c::libsql_cypher_t::LIBSQL_CYPHER_AES256
| c::libsql_cypher_t::LIBSQL_CYPHER_DEFAULT,
Some(key),
) => db.encryption_config(libsql::EncryptionConfig {
cipher: libsql::Cipher::Aes256Cbc,
encryption_key: key.to_bytes().into(),
}),
_ => db,
};
let db = if desc.sync_interval != 0 {
db.sync_interval(Duration::from_millis(desc.sync_interval))
} else {
db
};
let db = if desc.webpki {
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_webpki_roots()
.https_or_http()
.enable_http1()
.build();
db.connector(connector)
} else {
db
};
RT.block_on(async {
let version = VERSION.read().await;
let db = if let Some(ref version) = *version {
db.version(version.to_owned())
} else {
db
};
db.build().await
})
}
_ => bail!("invalid database description"),
};
Ok(db?)
})() {
Ok(db) => c::libsql_database_t {
inner: Box::into_raw(Box::new(db)) as *mut c_void,
..Default::default()
},
Err(err) => c::libsql_database_t {
err: CString::new(err.to_string()).unwrap().into_raw() as *mut c::libsql_error_t,
..Default::default()
},
}
}
#[doc = " Database description."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct libsql_database_desc_t {
#[doc = " The url to the primary database"]
pub url: *const ::std::os::raw::c_char,
#[doc = " Path to the database file or `:memory:`"]
pub path: *const ::std::os::raw::c_char,
#[doc = " Auth token to access the primary"]
pub auth_token: *const ::std::os::raw::c_char,
#[doc = " Encryption key to encrypt and decrypt the database in `path`"]
pub encryption_key: *const ::std::os::raw::c_char,
#[doc = " Interval to periodicaly sync with primary"]
pub sync_interval: u64,
#[doc = " Cypher to be used with `encryption_key`"]
pub cypher: libsql_cypher_t,
#[doc = " If set, disable `read_your_writes`. To mantain consistency."]
pub disable_read_your_writes: bool,
#[doc = " Enable Webpki connector"]
pub webpki: bool,
#[doc = " Offline writes"]
pub synced: bool,
#[doc = " Safety assert"]
pub disable_safety_assert: bool,
#[doc = " Provide a namespace through a header."]
pub namespace: *const ::std::os::raw::c_char,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment