Skip to content

Commit 6f8c357

Browse files
committed
refactor(sqlite): make background thread responsible for all FFI calls
1 parent b3091b0 commit 6f8c357

26 files changed

+1490
-1032
lines changed

Cargo.lock

+79-35
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ paste = "1.0.1"
150150
serde = { version = "1.0.111", features = ["derive"] }
151151
serde_json = "1.0.53"
152152
url = "2.1.1"
153-
153+
rand = "0.8.4"
154+
rand_xoshiro = "0.6.0"
155+
hex = "0.4"
154156
#
155157
# Any
156158
#

sqlx-core/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mysql = [
4343
"rand",
4444
"rsa",
4545
]
46-
sqlite = ["libsqlite3-sys"]
46+
sqlite = ["libsqlite3-sys", "futures-executor", "flume"]
4747
mssql = ["uuid", "encoding_rs", "regex"]
4848
any = []
4949

@@ -122,6 +122,9 @@ futures-channel = { version = "0.3.5", default-features = false, features = ["si
122122
futures-core = { version = "0.3.5", default-features = false }
123123
futures-intrusive = "0.4.0"
124124
futures-util = { version = "0.3.5", default-features = false, features = ["alloc", "sink"] }
125+
# used by the SQLite worker thread to block on the async mutex that locks the database handle
126+
futures-executor = { version = "0.3.17", optional = true }
127+
flume = { version = "0.10.9", optional = true, default-features = false, features = ["async"] }
125128
generic-array = { version = "0.14.4", default-features = false, optional = true }
126129
hex = "0.4.2"
127130
hmac = { version = "0.11.0", default-features = false, optional = true }

sqlx-core/src/common/mod.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
11
mod statement_cache;
22

33
pub(crate) use statement_cache::StatementCache;
4+
use std::fmt::{Debug, Formatter};
5+
use std::ops::{Deref, DerefMut};
6+
7+
/// A wrapper for `Fn`s that provides a debug impl that just says "Function"
8+
pub(crate) struct DebugFn<F: ?Sized>(pub F);
9+
10+
impl<F: ?Sized> Deref for DebugFn<F> {
11+
type Target = F;
12+
13+
fn deref(&self) -> &Self::Target {
14+
&self.0
15+
}
16+
}
17+
18+
impl<F: ?Sized> DerefMut for DebugFn<F> {
19+
fn deref_mut(&mut self) -> &mut Self::Target {
20+
&mut self.0
21+
}
22+
}
23+
24+
impl<F: ?Sized> Debug for DebugFn<F> {
25+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26+
f.debug_tuple("Function").finish()
27+
}
28+
}

sqlx-core/src/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum Error {
3939
Database(#[source] Box<dyn DatabaseError>),
4040

4141
/// Error communicating with the database backend.
42-
#[error("error communicating with the server: {0}")]
42+
#[error("error communicating with database: {0}")]
4343
Io(#[from] io::Error),
4444

4545
/// Error occurred while attempting to establish a TLS connection.

sqlx-core/src/sqlite/arguments.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ impl<'q> SqliteArguments<'q> {
3131
self.values.push(SqliteArgumentValue::Null);
3232
}
3333
}
34+
35+
pub(crate) fn into_static(self) -> SqliteArguments<'static> {
36+
SqliteArguments {
37+
values: self
38+
.values
39+
.into_iter()
40+
.map(SqliteArgumentValue::into_static)
41+
.collect(),
42+
}
43+
}
3444
}
3545

3646
impl<'q> Arguments<'q> for SqliteArguments<'q> {
@@ -49,7 +59,7 @@ impl<'q> Arguments<'q> for SqliteArguments<'q> {
4959
}
5060

5161
impl SqliteArguments<'_> {
52-
pub(super) fn bind(&self, handle: &StatementHandle, offset: usize) -> Result<usize, Error> {
62+
pub(super) fn bind(&self, handle: &mut StatementHandle, offset: usize) -> Result<usize, Error> {
5363
let mut arg_i = offset;
5464
// for handle in &statement.handles {
5565

@@ -95,7 +105,20 @@ impl SqliteArguments<'_> {
95105
}
96106

97107
impl SqliteArgumentValue<'_> {
98-
fn bind(&self, handle: &StatementHandle, i: usize) -> Result<(), Error> {
108+
fn into_static(self) -> SqliteArgumentValue<'static> {
109+
use SqliteArgumentValue::*;
110+
111+
match self {
112+
Null => Null,
113+
Text(text) => Text(text.into_owned().into()),
114+
Blob(blob) => Blob(blob.into_owned().into()),
115+
Int(v) => Int(v),
116+
Int64(v) => Int64(v),
117+
Double(v) => Double(v),
118+
}
119+
}
120+
121+
fn bind(&self, handle: &mut StatementHandle, i: usize) -> Result<(), Error> {
99122
use SqliteArgumentValue::*;
100123

101124
let status = match self {

0 commit comments

Comments
 (0)