🚧 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()]),
|
.values_panic(vec!["administrator".into(), "3".into()]),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
.unwrap_or_error(|e| DbErr::Custom(e.message()))
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::core::action::add_action;
|
use crate::core::action::add_action;
|
||||||
use crate::core::module::ModuleRef;
|
use crate::core::module::ModuleRef;
|
||||||
use crate::core::theme::all::THEMES;
|
use crate::core::theme::all::THEMES;
|
||||||
use crate::{service, trace, LazyStatic};
|
use crate::locale::L10n;
|
||||||
|
use crate::{service, trace, LazyStatic, ResultExt};
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
use crate::db::*;
|
use crate::db::*;
|
||||||
|
|
@ -109,6 +110,7 @@ pub fn init_modules() {
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
pub fn run_migrations() {
|
pub fn run_migrations() {
|
||||||
|
if let Some(dbconn) = &*DBCONN {
|
||||||
run_now({
|
run_now({
|
||||||
struct Migrator;
|
struct Migrator;
|
||||||
impl MigratorTrait for Migrator {
|
impl MigratorTrait for Migrator {
|
||||||
|
|
@ -120,9 +122,9 @@ pub fn run_migrations() {
|
||||||
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({
|
run_now({
|
||||||
struct Migrator;
|
struct Migrator;
|
||||||
|
|
@ -135,9 +137,10 @@ pub fn run_migrations() {
|
||||||
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 ******************************************************************************
|
// CONFIGURE SERVICES ******************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
//! Acceso unificado y normalizado a base de datos.
|
//! Acceso unificado y normalizado a base de datos.
|
||||||
|
|
||||||
|
use crate::locale::L10n;
|
||||||
|
use crate::result::{SafeResult, TraceErr};
|
||||||
use crate::{config, trace, LazyStatic, ResultExt};
|
use crate::{config, trace, LazyStatic, ResultExt};
|
||||||
|
|
||||||
pub use url::Url as DbUri;
|
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) 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!(
|
trace::info!(
|
||||||
"Connecting to database \"{}\" using a pool of {} connections",
|
"Connecting to database \"{}\" using a pool of {} connections",
|
||||||
&config::SETTINGS.database.db_name,
|
&config::SETTINGS.database.db_name,
|
||||||
|
|
@ -61,46 +64,88 @@ pub(crate) static DBCONN: LazyStatic<DbConn> = LazyStatic::new(|| {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Some(
|
||||||
run_now(Database::connect::<ConnectOptions>({
|
run_now(Database::connect::<ConnectOptions>({
|
||||||
let mut db_opt = ConnectOptions::new(db_uri.to_string());
|
let mut db_opt = ConnectOptions::new(db_uri.to_string());
|
||||||
db_opt.max_connections(config::SETTINGS.database.max_pool_size);
|
db_opt.max_connections(config::SETTINGS.database.max_pool_size);
|
||||||
db_opt
|
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) -> SafeResult<Option<Vec<QueryResult>>> {
|
||||||
|
match &*DBCONN {
|
||||||
pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Vec<QueryResult>, DbErr> {
|
Some(dbconn) => {
|
||||||
DBCONN
|
let dbbackend = dbconn.get_database_backend();
|
||||||
|
match dbconn
|
||||||
.query_all(Statement::from_string(
|
.query_all(Statement::from_string(
|
||||||
*DBBACKEND,
|
dbbackend,
|
||||||
match *DBBACKEND {
|
match dbbackend {
|
||||||
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
|
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
|
||||||
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
|
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
|
||||||
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
|
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.await
|
.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> {
|
pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<QueryResult>> {
|
||||||
DBCONN
|
match &*DBCONN {
|
||||||
|
Some(dbconn) => {
|
||||||
|
let dbbackend = dbconn.get_database_backend();
|
||||||
|
match dbconn
|
||||||
.query_one(Statement::from_string(
|
.query_one(Statement::from_string(
|
||||||
*DBBACKEND,
|
dbbackend,
|
||||||
match *DBBACKEND {
|
match dbbackend {
|
||||||
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
|
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
|
||||||
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
|
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
|
||||||
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
|
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.await
|
.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> {
|
pub async fn exec_raw(stmt: String) -> SafeResult<Option<ExecResult>> {
|
||||||
DBCONN
|
match &*DBCONN {
|
||||||
.execute(Statement::from_string(*DBBACKEND, stmt))
|
Some(dbconn) => {
|
||||||
|
let dbbackend = dbconn.get_database_backend();
|
||||||
|
match dbconn
|
||||||
|
.execute(Statement::from_string(dbbackend, stmt))
|
||||||
.await
|
.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)
|
// El siguiente módulo migration es una versión simplificada del módulo sea_orm_migration (v0.11.3)
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,7 @@
|
||||||
|
|
||||||
# ERRORS.
|
# ERRORS.
|
||||||
language_set_failure = Failed to set language. Unicode Language Identifier "{$language}" is not accepted. Using "en-US", check the settings file
|
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.
|
# DEBUG.
|
||||||
|
|
||||||
# ERRORS.
|
# 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> {
|
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 {
|
pub fn warn(trace: L10n, fallback: T) -> Self {
|
||||||
let message = trace.message();
|
let message = trace.message();
|
||||||
trace::warn!(message);
|
trace::warn!(message);
|
||||||
|
|
@ -21,6 +39,8 @@ impl<T> TraceErr<T> {
|
||||||
TraceErr { message, fallback }
|
TraceErr { message, fallback }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TraceErr GETTERS.
|
||||||
|
|
||||||
pub fn message(self) -> String {
|
pub fn message(self) -> String {
|
||||||
self.message
|
self.message
|
||||||
}
|
}
|
||||||
|
|
@ -36,10 +56,22 @@ pub enum SafeResult<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> 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 {
|
pub fn unwrap_or_fallback(self) -> T {
|
||||||
match self {
|
match self {
|
||||||
SafeResult::Ok(result) => result,
|
SafeResult::Ok(r) => r,
|
||||||
SafeResult::Err(trace) => trace.fallback(),
|
SafeResult::Err(e) => e.fallback(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,5 @@ async fn health_check_works() {
|
||||||
let req = service::test::TestRequest::get().uri("/").to_request();
|
let req = service::test::TestRequest::get().uri("/").to_request();
|
||||||
let _resp = service::test::call_service(&app, req).await;
|
let _resp = service::test::call_service(&app, req).await;
|
||||||
|
|
||||||
// assert_eq!("OK", "OK");
|
// assert_eq!("OK", "OK");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue