Añade configuración y conexión a la base de datos
This commit is contained in:
parent
b6dd473578
commit
76785af4dc
13 changed files with 210 additions and 83 deletions
12
Cargo.toml
12
Cargo.toml
|
|
@ -29,6 +29,7 @@ once_cell = "1.9.0"
|
|||
figlet-rs = "0.1.3"
|
||||
|
||||
config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
||||
url = "2.2.2"
|
||||
|
||||
tracing = "0.1"
|
||||
tracing-appender = "0.2"
|
||||
|
|
@ -47,9 +48,20 @@ downcast-rs = "1.2.0"
|
|||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.6"
|
||||
features = ["macros", "debug-print", "runtime-async-std-native-tls"]
|
||||
default-features = false
|
||||
|
||||
[build-dependencies]
|
||||
actix-web-static-files = "3.0.5"
|
||||
|
||||
[features]
|
||||
default = ["sea-orm/sqlx-mysql"]
|
||||
mysql = ["sea-orm/sqlx-mysql"]
|
||||
postgres = ["sea-orm/sqlx-postgres"]
|
||||
sqlite = ["sea-orm/sqlx-sqlite"]
|
||||
|
||||
[lib]
|
||||
name = "pagetop"
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,20 @@ prefix = "tracing.log"
|
|||
# Presentación de las trazas: "Json", "Full", "Compact" o "Pretty".
|
||||
format = "Json"
|
||||
|
||||
[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).
|
||||
db_host = "localhost"
|
||||
db_port = 0
|
||||
# Número máximo de conexiones habilitadas.
|
||||
max_pool_size = 5
|
||||
|
||||
[webserver]
|
||||
# Configuración del servidor web.
|
||||
bind_address = "localhost"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use crate::prelude::*;
|
||||
use super::l;
|
||||
|
||||
pub async fn summary() -> server::Result<Markup> {
|
||||
let top_menu = Menu::prepare()
|
||||
.add(MenuItem::label("Opción 1"))
|
||||
.add(MenuItem::label(l("module_fullname").as_str()))
|
||||
.add(MenuItem::link("Opción 2", "https://www.google.es"))
|
||||
.add(MenuItem::link_blank("Opción 3", "https://www.google.es"))
|
||||
.add(MenuItem::submenu("Submenú 1", Menu::prepare()
|
||||
|
|
|
|||
|
|
@ -87,6 +87,16 @@ pub struct Log {
|
|||
pub format : String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Database {
|
||||
pub db_name : String,
|
||||
pub db_user : String,
|
||||
pub db_pass : String,
|
||||
pub db_host : String,
|
||||
pub db_port : u16,
|
||||
pub max_pool_size : u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Webserver {
|
||||
pub bind_address : String,
|
||||
|
|
@ -97,6 +107,7 @@ pub struct Webserver {
|
|||
pub struct Settings {
|
||||
pub app : App,
|
||||
pub log : Log,
|
||||
pub database : Database,
|
||||
pub webserver : Webserver,
|
||||
}
|
||||
|
||||
|
|
@ -121,6 +132,14 @@ Ajustes globales y valores predeterminados para las secciones *\[app\]*,
|
|||
"log.prefix" => "tracing.log",
|
||||
"log.format" => "json",
|
||||
|
||||
// [database]
|
||||
"database.db_name" => "dbname",
|
||||
"database.db_user" => "dbuser",
|
||||
"database.db_pass" => "dbpass",
|
||||
"database.db_host" => "localhost",
|
||||
"database.db_port" => 0,
|
||||
"database.max_pool_size" => 5,
|
||||
|
||||
// [webserver]
|
||||
"webserver.bind_address" => "localhost",
|
||||
"webserver.bind_port" => 8088
|
||||
|
|
|
|||
138
src/core/server/app.rs
Normal file
138
src/core/server/app.rs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
use crate::{Lazy, base, locale, trace};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{Server, global, server};
|
||||
use crate::core::theme::register_theme;
|
||||
use crate::core::module::register_module;
|
||||
|
||||
use std::io::Error;
|
||||
use actix_web::middleware::normalize::{NormalizePath, TrailingSlash};
|
||||
|
||||
pub struct Application {
|
||||
server: Server,
|
||||
}
|
||||
|
||||
impl Application {
|
||||
pub async fn build(bootstrap: Option<fn()>) -> Result<Self, Error> {
|
||||
// Imprime rótulo (opcional) de bienvenida.
|
||||
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||
let figfont = figlet_rs::FIGfont::from_content(
|
||||
match SETTINGS.app.startup_banner.to_lowercase().as_str() {
|
||||
"slant" => include_str!("figfonts/slant.flf"),
|
||||
"small" => include_str!("figfonts/small.flf"),
|
||||
"speed" => include_str!("figfonts/speed.flf"),
|
||||
"starwars" => include_str!("figfonts/starwars.flf"),
|
||||
_ => {
|
||||
println!(
|
||||
"FIGfont \"{}\" not found for banner. {}. {}.",
|
||||
SETTINGS.app.startup_banner,
|
||||
"Using \"Small\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
include_str!("figfonts/small.flf")
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
println!("\n{} {}\n\n Powered by PageTop {}\n",
|
||||
figfont.convert(&SETTINGS.app.name).unwrap(),
|
||||
&SETTINGS.app.description,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
}
|
||||
|
||||
// Inicia registro de trazas y eventos.
|
||||
Lazy::force(&server::tracing::TRACING);
|
||||
|
||||
// Valida el identificador de idioma.
|
||||
Lazy::force(&locale::LANGID);
|
||||
|
||||
// Inicializa la conexión con la base de datos.
|
||||
trace::info!(
|
||||
"Connecting to database \"{}\" with a pool of {} connections.",
|
||||
&SETTINGS.database.db_name,
|
||||
&SETTINGS.database.max_pool_size
|
||||
);
|
||||
|
||||
#[cfg(any(feature = "default", feature = "mysql"))]
|
||||
let db_uri = format!(
|
||||
"mysql://{}/{}",
|
||||
&SETTINGS.database.db_host,
|
||||
&SETTINGS.database.db_name
|
||||
);
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
let db_uri = format!(
|
||||
"postgres://{}/{}",
|
||||
&SETTINGS.database.db_host,
|
||||
&SETTINGS.database.db_name
|
||||
);
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
let db_uri = format!("sqlite://{}", &SETTINGS.database.db_name);
|
||||
|
||||
let mut uri = url::Url::parse(&db_uri).unwrap();
|
||||
|
||||
// https://github.com/launchbadge/sqlx/issues/1624
|
||||
|
||||
#[cfg(not(feature = "sqlite"))]
|
||||
uri.set_username(&SETTINGS.database.db_user.as_str()).unwrap();
|
||||
|
||||
#[cfg(not(feature = "sqlite"))]
|
||||
uri.set_password(Some(&SETTINGS.database.db_pass.as_str())).unwrap();
|
||||
|
||||
#[cfg(not(feature = "sqlite"))]
|
||||
if SETTINGS.database.db_port != 0 {
|
||||
uri.set_port(Some(SETTINGS.database.db_port)).unwrap();
|
||||
}
|
||||
|
||||
let mut db_options = sea_orm::ConnectOptions::new(uri.to_string());
|
||||
db_options.max_connections(SETTINGS.database.max_pool_size);
|
||||
|
||||
let mut db_conn = server::dbconn::DBCONN.write().unwrap();
|
||||
*db_conn = Some(
|
||||
sea_orm::Database::connect::<sea_orm::ConnectOptions>(
|
||||
db_options.into()
|
||||
)
|
||||
.await
|
||||
.expect("Failed to connect to database")
|
||||
);
|
||||
|
||||
// Registra los temas predefinidos.
|
||||
register_theme(&base::theme::aliner::AlinerTheme);
|
||||
register_theme(&base::theme::minimal::MinimalTheme);
|
||||
register_theme(&base::theme::bootsier::BootsierTheme);
|
||||
|
||||
// Registra los módulos predeterminados.
|
||||
register_module(&base::module::admin::AdminModule);
|
||||
register_module(&base::module::user::UserModule);
|
||||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
if bootstrap != None {
|
||||
trace::debug!("Calling application bootstrap");
|
||||
let _ = &(bootstrap.unwrap())();
|
||||
}
|
||||
|
||||
// Registra el módulo para la página de inicio de PageTop.
|
||||
// Al ser el último, puede sobrecargarse con la función de inicio.
|
||||
register_module(&base::module::homepage::HomepageModule);
|
||||
|
||||
// Prepara el servidor web.
|
||||
let server = server::HttpServer::new(|| {
|
||||
server::App::new()
|
||||
.wrap(tracing_actix_web::TracingLogger)
|
||||
.wrap(NormalizePath::new(TrailingSlash::Trim))
|
||||
.configure(&global::themes)
|
||||
.configure(&global::modules)
|
||||
})
|
||||
.bind(format!("{}:{}",
|
||||
&SETTINGS.webserver.bind_address,
|
||||
&SETTINGS.webserver.bind_port
|
||||
))?
|
||||
.run();
|
||||
|
||||
Ok(Self { server })
|
||||
}
|
||||
|
||||
pub fn run(self) -> Result<Server, Error> {
|
||||
Ok(self.server)
|
||||
}
|
||||
}
|
||||
8
src/core/server/dbconn.rs
Normal file
8
src/core/server/dbconn.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
use crate::Lazy;
|
||||
use crate::database::DatabaseConnection;
|
||||
|
||||
use std::sync::RwLock;
|
||||
|
||||
pub static DBCONN: Lazy<RwLock<Option<DatabaseConnection>>> = Lazy::new(|| {
|
||||
RwLock::new(None)
|
||||
});
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
use crate::{Lazy, base, locale, trace};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{Server, global, server};
|
||||
use crate::core::theme::register_theme;
|
||||
use crate::core::module::register_module;
|
||||
|
||||
use actix_web::middleware::normalize;
|
||||
|
||||
pub fn run(bootstrap: Option<fn()>) -> Result<Server, std::io::Error> {
|
||||
// Imprime el rótulo (opcional) de bienvenida.
|
||||
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||
let figfont = figlet_rs::FIGfont::from_content(
|
||||
match SETTINGS.app.startup_banner.to_lowercase().as_str() {
|
||||
"slant" => include_str!("figfonts/slant.flf"),
|
||||
"small" => include_str!("figfonts/small.flf"),
|
||||
"speed" => include_str!("figfonts/speed.flf"),
|
||||
"starwars" => include_str!("figfonts/starwars.flf"),
|
||||
_ => {
|
||||
println!(
|
||||
"FIGfont \"{}\" not found for banner. {}. {}.",
|
||||
SETTINGS.app.startup_banner,
|
||||
"Using \"Small\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
include_str!("figfonts/small.flf")
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
println!("\n{} {}\n\n Powered by PageTop {}\n",
|
||||
figfont.convert(&SETTINGS.app.name).unwrap(),
|
||||
&SETTINGS.app.description,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
}
|
||||
|
||||
// Inicia registro de trazas y eventos.
|
||||
Lazy::force(&server::tracing::TRACING);
|
||||
|
||||
// Asigna identificador de idioma.
|
||||
Lazy::force(&locale::LANGID);
|
||||
|
||||
// Registra los temas predefinidos.
|
||||
register_theme(&base::theme::aliner::AlinerTheme);
|
||||
register_theme(&base::theme::minimal::MinimalTheme);
|
||||
register_theme(&base::theme::bootsier::BootsierTheme);
|
||||
|
||||
// Registra los módulos predeterminados.
|
||||
register_module(&base::module::admin::AdminModule);
|
||||
register_module(&base::module::user::UserModule);
|
||||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
if bootstrap != None {
|
||||
trace::debug!("Calling application bootstrap");
|
||||
let _ = &(bootstrap.unwrap())();
|
||||
}
|
||||
|
||||
// Registra el módulo para la página de inicio de PageTop.
|
||||
// Al ser el último, puede sobrecargarse en la función de arranque.
|
||||
register_module(&base::module::homepage::HomepageModule);
|
||||
|
||||
|
||||
// Inicializa el servidor web.
|
||||
let server = server::HttpServer::new(|| {
|
||||
server::App::new()
|
||||
.wrap(tracing_actix_web::TracingLogger)
|
||||
.wrap(normalize::NormalizePath::new(normalize::TrailingSlash::Trim))
|
||||
.configure(&global::themes)
|
||||
.configure(&global::modules)
|
||||
})
|
||||
.bind(format!("{}:{}",
|
||||
&SETTINGS.webserver.bind_address,
|
||||
&SETTINGS.webserver.bind_port
|
||||
))?
|
||||
.run();
|
||||
Ok(server)
|
||||
}
|
||||
|
|
@ -4,5 +4,7 @@ pub use actix_web::{
|
|||
|
||||
mod tracing;
|
||||
|
||||
mod main;
|
||||
pub use main::run;
|
||||
mod dbconn;
|
||||
|
||||
mod app;
|
||||
pub use app::Application;
|
||||
|
|
|
|||
1
src/database.rs
Normal file
1
src/database.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub use sea_orm::DatabaseConnection;
|
||||
|
|
@ -10,8 +10,11 @@ pub use once_cell::sync::Lazy;
|
|||
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.
|
||||
pub mod database; // Acceso a la base de datos.
|
||||
pub mod core; // Servidor web y sistemas para Temas, Módulos y Respuestas.
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ macro_rules! localize {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn l(key: &str) -> String {
|
||||
fn l(key: &str) -> String {
|
||||
LOCALES.lookup(&LANGID, key)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn t(
|
||||
fn t(
|
||||
key: &str,
|
||||
args: &std::collections::HashMap<String, FluentValue>
|
||||
) -> String {
|
||||
|
|
@ -57,7 +57,7 @@ macro_rules! localize {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn e(
|
||||
fn e(
|
||||
key: &str,
|
||||
args: &std::collections::HashMap<String, FluentValue>
|
||||
) -> crate::core::theme::PreEscaped<String> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
pagetop::core::server::run(None)?.await
|
||||
// ```
|
||||
// let app = pagetop::Application::build(None).await?;
|
||||
// app.run()?.await
|
||||
// ```
|
||||
pagetop::Application::build(None).await?.run()?.await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ pub use crate::util;
|
|||
pub use crate::config::SETTINGS;
|
||||
pub use crate::trace;
|
||||
pub use crate::localize;
|
||||
pub use crate::database;
|
||||
|
||||
pub use crate::core::theme::*;
|
||||
pub use crate::core::module::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue