Añade funciones de acceso básico a base de datos

This commit is contained in:
Manuel Cillero 2022-04-24 18:44:37 +02:00
parent d4c6a3b2f3
commit e7f9bf8778
17 changed files with 99 additions and 75 deletions

View file

@ -24,7 +24,7 @@ impl ModuleTrait for NodeModule {
cfg.route("/node", app::web::get().to(node)); cfg.route("/node", app::web::get().to(node));
} }
fn migrations(&self) -> Vec<Box<dyn db::migration::MigrationTrait>> { fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
vec![ vec![
boxed_migration!(m20220316_000001_create_table_node_type), boxed_migration!(m20220316_000001_create_table_node_type),
boxed_migration!(m20220316_000002_create_table_node), boxed_migration!(m20220316_000002_create_table_node),

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
/// Stores information about all defined {node} types. /// Stores information about all defined {node} types.
#[derive(Iden)] #[derive(Iden)]

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
/// The base table for nodes. /// The base table for nodes.
#[derive(Iden)] #[derive(Iden)]

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
// Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes. // Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.
#[derive(Iden)] #[derive(Iden)]

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
// Stores information about each saved version of a {node}. // Stores information about each saved version of a {node}.
#[derive(Iden)] #[derive(Iden)]

View file

@ -23,7 +23,7 @@ impl ModuleTrait for UserModule {
cfg.route("/user/login", app::web::get().to(login)); cfg.route("/user/login", app::web::get().to(login));
} }
fn migrations(&self) -> Vec<Box<dyn db::migration::MigrationTrait>> { fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
vec![ vec![
boxed_migration!(m20220312_000001_create_table_role), boxed_migration!(m20220312_000001_create_table_role),
boxed_migration!(m20220312_000002_create_table_role_permission), boxed_migration!(m20220312_000002_create_table_role_permission),

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
#[derive(Iden)] #[derive(Iden)]
enum Role { Table, enum Role { Table,
@ -12,49 +12,55 @@ pub struct Migration;
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager manager.create_table(
.create_table( // Store user roles.
// Store user roles. Table::create()
Table::create() .table(Role::Table)
.table(Role::Table) .if_not_exists()
.if_not_exists() // Primary Key: Unique role ID.
// Primary Key: Unique role ID. .col(ColumnDef::new(Role::Rid)
.col(ColumnDef::new(Role::Rid) .unsigned()
.unsigned() .not_null()
.not_null() .auto_increment()
.auto_increment() .primary_key()
.primary_key() )
) // Unique role name.
// Unique role name. .col(ColumnDef::new(Role::Name)
.col(ColumnDef::new(Role::Name) .string_len(64)
.string_len(64) .not_null()
.not_null() .unique_key()
.unique_key() )
) // The weight of this role in listings and the user interface.
// The weight of this role in listings and the user interface. .col(ColumnDef::new(Role::Weight)
.col(ColumnDef::new(Role::Weight) .integer()
.integer() .not_null()
.not_null() .default(0)
.default(0) )
) // INDEXES.
// INDEXES. .index(Index::create()
.index(Index::create() .name("name-weight")
.name("name-weight") .col(Role::Name)
.col(Role::Name) .col(Role::Weight)
.col(Role::Weight) )
) .to_owned()
.to_owned() )
) .await?;
.await
app::db::exec::<InsertStatement>(Query::insert()
.into_table(Role::Table)
.columns(vec![Role::Name])
.values_panic(vec!["anonymous".into()])
.values_panic(vec!["authenticated".into()])
)
.await.map(|_| ())
} }
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager manager.drop_table(Table::drop()
.drop_table(Table::drop() .table(Role::Table)
.table(Role::Table) .to_owned()
.to_owned() )
) .await
.await
} }
} }

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
#[derive(Iden)] #[derive(Iden)]
enum RolePermission { Table, enum RolePermission { Table,

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
#[derive(Iden)] #[derive(Iden)]
enum User { Table, enum User { Table,

View file

@ -1,4 +1,4 @@
use pagetop::db::migration::*; use pagetop::prelude::*;
#[derive(Iden)] #[derive(Iden)]
enum UserRole { Table, enum UserRole { Table,

View file

@ -21,7 +21,5 @@ default-features = false
actix-web = "3.3.3" actix-web = "3.3.3"
# Si se usa la macro html!: # Si se usa la macro html!:
maud = { version = "0.23.0" } maud = { version = "0.23.0" }
# Si se usa base de datos:
sea-orm = { version = "0.7.1" }
# Si se requiere serialización de estructuras de datos: # Si se requiere serialización de estructuras de datos:
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View file

@ -10,7 +10,5 @@ edition = "2021"
pagetop = { path = "../pagetop" } pagetop = { path = "../pagetop" }
# Si se usa la macro html!: # Si se usa la macro html!:
maud = { version = "0.23.0" } maud = { version = "0.23.0" }
# Si se usa base de datos:
sea-orm = { version = "0.7.1" }
# Si se requiere serialización de estructuras de datos: # Si se requiere serialización de estructuras de datos:
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View file

@ -1,10 +1,11 @@
use crate::{Lazy, db, run_now, trace}; use crate::{Lazy, run_now, trace};
use crate::config::SETTINGS; use crate::config::SETTINGS;
use crate::db::*;
use sea_orm::{ConnectOptions, Database}; use sea_orm::{ConnectionTrait, ConnectOptions, Database, DatabaseBackend, Statement};
use tracing_unwrap::ResultExt; use tracing_unwrap::ResultExt;
pub static DBCONN: Lazy<db::DbConn> = Lazy::new(|| { pub static DBCONN: Lazy<DbConn> = Lazy::new(|| {
trace::info!( trace::info!(
"Connecting to database \"{}\" using a pool of {} connections", "Connecting to database \"{}\" using a pool of {} connections",
&SETTINGS.database.db_name, &SETTINGS.database.db_name,
@ -13,7 +14,7 @@ pub static DBCONN: Lazy<db::DbConn> = Lazy::new(|| {
let db_uri = match SETTINGS.database.db_type.as_str() { let db_uri = match SETTINGS.database.db_type.as_str() {
"mysql" | "postgres" => { "mysql" | "postgres" => {
let mut tmp_uri = db::DbUri::parse(format!( let mut tmp_uri = DbUri::parse(format!(
"{}://{}/{}", "{}://{}/{}",
&SETTINGS.database.db_type, &SETTINGS.database.db_type,
&SETTINGS.database.db_host, &SETTINGS.database.db_host,
@ -33,7 +34,7 @@ pub static DBCONN: Lazy<db::DbConn> = Lazy::new(|| {
} }
tmp_uri tmp_uri
}, },
"sqlite" => db::DbUri::parse( "sqlite" => DbUri::parse(
format!("{}://{}", format!("{}://{}",
&SETTINGS.database.db_type, &SETTINGS.database.db_type,
&SETTINGS.database.db_name &SETTINGS.database.db_name
@ -43,7 +44,7 @@ pub static DBCONN: Lazy<db::DbConn> = Lazy::new(|| {
"Unrecognized database type \"{}\"", "Unrecognized database type \"{}\"",
&SETTINGS.database.db_type &SETTINGS.database.db_type
); );
db::DbUri::parse("").unwrap() DbUri::parse("").unwrap()
} }
}; };
@ -55,3 +56,34 @@ pub static DBCONN: Lazy<db::DbConn> = Lazy::new(|| {
}) })
).expect_or_log("Failed to connect to database") ).expect_or_log("Failed to connect to database")
}); });
static DBBACKEND: Lazy<DatabaseBackend> = Lazy::new(|| {
DBCONN.get_database_backend()
});
pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Vec<QueryResult>, DbErr> {
DBCONN.query_all(Statement::from_string(
*DBBACKEND,
match *DBBACKEND {
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
}
)).await
}
pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Option<QueryResult>, DbErr> {
DBCONN.query_one(Statement::from_string(
*DBBACKEND,
match *DBBACKEND {
DatabaseBackend::MySql => stmt.to_string(MysqlQueryBuilder),
DatabaseBackend::Postgres => stmt.to_string(PostgresQueryBuilder),
DatabaseBackend::Sqlite => stmt.to_string(SqliteQueryBuilder),
}
)).await
}
pub async fn exec_raw(stmt: String) -> Result<ExecResult, DbErr> {
DBCONN.execute(Statement::from_string(*DBBACKEND, stmt)).await
}

View file

@ -1,18 +1,8 @@
pub use url::Url as DbUri; pub use url::Url as DbUri;
pub use sea_orm::{ pub use sea_orm::{DatabaseConnection as DbConn, ExecResult, QueryResult};
DbErr,
DatabaseConnection as DbConn,
};
pub mod entity { pub use sea_schema::migration::prelude::*;
pub use sea_orm::entity::prelude::*;
}
pub mod migration {
pub use sea_schema::migration::prelude::*;
pub use crate::module_name;
}
#[macro_export] #[macro_export]
macro_rules! boxed_migration { macro_rules! boxed_migration {

View file

@ -1,5 +1,5 @@
use crate::{Lazy, app, run_now, trace}; use crate::{Lazy, app, run_now, trace};
use crate::db::migration::*; use crate::db::*;
use super::ModuleTrait; use super::ModuleTrait;
use std::sync::RwLock; use std::sync::RwLock;

View file

@ -23,7 +23,7 @@ pub trait ModuleTrait: Send + Sync {
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
#[allow(unused_variables)] #[allow(unused_variables)]
fn migrations(&self) -> Vec<Box<dyn db::migration::MigrationTrait>> { fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
vec![] vec![]
} }
} }

View file

@ -13,7 +13,7 @@ pub use crate::trace;
pub use crate::localize; pub use crate::localize;
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
pub use crate::{db, boxed_migration}; pub use crate::{db, db::*, boxed_migration};
pub use crate::html::*; pub use crate::html::*;
pub use crate::theme::*; pub use crate::theme::*;