Actualiza el uso opcional de la base de datos
Por defecto PageTop no hace uso de la base de datos. Se deberá indicar explícitamente qué tipo de base de datos usará para que tenga en cuenta la configuración utilizada.
This commit is contained in:
parent
ab0ac11f65
commit
dce2573f8c
17 changed files with 166 additions and 113 deletions
|
|
@ -9,12 +9,10 @@ language = "es-ES"
|
|||
theme = "Bootsier"
|
||||
|
||||
[database]
|
||||
db_type = "mysql"
|
||||
db_name = "drust"
|
||||
db_user = "drust"
|
||||
db_pass = "DrU__#3T"
|
||||
|
||||
[log]
|
||||
tracing = "Info"
|
||||
#Info,actix_server::builder=Error,tracing_actix_web=Warn"
|
||||
rolling = "Stdout"
|
||||
format = "Compact"
|
||||
tracing = "Info,sqlx::query=Warn"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,11 @@ homepage = "https://suitepro.cillero.es/projects/drust"
|
|||
repository = "https://gitlab.com/manuelcillero/drust"
|
||||
|
||||
[dependencies]
|
||||
pagetop = { path = "../pagetop" }
|
||||
actix-web = "3.3.3"
|
||||
maud = { version = "0.23.0" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.pagetop]
|
||||
path = "../pagetop"
|
||||
features = ["mysql"]
|
||||
default-features = false
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
|||
tracing = "0.1"
|
||||
tracing-appender = "0.2"
|
||||
tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] }
|
||||
tracing-unwrap = { version = "0.9", default-features = false }
|
||||
tracing-actix-web = "0.2"
|
||||
|
||||
fluent-templates = "0.6.1"
|
||||
|
|
@ -53,16 +54,19 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
version = "0.6"
|
||||
features = ["debug-print", "macros", "runtime-async-std-native-tls"]
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[dependencies.sea-schema]
|
||||
version = "0.5"
|
||||
features = ["debug-print", "migration"]
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
default = ["mysql"]
|
||||
mysql = ["sea-orm/sqlx-mysql"]
|
||||
postgres = ["sea-orm/sqlx-postgres"]
|
||||
default = []
|
||||
mysql = ["sea-orm", "sea-schema", "sea-orm/sqlx-mysql"]
|
||||
postgres = ["sea-orm", "sea-schema", "sea-orm/sqlx-postgres"]
|
||||
sqlite = ["sea-orm", "sea-schema", "sea-orm/sqlx-sqlite"]
|
||||
|
||||
[build-dependencies]
|
||||
actix-web-static-files = "3.0.5"
|
||||
|
|
|
|||
|
|
@ -15,24 +15,26 @@ startup_banner = "Small"
|
|||
# Ejemplos: "Error,actix_server::builder=Info,tracing_actix_web=Debug".
|
||||
tracing = "Info"
|
||||
# En terminal ("Stdout") o archivos "Daily", "Hourly", "Minutely" o "Endless".
|
||||
rolling = "Daily"
|
||||
rolling = "Stdout"
|
||||
# Directorio para los archivos de traza (si rolling != "Stdout").
|
||||
path = "log"
|
||||
# Prefijo para los archivos de traza (si rolling != "Stdout").
|
||||
prefix = "tracing.log"
|
||||
# Presentación de las trazas: "Json", "Full", "Compact" o "Pretty".
|
||||
format = "Json"
|
||||
# Presentación de las trazas: "Full", "Compact", "Pretty" o "Json".
|
||||
format = "Full"
|
||||
|
||||
[database]
|
||||
# Ajustes para conectar con la base de datos.
|
||||
# El tipo de base de datos es una característica de compilación.
|
||||
# Nombre (mysql/postgres) o referencia (sqlite) de la base de datos.
|
||||
db_name = "dbname"
|
||||
# Usuario y contraseña (mysql/postgres).
|
||||
db_user = "dbuser"
|
||||
db_pass = "dbpass"
|
||||
# Servidor (mysql/postgres) y puerto predeterminado (0 para 3306 ó 5432).
|
||||
# Conecta con una base de datos (opcional).
|
||||
# Tipo de la base de datos (mysql, postgres ó sqlite).
|
||||
db_type = ""
|
||||
# Nombre (para mysql/postgres) o referencia (para sqlite) de la base de datos.
|
||||
db_name = ""
|
||||
# Usuario y contraseña (para mysql/postgres).
|
||||
db_user = ""
|
||||
db_pass = ""
|
||||
# Servidor (para mysql/postgres).
|
||||
db_host = "localhost"
|
||||
# Puerto (para mysql/postgres), siendo 0 el puerto predeterminado (3306 ó 5432).
|
||||
db_port = 0
|
||||
# Número máximo de conexiones habilitadas.
|
||||
max_pool_size = 5
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
pub mod admin;
|
||||
pub mod homepage;
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub mod user;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ pub struct Log {
|
|||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Database {
|
||||
pub db_type : String,
|
||||
pub db_name : String,
|
||||
pub db_user : String,
|
||||
pub db_pass : String,
|
||||
|
|
@ -127,15 +128,16 @@ Ajustes globales y valores predeterminados para las secciones *\[app\]*,
|
|||
|
||||
// [log]
|
||||
"log.tracing" => "Info",
|
||||
"log.rolling" => "Daily",
|
||||
"log.rolling" => "Stdout",
|
||||
"log.path" => "log",
|
||||
"log.prefix" => "tracing.log",
|
||||
"log.format" => "json",
|
||||
"log.format" => "Full",
|
||||
|
||||
// [database]
|
||||
"database.db_name" => "dbname",
|
||||
"database.db_user" => "dbuser",
|
||||
"database.db_pass" => "dbpass",
|
||||
"database.db_type" => "",
|
||||
"database.db_name" => "",
|
||||
"database.db_user" => "",
|
||||
"database.db_pass" => "",
|
||||
"database.db_host" => "localhost",
|
||||
"database.db_port" => 0,
|
||||
"database.max_pool_size" => 5,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Lazy, db};
|
||||
use crate::{Lazy, trace};
|
||||
use crate::core::theme::Theme;
|
||||
use crate::core::module::Module;
|
||||
use crate::core::response::page::PageContainer;
|
||||
|
|
@ -42,9 +42,13 @@ pub fn modules(cfg: &mut server::web::ServiceConfig) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn migrations(dbconn: &db::DbConn) {
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub fn check_migrations() {
|
||||
trace::info!("Checking migrations.");
|
||||
for m in MODULES.read().unwrap().iter() {
|
||||
m.migrations(dbconn).expect("Failed to run migrations");
|
||||
m.migrations(
|
||||
&*server::db::DBCONN.read().unwrap()
|
||||
).expect("Failed to run migrations");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use crate::db;
|
||||
use crate::core::server;
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
use crate::db;
|
||||
|
||||
/// Los módulos deben implementar este *trait*.
|
||||
pub trait Module: Send + Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
|
|
@ -15,6 +17,7 @@ pub trait Module: Send + Sync {
|
|||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
#[allow(unused_variables)]
|
||||
fn migrations(&self, dbconn: &db::DbConn) -> Result<(), db::DbErr> {
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Lazy, base, db, locale, trace};
|
||||
use crate::{Lazy, base, trace};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{Server, global, server};
|
||||
use crate::core::theme::register_theme;
|
||||
|
|
@ -13,7 +13,7 @@ pub struct Application {
|
|||
|
||||
impl Application {
|
||||
pub async fn build(bootstrap: Option<fn()>) -> Result<Self, Error> {
|
||||
// Imprime rótulo (opcional) de bienvenida.
|
||||
// Imprime un rótulo de presentación (opcional).
|
||||
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||
let figfont = figlet_rs::FIGfont::from_content(
|
||||
match SETTINGS.app.startup_banner.to_lowercase().as_str() {
|
||||
|
|
@ -43,42 +43,11 @@ impl Application {
|
|||
Lazy::force(&server::tracing::TRACING);
|
||||
|
||||
// Valida el identificador de idioma.
|
||||
Lazy::force(&locale::LANGID);
|
||||
Lazy::force(&server::locale::LANGID);
|
||||
|
||||
// Inicializa la conexión con la base de datos.
|
||||
trace::info!(
|
||||
"Connecting to database \"{}\" using a pool of {} connections.",
|
||||
&SETTINGS.database.db_name,
|
||||
&SETTINGS.database.max_pool_size
|
||||
);
|
||||
|
||||
#[cfg(feature = "mysql")]
|
||||
let db_type = "mysql";
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
let db_type = "postgres";
|
||||
|
||||
// https://github.com/launchbadge/sqlx/issues/1624
|
||||
let mut db_uri = db::DbUri::parse(format!(
|
||||
"{}://{}/{}",
|
||||
db_type,
|
||||
&SETTINGS.database.db_host,
|
||||
&SETTINGS.database.db_name
|
||||
).as_str()).unwrap();
|
||||
db_uri.set_username(&SETTINGS.database.db_user.as_str()).unwrap();
|
||||
db_uri.set_password(Some(&SETTINGS.database.db_pass.as_str())).unwrap();
|
||||
if SETTINGS.database.db_port != 0 {
|
||||
db_uri.set_port(Some(SETTINGS.database.db_port)).unwrap();
|
||||
}
|
||||
|
||||
let mut db_options = sea_orm::ConnectOptions::new(db_uri.to_string());
|
||||
db_options.max_connections(SETTINGS.database.max_pool_size);
|
||||
|
||||
let dbconn = sea_orm::Database::connect::<sea_orm::ConnectOptions>(
|
||||
db_options.into()
|
||||
)
|
||||
.await
|
||||
.expect("Failed to connect to database");
|
||||
// Conecta con la base de datos (opcional).
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
Lazy::force(&server::db::DBCONN);
|
||||
|
||||
// Registra los temas predefinidos.
|
||||
register_theme(&base::theme::aliner::AlinerTheme);
|
||||
|
|
@ -87,6 +56,8 @@ impl Application {
|
|||
|
||||
// Registra los módulos predeterminados.
|
||||
register_module(&base::module::admin::AdminModule);
|
||||
// Registra los módulos que requieren base de datos.
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
register_module(&base::module::user::UserModule);
|
||||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
|
|
@ -99,16 +70,15 @@ impl Application {
|
|||
// Al ser el último, puede sobrecargarse con la función de inicio.
|
||||
register_module(&base::module::homepage::HomepageModule);
|
||||
|
||||
// Run migrations.
|
||||
trace::info!("Running migrations.");
|
||||
global::migrations(&dbconn);
|
||||
// Comprueba actualizaciones pendientes de la base de datos (opcional).
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
global::check_migrations();
|
||||
|
||||
// Prepara el servidor web.
|
||||
let server = server::HttpServer::new(move || {
|
||||
server::App::new()
|
||||
.wrap(tracing_actix_web::TracingLogger)
|
||||
.wrap(NormalizePath::new(TrailingSlash::Trim))
|
||||
.data(dbconn.clone())
|
||||
.configure(&global::themes)
|
||||
.configure(&global::modules)
|
||||
})
|
||||
|
|
|
|||
60
pagetop/src/core/server/db.rs
Normal file
60
pagetop/src/core/server/db.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use crate::{Lazy, db, run_now, trace};
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use std::sync::RwLock;
|
||||
use sea_orm::{ConnectOptions, Database};
|
||||
use tracing_unwrap::ResultExt;
|
||||
|
||||
pub static DBCONN: Lazy<RwLock<db::DbConn>> = Lazy::new(|| {
|
||||
trace::info!(
|
||||
"Connecting to database \"{}\" using a pool of {} connections.",
|
||||
&SETTINGS.database.db_name,
|
||||
&SETTINGS.database.max_pool_size
|
||||
);
|
||||
|
||||
let db_uri = match SETTINGS.database.db_type.as_str() {
|
||||
"mysql" | "postgres" => {
|
||||
let mut tmp_uri = db::DbUri::parse(format!(
|
||||
"{}://{}/{}",
|
||||
&SETTINGS.database.db_type,
|
||||
&SETTINGS.database.db_host,
|
||||
&SETTINGS.database.db_name
|
||||
).as_str()).unwrap();
|
||||
tmp_uri.set_username(
|
||||
&SETTINGS.database.db_user.as_str()
|
||||
).unwrap();
|
||||
// https://github.com/launchbadge/sqlx/issues/1624
|
||||
tmp_uri.set_password(
|
||||
Some(&SETTINGS.database.db_pass.as_str())
|
||||
).unwrap();
|
||||
if SETTINGS.database.db_port != 0 {
|
||||
tmp_uri.set_port(
|
||||
Some(SETTINGS.database.db_port)
|
||||
).unwrap();
|
||||
}
|
||||
tmp_uri
|
||||
},
|
||||
"sqlite" => db::DbUri::parse(
|
||||
format!("{}://{}",
|
||||
&SETTINGS.database.db_type,
|
||||
&SETTINGS.database.db_name
|
||||
).as_str()).unwrap(),
|
||||
_ => {
|
||||
trace::error!(
|
||||
"Unrecognized database type \"{}\".",
|
||||
&SETTINGS.database.db_type
|
||||
);
|
||||
db::DbUri::parse("").unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
let db_conn = run_now(
|
||||
Database::connect::<ConnectOptions>({
|
||||
let mut db_opt = ConnectOptions::new(db_uri.to_string());
|
||||
db_opt.max_connections(SETTINGS.database.max_pool_size);
|
||||
db_opt.into()
|
||||
})
|
||||
).expect_or_log("Failed to connect to database");
|
||||
|
||||
RwLock::new(db_conn)
|
||||
});
|
||||
23
pagetop/src/core/server/locale.rs
Normal file
23
pagetop/src/core/server/locale.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::{Lazy, trace};
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
/// Almacena el Identificador de Idioma Unicode ([Unicode Language Identifier]
|
||||
/// (https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)) de
|
||||
/// la aplicación, obtenido de `SETTINGS.app.language`.
|
||||
pub static LANGID: Lazy<LanguageIdentifier> = Lazy::new(|| {
|
||||
match SETTINGS.app.language.parse() {
|
||||
Ok(language) => language,
|
||||
Err(_) => {
|
||||
trace::warn!(
|
||||
"Failed to parse language \"{}\". {}. {}. {}.",
|
||||
SETTINGS.app.language,
|
||||
"Unrecognized Unicode Language Identifier",
|
||||
"Using \"en-US\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
"en-US".parse().unwrap()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -4,5 +4,9 @@ pub use actix_web::{
|
|||
|
||||
mod tracing;
|
||||
|
||||
mod app;
|
||||
pub use app::Application;
|
||||
pub mod locale;
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub mod db;
|
||||
|
||||
pub mod app;
|
||||
|
|
|
|||
|
|
@ -12,3 +12,14 @@ pub mod entity {
|
|||
pub mod migration {
|
||||
pub use sea_schema::migration::prelude::*;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! db_migrations {
|
||||
( $DBCONN:ident ) => {{
|
||||
$crate::run_now({
|
||||
use $crate::db::migration::MigratorTrait;
|
||||
|
||||
migration::Migrator::up($DBCONN, None)
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,14 @@ pub use futures::executor::block_on as run_now;
|
|||
pub mod config; // Gestión de la configuración.
|
||||
pub mod trace; // Registro de trazas y eventos de la aplicación.
|
||||
pub mod locale; // Localización.
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub mod db; // Acceso a la base de datos.
|
||||
|
||||
pub mod core; // Servidor web y APIs para Temas, Módulos y Respuestas web.
|
||||
pub mod base; // Temas, Módulos y Componentes base.
|
||||
pub mod util; // Macros y funciones útiles.
|
||||
|
||||
pub mod prelude; // Re-exporta recursos comunes.
|
||||
|
||||
pub use crate::core::server::Application;
|
||||
pub use crate::core::server::app::Application;
|
||||
|
|
|
|||
|
|
@ -2,35 +2,12 @@ pub use fluent_templates::{static_loader as static_locale, Loader as Locale};
|
|||
pub use fluent_templates;
|
||||
pub use fluent_templates::fluent_bundle::FluentValue;
|
||||
|
||||
use crate::{Lazy, trace};
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
/// Almacena el Identificador de Idioma Unicode ([Unicode Language Identifier]
|
||||
/// (https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)) de
|
||||
/// la aplicación, obtenido de `SETTINGS.app.language`.
|
||||
pub static LANGID: Lazy<LanguageIdentifier> = Lazy::new(|| {
|
||||
match SETTINGS.app.language.parse() {
|
||||
Ok(language) => language,
|
||||
Err(_) => {
|
||||
trace::warn!(
|
||||
"Failed to parse language \"{}\". {}. {}. {}.",
|
||||
SETTINGS.app.language,
|
||||
"Unicode Language Identifier not recognized",
|
||||
"Using \"en-US\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
"en-US".parse().unwrap()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[macro_export]
|
||||
/// Permite integrar fácilmente localización en temas, módulos y componentes.
|
||||
macro_rules! localize {
|
||||
( $DEF_LANGID:literal, $locales:literal $(, $core_locales:literal)? ) => {
|
||||
use $crate::locale::*;
|
||||
use $crate::core::server::locale::LANGID;
|
||||
|
||||
static_locale! {
|
||||
static LOCALES = {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
//! Re-exporta recursos comunes.
|
||||
|
||||
pub use crate::{
|
||||
args,
|
||||
db_migrations,
|
||||
};
|
||||
|
||||
pub use crate::args;
|
||||
pub use crate::config::SETTINGS;
|
||||
pub use crate::trace;
|
||||
pub use crate::localize;
|
||||
|
||||
pub use crate::db;
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub use crate::{db, db_migrations};
|
||||
|
||||
pub use crate::core::theme::*;
|
||||
pub use crate::core::module::*;
|
||||
|
|
|
|||
|
|
@ -18,17 +18,6 @@ macro_rules! args {
|
|||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! db_migrations {
|
||||
( $DBCONN:ident ) => {{
|
||||
$crate::run_now({
|
||||
use $crate::db::migration::MigratorTrait;
|
||||
|
||||
migration::Migrator::up($DBCONN, None)
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
||||
pub fn valid_id(id: &str) -> Option<String> {
|
||||
let id = id.trim().replace(" ", "_").to_lowercase();
|
||||
match id.is_empty() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue