Skip to content

Commit 57d5b21

Browse files
committed
Re-enable sqlite
Signed-off-by: Ryan Levick <[email protected]>
1 parent 70567b4 commit 57d5b21

File tree

5 files changed

+149
-116
lines changed

5 files changed

+149
-116
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,10 @@
44

55
To build `spin-test` from source, you'll need to [download the `WASI_SDK`](https://github.com/WebAssembly/wasi-sdk/releases/) (needed for the C compiler used to compile some C dependencies).
66

7-
Once you have the SDK on your machine somewhere, point to it via the `WASI_SDK_PATH` environment variable.
8-
9-
Then set the following environment variables:
7+
Once you have the SDK on your machine somewhere, point to it via the `WASI_SDK_PATH` environment variable:
108

119
```bash
12-
export LIBSQLITE3_FLAGS="\
13-
-DSQLITE_OS_OTHER \
14-
-USQLITE_TEMP_STORE \
15-
-DSQLITE_TEMP_STORE=3 \
16-
-USQLITE_THREADSAFE \
17-
-DSQLITE_THREADSAFE=0 \
18-
-DSQLITE_OMIT_LOCALTIME \
19-
-DSQLITE_OMIT_LOAD_EXTENSION \
20-
-DLONGDOUBLE_TYPE=double"
21-
export CC_wasm32_wasi=$WASI_SDK_PATH/bin/clang
22-
export WASI_SYS_ROOT=$WASI_SDK_PATH/share/wasi-sysroot
23-
export CC="$WASI_SDK_PATH/bin/clang --sysroot=$WASI_SYS_ROOT"
10+
export WASI_SDK_PATH=~/.wasi-sdk-22.0
2411
```
2512

2613
You can then run `cargo build --release` to build `spin-test`.

Cargo.lock

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,17 @@ fn ensure_wasi_sdk() -> Vec<(&'static str, String)> {
3434
clang_path.display()
3535
);
3636
}
37+
let wasi_sysroot = format!("{}/{}", wasi_sdk_path_string, "share/wasi-sysroot");
38+
if !std::path::Path::new(&wasi_sysroot).exists() {
39+
panic!(
40+
"WASI_SDK_PATH is set to a path that does not contain share/wasi-sysroot: {}",
41+
wasi_sysroot
42+
);
43+
}
44+
3745
vec![
3846
("WASI_SDK_PATH", wasi_sdk_path_string),
47+
("CC", format!("{clang_path_string} --sysroot={wasi_sysroot}")),
3948
("CC_wasm32_wasi", clang_path_string),
4049
("LIBSQLITE3_FLAGS", "-DSQLITE_OS_OTHER -USQLITE_TEMP_STORE -DSQLITE_TEMP_STORE=3 -USQLITE_THREADSAFE
4150
-DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOCALTIME -DSQLITE_OMIT_LOAD_EXTENSION -DLONGDOUBLE_TYPE=double".to_string()),

crates/spin-test-virt/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ spin-locked-app = { git = "https://github.com/spinframework/spin", rev = "9906b4
1515
spin-outbound-networking-config = { git = "https://github.com/spinframework/spin", rev = "9906b4e499e47bcc6ebff4e7fe70bb255a5f925d" }
1616
toml = { workspace = true }
1717
wit-bindgen-rt = { workspace = true }
18-
# rusqlite > 0.25 fails to build with various linker errors
19-
# rusqlite = { version = "0.25", features = ["bundled", "wasm32-wasi-vfs"] }
18+
rusqlite = { version = "0.36", features = ["bundled", "wasm32-wasi-vfs"] }
2019

2120

2221
[lib]

crates/spin-test-virt/src/lib.rs

Lines changed: 96 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -415,98 +415,95 @@ impl sqlite::Guest for Component {
415415
type Connection = SqliteConnection;
416416
}
417417

418-
// type ConnectionPool = HashMap<String, Arc<Mutex<rusqlite::Connection>>>;
419-
// static SQLITE_CONNECTION_POOL: std::sync::OnceLock<Mutex<ConnectionPool>> =
420-
// std::sync::OnceLock::new();
418+
type ConnectionPool = HashMap<String, Arc<Mutex<rusqlite::Connection>>>;
419+
static SQLITE_CONNECTION_POOL: std::sync::OnceLock<Mutex<ConnectionPool>> =
420+
std::sync::OnceLock::new();
421421

422422
struct SqliteConnection {
423-
// inner: Arc<Mutex<rusqlite::Connection>>,
423+
inner: Arc<Mutex<rusqlite::Connection>>,
424424
}
425425

426426
impl SqliteConnection {
427427
fn new(database: String) -> Result<Self, sqlite::Error> {
428-
Err(sqlite::Error::AccessDenied)
429-
// let conn = match SQLITE_CONNECTION_POOL
430-
// .get_or_init(Default::default)
431-
// .lock()
432-
// .unwrap()
433-
// .entry(database)
434-
// {
435-
// std::collections::hash_map::Entry::Occupied(c) => c.get().clone(),
436-
// std::collections::hash_map::Entry::Vacant(_) => {
437-
// let conn = rusqlite::Connection::open_in_memory()
438-
// .map_err(|e| sqlite::Error::Io(e.to_string()))?;
439-
// Arc::new(Mutex::new(conn))
440-
// }
441-
// };
442-
// Ok(Self { inner: conn })
428+
let conn = match SQLITE_CONNECTION_POOL
429+
.get_or_init(Default::default)
430+
.lock()
431+
.unwrap()
432+
.entry(database)
433+
{
434+
std::collections::hash_map::Entry::Occupied(c) => c.get().clone(),
435+
std::collections::hash_map::Entry::Vacant(_) => {
436+
let conn = rusqlite::Connection::open_in_memory()
437+
.map_err(|e| sqlite::Error::Io(e.to_string()))?;
438+
Arc::new(Mutex::new(conn))
439+
}
440+
};
441+
Ok(Self { inner: conn })
443442
}
444443

445444
fn execute(
446445
&self,
447446
statement: String,
448447
parameters: Vec<sqlite::Value>,
449448
) -> Result<sqlite::QueryResult, sqlite::Error> {
450-
Err(sqlite::Error::AccessDenied)
451-
// let conn = self.inner.lock().unwrap();
452-
// let mut prepared = conn
453-
// .prepare(&statement)
454-
// .map_err(|e| sqlite::Error::Io(e.to_string()))?;
455-
// let columns = prepared
456-
// .column_names()
457-
// .into_iter()
458-
// .map(String::from)
459-
// .collect();
460-
// let mut result = sqlite::QueryResult {
461-
// columns,
462-
// rows: vec![],
463-
// };
464-
// let params = parameters.into_iter().map(|v| match v {
465-
// sqlite::Value::Integer(i) => rusqlite::types::Value::Integer(i),
466-
// sqlite::Value::Real(r) => rusqlite::types::Value::Real(r),
467-
// sqlite::Value::Text(t) => rusqlite::types::Value::Text(t),
468-
// sqlite::Value::Blob(b) => rusqlite::types::Value::Blob(b),
469-
// sqlite::Value::Null => rusqlite::types::Value::Null,
470-
// });
471-
// let rows = prepared
472-
// .query_map(rusqlite::params_from_iter(params), |row| {
473-
// let mut values = Vec::new();
474-
// for i in 0..result.columns.len() {
475-
// let v = match row.get(i)? {
476-
// rusqlite::types::Value::Null => sqlite::Value::Null,
477-
// rusqlite::types::Value::Integer(i) => sqlite::Value::Integer(i),
478-
// rusqlite::types::Value::Real(f) => sqlite::Value::Real(f),
479-
// rusqlite::types::Value::Text(s) => sqlite::Value::Text(s),
480-
// rusqlite::types::Value::Blob(b) => sqlite::Value::Blob(b),
481-
// };
482-
// values.push(v);
483-
// }
484-
// Ok(sqlite::RowResult { values })
485-
// })
486-
// .map_err(|e| sqlite::Error::Io(e.to_string()))?;
487-
488-
// for row in rows {
489-
// result
490-
// .rows
491-
// .push(row.map_err(|e| sqlite::Error::Io(e.to_string()))?);
492-
// }
493-
// Ok(result)
449+
let conn = self.inner.lock().unwrap();
450+
let mut prepared = conn
451+
.prepare(&statement)
452+
.map_err(|e| sqlite::Error::Io(e.to_string()))?;
453+
let columns = prepared
454+
.column_names()
455+
.into_iter()
456+
.map(String::from)
457+
.collect();
458+
let mut result = sqlite::QueryResult {
459+
columns,
460+
rows: vec![],
461+
};
462+
let params = parameters.into_iter().map(|v| match v {
463+
sqlite::Value::Integer(i) => rusqlite::types::Value::Integer(i),
464+
sqlite::Value::Real(r) => rusqlite::types::Value::Real(r),
465+
sqlite::Value::Text(t) => rusqlite::types::Value::Text(t),
466+
sqlite::Value::Blob(b) => rusqlite::types::Value::Blob(b),
467+
sqlite::Value::Null => rusqlite::types::Value::Null,
468+
});
469+
let rows = prepared
470+
.query_map(rusqlite::params_from_iter(params), |row| {
471+
let mut values = Vec::new();
472+
for i in 0..result.columns.len() {
473+
let v = match row.get(i)? {
474+
rusqlite::types::Value::Null => sqlite::Value::Null,
475+
rusqlite::types::Value::Integer(i) => sqlite::Value::Integer(i),
476+
rusqlite::types::Value::Real(f) => sqlite::Value::Real(f),
477+
rusqlite::types::Value::Text(s) => sqlite::Value::Text(s),
478+
rusqlite::types::Value::Blob(b) => sqlite::Value::Blob(b),
479+
};
480+
values.push(v);
481+
}
482+
Ok(sqlite::RowResult { values })
483+
})
484+
.map_err(|e| sqlite::Error::Io(e.to_string()))?;
485+
486+
for row in rows {
487+
result
488+
.rows
489+
.push(row.map_err(|e| sqlite::Error::Io(e.to_string()))?);
490+
}
491+
Ok(result)
494492
}
495493
}
496494

497495
impl sqlite::GuestConnection for SqliteConnection {
498496
fn open(database: String) -> Result<sqlite::Connection, sqlite::Error> {
499-
Err(sqlite::Error::AccessDenied)
500-
// let component =
501-
// manifest::AppManifest::get_component().expect("component id has not been set");
502-
// let db = component
503-
// .sqlite_databases
504-
// .into_iter()
505-
// .find(|db| db == &database);
506-
// if db.is_none() {
507-
// return Err(sqlite::Error::AccessDenied);
508-
// }
509-
// Ok(sqlite::Connection::new(SqliteConnection::new(database)?))
497+
let component =
498+
manifest::AppManifest::get_component().expect("component id has not been set");
499+
let db = component
500+
.sqlite_databases
501+
.into_iter()
502+
.find(|db| db == &database);
503+
if db.is_none() {
504+
return Err(sqlite::Error::AccessDenied);
505+
}
506+
Ok(sqlite::Connection::new(SqliteConnection::new(database)?))
510507
}
511508

512509
fn execute(
@@ -540,31 +537,31 @@ impl spin_test_virt::sqlite::GuestConnection for SqliteConnection {
540537
}
541538
}
542539

543-
// impl std::hash::Hash for sqlite::Value {
544-
// fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
545-
// match self {
546-
// sqlite::Value::Null => 0.hash(state),
547-
// sqlite::Value::Integer(i) => i.hash(state),
548-
// sqlite::Value::Real(f) => f.to_bits().hash(state),
549-
// sqlite::Value::Text(s) => s.hash(state),
550-
// sqlite::Value::Blob(b) => b.hash(state),
551-
// }
552-
// }
553-
// }
554-
555-
// impl PartialEq for sqlite::Value {
556-
// fn eq(&self, other: &Self) -> bool {
557-
// match (self, other) {
558-
// (sqlite::Value::Null, sqlite::Value::Null) => true,
559-
// (sqlite::Value::Integer(a), sqlite::Value::Integer(b)) => a == b,
560-
// (sqlite::Value::Real(a), sqlite::Value::Real(b)) => a == b,
561-
// (sqlite::Value::Text(a), sqlite::Value::Text(b)) => a == b,
562-
// (sqlite::Value::Blob(a), sqlite::Value::Blob(b)) => a == b,
563-
// _ => false,
564-
// }
565-
// }
566-
// }
567-
// impl Eq for sqlite::Value {}
540+
impl std::hash::Hash for sqlite::Value {
541+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
542+
match self {
543+
sqlite::Value::Null => 0.hash(state),
544+
sqlite::Value::Integer(i) => i.hash(state),
545+
sqlite::Value::Real(f) => f.to_bits().hash(state),
546+
sqlite::Value::Text(s) => s.hash(state),
547+
sqlite::Value::Blob(b) => b.hash(state),
548+
}
549+
}
550+
}
551+
552+
impl PartialEq for sqlite::Value {
553+
fn eq(&self, other: &Self) -> bool {
554+
match (self, other) {
555+
(sqlite::Value::Null, sqlite::Value::Null) => true,
556+
(sqlite::Value::Integer(a), sqlite::Value::Integer(b)) => a == b,
557+
(sqlite::Value::Real(a), sqlite::Value::Real(b)) => a == b,
558+
(sqlite::Value::Text(a), sqlite::Value::Text(b)) => a == b,
559+
(sqlite::Value::Blob(a), sqlite::Value::Blob(b)) => a == b,
560+
_ => false,
561+
}
562+
}
563+
}
564+
impl Eq for sqlite::Value {}
568565

569566
impl mysql::Guest for Component {
570567
type Connection = MySqlConnection;

0 commit comments

Comments
 (0)