Elimina Refinery y Barrel en favor de SeaORM
Se integran las funcionalidades de SeaORM en el funcionamiento de PageTop para abstraer el uso y acceso a la base de datos.
This commit is contained in:
parent
619b7b73c6
commit
4b5d8ce38a
16 changed files with 150 additions and 98 deletions
29
Cargo.toml
29
Cargo.toml
|
|
@ -25,8 +25,11 @@ categories = [
|
|||
|
||||
[dependencies]
|
||||
doc-comment = "0.3.3"
|
||||
once_cell = "1.9.0"
|
||||
figlet-rs = "0.1.3"
|
||||
downcast-rs = "1.2.0"
|
||||
figlet-rs = "0.1.3"
|
||||
futures = "0.3"
|
||||
once_cell = "1.9.0"
|
||||
url = "2.2.2"
|
||||
|
||||
config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
||||
|
||||
|
|
@ -44,26 +47,22 @@ actix-web-static-files = "3.0.5"
|
|||
maud = { version = "0.23.0", features = ["actix-web"] }
|
||||
sycamore = { version = "0.7.1", features = ["ssr"] }
|
||||
|
||||
downcast-rs = "1.2.0"
|
||||
url = "2.2.2"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.sqlx]
|
||||
version = "0.5.11"
|
||||
features = ["migrate", "runtime-async-std-native-tls"]
|
||||
[dependencies.sea-orm]
|
||||
version = "0.6"
|
||||
features = ["debug-print", "macros", "runtime-async-std-native-tls"]
|
||||
default-features = false
|
||||
|
||||
[dependencies.refinery]
|
||||
version = "0.8.4"
|
||||
|
||||
[dependencies.barrel]
|
||||
version = "0.7.0"
|
||||
[dependencies.sea-schema]
|
||||
version = "0.5"
|
||||
features = ["debug-print", "migration"]
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = ["mysql"]
|
||||
mysql = ["sqlx/mysql", "refinery/mysql", "barrel/mysql"]
|
||||
postgres = ["sqlx/postgres", "refinery/postgres", "barrel/pg"]
|
||||
mysql = ["sea-orm/sqlx-mysql"]
|
||||
postgres = ["sea-orm/sqlx-postgres"]
|
||||
|
||||
[build-dependencies]
|
||||
actix-web-static-files = "3.0.5"
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub fn migration() -> String {
|
||||
let mut m = db::Migration::new();
|
||||
|
||||
m.create_table("system", |t| {
|
||||
t.add_column("id", db::types::primary());
|
||||
t.add_column("title", db::types::varchar(255));
|
||||
t.add_column("is_completed", db::types::boolean().default(false));
|
||||
});
|
||||
|
||||
m.make::<db::Database>()
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("en-US", "src/base/module/admin/locales");
|
||||
embed_migrations!("src/base/module/admin/migrations");
|
||||
|
||||
mod summary;
|
||||
|
||||
|
|
@ -26,8 +25,4 @@ impl Module for AdminModule {
|
|||
.route("", server::web::get().to(summary::summary))
|
||||
);
|
||||
}
|
||||
|
||||
fn configure_migrations(&self) -> Option<db::Migrations> {
|
||||
Some(migrations::runner())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
src/base/module/user/entity/mod.rs
Normal file
1
src/base/module/user/entity/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod user;
|
||||
18
src/base/module/user/entity/user.rs
Normal file
18
src/base/module/user/entity/user.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use crate::db::entity::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
|
||||
#[sea_orm(table_name = "user")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
#[serde(skip_deserializing)]
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
#[sea_orm(column_type = "Text")]
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
use crate::db::migration::*;
|
||||
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table,
|
||||
Id,
|
||||
Title,
|
||||
Text,
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220312_000001_create_table_user"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(User::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(User::Id)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(User::Title)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::Text)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop()
|
||||
.table(User::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
12
src/base/module/user/migration/mod.rs
Normal file
12
src/base/module/user/migration/mod.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
use crate::db::migration::*;
|
||||
|
||||
pub mod m20220312_000001_create_table_user;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![Box::new(m20220312_000001_create_table_user::Migration)]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub fn migration() -> String {
|
||||
let mut m = db::Migration::new();
|
||||
|
||||
m.create_table("user", |t| {
|
||||
t.add_column("id", db::types::primary());
|
||||
t.add_column("title", db::types::varchar(255));
|
||||
t.add_column("is_completed", db::types::boolean().default(false));
|
||||
});
|
||||
|
||||
m.make::<db::Database>()
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("en-US", "src/base/module/user/locales");
|
||||
embed_migrations!("src/base/module/user/migrations");
|
||||
|
||||
mod entity;
|
||||
mod migration;
|
||||
|
||||
pub struct UserModule;
|
||||
|
||||
|
|
@ -22,8 +24,8 @@ impl Module for UserModule {
|
|||
cfg.route("/user/login", server::web::get().to(login));
|
||||
}
|
||||
|
||||
fn configure_migrations(&self) -> Option<db::Migrations> {
|
||||
Some(migrations::runner())
|
||||
fn migrations(&self, dbconn: &db::DbConn) -> Result<(), db::DbErr> {
|
||||
db_migrations!(dbconn)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,15 +42,9 @@ pub fn modules(cfg: &mut server::web::ServiceConfig) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn migrations(db_uri: db::Uri) {
|
||||
let mut conn = refinery::config::Config::try_from(db_uri).unwrap();
|
||||
pub fn migrations(dbconn: &db::DbConn) {
|
||||
for m in MODULES.read().unwrap().iter() {
|
||||
match m.configure_migrations() {
|
||||
Some(migrations) => {
|
||||
migrations.run(&mut conn).expect("Failed to run migrations");
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
m.migrations(dbconn).expect("Failed to run migrations");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ pub trait Module: Send + Sync {
|
|||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
}
|
||||
|
||||
fn configure_migrations(&self) -> Option<db::Migrations> {
|
||||
None
|
||||
#[allow(unused_variables)]
|
||||
fn migrations(&self, dbconn: &db::DbConn) -> Result<(), db::DbErr> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,19 +5,8 @@ use crate::core::theme::register_theme;
|
|||
use crate::core::module::register_module;
|
||||
|
||||
use std::io::Error;
|
||||
use std::sync::RwLock;
|
||||
use actix_web::middleware::normalize::{NormalizePath, TrailingSlash};
|
||||
|
||||
#[cfg(feature = "mysql")]
|
||||
use sqlx::mysql::MySqlPoolOptions as DbPoolOptions;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use sqlx::postgres::PgPoolOptions as DbPoolOptions;
|
||||
|
||||
static DBCONN: Lazy<RwLock<Option<db::Conn>>> = Lazy::new(|| {
|
||||
RwLock::new(None)
|
||||
});
|
||||
|
||||
pub struct Application {
|
||||
server: Server,
|
||||
}
|
||||
|
|
@ -70,7 +59,7 @@ impl Application {
|
|||
let db_type = "postgres";
|
||||
|
||||
// https://github.com/launchbadge/sqlx/issues/1624
|
||||
let mut db_uri = db::Uri::parse(format!(
|
||||
let mut db_uri = db::DbUri::parse(format!(
|
||||
"{}://{}/{}",
|
||||
db_type,
|
||||
&SETTINGS.database.db_host,
|
||||
|
|
@ -82,14 +71,14 @@ impl Application {
|
|||
db_uri.set_port(Some(SETTINGS.database.db_port)).unwrap();
|
||||
}
|
||||
|
||||
let db_pool = DbPoolOptions::new()
|
||||
.max_connections(SETTINGS.database.max_pool_size)
|
||||
.connect(db_uri.as_str())
|
||||
.await
|
||||
.expect("Failed to connect to database");
|
||||
let mut db_options = sea_orm::ConnectOptions::new(db_uri.to_string());
|
||||
db_options.max_connections(SETTINGS.database.max_pool_size);
|
||||
|
||||
let mut dbconn = DBCONN.write().unwrap();
|
||||
*dbconn = Some(db_pool);
|
||||
let dbconn = 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);
|
||||
|
|
@ -112,13 +101,14 @@ impl Application {
|
|||
|
||||
// Run migrations.
|
||||
trace::info!("Running migrations.");
|
||||
global::migrations(db_uri);
|
||||
global::migrations(&dbconn);
|
||||
|
||||
// Prepara el servidor web.
|
||||
let server = server::HttpServer::new(|| {
|
||||
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)
|
||||
})
|
||||
|
|
|
|||
23
src/db.rs
23
src/db.rs
|
|
@ -1,17 +1,14 @@
|
|||
pub use url::Url as Uri;
|
||||
pub use url::Url as DbUri;
|
||||
|
||||
#[cfg(feature = "mysql")]
|
||||
pub use {
|
||||
barrel::backend::MySql as Database,
|
||||
sqlx::MySqlPool as Conn,
|
||||
pub use sea_orm::{
|
||||
DbErr,
|
||||
DatabaseConnection as DbConn,
|
||||
};
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
pub use {
|
||||
barrel::backend::Pg as Database,
|
||||
sqlx::PgPool as Conn,
|
||||
};
|
||||
pub mod entity {
|
||||
pub use sea_orm::entity::prelude::*;
|
||||
}
|
||||
|
||||
pub use barrel::{Migration, types};
|
||||
pub use refinery::embed_migrations;
|
||||
pub use refinery::Runner as Migrations;
|
||||
pub mod migration {
|
||||
pub use sea_schema::migration::prelude::*;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
pub use doc_comment::doc_comment;
|
||||
pub use once_cell::sync::Lazy;
|
||||
pub use futures::executor::block_on as run_now;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// APIs públicas.
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
//! Re-exporta recursos comunes.
|
||||
|
||||
pub use crate::args;
|
||||
pub use crate::util;
|
||||
pub use crate::{
|
||||
args,
|
||||
db_migrations,
|
||||
};
|
||||
|
||||
pub use crate::config::SETTINGS;
|
||||
pub use crate::trace;
|
||||
pub use crate::localize;
|
||||
|
||||
pub use crate::db;
|
||||
pub use crate::db::embed_migrations;
|
||||
|
||||
pub use crate::core::theme::*;
|
||||
pub use crate::core::module::*;
|
||||
|
|
@ -16,3 +17,5 @@ pub use crate::core::response::page::*;
|
|||
pub use crate::core::server;
|
||||
|
||||
pub use crate::base::component::*;
|
||||
|
||||
pub use crate::util;
|
||||
|
|
|
|||
15
src/util.rs
15
src/util.rs
|
|
@ -9,15 +9,26 @@
|
|||
/// ];
|
||||
/// ```
|
||||
macro_rules! args {
|
||||
( $($key:expr => $value:expr),* ) => {{
|
||||
( $($KEY:expr => $VALUE:expr),* ) => {{
|
||||
let mut a = std::collections::HashMap::new();
|
||||
$(
|
||||
a.insert(String::from($key), $value.into());
|
||||
a.insert(String::from($KEY), $VALUE.into());
|
||||
)*
|
||||
a
|
||||
}};
|
||||
}
|
||||
|
||||
#[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