|
@@ -1,23 +1,26 @@
|
|
-pub mod migration;
|
|
|
|
-mod rusqlite_utils;
|
|
|
|
|
|
+pub mod migration; // 定义数据库迁移模块
|
|
|
|
+mod rusqlite_utils; // 定义一些辅助工具模块
|
|
|
|
|
|
-use anyhow::{anyhow, Result};
|
|
|
|
-use rusqlite::{types::Value as SqliteValue, Connection, OpenFlags, ToSql};
|
|
|
|
-use serde_json::Value as JsonValue;
|
|
|
|
-use std::collections::HashMap;
|
|
|
|
-use std::sync::{Arc, Mutex, RwLock};
|
|
|
|
|
|
+use anyhow::{anyhow, Result}; // 引入错误处理库
|
|
|
|
+use rusqlite::{types::Value as SqliteValue, Connection, OpenFlags, ToSql}; // 引入rusqlite库
|
|
|
|
+use serde_json::Value as JsonValue; // 引入JSON库
|
|
|
|
+use std::collections::HashMap; // 引入HashMap数据结构
|
|
|
|
+use std::sync::{Arc, Mutex, RwLock}; // 引入并发处理库
|
|
|
|
|
|
|
|
+// 定义一个全局的数据库连接缓存,使用RwLock进行读写锁定
|
|
lazy_static::lazy_static! {
|
|
lazy_static::lazy_static! {
|
|
pub(crate) static ref CONNECTIONS: RwLock<HashMap<String, Arc<Mutex<Connection>>>> =
|
|
pub(crate) static ref CONNECTIONS: RwLock<HashMap<String, Arc<Mutex<Connection>>>> =
|
|
RwLock::new(HashMap::new());
|
|
RwLock::new(HashMap::new());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 打开数据库连接
|
|
pub async fn open(path: &String) -> Result<Arc<Mutex<Connection>>> {
|
|
pub async fn open(path: &String) -> Result<Arc<Mutex<Connection>>> {
|
|
open_with_flags(path, OpenFlags::default()).await
|
|
open_with_flags(path, OpenFlags::default()).await
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 打开带有标志的数据库连接
|
|
pub async fn open_with_flags(path: &String, flags: OpenFlags) -> Result<Arc<Mutex<Connection>>> {
|
|
pub async fn open_with_flags(path: &String, flags: OpenFlags) -> Result<Arc<Mutex<Connection>>> {
|
|
- //判断是否已经打开
|
|
|
|
|
|
+ // 判断是否已经打开
|
|
let exist = CONNECTIONS.read().unwrap().contains_key(path);
|
|
let exist = CONNECTIONS.read().unwrap().contains_key(path);
|
|
|
|
|
|
if exist {
|
|
if exist {
|
|
@@ -27,18 +30,20 @@ pub async fn open_with_flags(path: &String, flags: OpenFlags) -> Result<Arc<Mute
|
|
Err(anyhow!("获取失败"))
|
|
Err(anyhow!("获取失败"))
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- //
|
|
|
|
|
|
+ // 构造数据库路径
|
|
let mut storage_path = crate::utils::system_tools_home_path()?.join("sqlite");
|
|
let mut storage_path = crate::utils::system_tools_home_path()?.join("sqlite");
|
|
storage_path.push(path.clone());
|
|
storage_path.push(path.clone());
|
|
|
|
|
|
let prefix = storage_path.parent().unwrap_or(storage_path.as_path());
|
|
let prefix = storage_path.parent().unwrap_or(storage_path.as_path());
|
|
std::fs::create_dir_all(prefix).map_err(|err| anyhow::anyhow!(err))?;
|
|
std::fs::create_dir_all(prefix).map_err(|err| anyhow::anyhow!(err))?;
|
|
|
|
|
|
|
|
+ // 打开数据库连接
|
|
let arc_conn = Arc::new(Mutex::new(Connection::open_with_flags(
|
|
let arc_conn = Arc::new(Mutex::new(Connection::open_with_flags(
|
|
&storage_path,
|
|
&storage_path,
|
|
flags,
|
|
flags,
|
|
)?));
|
|
)?));
|
|
|
|
|
|
|
|
+ // 将连接缓存
|
|
let mut cache = CONNECTIONS.write().unwrap();
|
|
let mut cache = CONNECTIONS.write().unwrap();
|
|
cache.insert(path.clone(), arc_conn.clone());
|
|
cache.insert(path.clone(), arc_conn.clone());
|
|
|
|
|
|
@@ -46,6 +51,7 @@ pub async fn open_with_flags(path: &String, flags: OpenFlags) -> Result<Arc<Mute
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 执行SQL语句
|
|
pub async fn execute_sql(path: &String, sql: &String) -> Result<usize> {
|
|
pub async fn execute_sql(path: &String, sql: &String) -> Result<usize> {
|
|
let arc_conn = open(path).await?;
|
|
let arc_conn = open(path).await?;
|
|
|
|
|
|
@@ -57,6 +63,7 @@ pub async fn execute_sql(path: &String, sql: &String) -> Result<usize> {
|
|
Ok(res)
|
|
Ok(res)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 关闭数据库连接
|
|
pub async fn close(path: &String) -> Result<bool> {
|
|
pub async fn close(path: &String) -> Result<bool> {
|
|
let arc_conn = open(path).await?;
|
|
let arc_conn = open(path).await?;
|
|
|
|
|
|
@@ -65,7 +72,7 @@ pub async fn close(path: &String) -> Result<bool> {
|
|
.map_err(|err| anyhow!("lock数据库连接失败:{}", err))?;
|
|
.map_err(|err| anyhow!("lock数据库连接失败:{}", err))?;
|
|
|
|
|
|
drop(conn);
|
|
drop(conn);
|
|
- //移除
|
|
|
|
|
|
+ // 移除缓存
|
|
let mut cache = CONNECTIONS
|
|
let mut cache = CONNECTIONS
|
|
.write()
|
|
.write()
|
|
.map_err(|err| anyhow!("获取锁失败:{}", err))?;
|
|
.map_err(|err| anyhow!("获取锁失败:{}", err))?;
|
|
@@ -74,6 +81,7 @@ pub async fn close(path: &String) -> Result<bool> {
|
|
Ok(true)
|
|
Ok(true)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 批量执行SQL语句
|
|
pub async fn execute_batch(path: &String, sql: &String) -> Result<bool> {
|
|
pub async fn execute_batch(path: &String, sql: &String) -> Result<bool> {
|
|
let arc_conn = open(path).await?;
|
|
let arc_conn = open(path).await?;
|
|
|
|
|
|
@@ -85,6 +93,7 @@ pub async fn execute_batch(path: &String, sql: &String) -> Result<bool> {
|
|
Ok(true)
|
|
Ok(true)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 执行带参数的SQL语句
|
|
pub async fn execute(path: &String, sql: &String, args: &JsonValue) -> Result<usize> {
|
|
pub async fn execute(path: &String, sql: &String, args: &JsonValue) -> Result<usize> {
|
|
let arc_conn = open(path).await?;
|
|
let arc_conn = open(path).await?;
|
|
|
|
|
|
@@ -92,13 +101,13 @@ pub async fn execute(path: &String, sql: &String, args: &JsonValue) -> Result<us
|
|
.lock()
|
|
.lock()
|
|
.map_err(|err| anyhow!("lock数据库连接失败:{}", err))?;
|
|
.map_err(|err| anyhow!("lock数据库连接失败:{}", err))?;
|
|
|
|
|
|
|
|
+ // 将参数转换为SQLite的值
|
|
let mut args_sqlite_values = HashMap::<String, SqliteValue>::new();
|
|
let mut args_sqlite_values = HashMap::<String, SqliteValue>::new();
|
|
let mut named_args: Vec<(&str, &dyn ToSql)> = vec![];
|
|
let mut named_args: Vec<(&str, &dyn ToSql)> = vec![];
|
|
|
|
|
|
if let JsonValue::Object(json_value) = args {
|
|
if let JsonValue::Object(json_value) = args {
|
|
for (k, v) in json_value {
|
|
for (k, v) in json_value {
|
|
args_sqlite_values.insert(k.clone(), rusqlite_utils::value_to_rusqlite_value(v)?);
|
|
args_sqlite_values.insert(k.clone(), rusqlite_utils::value_to_rusqlite_value(v)?);
|
|
- //
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -110,6 +119,7 @@ pub async fn execute(path: &String, sql: &String, args: &JsonValue) -> Result<us
|
|
return Ok(res);
|
|
return Ok(res);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 执行带参数的查询语句
|
|
pub async fn query_with_args(
|
|
pub async fn query_with_args(
|
|
path: &String,
|
|
path: &String,
|
|
sql: &String,
|
|
sql: &String,
|
|
@@ -150,9 +160,8 @@ pub async fn query_with_args(
|
|
|
|
|
|
for table_result in schema_iter {
|
|
for table_result in schema_iter {
|
|
if let Ok(row_value) = table_result {
|
|
if let Ok(row_value) = table_result {
|
|
- //
|
|
|
|
result.push(row_value);
|
|
result.push(row_value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Ok(result)
|
|
Ok(result)
|
|
-}
|
|
|
|
|
|
+}
|