Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ include = [
]

[patch.crates-io]
rsqlite-vfs = { path = "./crates/rsqlite-vfs" }
sqlite-wasm-rs = { path = "./" }
sqlite-wasm-vfs = { path = "./crates/sqlite-wasm-vfs" }
513 changes: 508 additions & 5 deletions crates/rsqlite-vfs/src/ffi.rs

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions crates/sqlite-wasm-vfs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sqlite-wasm-vfs"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
authors = ["Spxg <unsafe@outlook.es>"]
readme = "README.md"
Expand All @@ -11,7 +11,7 @@ categories = ["development-tools::ffi", "wasm", "database"]
keywords = ["sqlite", "sqlite-wasm", "wasm", "webassembly", "javascript"]

[dependencies]
sqlite-wasm-rs = { version = "0.5.1", default-features = false }
rsqlite-vfs = "0.1"

wasm-bindgen = "0.2.104"
js-sys = "0.3.81"
Expand All @@ -33,6 +33,7 @@ indexed_db_futures = "0.6.4"

[dev-dependencies]
wasm-bindgen-test = "0.3.54"
sqlite-wasm-rs = { version = "0.5.1", default-features = false }

[package.metadata.docs.rs]
targets = ["wasm32-unknown-unknown"]
43 changes: 24 additions & 19 deletions crates/sqlite-wasm-vfs/src/relaxed_idb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//!
//! async fn open_db() {
//! // install relaxed-idb persistent vfs and set as default vfs
//! install_idb_vfs(&RelaxedIdbCfg::default(), true)
//! install_idb_vfs::<ffi::WasmOsCallback>(&RelaxedIdbCfg::default(), true)
//! .await
//! .unwrap();
//!
Expand Down Expand Up @@ -44,19 +44,18 @@
//! It is particularly important to note that using it on multiple pages may cause DB corruption.
//! It is recommended to use it in SharedWorker.
use sqlite_wasm_rs::{
utils::{
bail, check_db_and_page_size, check_import_db, check_option, check_result, register_vfs,
registered_vfs, sqlite3_file, sqlite3_vfs, ImportDbError, MemChunksFile, OsCallback,
RegisterVfsError, SQLiteIoMethods, SQLiteVfs, SQLiteVfsFile, VfsAppData, VfsError, VfsFile,
VfsResult, VfsStore,
use rsqlite_vfs::{
bail, check_db_and_page_size, check_import_db, check_option, check_result,
ffi::{
sqlite3_file, sqlite3_vfs, SQLITE_ERROR, SQLITE_FCNTL_COMMIT_PHASETWO, SQLITE_FCNTL_PRAGMA,
SQLITE_FCNTL_SYNC, SQLITE_IOERR, SQLITE_IOERR_DELETE, SQLITE_NOTFOUND, SQLITE_OK,
SQLITE_OPEN_MAIN_DB,
},
WasmOsCallback, SQLITE_ERROR, SQLITE_FCNTL_COMMIT_PHASETWO, SQLITE_FCNTL_PRAGMA,
SQLITE_FCNTL_SYNC, SQLITE_IOERR, SQLITE_IOERR_DELETE, SQLITE_NOTFOUND, SQLITE_OK,
SQLITE_OPEN_MAIN_DB,
register_vfs, registered_vfs, ImportDbError, MemChunksFile, OsCallback, RegisterVfsError,
SQLiteIoMethods, SQLiteVfs, SQLiteVfsFile, VfsAppData, VfsError, VfsFile, VfsResult, VfsStore,
};
use std::cell::RefCell;
use std::time::Duration;
use std::{cell::RefCell, marker::PhantomData};

use indexed_db_futures::database::Database;
use indexed_db_futures::prelude::*;
Expand Down Expand Up @@ -717,21 +716,24 @@ impl SQLiteIoMethods for RelaxedIdbIoMethods {
}
}

struct RelaxedIdbVfs;
struct RelaxedIdbVfs<C>(PhantomData<C>);

impl SQLiteVfs<RelaxedIdbIoMethods> for RelaxedIdbVfs {
impl<C> SQLiteVfs<RelaxedIdbIoMethods> for RelaxedIdbVfs<C>
where
C: OsCallback,
{
const VERSION: ::std::os::raw::c_int = 1;

fn sleep(dur: Duration) {
WasmOsCallback::sleep(dur);
C::sleep(dur);
}

fn random(buf: &mut [u8]) {
WasmOsCallback::random(buf);
C::random(buf);
}

fn epoch_timestamp_in_ms() -> i64 {
WasmOsCallback::epoch_timestamp_in_ms()
C::epoch_timestamp_in_ms()
}
}

Expand Down Expand Up @@ -907,7 +909,10 @@ impl RelaxedIdbUtil {
///
/// If the vfs corresponding to `options.vfs_name` has been registered,
/// only return a management tool without register.
pub async fn install(options: &RelaxedIdbCfg, default_vfs: bool) -> Result<RelaxedIdbUtil> {
pub async fn install<C: OsCallback>(
options: &RelaxedIdbCfg,
default_vfs: bool,
) -> Result<RelaxedIdbUtil> {
static REGISTER_GUARD: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(());
let _guard = REGISTER_GUARD.lock().await;

Expand All @@ -916,7 +921,7 @@ pub async fn install(options: &RelaxedIdbCfg, default_vfs: bool) -> Result<Relax
} else {
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
let pool = RelaxedIdb::new(options, tx).await?;
let vfs = register_vfs::<RelaxedIdbIoMethods, RelaxedIdbVfs>(
let vfs = register_vfs::<RelaxedIdbIoMethods, RelaxedIdbVfs<C>>(
&options.vfs_name,
pool,
default_vfs,
Expand All @@ -933,7 +938,7 @@ pub async fn install(options: &RelaxedIdbCfg, default_vfs: bool) -> Result<Relax
#[cfg(test)]
mod tests {
use super::{IdbFile, RelaxedIdb, RelaxedIdbCfgBuilder, RelaxedIdbStore};
use sqlite_wasm_rs::utils::{test_suite::test_vfs_store, VfsAppData};
use rsqlite_vfs::{test_suite::test_vfs_store, VfsAppData};
use wasm_bindgen_test::wasm_bindgen_test;

#[wasm_bindgen_test]
Expand Down
57 changes: 34 additions & 23 deletions crates/sqlite-wasm-vfs/src/sahpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//!
//! async fn open_db() {
//! // install opfs-sahpool persistent vfs and set as default vfs
//! install_opfs_sahpool(&OpfsSAHPoolCfg::default(), true)
//! install_opfs_sahpool::<ffi::WasmOsCallback>(&OpfsSAHPoolCfg::default(), true)
//! .await
//! .unwrap();
//!
Expand All @@ -32,20 +32,23 @@
//! [`opfs-explorer`](https://chromewebstore.google.com/detail/opfs-explorer/acndjpgkpaclldomagafnognkcgjignd)
//! plugin to browse files.
use sqlite_wasm_rs::{
utils::{
check_import_db, register_vfs, registered_vfs, sqlite3_file, sqlite3_filename, sqlite3_vfs,
sqlite3_vfs_register, sqlite3_vfs_unregister, ImportDbError, OsCallback, RegisterVfsError,
SQLiteIoMethods, SQLiteVfs, SQLiteVfsFile, VfsAppData, VfsError, VfsFile, VfsResult,
VfsStore,
use rsqlite_vfs::{
check_import_db,
ffi::{
sqlite3_file, sqlite3_filename, sqlite3_vfs, sqlite3_vfs_register, sqlite3_vfs_unregister,
SQLITE_CANTOPEN, SQLITE_ERROR, SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN, SQLITE_IOERR,
SQLITE_IOERR_DELETE, SQLITE_OK, SQLITE_OPEN_DELETEONCLOSE, SQLITE_OPEN_MAIN_DB,
SQLITE_OPEN_MAIN_JOURNAL, SQLITE_OPEN_SUPER_JOURNAL, SQLITE_OPEN_WAL,
},
WasmOsCallback, SQLITE_CANTOPEN, SQLITE_ERROR, SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN,
SQLITE_IOERR, SQLITE_IOERR_DELETE, SQLITE_OK, SQLITE_OPEN_DELETEONCLOSE, SQLITE_OPEN_MAIN_DB,
SQLITE_OPEN_MAIN_JOURNAL, SQLITE_OPEN_SUPER_JOURNAL, SQLITE_OPEN_WAL,
register_vfs, registered_vfs, ImportDbError, OsCallback, RegisterVfsError, SQLiteIoMethods,
SQLiteVfs, SQLiteVfsFile, VfsAppData, VfsError, VfsFile, VfsResult, VfsStore,
};
use std::cell::{Cell, RefCell};
use std::collections::{HashMap, HashSet};
use std::time::Duration;
use std::{
cell::{Cell, RefCell},
marker::PhantomData,
};

use js_sys::{Array, DataView, IteratorNext, Reflect, Uint8Array};
use wasm_bindgen::{JsCast, JsValue};
Expand Down Expand Up @@ -97,10 +100,11 @@ struct OpfsSAHPool {
open_files: RefCell<HashSet<String>>,
/// A tuple holding the raw pointer to the `sqlite3_vfs` struct and whether it was registered as the default.
vfs: Cell<(*mut sqlite3_vfs, bool)>,
random: fn(&mut [u8]),
}

impl OpfsSAHPool {
async fn new(options: &OpfsSAHPoolCfg) -> Result<OpfsSAHPool> {
async fn new<C: OsCallback>(options: &OpfsSAHPoolCfg) -> Result<OpfsSAHPool> {
const OPAQUE_DIR_NAME: &str = ".opaque";

let vfs_dir = &options.directory;
Expand Down Expand Up @@ -154,6 +158,7 @@ impl OpfsSAHPool {
is_paused: Cell::new(false),
open_files: RefCell::new(HashSet::new()),
vfs: Cell::new((std::ptr::null_mut(), false)),
random: C::random,
};

pool.acquire_access_handles(clear_files).await?;
Expand All @@ -164,7 +169,7 @@ impl OpfsSAHPool {

async fn add_capacity(&self, n: u32) -> Result<u32> {
for _ in 0..n {
let opaque = sqlite_wasm_rs::utils::random_name(WasmOsCallback::random);
let opaque = rsqlite_vfs::random_name(self.random);
let handle: FileSystemFileHandle =
JsFuture::from(self.dh_opaque.get_file_handle_with_options(&opaque, &{
let options = FileSystemGetFileOptions::new();
Expand Down Expand Up @@ -670,9 +675,12 @@ impl SQLiteIoMethods for SyncAccessHandleIoMethods {
}
}

struct SyncAccessHandleVfs;
struct SyncAccessHandleVfs<C>(PhantomData<C>);

impl SQLiteVfs<SyncAccessHandleIoMethods> for SyncAccessHandleVfs {
impl<C> SQLiteVfs<SyncAccessHandleIoMethods> for SyncAccessHandleVfs<C>
where
C: OsCallback,
{
const VERSION: ::std::os::raw::c_int = 2;
const MAX_PATH_SIZE: ::std::os::raw::c_int = HEADER_MAX_FILENAME_SIZE as _;

Expand All @@ -698,15 +706,15 @@ impl SQLiteVfs<SyncAccessHandleIoMethods> for SyncAccessHandleVfs {
}

fn sleep(dur: Duration) {
WasmOsCallback::sleep(dur);
C::sleep(dur);
}

fn random(buf: &mut [u8]) {
WasmOsCallback::random(buf);
C::random(buf);
}

fn epoch_timestamp_in_ms() -> i64 {
WasmOsCallback::epoch_timestamp_in_ms()
C::epoch_timestamp_in_ms()
}
}

Expand Down Expand Up @@ -946,15 +954,18 @@ impl OpfsSAHPoolUtil {
///
/// If the vfs corresponding to `options.vfs_name` has been registered,
/// only return a management tool without register.
pub async fn install(options: &OpfsSAHPoolCfg, default_vfs: bool) -> Result<OpfsSAHPoolUtil> {
pub async fn install<C: OsCallback>(
options: &OpfsSAHPoolCfg,
default_vfs: bool,
) -> Result<OpfsSAHPoolUtil> {
static REGISTER_GUARD: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(());
let _guard = REGISTER_GUARD.lock().await;

let vfs = match registered_vfs(&options.vfs_name)? {
Some(vfs) => vfs,
None => register_vfs::<SyncAccessHandleIoMethods, SyncAccessHandleVfs>(
None => register_vfs::<SyncAccessHandleIoMethods, SyncAccessHandleVfs<C>>(
&options.vfs_name,
OpfsSAHPool::new(options).await?,
OpfsSAHPool::new::<C>(options).await?,
default_vfs,
)?,
};
Expand All @@ -971,12 +982,12 @@ mod tests {
OpfsSAHPool, OpfsSAHPoolCfgBuilder, SyncAccessFile, SyncAccessHandleAppData,
SyncAccessHandleStore,
};
use sqlite_wasm_rs::utils::{test_suite::test_vfs_store, VfsAppData};
use rsqlite_vfs::{test_suite::test_vfs_store, VfsAppData};
use wasm_bindgen_test::wasm_bindgen_test;

#[wasm_bindgen_test]
async fn test_opfs_vfs_store() {
let data = OpfsSAHPool::new(
let data = OpfsSAHPool::new::<sqlite_wasm_rs::WasmOsCallback>(
&OpfsSAHPoolCfgBuilder::new()
.directory("test_opfs_suite")
.build(),
Expand Down
6 changes: 3 additions & 3 deletions examples/implement-a-vfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
use sqlite_wasm_rs::{
sqlite3_close, sqlite3_exec, sqlite3_open_v2,
utils::{
register_vfs, sqlite3_file, sqlite3_vfs, OsCallback, SQLiteIoMethods, SQLiteVfs,
SQLiteVfsFile, VfsFile, VfsResult, VfsStore,
ffi::{sqlite3_file, sqlite3_vfs, SQLITE_OK, SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE},
register_vfs, OsCallback, SQLiteIoMethods, SQLiteVfs, SQLiteVfsFile, VfsFile, VfsResult,
VfsStore,
},
SQLITE_OK, SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE,
};
use std::time::Duration;
use std::{cell::RefCell, collections::HashMap};
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod utils {
VfsStore, SQLITE3_HEADER,
};

pub use rsqlite_vfs::ffi::*;
pub use rsqlite_vfs::ffi;

#[doc(hidden)]
pub use rsqlite_vfs::test_suite;
Expand All @@ -28,6 +28,7 @@ pub use self::utils::{bail, check_option, check_result};
/// Raw C-style bindings to the underlying `libsqlite3` library.
pub use wsqlite3_sys::*;

/// Wasm platform implementation
pub use self::shim::WasmOsCallback;
/// In-memory VFS implementation.
pub use rsqlite_vfs::memvfs::{MemVfsError, MemVfsUtil};
2 changes: 1 addition & 1 deletion tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
publish = false

[dependencies]
sqlite-wasm-vfs = "0.1.0"
sqlite-wasm-vfs = "0.2.0"
sqlite-wasm-rs = "0.5.0"
wasm-bindgen-test = "0.3.54"

Expand Down
4 changes: 2 additions & 2 deletions tests/tests/full/sqlite3mc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ unsafe fn test_memvfs_cipher(cipher: &str) {
}

async unsafe fn test_relaxed_idb_vfs_cipher(cipher: &str) {
let util = sqlite_wasm_vfs::relaxed_idb::install(
let util = sqlite_wasm_vfs::relaxed_idb::install::<sqlite_wasm_rs::WasmOsCallback>(
&sqlite_wasm_vfs::relaxed_idb::RelaxedIdbCfgBuilder::new()
.vfs_name("relaxed-db-cipher")
.clear_on_init(true)
Expand Down Expand Up @@ -126,7 +126,7 @@ async unsafe fn test_relaxed_idb_vfs_cipher(cipher: &str) {
}

async unsafe fn test_opfs_sah_vfs_cipher(cipher: &str) {
let util = sqlite_wasm_vfs::sahpool::install(
let util = sqlite_wasm_vfs::sahpool::install::<sqlite_wasm_rs::WasmOsCallback>(
&OpfsSAHPoolCfgBuilder::new()
.vfs_name("sah-cipher")
.directory("sah-cipher")
Expand Down
9 changes: 8 additions & 1 deletion tests/tests/full/vfs/relaxed_idb.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
use sqlite_wasm_rs::*;
use sqlite_wasm_vfs::relaxed_idb::{
install as install_idb_vfs, Preload, RelaxedIdbCfg, RelaxedIdbCfgBuilder,
install, Preload, RelaxedIdbCfg, RelaxedIdbCfgBuilder, RelaxedIdbError, RelaxedIdbUtil,
};
use wasm_bindgen_test::wasm_bindgen_test;

use crate::full::{check_persistent, prepare_simple_db};

pub async fn install_idb_vfs(
options: &RelaxedIdbCfg,
default_vfs: bool,
) -> Result<RelaxedIdbUtil, RelaxedIdbError> {
install::<sqlite_wasm_rs::WasmOsCallback>(options, default_vfs).await
}

#[wasm_bindgen_test]
async fn test_idb_vfs_default() {
install_idb_vfs(&RelaxedIdbCfg::default(), true)
Expand Down
11 changes: 10 additions & 1 deletion tests/tests/full/vfs/sahpool.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
use sqlite_wasm_rs::*;
use sqlite_wasm_vfs::sahpool::{install as install_opfs_sahpool, *};
use sqlite_wasm_vfs::sahpool::{
install, OpfsSAHError, OpfsSAHPoolCfg, OpfsSAHPoolCfgBuilder, OpfsSAHPoolUtil,
};
use wasm_bindgen_test::wasm_bindgen_test;

pub async fn install_opfs_sahpool(
options: &OpfsSAHPoolCfg,
default_vfs: bool,
) -> Result<OpfsSAHPoolUtil, OpfsSAHError> {
install::<sqlite_wasm_rs::WasmOsCallback>(options, default_vfs).await
}

use crate::full::{check_persistent, prepare_simple_db};

#[wasm_bindgen_test]
Expand Down