For years, SQLite has been my go-to solution for storing any kind of structured local data for apps. The ability to update multiple pieces of data in a transaction has been extremely useful.
Naturally, when building my app in Tauri, I wanted to use SQLite from my Rust backend code.
A bit of poking around led toRusqlite for an ergonomic SQLite wrapper.
But there's a couple other questions to answer in order to tie it in with Tauri.
Where do you store the SQLite file?
Insidesetup()
we can create an app handle and callapp_handle.path_resolver().app_data_dir()
. That's the designated place to store our app data. From there we can initialize our DB file.
How do we access theConnection
from a Tauri command?
Tauri has a built-in ability to store app state. We'll set up struct to hold it:
pubstructAppState{pubdb:std::sync::Mutex<Option<Connection>>,}
The Mutex protects access to the connection object. The idea is that you get theConnection
, run a query on it, then release the Mutex.
Insetup()
we can populate this app state with the DB connection.
letapp_state:State<AppState>=handle.state();*app_state.db.lock().unwrap()=Some(db);
We can also add a convenience trait to easily access theConnection
object without jumping through theState
fetch andMutex
lock.
pubtraitServiceAccess{fndb<F,TResult>(&self,operation:F)->TResultwhereF:FnOnce(&Connection)->TResult;}implServiceAccessforAppHandle{fndb<F,TResult>(&self,operation:F)->TResultwhereF:FnOnce(&Connection)->TResult{letapp_state:State<AppState>=self.state();letdb_connection_guard=app_state.db.lock().unwrap();letdb=db_connection_guard.as_ref().unwrap();operation(db)}}
Inside Tauri commands we can supply aapp_handle: AppHandle
argument, which will be automatically populated by the Tauri framework. From there we can call ourdb()
trait method onapp_handle
to do database operations. Anything returned from the closure will be passed through.
letmy_result=app_handle.db(|db:&Connection|{/* Do something with the DB connection and return a value */});
I pass theAppHandle
through to any other modules that need it, so they also have access to theConnection
. You can also callapp_handle.clone()
in case you run into ownership issues.
Full example code
Top comments(3)

Tauri has a sqlite plugin at "github.com/tauri-apps/tauri-plugin...".
Could you make a post using the plugin as an update to this?

github.com/tauri-apps/plugins-work...
tauri plugin for sql haven't the feature yet to be called from backend side, hope this will be implemented soon

- LocationFlorianópolis, Brazil
- EducationFederal University of Santa Catarina
- WorkBackend Engineer at Clevertech
- Joined
Exactly, this is the main reason I'm not using tauri plugin.
Nice article, it was very helpful.
For further actions, you may consider blocking this person and/orreporting abuse