feat: run rustfmt with custom defined fmt configuration (#1848)

* chore: update rustfmt

* chore: apply rustfmt format
This commit is contained in:
Nathan.fooo
2023-02-13 09:29:49 +08:00
committed by GitHub
parent e2496e734c
commit 6bb1c4e89c
459 changed files with 50554 additions and 46600 deletions

View File

@ -6,182 +6,182 @@ use lazy_static::lazy_static;
use std::{path::Path, sync::RwLock};
macro_rules! impl_get_func {
(
(
$func_name:ident,
$get_method:ident=>$target:ident
) => {
#[allow(dead_code)]
pub fn $func_name(k: &str) -> Option<$target> {
match KV::get(k) {
Ok(item) => item.$get_method,
Err(_) => None,
}
}
};
#[allow(dead_code)]
pub fn $func_name(k: &str) -> Option<$target> {
match KV::get(k) {
Ok(item) => item.$get_method,
Err(_) => None,
}
}
};
}
macro_rules! impl_set_func {
($func_name:ident,$set_method:ident,$key_type:ident) => {
#[allow(dead_code)]
pub fn $func_name(key: &str, value: $key_type) {
let mut item = KeyValue::new(key);
item.$set_method = Some(value);
match KV::set(item) {
Ok(_) => {}
Err(e) => {
tracing::error!("{:?}", e)
}
};
}
};
($func_name:ident,$set_method:ident,$key_type:ident) => {
#[allow(dead_code)]
pub fn $func_name(key: &str, value: $key_type) {
let mut item = KeyValue::new(key);
item.$set_method = Some(value);
match KV::set(item) {
Ok(_) => {},
Err(e) => {
tracing::error!("{:?}", e)
},
};
}
};
}
const DB_NAME: &str = "kv.db";
lazy_static! {
static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV::new());
static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV::new());
}
pub struct KV {
database: Option<Database>,
database: Option<Database>,
}
impl KV {
fn new() -> Self {
KV { database: None }
fn new() -> Self {
KV { database: None }
}
fn set(value: KeyValue) -> Result<(), String> {
// tracing::trace!("[KV]: set value: {:?}", value);
let _ = diesel::replace_into(kv_table::table)
.values(&value)
.execute(&*(get_connection()?))
.map_err(|e| format!("KV set error: {:?}", e))?;
Ok(())
}
fn get(key: &str) -> Result<KeyValue, String> {
let conn = get_connection()?;
let value = dsl::kv_table
.filter(kv_table::key.eq(key))
.first::<KeyValue>(&*conn)
.map_err(|e| format!("KV get error: {:?}", e))?;
Ok(value)
}
#[allow(dead_code)]
pub fn remove(key: &str) -> Result<(), String> {
// tracing::debug!("remove key: {}", key);
let conn = get_connection()?;
let sql = dsl::kv_table.filter(kv_table::key.eq(key));
let _ = diesel::delete(sql)
.execute(&*conn)
.map_err(|e| format!("KV remove error: {:?}", e))?;
Ok(())
}
#[tracing::instrument(level = "trace", err)]
pub fn init(root: &str) -> Result<(), String> {
if !Path::new(root).exists() {
return Err(format!("Init KVStore failed. {} not exists", root));
}
fn set(value: KeyValue) -> Result<(), String> {
// tracing::trace!("[KV]: set value: {:?}", value);
let _ = diesel::replace_into(kv_table::table)
.values(&value)
.execute(&*(get_connection()?))
.map_err(|e| format!("KV set error: {:?}", e))?;
let pool_config = PoolConfig::default();
let database = Database::new(root, DB_NAME, pool_config).unwrap();
let conn = database.get_connection().unwrap();
SqliteConnection::execute(&*conn, KV_SQL).unwrap();
Ok(())
let mut store = KV_HOLDER
.write()
.map_err(|e| format!("KVStore write failed: {:?}", e))?;
tracing::trace!("Init kv with path: {}", root);
store.database = Some(database);
Ok(())
}
pub fn get_bool(key: &str) -> bool {
match KV::get(key) {
Ok(item) => item.bool_value.unwrap_or(false),
Err(_) => false,
}
}
fn get(key: &str) -> Result<KeyValue, String> {
let conn = get_connection()?;
let value = dsl::kv_table
.filter(kv_table::key.eq(key))
.first::<KeyValue>(&*conn)
.map_err(|e| format!("KV get error: {:?}", e))?;
impl_set_func!(set_str, str_value, String);
Ok(value)
}
impl_set_func!(set_bool, bool_value, bool);
#[allow(dead_code)]
pub fn remove(key: &str) -> Result<(), String> {
// tracing::debug!("remove key: {}", key);
let conn = get_connection()?;
let sql = dsl::kv_table.filter(kv_table::key.eq(key));
let _ = diesel::delete(sql)
.execute(&*conn)
.map_err(|e| format!("KV remove error: {:?}", e))?;
Ok(())
}
impl_set_func!(set_int, int_value, i64);
#[tracing::instrument(level = "trace", err)]
pub fn init(root: &str) -> Result<(), String> {
if !Path::new(root).exists() {
return Err(format!("Init KVStore failed. {} not exists", root));
}
impl_set_func!(set_float, float_value, f64);
let pool_config = PoolConfig::default();
let database = Database::new(root, DB_NAME, pool_config).unwrap();
let conn = database.get_connection().unwrap();
SqliteConnection::execute(&*conn, KV_SQL).unwrap();
impl_get_func!(get_str,str_value=>String);
let mut store = KV_HOLDER
.write()
.map_err(|e| format!("KVStore write failed: {:?}", e))?;
tracing::trace!("Init kv with path: {}", root);
store.database = Some(database);
impl_get_func!(get_int,int_value=>i64);
Ok(())
}
pub fn get_bool(key: &str) -> bool {
match KV::get(key) {
Ok(item) => item.bool_value.unwrap_or(false),
Err(_) => false,
}
}
impl_set_func!(set_str, str_value, String);
impl_set_func!(set_bool, bool_value, bool);
impl_set_func!(set_int, int_value, i64);
impl_set_func!(set_float, float_value, f64);
impl_get_func!(get_str,str_value=>String);
impl_get_func!(get_int,int_value=>i64);
impl_get_func!(get_float,float_value=>f64);
impl_get_func!(get_float,float_value=>f64);
}
fn get_connection() -> Result<DBConnection, String> {
match KV_HOLDER.read() {
Ok(store) => {
let conn = store
.database
.as_ref()
.expect("KVStore is not init")
.get_connection()
.map_err(|e| format!("KVStore error: {:?}", e))?;
Ok(conn)
}
Err(e) => {
let msg = format!("KVStore get connection failed: {:?}", e);
tracing::error!("{:?}", msg);
Err(msg)
}
}
match KV_HOLDER.read() {
Ok(store) => {
let conn = store
.database
.as_ref()
.expect("KVStore is not init")
.get_connection()
.map_err(|e| format!("KVStore error: {:?}", e))?;
Ok(conn)
},
Err(e) => {
let msg = format!("KVStore get connection failed: {:?}", e);
tracing::error!("{:?}", msg);
Err(msg)
},
}
}
#[derive(Clone, Debug, Default, Queryable, Identifiable, Insertable, AsChangeset)]
#[table_name = "kv_table"]
#[primary_key(key)]
pub struct KeyValue {
pub key: String,
pub str_value: Option<String>,
pub int_value: Option<i64>,
pub float_value: Option<f64>,
pub bool_value: Option<bool>,
pub key: String,
pub str_value: Option<String>,
pub int_value: Option<i64>,
pub float_value: Option<f64>,
pub bool_value: Option<bool>,
}
impl KeyValue {
pub fn new(key: &str) -> Self {
KeyValue {
key: key.to_string(),
..Default::default()
}
pub fn new(key: &str) -> Self {
KeyValue {
key: key.to_string(),
..Default::default()
}
}
}
#[cfg(test)]
mod tests {
use crate::kv::KV;
use crate::kv::KV;
#[test]
fn kv_store_test() {
let dir = "./temp/";
if !std::path::Path::new(dir).exists() {
std::fs::create_dir_all(dir).unwrap();
}
KV::init(dir).unwrap();
KV::set_str("1", "hello".to_string());
assert_eq!(KV::get_str("1").unwrap(), "hello");
assert_eq!(KV::get_str("2"), None);
KV::set_bool("1", true);
assert!(KV::get_bool("1"));
assert!(!KV::get_bool("2"));
#[test]
fn kv_store_test() {
let dir = "./temp/";
if !std::path::Path::new(dir).exists() {
std::fs::create_dir_all(dir).unwrap();
}
KV::init(dir).unwrap();
KV::set_str("1", "hello".to_string());
assert_eq!(KV::get_str("1").unwrap(), "hello");
assert_eq!(KV::get_str("2"), None);
KV::set_bool("1", true);
assert!(KV::get_bool("1"));
assert!(!KV::get_bool("2"));
}
}

View File

@ -22,34 +22,34 @@ extern crate diesel_migrations;
pub type Error = diesel::result::Error;
pub mod prelude {
pub use super::UserDatabaseConnection;
pub use crate::*;
pub use diesel::SqliteConnection;
pub use diesel::{query_dsl::*, BelongingToDsl, ExpressionMethods, RunQueryDsl};
pub use super::UserDatabaseConnection;
pub use crate::*;
pub use diesel::SqliteConnection;
pub use diesel::{query_dsl::*, BelongingToDsl, ExpressionMethods, RunQueryDsl};
}
embed_migrations!("../flowy-sqlite/migrations/");
pub const DB_NAME: &str = "flowy-database.db";
pub fn init(storage_path: &str) -> Result<Database, io::Error> {
if !Path::new(storage_path).exists() {
std::fs::create_dir_all(storage_path)?;
}
let pool_config = PoolConfig::default();
let database = Database::new(storage_path, DB_NAME, pool_config).map_err(as_io_error)?;
let conn = database.get_connection().map_err(as_io_error)?;
embedded_migrations::run(&*conn).map_err(as_io_error)?;
Ok(database)
if !Path::new(storage_path).exists() {
std::fs::create_dir_all(storage_path)?;
}
let pool_config = PoolConfig::default();
let database = Database::new(storage_path, DB_NAME, pool_config).map_err(as_io_error)?;
let conn = database.get_connection().map_err(as_io_error)?;
embedded_migrations::run(&*conn).map_err(as_io_error)?;
Ok(database)
}
fn as_io_error<E>(e: E) -> io::Error
where
E: Into<crate::sqlite::Error> + Debug,
E: Into<crate::sqlite::Error> + Debug,
{
let msg = format!("{:?}", e);
io::Error::new(io::ErrorKind::NotConnected, msg)
let msg = format!("{:?}", e);
io::Error::new(io::ErrorKind::NotConnected, msg)
}
pub trait UserDatabaseConnection: Send + Sync {
fn get_connection(&self) -> Result<DBConnection, String>;
fn get_connection(&self) -> Result<DBConnection, String>;
}

View File

@ -48,166 +48,173 @@ macro_rules! diesel_insert_table {
#[macro_export]
macro_rules! diesel_record_count {
(
(
$table_name:ident,
$id:expr,
$connection:expr
) => {
$table_name::dsl::$table_name
.filter($table_name::dsl::id.eq($id.clone()))
.count()
.get_result($connection)
.unwrap_or(0);
};
$table_name::dsl::$table_name
.filter($table_name::dsl::id.eq($id.clone()))
.count()
.get_result($connection)
.unwrap_or(0);
};
}
#[macro_export]
macro_rules! diesel_revision_record_count {
(
(
$table_name:expr,
$filter:expr,
$connection:expr
) => {
$table_name
.filter($table_name::dsl::id.eq($id))
.count()
.get_result($connection)
.unwrap_or(0);
};
$table_name
.filter($table_name::dsl::id.eq($id))
.count()
.get_result($connection)
.unwrap_or(0);
};
}
#[macro_export]
macro_rules! diesel_update_table {
(
(
$table_name:ident,
$changeset:expr,
$connection:expr
) => {{
let filter = $table_name::dsl::$table_name.filter($table_name::dsl::id.eq($changeset.id.clone()));
let affected_row = diesel::update(filter).set($changeset).execute($connection)?;
debug_assert_eq!(affected_row, 1);
}};
let filter =
$table_name::dsl::$table_name.filter($table_name::dsl::id.eq($changeset.id.clone()));
let affected_row = diesel::update(filter)
.set($changeset)
.execute($connection)?;
debug_assert_eq!(affected_row, 1);
}};
}
#[macro_export]
macro_rules! diesel_delete_table {
(
(
$table_name:ident,
$id:ident,
$connection:ident
) => {
let filter = $table_name::dsl::$table_name.filter($table_name::dsl::id.eq($id));
let affected_row = diesel::delete(filter).execute(&*$connection)?;
debug_assert_eq!(affected_row, 1);
};
let filter = $table_name::dsl::$table_name.filter($table_name::dsl::id.eq($id));
let affected_row = diesel::delete(filter).execute(&*$connection)?;
debug_assert_eq!(affected_row, 1);
};
}
#[macro_export]
macro_rules! impl_sql_binary_expression {
($target:ident) => {
impl diesel::serialize::ToSql<diesel::sql_types::Binary, diesel::sqlite::Sqlite> for $target {
fn to_sql<W: std::io::Write>(
&self,
out: &mut diesel::serialize::Output<W, diesel::sqlite::Sqlite>,
) -> diesel::serialize::Result {
let bytes: Vec<u8> = self.try_into().map_err(|e| format!("{:?}", e))?;
diesel::serialize::ToSql::<diesel::sql_types::Binary, diesel::sqlite::Sqlite>::to_sql(&bytes, out)
}
}
// https://docs.diesel.rs/src/diesel/sqlite/types/mod.rs.html#30-33
// impl FromSql<sql_types::Binary, Sqlite> for *const [u8] {
// fn from_sql(bytes: Option<&SqliteValue>) -> deserialize::Result<Self> {
// let bytes = not_none!(bytes).read_blob();
// Ok(bytes as *const _)
// }
// }
impl<DB> diesel::deserialize::FromSql<diesel::sql_types::Binary, DB> for $target
where
DB: diesel::backend::Backend,
*const [u8]: diesel::deserialize::FromSql<diesel::sql_types::Binary, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
let slice_ptr =
<*const [u8] as diesel::deserialize::FromSql<diesel::sql_types::Binary, DB>>::from_sql(bytes)?;
let bytes = unsafe { &*slice_ptr };
($target:ident) => {
impl diesel::serialize::ToSql<diesel::sql_types::Binary, diesel::sqlite::Sqlite> for $target {
fn to_sql<W: std::io::Write>(
&self,
out: &mut diesel::serialize::Output<W, diesel::sqlite::Sqlite>,
) -> diesel::serialize::Result {
let bytes: Vec<u8> = self.try_into().map_err(|e| format!("{:?}", e))?;
diesel::serialize::ToSql::<diesel::sql_types::Binary, diesel::sqlite::Sqlite>::to_sql(
&bytes, out,
)
}
}
// https://docs.diesel.rs/src/diesel/sqlite/types/mod.rs.html#30-33
// impl FromSql<sql_types::Binary, Sqlite> for *const [u8] {
// fn from_sql(bytes: Option<&SqliteValue>) -> deserialize::Result<Self> {
// let bytes = not_none!(bytes).read_blob();
// Ok(bytes as *const _)
// }
// }
impl<DB> diesel::deserialize::FromSql<diesel::sql_types::Binary, DB> for $target
where
DB: diesel::backend::Backend,
*const [u8]: diesel::deserialize::FromSql<diesel::sql_types::Binary, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
let slice_ptr = <*const [u8] as diesel::deserialize::FromSql<
diesel::sql_types::Binary,
DB,
>>::from_sql(bytes)?;
let bytes = unsafe { &*slice_ptr };
match $target::try_from(bytes) {
Ok(object) => Ok(object),
Err(e) => {
log::error!(
"{:?} deserialize from bytes fail. {:?}",
std::any::type_name::<$target>(),
e
);
panic!();
}
}
}
match $target::try_from(bytes) {
Ok(object) => Ok(object),
Err(e) => {
log::error!(
"{:?} deserialize from bytes fail. {:?}",
std::any::type_name::<$target>(),
e
);
panic!();
},
}
};
}
}
};
}
#[macro_export]
macro_rules! impl_sql_integer_expression {
($target:ident) => {
impl<DB> diesel::serialize::ToSql<Integer, DB> for $target
where
DB: diesel::backend::Backend,
i32: diesel::serialize::ToSql<Integer, DB>,
{
fn to_sql<W: std::io::Write>(
&self,
out: &mut diesel::serialize::Output<W, DB>,
) -> diesel::serialize::Result {
(*self as i32).to_sql(out)
}
}
($target:ident) => {
impl<DB> diesel::serialize::ToSql<Integer, DB> for $target
where
DB: diesel::backend::Backend,
i32: diesel::serialize::ToSql<Integer, DB>,
{
fn to_sql<W: std::io::Write>(
&self,
out: &mut diesel::serialize::Output<W, DB>,
) -> diesel::serialize::Result {
(*self as i32).to_sql(out)
}
}
impl<DB> diesel::deserialize::FromSql<Integer, DB> for $target
where
DB: diesel::backend::Backend,
i32: diesel::deserialize::FromSql<Integer, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
let smaill_int = i32::from_sql(bytes)?;
Ok($target::from(smaill_int))
}
}
};
impl<DB> diesel::deserialize::FromSql<Integer, DB> for $target
where
DB: diesel::backend::Backend,
i32: diesel::deserialize::FromSql<Integer, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
let smaill_int = i32::from_sql(bytes)?;
Ok($target::from(smaill_int))
}
}
};
}
#[macro_export]
macro_rules! impl_rev_state_map {
($target:ident) => {
impl std::convert::From<i32> for $target {
fn from(value: i32) -> Self {
match value {
0 => $target::Sync,
1 => $target::Ack,
o => {
tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o);
$target::Sync
}
}
}
($target:ident) => {
impl std::convert::From<i32> for $target {
fn from(value: i32) -> Self {
match value {
0 => $target::Sync,
1 => $target::Ack,
o => {
tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o);
$target::Sync
},
}
}
}
impl std::convert::From<$target> for RevisionState {
fn from(s: $target) -> Self {
match s {
$target::Sync => RevisionState::Sync,
$target::Ack => RevisionState::Ack,
}
}
impl std::convert::From<$target> for RevisionState {
fn from(s: $target) -> Self {
match s {
$target::Sync => RevisionState::Sync,
$target::Ack => RevisionState::Ack,
}
}
}
impl std::convert::From<RevisionState> for $target {
fn from(s: RevisionState) -> Self {
match s {
RevisionState::Sync => $target::Sync,
RevisionState::Ack => $target::Ack,
}
}
impl std::convert::From<RevisionState> for $target {
fn from(s: RevisionState) -> Self {
match s {
RevisionState::Sync => $target::Sync,
RevisionState::Ack => $target::Ack,
}
};
}
}
};
}

View File

@ -178,20 +178,20 @@ diesel::table! {
}
diesel::allow_tables_to_appear_in_same_query!(
app_table,
document_rev_snapshot,
document_rev_table,
folder_rev_snapshot,
grid_block_index_table,
grid_meta_rev_table,
grid_rev_snapshot,
grid_rev_table,
grid_view_rev_table,
kv_table,
rev_snapshot,
rev_table,
trash_table,
user_table,
view_table,
workspace_table,
app_table,
document_rev_snapshot,
document_rev_table,
folder_rev_snapshot,
grid_block_index_table,
grid_meta_rev_table,
grid_rev_snapshot,
grid_rev_table,
grid_view_rev_table,
kv_table,
rev_snapshot,
rev_table,
trash_table,
user_table,
view_table,
workspace_table,
);

View File

@ -1,23 +1,25 @@
use crate::sqlite::errors::*;
use diesel::{dsl::sql, expression::SqlLiteral, query_dsl::LoadQuery, Connection, RunQueryDsl, SqliteConnection};
use diesel::{
dsl::sql, expression::SqlLiteral, query_dsl::LoadQuery, Connection, RunQueryDsl, SqliteConnection,
};
pub trait ConnectionExtension: Connection {
fn query<ST, T>(&self, query: &str) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>;
fn query<ST, T>(&self, query: &str) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>;
fn exec(&self, query: impl AsRef<str>) -> Result<usize>;
fn exec(&self, query: impl AsRef<str>) -> Result<usize>;
}
impl ConnectionExtension for SqliteConnection {
fn query<ST, T>(&self, query: &str) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
Ok(sql::<ST>(query).get_result(self)?)
}
fn query<ST, T>(&self, query: &str) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
Ok(sql::<ST>(query).get_result(self)?)
}
fn exec(&self, query: impl AsRef<str>) -> Result<usize> {
Ok(SqliteConnection::execute(self, query.as_ref())?)
}
fn exec(&self, query: impl AsRef<str>) -> Result<usize> {
Ok(SqliteConnection::execute(self, query.as_ref())?)
}
}

View File

@ -1,53 +1,53 @@
use crate::sqlite::{
errors::*,
pool::{ConnectionManager, ConnectionPool, PoolConfig},
errors::*,
pool::{ConnectionManager, ConnectionPool, PoolConfig},
};
use r2d2::PooledConnection;
use std::sync::Arc;
pub struct Database {
uri: String,
pool: Arc<ConnectionPool>,
uri: String,
pool: Arc<ConnectionPool>,
}
pub type DBConnection = PooledConnection<ConnectionManager>;
impl Database {
pub fn new(dir: &str, name: &str, pool_config: PoolConfig) -> Result<Self> {
let uri = db_file_uri(dir, name);
pub fn new(dir: &str, name: &str, pool_config: PoolConfig) -> Result<Self> {
let uri = db_file_uri(dir, name);
if !std::path::PathBuf::from(dir).exists() {
tracing::error!("Create database failed. {} not exists", &dir);
}
let pool = ConnectionPool::new(pool_config, &uri)?;
Ok(Self {
uri,
pool: Arc::new(pool),
})
if !std::path::PathBuf::from(dir).exists() {
tracing::error!("Create database failed. {} not exists", &dir);
}
pub fn get_uri(&self) -> &str {
&self.uri
}
let pool = ConnectionPool::new(pool_config, &uri)?;
Ok(Self {
uri,
pool: Arc::new(pool),
})
}
pub fn get_connection(&self) -> Result<DBConnection> {
let conn = self.pool.get()?;
Ok(conn)
}
pub fn get_uri(&self) -> &str {
&self.uri
}
pub fn get_pool(&self) -> Arc<ConnectionPool> {
self.pool.clone()
}
pub fn get_connection(&self) -> Result<DBConnection> {
let conn = self.pool.get()?;
Ok(conn)
}
pub fn get_pool(&self) -> Arc<ConnectionPool> {
self.pool.clone()
}
}
pub fn db_file_uri(dir: &str, name: &str) -> String {
use std::path::MAIN_SEPARATOR;
use std::path::MAIN_SEPARATOR;
let mut uri = dir.to_owned();
if !uri.ends_with(MAIN_SEPARATOR) {
uri.push(MAIN_SEPARATOR);
}
uri.push_str(name);
uri
let mut uri = dir.to_owned();
if !uri.ends_with(MAIN_SEPARATOR) {
uri.push(MAIN_SEPARATOR);
}
uri.push_str(name);
uri
}

View File

@ -1,5 +1,6 @@
use error_chain::{
error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed, impl_extract_backtrace,
error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed,
impl_extract_backtrace,
};
error_chain! {

View File

@ -11,144 +11,144 @@ lazy_static::lazy_static! {
}
pub struct ConnectionPool {
pub(crate) inner: Pool<ConnectionManager>,
pub(crate) inner: Pool<ConnectionManager>,
}
impl std::ops::Deref for ConnectionPool {
type Target = Pool<ConnectionManager>;
type Target = Pool<ConnectionManager>;
fn deref(&self) -> &Self::Target {
&self.inner
}
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl ConnectionPool {
pub fn new<T>(config: PoolConfig, uri: T) -> Result<Self>
where
T: Into<String>,
{
let manager = ConnectionManager::new(uri);
let thread_pool = DB_POOL.clone();
let config = Arc::new(config);
let customizer_config = DatabaseCustomizerConfig::default();
pub fn new<T>(config: PoolConfig, uri: T) -> Result<Self>
where
T: Into<String>,
{
let manager = ConnectionManager::new(uri);
let thread_pool = DB_POOL.clone();
let config = Arc::new(config);
let customizer_config = DatabaseCustomizerConfig::default();
let pool = r2d2::Pool::builder()
.thread_pool(thread_pool)
.min_idle(Some(config.min_idle))
.connection_customizer(Box::new(DatabaseCustomizer::new(customizer_config)))
.max_size(config.max_size)
.max_lifetime(None)
.connection_timeout(config.connection_timeout)
.idle_timeout(Some(config.idle_timeout))
.build_unchecked(manager);
Ok(ConnectionPool { inner: pool })
}
let pool = r2d2::Pool::builder()
.thread_pool(thread_pool)
.min_idle(Some(config.min_idle))
.connection_customizer(Box::new(DatabaseCustomizer::new(customizer_config)))
.max_size(config.max_size)
.max_lifetime(None)
.connection_timeout(config.connection_timeout)
.idle_timeout(Some(config.idle_timeout))
.build_unchecked(manager);
Ok(ConnectionPool { inner: pool })
}
}
#[allow(dead_code)]
pub type OnExecFunc = Box<dyn Fn() -> Box<dyn Fn(&SqliteConnection, &str)> + Send + Sync>;
pub struct PoolConfig {
min_idle: u32,
max_size: u32,
connection_timeout: Duration,
idle_timeout: Duration,
min_idle: u32,
max_size: u32,
connection_timeout: Duration,
idle_timeout: Duration,
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
min_idle: 1,
max_size: 10,
connection_timeout: Duration::from_secs(10),
idle_timeout: Duration::from_secs(5 * 60),
}
fn default() -> Self {
Self {
min_idle: 1,
max_size: 10,
connection_timeout: Duration::from_secs(10),
idle_timeout: Duration::from_secs(5 * 60),
}
}
}
impl PoolConfig {
#[allow(dead_code)]
pub fn min_idle(mut self, min_idle: u32) -> Self {
self.min_idle = min_idle;
self
}
#[allow(dead_code)]
pub fn min_idle(mut self, min_idle: u32) -> Self {
self.min_idle = min_idle;
self
}
#[allow(dead_code)]
pub fn max_size(mut self, max_size: u32) -> Self {
self.max_size = max_size;
self
}
#[allow(dead_code)]
pub fn max_size(mut self, max_size: u32) -> Self {
self.max_size = max_size;
self
}
}
pub struct ConnectionManager {
db_uri: String,
db_uri: String,
}
impl ManageConnection for ConnectionManager {
type Connection = SqliteConnection;
type Error = crate::sqlite::Error;
type Connection = SqliteConnection;
type Error = crate::sqlite::Error;
fn connect(&self) -> Result<Self::Connection> {
Ok(SqliteConnection::establish(&self.db_uri)?)
}
fn connect(&self) -> Result<Self::Connection> {
Ok(SqliteConnection::establish(&self.db_uri)?)
}
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> {
Ok(conn.execute("SELECT 1").map(|_| ())?)
}
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> {
Ok(conn.execute("SELECT 1").map(|_| ())?)
}
fn has_broken(&self, _conn: &mut Self::Connection) -> bool {
false
}
fn has_broken(&self, _conn: &mut Self::Connection) -> bool {
false
}
}
impl ConnectionManager {
pub fn new<S: Into<String>>(uri: S) -> Self {
ConnectionManager { db_uri: uri.into() }
}
pub fn new<S: Into<String>>(uri: S) -> Self {
ConnectionManager { db_uri: uri.into() }
}
}
#[derive(Debug)]
pub struct DatabaseCustomizerConfig {
pub(crate) journal_mode: SQLiteJournalMode,
pub(crate) synchronous: SQLiteSynchronous,
pub(crate) busy_timeout: i32,
#[allow(dead_code)]
pub(crate) secure_delete: bool,
pub(crate) journal_mode: SQLiteJournalMode,
pub(crate) synchronous: SQLiteSynchronous,
pub(crate) busy_timeout: i32,
#[allow(dead_code)]
pub(crate) secure_delete: bool,
}
impl Default for DatabaseCustomizerConfig {
fn default() -> Self {
Self {
journal_mode: SQLiteJournalMode::WAL,
synchronous: SQLiteSynchronous::NORMAL,
busy_timeout: 5000,
secure_delete: true,
}
fn default() -> Self {
Self {
journal_mode: SQLiteJournalMode::WAL,
synchronous: SQLiteSynchronous::NORMAL,
busy_timeout: 5000,
secure_delete: true,
}
}
}
#[derive(Debug)]
struct DatabaseCustomizer {
config: DatabaseCustomizerConfig,
config: DatabaseCustomizerConfig,
}
impl DatabaseCustomizer {
fn new(config: DatabaseCustomizerConfig) -> Self
where
Self: Sized,
{
Self { config }
}
fn new(config: DatabaseCustomizerConfig) -> Self
where
Self: Sized,
{
Self { config }
}
}
impl CustomizeConnection<SqliteConnection, crate::sqlite::Error> for DatabaseCustomizer {
fn on_acquire(&self, conn: &mut SqliteConnection) -> Result<()> {
conn.pragma_set_busy_timeout(self.config.busy_timeout)?;
if self.config.journal_mode != SQLiteJournalMode::WAL {
conn.pragma_set_journal_mode(self.config.journal_mode, None)?;
}
conn.pragma_set_synchronous(self.config.synchronous, None)?;
Ok(())
fn on_acquire(&self, conn: &mut SqliteConnection) -> Result<()> {
conn.pragma_set_busy_timeout(self.config.busy_timeout)?;
if self.config.journal_mode != SQLiteJournalMode::WAL {
conn.pragma_set_journal_mode(self.config.journal_mode, None)?;
}
conn.pragma_set_synchronous(self.config.synchronous, None)?;
Ok(())
}
}

View File

@ -1,170 +1,183 @@
#![allow(clippy::upper_case_acronyms)]
use crate::sqlite::errors::{Error, Result};
use diesel::{
expression::SqlLiteral,
query_dsl::load_dsl::LoadQuery,
sql_types::{Integer, Text},
SqliteConnection,
expression::SqlLiteral,
query_dsl::load_dsl::LoadQuery,
sql_types::{Integer, Text},
SqliteConnection,
};
use crate::sqlite::conn_ext::ConnectionExtension;
use std::{
convert::{TryFrom, TryInto},
fmt,
str::FromStr,
convert::{TryFrom, TryInto},
fmt,
str::FromStr,
};
pub trait PragmaExtension: ConnectionExtension {
fn pragma<D: std::fmt::Display>(&self, key: &str, val: D, schema: Option<&str>) -> Result<()> {
let query = match schema {
Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val),
None => format!("PRAGMA {} = '{}'", key, val),
};
tracing::trace!("SQLITE {}", query);
self.exec(&query)?;
Ok(())
}
fn pragma<D: std::fmt::Display>(&self, key: &str, val: D, schema: Option<&str>) -> Result<()> {
let query = match schema {
Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val),
None => format!("PRAGMA {} = '{}'", key, val),
};
tracing::trace!("SQLITE {}", query);
self.exec(&query)?;
Ok(())
}
fn pragma_ret<ST, T, D: std::fmt::Display>(&self, key: &str, val: D, schema: Option<&str>) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
let query = match schema {
Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val),
None => format!("PRAGMA {} = '{}'", key, val),
};
tracing::trace!("SQLITE {}", query);
self.query::<ST, T>(&query)
}
fn pragma_ret<ST, T, D: std::fmt::Display>(
&self,
key: &str,
val: D,
schema: Option<&str>,
) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
let query = match schema {
Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val),
None => format!("PRAGMA {} = '{}'", key, val),
};
tracing::trace!("SQLITE {}", query);
self.query::<ST, T>(&query)
}
fn pragma_get<ST, T>(&self, key: &str, schema: Option<&str>) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
let query = match schema {
Some(schema) => format!("PRAGMA {}.{}", schema, key),
None => format!("PRAGMA {}", key),
};
tracing::trace!("SQLITE {}", query);
self.query::<ST, T>(&query)
}
fn pragma_get<ST, T>(&self, key: &str, schema: Option<&str>) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
let query = match schema {
Some(schema) => format!("PRAGMA {}.{}", schema, key),
None => format!("PRAGMA {}", key),
};
tracing::trace!("SQLITE {}", query);
self.query::<ST, T>(&query)
}
fn pragma_set_busy_timeout(&self, timeout_ms: i32) -> Result<i32> {
self.pragma_ret::<Integer, i32, i32>("busy_timeout", timeout_ms, None)
}
fn pragma_set_busy_timeout(&self, timeout_ms: i32) -> Result<i32> {
self.pragma_ret::<Integer, i32, i32>("busy_timeout", timeout_ms, None)
}
fn pragma_get_busy_timeout(&self) -> Result<i32> {
self.pragma_get::<Integer, i32>("busy_timeout", None)
}
fn pragma_get_busy_timeout(&self) -> Result<i32> {
self.pragma_get::<Integer, i32>("busy_timeout", None)
}
fn pragma_set_journal_mode(&self, mode: SQLiteJournalMode, schema: Option<&str>) -> Result<i32> {
self.pragma_ret::<Integer, i32, SQLiteJournalMode>("journal_mode", mode, schema)
}
fn pragma_set_journal_mode(&self, mode: SQLiteJournalMode, schema: Option<&str>) -> Result<i32> {
self.pragma_ret::<Integer, i32, SQLiteJournalMode>("journal_mode", mode, schema)
}
fn pragma_get_journal_mode(&self, schema: Option<&str>) -> Result<SQLiteJournalMode> {
self.pragma_get::<Text, String>("journal_mode", schema)?.parse()
}
fn pragma_get_journal_mode(&self, schema: Option<&str>) -> Result<SQLiteJournalMode> {
self
.pragma_get::<Text, String>("journal_mode", schema)?
.parse()
}
fn pragma_set_synchronous(&self, synchronous: SQLiteSynchronous, schema: Option<&str>) -> Result<()> {
self.pragma("synchronous", synchronous as u8, schema)
}
fn pragma_set_synchronous(
&self,
synchronous: SQLiteSynchronous,
schema: Option<&str>,
) -> Result<()> {
self.pragma("synchronous", synchronous as u8, schema)
}
fn pragma_get_synchronous(&self, schema: Option<&str>) -> Result<SQLiteSynchronous> {
self.pragma_get::<Integer, i32>("synchronous", schema)?.try_into()
}
fn pragma_get_synchronous(&self, schema: Option<&str>) -> Result<SQLiteSynchronous> {
self
.pragma_get::<Integer, i32>("synchronous", schema)?
.try_into()
}
}
impl PragmaExtension for SqliteConnection {}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SQLiteJournalMode {
DELETE,
TRUNCATE,
PERSIST,
MEMORY,
WAL,
OFF,
DELETE,
TRUNCATE,
PERSIST,
MEMORY,
WAL,
OFF,
}
impl fmt::Display for SQLiteJournalMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::DELETE => "DELETE",
Self::TRUNCATE => "TRUNCATE",
Self::PERSIST => "PERSIST",
Self::MEMORY => "MEMORY",
Self::WAL => "WAL",
Self::OFF => "OFF",
}
)
}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::DELETE => "DELETE",
Self::TRUNCATE => "TRUNCATE",
Self::PERSIST => "PERSIST",
Self::MEMORY => "MEMORY",
Self::WAL => "WAL",
Self::OFF => "OFF",
}
)
}
}
impl FromStr for SQLiteJournalMode {
type Err = Error;
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s.to_uppercase().as_ref() {
"DELETE" => Ok(Self::DELETE),
"TRUNCATE" => Ok(Self::TRUNCATE),
"PERSIST" => Ok(Self::PERSIST),
"MEMORY" => Ok(Self::MEMORY),
"WAL" => Ok(Self::WAL),
"OFF" => Ok(Self::OFF),
_ => Err(format!("Unknown value {} for JournalMode", s).into()),
}
fn from_str(s: &str) -> Result<Self> {
match s.to_uppercase().as_ref() {
"DELETE" => Ok(Self::DELETE),
"TRUNCATE" => Ok(Self::TRUNCATE),
"PERSIST" => Ok(Self::PERSIST),
"MEMORY" => Ok(Self::MEMORY),
"WAL" => Ok(Self::WAL),
"OFF" => Ok(Self::OFF),
_ => Err(format!("Unknown value {} for JournalMode", s).into()),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SQLiteSynchronous {
EXTRA = 3,
FULL = 2,
NORMAL = 1,
OFF = 0,
EXTRA = 3,
FULL = 2,
NORMAL = 1,
OFF = 0,
}
impl fmt::Display for SQLiteSynchronous {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::OFF => "OFF",
Self::NORMAL => "NORMAL",
Self::FULL => "FULL",
Self::EXTRA => "EXTRA",
}
)
}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::OFF => "OFF",
Self::NORMAL => "NORMAL",
Self::FULL => "FULL",
Self::EXTRA => "EXTRA",
}
)
}
}
impl TryFrom<i32> for SQLiteSynchronous {
type Error = Error;
type Error = Error;
fn try_from(v: i32) -> Result<Self> {
match v {
0 => Ok(Self::OFF),
1 => Ok(Self::NORMAL),
2 => Ok(Self::FULL),
3 => Ok(Self::EXTRA),
_ => Err(format!("Unknown value {} for Synchronous", v).into()),
}
fn try_from(v: i32) -> Result<Self> {
match v {
0 => Ok(Self::OFF),
1 => Ok(Self::NORMAL),
2 => Ok(Self::FULL),
3 => Ok(Self::EXTRA),
_ => Err(format!("Unknown value {} for Synchronous", v).into()),
}
}
}
impl FromStr for SQLiteSynchronous {
type Err = Error;
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s.to_uppercase().as_ref() {
"0" | "OFF" => Ok(Self::OFF),
"1" | "NORMAL" => Ok(Self::NORMAL),
"2" | "FULL" => Ok(Self::FULL),
"3" | "EXTRA" => Ok(Self::EXTRA),
_ => Err(format!("Unknown value {} for Synchronous", s).into()),
}
fn from_str(s: &str) -> Result<Self> {
match s.to_uppercase().as_ref() {
"0" | "OFF" => Ok(Self::OFF),
"1" | "NORMAL" => Ok(Self::NORMAL),
"2" | "FULL" => Ok(Self::FULL),
"3" | "EXTRA" => Ok(Self::EXTRA),
_ => Err(format!("Unknown value {} for Synchronous", s).into()),
}
}
}