Comments (7)
I'm not sure that's actually possible, in general. SQLite's C API doesn't provide the equivalent of a "clone connection". To share an in-memory database, you have to open using a URI filename and enabled shared caching. We should definitely allow that, and I don't think we provide all the hooks necessary at the moment.
To the more general question of implementing Clone
- the only way I can think to do it would be to save off the path that a connection was opened with and attempt to open it again. That won't let us impl clone
though, since it might fail, or worse, it might succeed but not actually be a second connection to the same database.
Another possibility is to add a second connection type that implements Sync
which performs the open in Serialized mode.
from rusqlite.
Ah, I was afraid this was the case. Too bad, but I completely understand the reasoning.
Could you elaborate a bit on the second option? I don't see how Serialized mode and the Sync
trait are related, as Sync
allows threads to share a single connection and serialized mode makes concurrent connections play nice together.
from rusqlite.
Multi-thread mode (the second item on SQLite's threadsafety page) allows SQLite to be used from multiple threads as long as each thread uses its own connection. This is the level of multithreading that rusqlite currently assumes. The default threading mode (Serialized) allows a single connection to be shared and used from multiple threads simultaneously; this was added in SQLite 3.5 way back in 2007 - see the 3.5 Changelog, section 4.0.
Currently rusqlite doesn't really do anything special, and may even be unintentionally unsafe (e.g., if SQLite was compiled for single-threaded use only, rusqlite should not be used from multiple threads either.) I'm not sure what the right level of support / detail to provide is. Some options:
- Stick with the interface rusqlite currently has, which restricts connections to
Send
. We should perhaps add a check that the SQLite we link against wasn't compiled in single-threaded mode, although I could see an argument for not even doing that (if someone wants to use rusqlite with a single-threaded SQLite, that seems reasonable, but I don't know how to enforce the "you can't use rusqlite from multiple threads at all even with different connections" in Rust). - Provide different Rust connection handles for each of the three different SQLite threading modes. I don't think I want to do this, because it doesn't play nicely with people passing their own arguments to
open
(since open arguments can change the threading mode for that connection).
It is unfortunate that rusqlite may be more restrictive than SQLite, though, since in many cases the connection could be Sync
. Nontrivial changes on the Rust side would be necessary to support this (SqliteConnection
currently uses a RefCell
, for example), and some operations would become inherently racy (like last_insert_rowid()
).
What do you think?
from rusqlite.
@jgallagher would it be better to share the same connection through something like Arc<RwLock<T>>
?
EDIT as of Dec 17, 2015: suggestion won't work b/c of missing Sync
trait
from rusqlite.
You shouldn't be able to put a connection into an RwLock
and have it be usable from multiple threads because the connections don't implement Sync
. This will (correctly) fail to compile:
let locked = Arc::new(RwLock::new(SqliteConnection::open("foo.db").unwrap()));
thread::spawn(move || {
let db = locked.lock().unwrap();
// do something with db
});
Since Rust provides this kind of threading guarantee, our default flags for opening connections includes the SQLITE_OPEN_NOMUTEX
flag, which puts SQLite into multi-thread mode:
In this mode, SQLite can be safely used by multiple threads provided that no single database connection is used simultaneously in two or more threads.
We could always open SQLite in serialized mode and then impl Sync
for the connection, allowing it to be shared across threads, but that seems not ideal because we're forcing everyone to use SQLite's internal locking, even if they don't use the connection across multiple threads.
If you must share the same connection object, you can put it into an Arc<Mutex<_>>
(which obviously will only allow one thread at a time to do anything). A better solution is probably just to open multiple connections to the same database for each thread.
from rusqlite.
I'm going to go ahead and close this since the original issue (implementing Clone
for connections) isn't possible. If there are other threading issues, please open them!
from rusqlite.
@jgallagher ah yeah, I was learning the ropes of rust when I made the suggestion at https://github.com/jgallagher/rusqlite/issues/28#issuecomment-151867432. You pretty much described why it wouldn't work when I attempted it. I've edited my comment for any future github issue lurkers.
from rusqlite.
Related Issues (20)
- libsqlite3-sys fails to build on arm64: error[E0308]: mismatched types HOT 2
- release the latest version HOT 4
- FromSql vs TryFrom / ToSql vs TryInto HOT 1
- `sqlite3_compileoption_used` and Rust `const fn`
- called `Result::unwrap()` on an `Err` value: SqliteFailure(Error { code: Unknown, extended_code: 1 }, Some("json_object() requires an even number of arguments")) HOT 2
- Apps using `winsqlite3` feature no longer builds HOT 5
- Question: Is there any way to use SQLite 3.45 with rusqlite 0.30.0? HOT 2
- Trait for abstracting over `Connection`/`Transaction`? HOT 3
- SqlInputError { error: Error { code: Unknown, extended_code: 1 }, msg: "unrecognized token: \"{\"" HOT 1
- Release 0.31.0 with SQLite 3.45? HOT 2
- Type issue on select with digits only in a "string" colums. HOT 2
- wasm32-wasi target fails on Apple M3
- How to get "returning *" from insert HOT 3
- Stale Connection Handler on Multi-Threaded Situation HOT 1
- sqlite3_snapshot iteration HOT 2
- Creating `Value::Blob` without necessarily allocating heap HOT 5
- Using rusqlite::vtab::VTabConnection::handle() HOT 4
- Add bindings for `sqlite3_trace_v2` API HOT 4
- iOS Linker Warning: SQLite was build for newer version than being linked HOT 2
- the first query is failure due to below error HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rusqlite.