目的,想要在对JS能调用的invoke接口中提供持续的db connection对象,一开始想用比较简单粗暴的方式每次都重新连接一次本地的sqlite数据库,后来发现Tauri可以注入的功能,就有了以下的使用方法:
main.rs
use rusqlite::Connection; use tauri::State; use std::sync::Mutex; struct DbConnection { db: Mutex<Option<Connection>>, } // 注入的state会自动匹配声明的变量 #[tauri::command] fn query(some_param: i32, connection: State<DbConnection>) -> Vec<String> { println!("some_param={}", some_param); let db = connection.db.lock(); let conn = db.as_ref().unwrap().as_ref().unwrap(); let mut stmt = conn.prepare("SELECT name_en FROM books").unwrap(); let rows = stmt.query_map([], |row| row.get(0)).unwrap(); let mut names = Vec::new(); for name_result in rows { names.push(name_result.unwrap()); } names } fn main() { tauri::Builder::default() // 注入state .manage(DbConnection { db: Mutex::new(Some( Connection::open("./resources/db.sqlite").unwrap(), )), }) .invoke_handler(tauri::generate_handler![query]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
在React中使用接口:
App.tsx
import { invoke } from '@tauri-apps/api' import { FunctionComponent } from 'react' interface AppProps {} const App: FunctionComponent<AppProps> = () => { return ( <div className="tw-w-screen tw-h-screen"> <button onClick={async () => { const names = await invoke('query', { someParam: 123 }) console.log(names) }} > query3 </button> </div> ) } export default App
这样就能在所有的tauri接口中使用同一个db 的connection对象了!
文档:https://docs.rs/tauri/1.2.4/tauri/trait.Manager.html#method.manage