Add database module
This commit is contained in:
parent
e91fd0f2bf
commit
c4c5ef0027
7 changed files with 185 additions and 72 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -775,6 +775,7 @@ name = "dpts"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dpts-csv",
|
||||
"dpts-database",
|
||||
"dpts-entity",
|
||||
"dpts-error",
|
||||
"dpts-migration",
|
||||
|
@ -800,6 +801,21 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dpts-database"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-graphql",
|
||||
"axum",
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"dpts-entity",
|
||||
"dpts-migration",
|
||||
"log",
|
||||
"sea-orm",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dpts-entity"
|
||||
version = "0.1.0"
|
||||
|
@ -808,6 +824,7 @@ dependencies = [
|
|||
"axum",
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"dpts-database",
|
||||
"dpts-migration",
|
||||
"log",
|
||||
"sea-orm",
|
||||
|
|
|
@ -10,6 +10,7 @@ dpts-csv = { workspace = true }
|
|||
dpts-entity = { workspace = true }
|
||||
dpts-error = { workspace = true }
|
||||
dpts-migration = { workspace = true }
|
||||
dpts-database = { workspace = true }
|
||||
|
||||
[workspace]
|
||||
members = [".", "dpts-*"]
|
||||
|
@ -17,13 +18,14 @@ members = [".", "dpts-*"]
|
|||
[workspace.dependencies]
|
||||
dpts = { path = "." }
|
||||
dpts-csv = { path = "dpts-csv" }
|
||||
dpts-database = { path = "dpts-database" }
|
||||
dpts-entity = { path = "dpts-entity" }
|
||||
dpts-error = { path = "dpts-error" }
|
||||
dpts-migration = {path = "dpts-migration"}
|
||||
chrono = {version = "0.4", features = ["serde"]}
|
||||
clap = "4.5"
|
||||
dotenv = "0.15.0"
|
||||
serde = "1.0.219"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
|
|
31
dpts-database/Cargo.toml
Normal file
31
dpts-database/Cargo.toml
Normal file
|
@ -0,0 +1,31 @@
|
|||
[package]
|
||||
name = "dpts-database"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
test = []
|
||||
|
||||
[dependencies]
|
||||
dpts-entity = { workspace = true }
|
||||
dpts-migration = { workspace = true }
|
||||
async-graphql = {version = "7.0", features = ["chrono"]}
|
||||
axum = "0.8"
|
||||
chrono = {workspace = true}
|
||||
dotenv = {workspace = true}
|
||||
log = "0.4.27"
|
||||
tokio = "1.44.2"
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "1.1"
|
||||
features = [
|
||||
"macros",
|
||||
"debug-print",
|
||||
"runtime-tokio-native-tls",
|
||||
"sqlx-sqlite",
|
||||
"with-chrono",
|
||||
]
|
||||
default-features = false
|
123
dpts-database/src/connection.rs
Normal file
123
dpts-database/src/connection.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use std::time::Duration;
|
||||
use sea_orm::{entity::*, query::*, ConnectOptions, Database, DatabaseConnection};
|
||||
use dpts_migration::{Migrator, MigratorTrait};
|
||||
|
||||
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
pub struct OnceDatabaseConnection {
|
||||
inner: OnceCell<DatabaseConnection>,
|
||||
}
|
||||
|
||||
impl OnceDatabaseConnection {
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
inner: OnceCell::const_new(),
|
||||
}
|
||||
}
|
||||
pub fn get(&self) -> Option<&DatabaseConnection> {
|
||||
self.inner.get()
|
||||
}
|
||||
pub async fn get_or_init<F, T>(&self, f: F) -> &DatabaseConnection where
|
||||
F: FnOnce() -> T,
|
||||
T: Future<Output = DatabaseConnection>
|
||||
{
|
||||
self.inner.get_or_init(f).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub async fn init_test(&self) {
|
||||
self.get_or_init( || async {
|
||||
let mut opt = ConnectOptions::new("sqlite::memory:");
|
||||
opt.max_connections(100)
|
||||
.min_connections(5)
|
||||
.connect_timeout(Duration::from_secs(8))
|
||||
.acquire_timeout(Duration::from_secs(8))
|
||||
.idle_timeout(Duration::from_secs(8))
|
||||
.max_lifetime(Duration::from_secs(8))
|
||||
.sqlx_logging(true)
|
||||
.sqlx_logging_level(log::LevelFilter::Info);
|
||||
//.set_schema_search_path("my_schema"); // Setting default PostgreSQL schema
|
||||
let db = Database::connect(opt).await.unwrap();
|
||||
Migrator::fresh(&db).await.unwrap();
|
||||
db
|
||||
}).await;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub static DATABASE_CONNECTION: OnceDatabaseConnection = OnceDatabaseConnection::new();
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::time::Duration;
|
||||
use chrono::{offset, FixedOffset, Local, TimeZone};
|
||||
use sea_orm::{entity::*, query::*, ConnectOptions, Database};
|
||||
use dpts_migration::{Migrator, MigratorTrait};
|
||||
use dpts_entity::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn check_database_connection() {
|
||||
DATABASE_CONNECTION.init_test().await;
|
||||
let db = DATABASE_CONNECTION.get().unwrap();
|
||||
assert!(db.ping().await.is_ok());
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn check_insert_entity() {
|
||||
DATABASE_CONNECTION.init_test().await;
|
||||
let db = DATABASE_CONNECTION.get().unwrap();
|
||||
|
||||
|
||||
let local_date_time = Local::now();
|
||||
let offset_date_time = local_date_time.with_timezone(local_date_time.offset());
|
||||
|
||||
let user = UserActiveModel{
|
||||
login_name: Set("admin".to_owned()),
|
||||
password_hash: Set("admin".to_owned()),
|
||||
created_at: Set(offset_date_time),
|
||||
updated_at: Set(offset_date_time),
|
||||
..Default::default()
|
||||
}.insert(db)
|
||||
.await.unwrap();
|
||||
|
||||
|
||||
let record_tag = RecordTagActiveModel{
|
||||
user_id: Set(user.id),
|
||||
name: Set("test".to_owned()),
|
||||
..Default::default()
|
||||
}.insert(db)
|
||||
.await.unwrap();
|
||||
|
||||
let record_header = RecordHeaderActiveModel{
|
||||
user_id: Set(user.id),
|
||||
created_at: Set(offset_date_time),
|
||||
updated_at: Set(offset_date_time),
|
||||
recorded_at: Set(offset_date_time),
|
||||
comment: Set("".to_owned()),
|
||||
..Default::default()
|
||||
}.insert(db)
|
||||
.await.unwrap();
|
||||
|
||||
RecordDetailActiveModel {
|
||||
record_header_id: Set(record_header.id),
|
||||
record_tag_id: Set(record_tag.id),
|
||||
count: Set(1),
|
||||
..Default::default()
|
||||
}.insert(db)
|
||||
.await.unwrap();
|
||||
RecordDetailActiveModel {
|
||||
record_header_id: Set(record_header.id),
|
||||
record_tag_id: Set(record_tag.id),
|
||||
count: Set(2),
|
||||
..Default::default()
|
||||
}.insert(db)
|
||||
.await.unwrap();
|
||||
|
||||
|
||||
Migrator::reset(db).await.unwrap();
|
||||
db.clone().close().await.unwrap();
|
||||
}
|
||||
}
|
7
dpts-database/src/lib.rs
Normal file
7
dpts-database/src/lib.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
mod connection;
|
||||
|
||||
pub use connection::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
}
|
|
@ -12,7 +12,7 @@ axum = "0.8"
|
|||
chrono = {workspace = true}
|
||||
dotenv = {workspace = true}
|
||||
log = "0.4.27"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde = { workspace = true }
|
||||
tokio = "1.44.2"
|
||||
|
||||
[dependencies.sea-orm]
|
||||
|
@ -25,3 +25,6 @@ features = [
|
|||
"with-chrono",
|
||||
]
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies]
|
||||
dpts-database = { workspace = true, features = ["test"] }
|
|
@ -1,70 +0,0 @@
|
|||
use std::time::Duration;
|
||||
use chrono::{offset, FixedOffset, Local, TimeZone};
|
||||
use sea_orm::{entity::*, query::*, ConnectOptions, Database};
|
||||
use dpts_migration::{Migrator, MigratorTrait};
|
||||
use dpts_entity::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn main() {
|
||||
let mut opt = ConnectOptions::new("sqlite::memory:");
|
||||
opt.max_connections(100)
|
||||
.min_connections(5)
|
||||
.connect_timeout(Duration::from_secs(8))
|
||||
.acquire_timeout(Duration::from_secs(8))
|
||||
.idle_timeout(Duration::from_secs(8))
|
||||
.max_lifetime(Duration::from_secs(8))
|
||||
.sqlx_logging(true)
|
||||
.sqlx_logging_level(log::LevelFilter::Info);
|
||||
//.set_schema_search_path("my_schema"); // Setting default PostgreSQL schema
|
||||
let db= Database::connect(opt).await.unwrap();
|
||||
Migrator::fresh(&db).await.unwrap();
|
||||
|
||||
let local_date_time = Local::now();
|
||||
let offset_date_time = local_date_time.with_timezone(local_date_time.offset());
|
||||
|
||||
let user = UserActiveModel{
|
||||
login_name: Set("admin".to_owned()),
|
||||
password_hash: Set("admin".to_owned()),
|
||||
created_at: Set(offset_date_time),
|
||||
updated_at: Set(offset_date_time),
|
||||
..Default::default()
|
||||
}.insert(&db)
|
||||
.await.unwrap();
|
||||
|
||||
|
||||
let record_tag = RecordTagActiveModel{
|
||||
user_id: Set(user.id),
|
||||
name: Set("test".to_owned()),
|
||||
..Default::default()
|
||||
}.insert(&db)
|
||||
.await.unwrap();
|
||||
|
||||
let record_header = RecordHeaderActiveModel{
|
||||
user_id: Set(user.id),
|
||||
created_at: Set(offset_date_time),
|
||||
updated_at: Set(offset_date_time),
|
||||
recorded_at: Set(offset_date_time),
|
||||
comment: Set("".to_owned()),
|
||||
..Default::default()
|
||||
}.insert(&db)
|
||||
.await.unwrap();
|
||||
|
||||
RecordDetailActiveModel {
|
||||
record_header_id: Set(record_header.id),
|
||||
record_tag_id: Set(record_tag.id),
|
||||
count: Set(1),
|
||||
..Default::default()
|
||||
}.insert(&db)
|
||||
.await.unwrap();
|
||||
RecordDetailActiveModel {
|
||||
record_header_id: Set(record_header.id),
|
||||
record_tag_id: Set(record_tag.id),
|
||||
count: Set(2),
|
||||
..Default::default()
|
||||
}.insert(&db)
|
||||
.await.unwrap();
|
||||
|
||||
|
||||
Migrator::reset(&db).await.unwrap();
|
||||
db.close().await.unwrap();
|
||||
}
|
Loading…
Add table
Reference in a new issue