🚧 Prevent database errors in test cases
This commit is contained in:
parent
d7762a10fa
commit
46ccbc10eb
7 changed files with 194 additions and 105 deletions
|
|
@ -60,6 +60,7 @@ impl MigrationTrait for Migration {
|
|||
.values_panic(vec!["administrator".into(), "3".into()]),
|
||||
)
|
||||
.await
|
||||
.unwrap_or_error(|e| DbErr::Custom(e.message()))
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use crate::core::action::add_action;
|
||||
use crate::core::module::ModuleRef;
|
||||
use crate::core::theme::all::THEMES;
|
||||
use crate::{service, trace, LazyStatic};
|
||||
use crate::locale::L10n;
|
||||
use crate::{service, trace, LazyStatic, ResultExt};
|
||||
|
||||
#[cfg(feature = "database")]
|
||||
use crate::db::*;
|
||||
|
|
@ -109,6 +110,7 @@ pub fn init_modules() {
|
|||
|
||||
#[cfg(feature = "database")]
|
||||
pub fn run_migrations() {
|
||||
if let Some(dbconn) = &*DBCONN {
|
||||
run_now({
|
||||
struct Migrator;
|
||||
impl MigratorTrait for Migrator {
|
||||
|
|
@ -120,9 +122,9 @@ pub fn run_migrations() {
|
|||
migrations
|
||||
}
|
||||
}
|
||||
Migrator::up(SchemaManagerConnection::Connection(&DBCONN), None)
|
||||
Migrator::up(SchemaManagerConnection::Connection(dbconn), None)
|
||||
})
|
||||
.unwrap();
|
||||
.expect_or_log(L10n::l("db_migration_fail").message().as_str());
|
||||
|
||||
run_now({
|
||||
struct Migrator;
|
||||
|
|
@ -135,9 +137,10 @@ pub fn run_migrations() {
|
|||
migrations
|
||||
}
|
||||
}
|
||||
Migrator::down(SchemaManagerConnection::Connection(&DBCONN), None)
|
||||
Migrator::down(SchemaManagerConnection::Connection(dbconn), None)
|
||||
})
|
||||
.unwrap();
|
||||
.expect_or_log(L10n::l("db_migration_fail").message().as_str());
|
||||
}
|
||||
}
|
||||
|
||||
// CONFIGURE SERVICES ******************************************************************************
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! Acceso unificado y normalizado a base de datos.
|
||||
|
||||
use crate::locale::L10n;
|
||||
use crate::result::{SafeResult, TraceErr};
|
||||
use crate::{config, trace, LazyStatic, ResultExt};
|
||||
|
||||
pub use url::Url as DbUri;
|
||||
|
|
@ -10,7 +12,8 @@ use sea_orm::{ConnectOptions, ConnectionTrait, Database, DatabaseBackend, Statem
|
|||
|
||||
pub(crate) use futures::executor::block_on as run_now;
|
||||
|
||||
pub(crate) static DBCONN: LazyStatic<DbConn> = LazyStatic::new(|| {
|
||||
pub(crate) static DBCONN: LazyStatic<Option<DbConn>> = LazyStatic::new(|| {
|
||||
if !config::SETTINGS.database.db_name.trim().is_empty() {
|
||||
trace::info!(
|
||||
"Connecting to database \"{}\" using a pool of {} connections",
|
||||
&config::SETTINGS.database.db_name,
|
||||
|
|
@ -61,46 +64,88 @@ pub(crate) static DBCONN: LazyStatic<DbConn> = LazyStatic::new(|| {
|
|||
}
|
||||
};
|
||||
|
||||
Some(
|
||||
run_now(Database::connect::<ConnectOptions>({
|
||||
let mut db_opt = ConnectOptions::new(db_uri.to_string());
|
||||
db_opt.max_connections(config::SETTINGS.database.max_pool_size);
|
||||
db_opt
|
||||
}))
|
||||
.expect_or_log("Failed to connect to database")
|
||||
.expect_or_log(L10n::l("db_connection_fail").message().as_str()),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
static DBBACKEND: LazyStatic<DatabaseBackend> = LazyStatic::new(|| DBCONN.get_database_backend());
|
||||
|
||||
pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Vec<QueryResult>, DbErr> {
|
||||
DBCONN
|
||||
pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<Vec<QueryResult>>> {
|
||||
match &*DBCONN {
|
||||
Some(dbconn) => {
|
||||
let dbbackend = dbconn.get_database_backend();
|
||||
match dbconn
|
||||
.query_all(Statement::from_string(
|
||||
*DBBACKEND,
|
||||
match *DBBACKEND {
|
||||
dbbackend,
|
||||
match dbbackend {
|
||||
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
|
||||
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
|
||||
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
|
||||
},
|
||||
))
|
||||
.await
|
||||
{
|
||||
Ok(result) => SafeResult::Ok(Some(result)),
|
||||
Err(e) => SafeResult::Err(TraceErr::error(L10n::n(e.to_string()), None)),
|
||||
}
|
||||
}
|
||||
None => SafeResult::Err(TraceErr::trace(
|
||||
L10n::l("db_connection_not_initialized"),
|
||||
None,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Option<QueryResult>, DbErr> {
|
||||
DBCONN
|
||||
pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<QueryResult>> {
|
||||
match &*DBCONN {
|
||||
Some(dbconn) => {
|
||||
let dbbackend = dbconn.get_database_backend();
|
||||
match dbconn
|
||||
.query_one(Statement::from_string(
|
||||
*DBBACKEND,
|
||||
match *DBBACKEND {
|
||||
dbbackend,
|
||||
match dbbackend {
|
||||
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
|
||||
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
|
||||
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
|
||||
},
|
||||
))
|
||||
.await
|
||||
{
|
||||
Ok(result) => SafeResult::Ok(result),
|
||||
Err(e) => SafeResult::Err(TraceErr::error(L10n::n(e.to_string()), None)),
|
||||
}
|
||||
}
|
||||
None => SafeResult::Err(TraceErr::trace(
|
||||
L10n::l("db_connection_not_initialized"),
|
||||
None,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn exec_raw(stmt: String) -> Result<ExecResult, DbErr> {
|
||||
DBCONN
|
||||
.execute(Statement::from_string(*DBBACKEND, stmt))
|
||||
pub async fn exec_raw(stmt: String) -> SafeResult<Option<ExecResult>> {
|
||||
match &*DBCONN {
|
||||
Some(dbconn) => {
|
||||
let dbbackend = dbconn.get_database_backend();
|
||||
match dbconn
|
||||
.execute(Statement::from_string(dbbackend, stmt))
|
||||
.await
|
||||
{
|
||||
Ok(result) => SafeResult::Ok(Some(result)),
|
||||
Err(e) => SafeResult::Err(TraceErr::error(L10n::n(e.to_string()), None)),
|
||||
}
|
||||
}
|
||||
None => SafeResult::Err(TraceErr::trace(
|
||||
L10n::l("db_connection_not_initialized"),
|
||||
None,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// El siguiente módulo migration es una versión simplificada del módulo sea_orm_migration (v0.11.3)
|
||||
|
|
|
|||
|
|
@ -2,3 +2,7 @@
|
|||
|
||||
# ERRORS.
|
||||
language_set_failure = Failed to set language. Unicode Language Identifier "{$language}" is not accepted. Using "en-US", check the settings file
|
||||
|
||||
db_connection_fail = Failed to connect to database
|
||||
db_connection_not_initialized = Database connection not initialized
|
||||
db_migration_fail = Database update failed
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
# DEBUG.
|
||||
|
||||
# ERRORS.
|
||||
language_set_failure = Error al establecer idioma. El Identificador de Lenguaje Unicode "{$language}" no es válido. Se usará "en-US". Comprobar archivo de configuración
|
||||
language_set_failure = Fallo al asignar idioma. El Identificador de Lenguaje Unicode "{$language}" no es válido. Se usará "en-US". Comprobar archivo de configuración
|
||||
|
||||
db_connection_fail = Fallo al conectar con la base de datos
|
||||
db_connection_not_initialized = Conexión a la base de datos no inicializada
|
||||
db_migration_fail = Fallo en la actualización de la base de datos
|
||||
|
|
|
|||
|
|
@ -9,6 +9,24 @@ pub struct TraceErr<T> {
|
|||
}
|
||||
|
||||
impl<T> TraceErr<T> {
|
||||
pub fn trace(trace: L10n, fallback: T) -> Self {
|
||||
let message = trace.message();
|
||||
trace::trace!(message);
|
||||
TraceErr { message, fallback }
|
||||
}
|
||||
|
||||
pub fn debug(trace: L10n, fallback: T) -> Self {
|
||||
let message = trace.message();
|
||||
trace::debug!(message);
|
||||
TraceErr { message, fallback }
|
||||
}
|
||||
|
||||
pub fn info(trace: L10n, fallback: T) -> Self {
|
||||
let message = trace.message();
|
||||
trace::info!(message);
|
||||
TraceErr { message, fallback }
|
||||
}
|
||||
|
||||
pub fn warn(trace: L10n, fallback: T) -> Self {
|
||||
let message = trace.message();
|
||||
trace::warn!(message);
|
||||
|
|
@ -21,6 +39,8 @@ impl<T> TraceErr<T> {
|
|||
TraceErr { message, fallback }
|
||||
}
|
||||
|
||||
// TraceErr GETTERS.
|
||||
|
||||
pub fn message(self) -> String {
|
||||
self.message
|
||||
}
|
||||
|
|
@ -36,10 +56,22 @@ pub enum SafeResult<T> {
|
|||
}
|
||||
|
||||
impl<T> SafeResult<T> {
|
||||
#[inline]
|
||||
pub fn unwrap_or_error<F, E>(self, f: F) -> Result<T, E>
|
||||
where
|
||||
F: FnOnce(TraceErr<T>) -> E,
|
||||
{
|
||||
match self {
|
||||
SafeResult::Ok(r) => Ok(r),
|
||||
SafeResult::Err(e) => Err(f(e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unwrap_or_fallback(self) -> T {
|
||||
match self {
|
||||
SafeResult::Ok(result) => result,
|
||||
SafeResult::Err(trace) => trace.fallback(),
|
||||
SafeResult::Ok(r) => r,
|
||||
SafeResult::Err(e) => e.fallback(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue