mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
refactor: replace native_db with memdb and add tests
This commit is contained in:
@@ -328,7 +328,14 @@ pub struct Settings {
|
||||
|
||||
impl Settings {
|
||||
pub fn init() -> Self {
|
||||
let s = Self::parse();
|
||||
// `cargo test` passes test-filter names and flags (e.g. --nocapture)
|
||||
// as extra positional arguments. Try the full argv first; if clap
|
||||
// rejects it, fall back to parsing with only the binary name so that
|
||||
// the settings come entirely from environment variables.
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let s = Self::try_parse_from(&args).unwrap_or_else(|_| {
|
||||
Self::parse_from(std::iter::once(args[0].clone()))
|
||||
});
|
||||
if s.bichon_encrypt_password.is_none() && s.bichon_encrypt_password_file.is_none() {
|
||||
panic!(
|
||||
"One of --bichon_encrypt_password or --bichon_encrypt_password_file has to be set"
|
||||
|
||||
@@ -25,8 +25,7 @@ use crate::{
|
||||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
pub const META_FILE: &str = "meta.db";
|
||||
pub const MAILBOX_FILE: &str = "mailbox.db";
|
||||
const MEMDB_DIR: &str = "memdb";
|
||||
const INDICES: &str = "bichon-indices";
|
||||
const MAIL_METADATA: &str = "mail_metadata";
|
||||
const ATTACHMENT_METADATA: &str = "attachment_metadata";
|
||||
@@ -43,8 +42,7 @@ pub static DATA_DIR_MANAGER: LazyLock<DataDirManager> =
|
||||
#[derive(Debug)]
|
||||
pub struct DataDirManager {
|
||||
pub root_dir: PathBuf,
|
||||
pub meta_db: PathBuf,
|
||||
pub mailbox_db: PathBuf,
|
||||
pub memdb_dir: PathBuf,
|
||||
pub temp_dir: PathBuf,
|
||||
pub tls_cert: PathBuf,
|
||||
pub tls_key: PathBuf,
|
||||
@@ -84,8 +82,7 @@ impl DataDirManager {
|
||||
|
||||
Self {
|
||||
root_dir: root_dir.clone(),
|
||||
meta_db: root_dir.join(META_FILE),
|
||||
mailbox_db: root_dir.join(MAILBOX_FILE),
|
||||
memdb_dir: root_dir.join(MEMDB_DIR),
|
||||
tls_key: root_dir.join(TLS_KEY),
|
||||
tls_cert: root_dir.join(TLS_CERT),
|
||||
log_dir: root_dir.join(LOG_DIR),
|
||||
|
||||
@@ -16,31 +16,23 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use native_db::*;
|
||||
use native_model::{native_model, Model};
|
||||
//use poem_openapi::Object;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
id,
|
||||
{
|
||||
database::{
|
||||
async_find_impl, delete_impl, insert_impl, list_all_impl, manager::DB_MANAGER,
|
||||
update_impl,
|
||||
},
|
||||
error::{code::ErrorCode, BichonResult},
|
||||
utils::net::parse_proxy_addr,
|
||||
database::{
|
||||
delete_impl, find_impl, insert_impl, list_all_impl, manager::DB_MANAGER, update_impl,
|
||||
MemDbModel,
|
||||
},
|
||||
raise_error, utc_now,
|
||||
error::{code::ErrorCode, BichonResult},
|
||||
id, raise_error, utc_now,
|
||||
utils::net::parse_proxy_addr,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "web-api", derive(poem_openapi::Object))]
|
||||
#[native_model(id = 8, version = 1)]
|
||||
#[native_db]
|
||||
pub struct Proxy {
|
||||
/// The unique identifier for this proxy configuration.
|
||||
#[primary_key]
|
||||
pub id: u64,
|
||||
|
||||
/// The proxy URL (e.g., socks5://127.0.0.1:1080) used to route network requests.
|
||||
@@ -53,6 +45,15 @@ pub struct Proxy {
|
||||
pub updated_at: i64,
|
||||
}
|
||||
|
||||
impl MemDbModel for Proxy {
|
||||
fn collection() -> &'static str {
|
||||
"proxies"
|
||||
}
|
||||
fn key(&self) -> String {
|
||||
self.id.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Proxy {
|
||||
/// Create a new Proxy instance with the given URL and timestamps.
|
||||
pub fn new(url: String) -> Self {
|
||||
@@ -64,59 +65,37 @@ impl Proxy {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get(id: u64) -> BichonResult<Proxy> {
|
||||
async_find_impl(DB_MANAGER.meta_db(), id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
raise_error!(
|
||||
format!("Proxy with id={} not found", id),
|
||||
ErrorCode::ResourceNotFound
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn list_all() -> BichonResult<Vec<Proxy>> {
|
||||
list_all_impl(DB_MANAGER.meta_db()).await
|
||||
}
|
||||
|
||||
pub async fn delete(id: u64) -> BichonResult<()> {
|
||||
delete_impl(DB_MANAGER.meta_db(), move |rw| {
|
||||
rw.get()
|
||||
.primary::<Proxy>(id)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(|| raise_error!("proxy missing".into(), ErrorCode::InternalError))
|
||||
pub fn get(id: u64) -> BichonResult<Proxy> {
|
||||
let key = id.to_string();
|
||||
find_impl::<Proxy>(DB_MANAGER.db(), &key)?.ok_or_else(|| {
|
||||
raise_error!(
|
||||
format!("Proxy with id={} not found", id),
|
||||
ErrorCode::ResourceNotFound
|
||||
)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update(id: u64, url: String) -> BichonResult<()> {
|
||||
update_impl(
|
||||
DB_MANAGER.meta_db(),
|
||||
move |rw| {
|
||||
rw.get()
|
||||
.primary::<Proxy>(id)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(|| {
|
||||
raise_error!(
|
||||
format!("Proxy with id={} not found", id),
|
||||
ErrorCode::ResourceNotFound
|
||||
)
|
||||
})
|
||||
},
|
||||
move |current| {
|
||||
let mut updated = current.clone();
|
||||
updated.url = url;
|
||||
updated.updated_at = utc_now!();
|
||||
Ok(updated)
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
pub fn list_all() -> BichonResult<Vec<Proxy>> {
|
||||
list_all_impl::<Proxy>(DB_MANAGER.db())
|
||||
}
|
||||
|
||||
pub fn delete(id: u64) -> BichonResult<()> {
|
||||
delete_impl::<Proxy>(DB_MANAGER.db(), &id.to_string())
|
||||
}
|
||||
|
||||
pub fn update(id: u64, url: String) -> BichonResult<()> {
|
||||
update_impl(DB_MANAGER.db(), &id.to_string(), move |current: Proxy| {
|
||||
let mut updated = current.clone();
|
||||
updated.url = url;
|
||||
updated.updated_at = utc_now!();
|
||||
Ok(updated)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn save(&self) -> BichonResult<()> {
|
||||
pub fn save(&self) -> BichonResult<()> {
|
||||
self.validate()?;
|
||||
insert_impl(DB_MANAGER.meta_db(), self.to_owned()).await
|
||||
insert_impl(DB_MANAGER.db(), self.to_owned())
|
||||
}
|
||||
|
||||
/// Validate that the URL is a valid SOCKS5 proxy URL.
|
||||
|
||||
@@ -16,15 +16,10 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use native_db::*;
|
||||
use native_model::{native_model, Model};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
|
||||
#[native_model(id = 2, version = 1)]
|
||||
#[native_db]
|
||||
pub struct SystemSetting {
|
||||
#[primary_key]
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
pub created_at: i64,
|
||||
|
||||
Reference in New Issue
Block a user