Update global database connection
This commit is contained in:
parent
47da8152e6
commit
7f8000ef42
16 changed files with 415 additions and 58 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2287,6 +2287,7 @@ dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"log",
|
"log",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
|
"sea-orm-migration",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -2313,6 +2314,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"progress-pile-core",
|
"progress-pile-core",
|
||||||
"rand 0.9.1",
|
"rand 0.9.1",
|
||||||
|
"sea-orm",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
|
@ -20,18 +20,22 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use sea_orm::entity::*;
|
use progress_pile_core::global::GlobalDatabase;
|
||||||
|
use sea_orm::{entity::*, DatabaseConnection};
|
||||||
use progress_pile_migration::{ClientMigrator, MigratorTrait};
|
use progress_pile_migration::{ClientMigrator, MigratorTrait};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::database_connection::DATABASE_CONNECTION;
|
use crate::error::Error;
|
||||||
|
|
||||||
|
async fn get_or_try_init_test_database() -> Result<&'static DatabaseConnection, Error> {
|
||||||
|
Ok(GlobalDatabase::get_or_try_init("sqlite::memory:", ClientMigrator).await?)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn check_insert_entity() {
|
async fn check_insert_entity() {
|
||||||
let db = DATABASE_CONNECTION.get_or_init("sqlite::memory:").await;
|
let db = get_or_try_init_test_database().await.unwrap();
|
||||||
ClientMigrator::up(db, None).await.unwrap();
|
|
||||||
let local_date_time = Local::now();
|
|
||||||
let offset_date_time = local_date_time.with_timezone(local_date_time.offset());
|
|
||||||
|
|
||||||
let category = ProgressCategoryActiveModel{
|
let category = ProgressCategoryActiveModel{
|
||||||
name: Set("test_category".to_owned()),
|
name: Set("test_category".to_owned()),
|
||||||
|
@ -42,8 +46,10 @@ mod tests {
|
||||||
progress_category_id: Set(category.id),
|
progress_category_id: Set(category.id),
|
||||||
..ProgressEntryActiveModel::new()
|
..ProgressEntryActiveModel::new()
|
||||||
}.insert(db).await.unwrap();
|
}.insert(db).await.unwrap();
|
||||||
|
}
|
||||||
ClientMigrator::reset(db).await.unwrap();
|
#[tokio::test]
|
||||||
//db.clone().close().await.unwrap();
|
async fn connect_database () {
|
||||||
|
let db = get_or_try_init_test_database().await.unwrap();
|
||||||
|
assert!(db.ping().await.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,9 @@ pub mod auth;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
|
|
||||||
pub use progress_pile_core::*;
|
pub use progress_pile_core::{
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ repository.workspace = true
|
||||||
[features]
|
[features]
|
||||||
default = ["clap",]
|
default = ["clap",]
|
||||||
clap = ["dep:clap"]
|
clap = ["dep:clap"]
|
||||||
|
postgres = ["sea-orm/sqlx-postgres", "sea-orm/sqlx-postgres"]
|
||||||
|
server = ["clap", "postgres"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-graphql.workspace = true
|
async-graphql.workspace = true
|
||||||
|
@ -21,6 +23,7 @@ dotenv = {workspace = true}
|
||||||
iana-time-zone = "0.1.63"
|
iana-time-zone = "0.1.63"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
sea-orm.workspace = true
|
sea-orm.workspace = true
|
||||||
|
sea-orm-migration.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
use crate::config::{
|
|
||||||
DATABASE_CONFIG,
|
|
||||||
DatabaseConfig
|
|
||||||
};
|
|
||||||
use std::time::Duration;
|
|
||||||
use sea_orm::{entity::*, query::*, ConnectOptions, Database, DatabaseConnection};
|
|
||||||
|
|
||||||
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<T>(&self, c: T) -> &DatabaseConnection where
|
|
||||||
T: Into<ConnectOptions>
|
|
||||||
{
|
|
||||||
self.inner.get_or_init(|| async {
|
|
||||||
Database::connect(c).await.unwrap()
|
|
||||||
}).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub static DATABASE_CONNECTION: OnceDatabaseConnection = OnceDatabaseConnection::new();
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
//#[tokio::test]
|
|
||||||
async fn check_database_connection() {
|
|
||||||
DATABASE_CONNECTION.get_or_init("sqlite::memory:").await;
|
|
||||||
let db = DATABASE_CONNECTION.get().unwrap();
|
|
||||||
assert!(db.ping().await.is_ok());
|
|
||||||
}
|
|
||||||
}
|
|
0
progress-pile-core/src/global/config.rs
Normal file
0
progress-pile-core/src/global/config.rs
Normal file
63
progress-pile-core/src/global/database.rs
Normal file
63
progress-pile-core/src/global/database.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::error::Error;
|
||||||
|
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
||||||
|
|
||||||
|
use sea_orm_migration::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_try_init<T, U>(&self, options: T, _: U) -> Result<&DatabaseConnection, Error> where
|
||||||
|
T: Into<ConnectOptions>,
|
||||||
|
U: MigratorTrait
|
||||||
|
{
|
||||||
|
self.inner.get_or_try_init(|| async {
|
||||||
|
let db = Database::connect(options).await?;
|
||||||
|
U::up(&db, None).await?;
|
||||||
|
Ok(db)
|
||||||
|
}).await
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub static DATABASE_CONNECTION: OnceDatabaseConnection = OnceDatabaseConnection::new();
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub static DATABASE_CONNECTION: OnceCell<DatabaseConnection> = OnceCell::const_new();
|
||||||
|
|
||||||
|
pub struct GlobalDatabase;
|
||||||
|
|
||||||
|
impl GlobalDatabase {
|
||||||
|
pub fn get() -> Option<&'static DatabaseConnection> {
|
||||||
|
DATABASE_CONNECTION.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_or_try_init<T, U>(options: T, _: U) -> Result<&'static DatabaseConnection, Error> where
|
||||||
|
T: Into<ConnectOptions>,
|
||||||
|
U: MigratorTrait
|
||||||
|
{
|
||||||
|
DATABASE_CONNECTION.get_or_try_init(|| async {
|
||||||
|
let db = Database::connect(options).await?;
|
||||||
|
U::up(&db, None).await?;
|
||||||
|
Ok(db)
|
||||||
|
}).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
}
|
4
progress-pile-core/src/global/mod.rs
Normal file
4
progress-pile-core/src/global/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod config;
|
||||||
|
mod database;
|
||||||
|
|
||||||
|
pub use database::GlobalDatabase;
|
|
@ -1,8 +1,8 @@
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod csv;
|
pub mod csv;
|
||||||
pub mod database_connection;
|
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
pub mod global;
|
||||||
pub mod graphql;
|
pub mod graphql;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -12,6 +12,7 @@ axum = "0.8.4"
|
||||||
clap = {workspace = true, features = ["derive"]}
|
clap = {workspace = true, features = ["derive"]}
|
||||||
progress-pile-core = {workspace = true}
|
progress-pile-core = {workspace = true}
|
||||||
chrono = {workspace = true}
|
chrono = {workspace = true}
|
||||||
|
sea-orm = { workspace = true, features = ["sqlx-postgres"] }
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
55
progress-pile-server/src/entity/access_token.rs
Normal file
55
progress-pile-server/src/entity/access_token.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
use core::time;
|
||||||
|
|
||||||
|
use async_graphql::*;
|
||||||
|
use chrono::Local;
|
||||||
|
use sea_orm::entity::{
|
||||||
|
Set,
|
||||||
|
prelude::*
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize, SimpleObject)]
|
||||||
|
#[sea_orm(table_name = "access_token")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub user_id: i32,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub token_value: String,
|
||||||
|
pub note: String,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub created_at: DateTimeWithTimeZone,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub updated_at: DateTimeWithTimeZone,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub expired_at: Option<DateTimeWithTimeZone>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::user::Entity",
|
||||||
|
from = "Column::UserId",
|
||||||
|
to = "super::user::Column::Id"
|
||||||
|
)]
|
||||||
|
User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::user::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::User.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ActiveModel {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let timestamp = Local::now().fixed_offset();
|
||||||
|
Self{
|
||||||
|
note: Set("".to_string()),
|
||||||
|
created_at: Set(timestamp),
|
||||||
|
updated_at: Set(timestamp),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
112
progress-pile-server/src/entity/mod.rs
Normal file
112
progress-pile-server/src/entity/mod.rs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
mod access_token;
|
||||||
|
mod progress_category;
|
||||||
|
mod progress_entry;
|
||||||
|
mod user;
|
||||||
|
|
||||||
|
|
||||||
|
pub use access_token::{
|
||||||
|
ActiveModel as AccessTokenActiveModel,
|
||||||
|
Column as AccessTokenColumn,
|
||||||
|
Entity as AccessTokenEntity,
|
||||||
|
Model as AccessTokenModel,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub use progress_category::{
|
||||||
|
ActiveModel as ProgressCategoryActiveModel,
|
||||||
|
Column as ProgressCategoryColumn,
|
||||||
|
Entity as ProgressCategoryEntity,
|
||||||
|
Model as ProgressCategoryModel,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub use progress_entry::{
|
||||||
|
ActiveModel as ProgressEntryActiveModel,
|
||||||
|
Column as ProgressEntryColumn,
|
||||||
|
Entity as ProgressEntryEntity,
|
||||||
|
Model as ProgressEntryModel,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub use user::{
|
||||||
|
ActiveModel as UserActiveModel,
|
||||||
|
Column as UserColumn,
|
||||||
|
Entity as UserEntity,
|
||||||
|
Model as UserModel,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub use progress_pile_core::entity::*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
use chrono::{offset, FixedOffset, Local, TimeZone};
|
||||||
|
use sea_orm::{entity::*, query::*, ConnectOptions, Database};
|
||||||
|
use progress_pile_migration_server::{Migrator, MigratorTrait};
|
||||||
|
use crate::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();
|
||||||
|
}
|
||||||
|
}
|
43
progress-pile-server/src/entity/progress_category.rs
Normal file
43
progress-pile-server/src/entity/progress_category.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use async_graphql::*;
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize, SimpleObject)]
|
||||||
|
#[sea_orm(table_name = "record_tag")]
|
||||||
|
#[graphql(concrete(name = "RecordTag", params()))]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
pub user_id: i32,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::record_detail::Entity")]
|
||||||
|
RecordDetail,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::user::Entity",
|
||||||
|
from = "Column::UserId",
|
||||||
|
to = "super::user::Column::Id"
|
||||||
|
)]
|
||||||
|
User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::record_detail::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::RecordDetail.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::user::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::User.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
46
progress-pile-server/src/entity/progress_entry.rs
Normal file
46
progress-pile-server/src/entity/progress_entry.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
use async_graphql::*;
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize, SimpleObject)]
|
||||||
|
#[sea_orm(table_name = "record_detail")]
|
||||||
|
#[graphql(concrete(name = "RecordDetail", params()))]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
pub record_header_id: i32,
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
pub record_tag_id: i32,
|
||||||
|
pub count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::record_header::Entity",
|
||||||
|
from = "Column::RecordHeaderId",
|
||||||
|
to = "super::record_header::Column::Id"
|
||||||
|
)]
|
||||||
|
RecordHeader,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::record_tag::Entity",
|
||||||
|
from = "Column::RecordTagId",
|
||||||
|
to = "super::record_tag::Column::Id"
|
||||||
|
)]
|
||||||
|
RecordTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::record_header::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::RecordHeader.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::record_tag::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::RecordTag.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
65
progress-pile-server/src/entity/user.rs
Normal file
65
progress-pile-server/src/entity/user.rs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
use async_graphql::SimpleObject;
|
||||||
|
use chrono::{DateTime, FixedOffset, Local,};
|
||||||
|
use sea_orm::{entity::prelude::*, ActiveValue::Set};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, SimpleObject, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "user")]
|
||||||
|
#[graphql(concrete(name = "User", params()))]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
pub id: i32,
|
||||||
|
#[sea_orm(unique, indexed)]
|
||||||
|
pub login_name: String,
|
||||||
|
pub password_hash: String,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub created_at: DateTimeWithTimeZone,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub updated_at: DateTimeWithTimeZone,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub deleted_at: Option<DateTimeWithTimeZone>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::access_token::Entity")]
|
||||||
|
AccessToken,
|
||||||
|
#[sea_orm(has_many = "super::progress_category::Entity")]
|
||||||
|
ProgressCategory,
|
||||||
|
#[sea_orm(has_many = "super::progress_entry::Entity")]
|
||||||
|
ProgressEntry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::access_token::Entity> for Model {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::AccessToken.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::progress_category::Entity> for Model {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::ProgressCategory.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::progress_entry::Entity> for Model {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::ProgressEntry.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModel {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let timestamp = Local::now().fixed_offset();
|
||||||
|
Self {
|
||||||
|
created_at: Set(timestamp),
|
||||||
|
updated_at: Set(timestamp),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
mod args;
|
mod args;
|
||||||
mod auth;
|
mod auth;
|
||||||
mod config;
|
mod config;
|
||||||
|
pub mod entity;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod graphql;
|
pub mod graphql;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue