Implement migration and entity for client
This commit is contained in:
parent
c88605e5d6
commit
47da8152e6
21 changed files with 215 additions and 355 deletions
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -2257,14 +2257,19 @@ dependencies = [
|
|||
name = "progress-pile-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-graphql",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"clap",
|
||||
"dirs",
|
||||
"progress-pile-core",
|
||||
"progress-pile-migration",
|
||||
"sea-orm",
|
||||
"serde",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"toml",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2630,6 +2635,7 @@ dependencies = [
|
|||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2689,6 +2695,7 @@ dependencies = [
|
|||
"inherent",
|
||||
"ordered-float",
|
||||
"sea-query-derive",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2700,6 +2707,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"sea-query",
|
||||
"sqlx",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2973,6 +2981,7 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
|
@ -3055,6 +3064,7 @@ dependencies = [
|
|||
"stringprep",
|
||||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"uuid",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
|
@ -3093,6 +3103,7 @@ dependencies = [
|
|||
"stringprep",
|
||||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"uuid",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
|
@ -3119,6 +3130,7 @@ dependencies = [
|
|||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3594,6 +3606,16 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||
dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-bag"
|
||||
version = "1.11.1"
|
||||
|
|
|
@ -17,6 +17,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
thiserror = "2.0.12"
|
||||
tokio = "1.44.2"
|
||||
toml = "0.8.22"
|
||||
uuid = { version = "1.16.0", features = [ "serde", "v4" ] }
|
||||
|
||||
[workspace.dependencies.sea-orm]
|
||||
version = "1.1"
|
||||
|
@ -26,6 +27,7 @@ features = [
|
|||
"runtime-tokio-native-tls",
|
||||
"sqlx-sqlite",
|
||||
"with-chrono",
|
||||
"with-uuid",
|
||||
]
|
||||
default-features = false
|
||||
|
||||
|
|
|
@ -8,11 +8,16 @@ default = ["clap"]
|
|||
clap = ["dep:clap"]
|
||||
|
||||
[dependencies]
|
||||
async-graphql.workspace = true
|
||||
chrono.workspace = true
|
||||
chrono-tz.workspace = true
|
||||
clap = { workspace = true, optional = true }
|
||||
dirs.workspace = true
|
||||
progress-pile-core.workspace = true
|
||||
progress-pile-migration = { workspace = true, features = ["client"]}
|
||||
sea-orm.workspace = true
|
||||
serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
toml.workspace = true
|
||||
uuid.workspace = true
|
49
progress-pile-client/src/entity/mod.rs
Normal file
49
progress-pile-client/src/entity/mod.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
mod progress_category;
|
||||
mod progress_entry;
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use chrono::Local;
|
||||
use sea_orm::entity::*;
|
||||
use progress_pile_migration::{ClientMigrator, MigratorTrait};
|
||||
use uuid::Uuid;
|
||||
use crate::database_connection::DATABASE_CONNECTION;
|
||||
|
||||
|
||||
#[tokio::test]
|
||||
async fn check_insert_entity() {
|
||||
let db = DATABASE_CONNECTION.get_or_init("sqlite::memory:").await;
|
||||
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{
|
||||
name: Set("test_category".to_owned()),
|
||||
..ProgressCategoryActiveModel::new()
|
||||
}.insert(db).await.unwrap();
|
||||
|
||||
let entry1= ProgressEntryActiveModel {
|
||||
progress_category_id: Set(category.id),
|
||||
..ProgressEntryActiveModel::new()
|
||||
}.insert(db).await.unwrap();
|
||||
|
||||
ClientMigrator::reset(db).await.unwrap();
|
||||
//db.clone().close().await.unwrap();
|
||||
}
|
||||
}
|
52
progress-pile-client/src/entity/progress_category.rs
Normal file
52
progress-pile-client/src/entity/progress_category.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use core::time;
|
||||
|
||||
use async_graphql::*;
|
||||
use chrono::Local;
|
||||
use sea_orm::entity::{
|
||||
*,
|
||||
prelude::*
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "progress_category")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
#[sea_orm(indexed)]
|
||||
pub name: 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::ProgressEntryEntity")]
|
||||
ProgressEntry,
|
||||
}
|
||||
|
||||
impl Related<super::ProgressEntryEntity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ProgressEntry.def()
|
||||
}
|
||||
|
||||
}
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl ActiveModel {
|
||||
pub fn new() -> Self {
|
||||
let timestamp: DateTimeWithTimeZone = Local::now().fixed_offset();
|
||||
Self{
|
||||
id: Set(Uuid::new_v4()),
|
||||
created_at: Set(timestamp),
|
||||
updated_at: Set(timestamp),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
62
progress-pile-client/src/entity/progress_entry.rs
Normal file
62
progress-pile-client/src/entity/progress_entry.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use async_graphql::*;
|
||||
use chrono::Local;
|
||||
use sea_orm::entity::{
|
||||
*,
|
||||
prelude::*
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize,)]
|
||||
#[sea_orm(table_name = "progress_entry")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
#[sea_orm(indexed)]
|
||||
pub progress_category_id: Uuid,
|
||||
#[sea_orm(indexed)]
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(indexed)]
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(indexed)]
|
||||
pub deleted_at: Option<DateTimeWithTimeZone>,
|
||||
#[sea_orm(indexed)]
|
||||
pub progressed_at: DateTimeWithTimeZone,
|
||||
pub quantity: i32,
|
||||
pub note: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||
pub enum Relation {
|
||||
|
||||
#[sea_orm(
|
||||
belongs_to = "super::ProgressCategoryEntity",
|
||||
from = "Column::ProgressCategoryId",
|
||||
to = "super::ProgressCategoryColumn::Id"
|
||||
)]
|
||||
ProgressCategory,
|
||||
}
|
||||
|
||||
|
||||
impl Related<super::progress_category::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ProgressCategory.def()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl ActiveModel {
|
||||
pub fn new() -> Self {
|
||||
let timestamp: DateTimeWithTimeZone = Local::now().fixed_offset();
|
||||
Self{
|
||||
id: Set(Uuid::new_v4()),
|
||||
created_at: Set(timestamp),
|
||||
updated_at: Set(timestamp),
|
||||
progressed_at: Set(timestamp),
|
||||
quantity: Set(1),
|
||||
note: Set("".to_string()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
pub mod auth;
|
||||
pub mod config;
|
||||
pub mod entity;
|
||||
|
||||
pub use progress_pile_core::error;
|
||||
pub use progress_pile_core::*;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ clap = { workspace = true, optional = true }
|
|||
csv = "1.3.1"
|
||||
cynic = "3.10.0"
|
||||
dotenv = {workspace = true}
|
||||
progress-pile-migration-server.workspace = true
|
||||
iana-time-zone = "0.1.63"
|
||||
log = "0.4.27"
|
||||
sea-orm.workspace = true
|
||||
|
|
|
@ -6,7 +6,7 @@ use sea_orm::ConnectOptions;
|
|||
use serde::Deserialize;
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
use crate::Error;
|
||||
use crate::error::Error;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
pub struct DatabaseConfig {
|
||||
|
|
|
@ -4,7 +4,7 @@ use clap::Args;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
use crate::Error;
|
||||
use crate::error::Error;
|
||||
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
use chrono::{DateTime, NaiveDateTime};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use crate::{
|
||||
entity::RecordDetailModel,
|
||||
error::Error,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct CsvRecord{
|
||||
|
@ -12,10 +8,3 @@ pub struct CsvRecord{
|
|||
pub tag: String,
|
||||
pub count: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<RecordDetailModel> for CsvRecord{
|
||||
type Error = Error;
|
||||
fn try_from(model: RecordDetailModel) -> Result<Self, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ use crate::config::{
|
|||
};
|
||||
use std::time::Duration;
|
||||
use sea_orm::{entity::*, query::*, ConnectOptions, Database, DatabaseConnection};
|
||||
use progress_pile_migration_server::{Migrator, MigratorTrait};
|
||||
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
|
@ -21,44 +20,14 @@ impl OnceDatabaseConnection {
|
|||
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
|
||||
}
|
||||
|
||||
pub async fn get_or_init_with_server_config(&self, c: &DatabaseConfig) -> &DatabaseConnection {
|
||||
self.get_or_init( || async {
|
||||
let db = Database::connect(c).await.unwrap();
|
||||
Migrator::fresh(&db).await.unwrap();
|
||||
db
|
||||
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 async fn get_or_init_with_static_server_config(&self) -> &DatabaseConnection {
|
||||
self.get_or_init_with_server_config(DATABASE_CONFIG.get().unwrap()).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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,71 +37,10 @@ pub static DATABASE_CONNECTION: OnceDatabaseConnection = OnceDatabaseConnection:
|
|||
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]
|
||||
//#[tokio::test]
|
||||
async fn check_database_connection() {
|
||||
DATABASE_CONNECTION.init_test().await;
|
||||
DATABASE_CONNECTION.get_or_init("sqlite::memory:").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
progress-pile-core/src/entity.rs
Normal file
7
progress-pile-core/src/entity.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
pub trait ProgressCategoryModelTrait {
|
||||
|
||||
}
|
||||
|
||||
pub trait ProgressEntityModelTrait {
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
mod record_detail;
|
||||
mod record_header;
|
||||
mod record_tag;
|
||||
mod user;
|
||||
|
||||
pub use user::{
|
||||
ActiveModel as UserActiveModel,
|
||||
Column as UserColumn,
|
||||
Entity as UserEntity,
|
||||
Model as UserModel,
|
||||
};
|
||||
|
||||
pub use record_detail::{
|
||||
ActiveModel as RecordDetailActiveModel,
|
||||
Entity as RecordDetailEntity,
|
||||
Model as RecordDetailModel,
|
||||
};
|
||||
|
||||
pub use record_header::{
|
||||
ActiveModel as RecordHeaderActiveModel,
|
||||
Entity as RecordHeaderEntity,
|
||||
Model as RecordHeaderModel,
|
||||
};
|
||||
|
||||
pub use record_tag::{
|
||||
ActiveModel as RecordTagActiveModel,
|
||||
Entity as RecordTagEntity,
|
||||
Model as RecordTagModel,
|
||||
};
|
|
@ -1,46 +0,0 @@
|
|||
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 {}
|
|
@ -1,46 +0,0 @@
|
|||
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_header")]
|
||||
#[graphql(concrete(name = "RecordHeader", params()))]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
#[serde(skip_deserializing)]
|
||||
pub id: i32,
|
||||
#[sea_orm(indexed)]
|
||||
#[serde(skip_deserializing)]
|
||||
pub user_id: i32,
|
||||
pub comment: String,
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(indexed)]
|
||||
pub recorded_at: DateTimeWithTimeZone,
|
||||
}
|
||||
|
||||
#[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 {}
|
|
@ -1,43 +0,0 @@
|
|||
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 {}
|
|
@ -1,64 +0,0 @@
|
|||
use async_graphql::SimpleObject;
|
||||
use chrono::{DateTime, FixedOffset,};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::error::Error;
|
||||
|
||||
use crate::DATABASE_CONNECTION;
|
||||
|
||||
#[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,
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
pub async fn find_by_name(user_name: &str) -> Result<Option<Model>, Error> {
|
||||
Ok(Entity::find()
|
||||
.filter(Column::LoginName.contains(user_name))
|
||||
.one(DATABASE_CONNECTION.get().unwrap())
|
||||
.await?
|
||||
)
|
||||
}
|
||||
pub async fn find_all() -> Result<Vec<Model>, Error> {
|
||||
Ok(Entity::find()
|
||||
.all(DATABASE_CONNECTION.get().unwrap())
|
||||
.await?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_many = "super::record_header::Entity")]
|
||||
RecordHeader,
|
||||
#[sea_orm(has_many = "super::record_tag::Entity")]
|
||||
RecordTag,
|
||||
}
|
||||
|
||||
impl Related<super::record_header::Entity> for Model {
|
||||
fn to() -> RelationDef {
|
||||
Relation::RecordHeader.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::record_tag::Entity> for Model {
|
||||
fn to() -> RelationDef {
|
||||
Relation::RecordTag.def()
|
||||
}
|
||||
}
|
||||
impl ActiveModel {
|
||||
pub async fn create_user(login_name: &str, password: &str) -> Result<Model, Error>{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
use async_graphql::*;
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
|
||||
use crate::entity::UserModel;
|
||||
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
pub struct PartialUser {
|
||||
pub id: Option<i32>,
|
||||
|
@ -12,11 +9,6 @@ pub struct PartialUser {
|
|||
pub updated_at: Option<DateTime<FixedOffset>>,
|
||||
}
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
pub struct Users{
|
||||
users: Vec<UserModel>
|
||||
}
|
||||
|
||||
pub struct CreateUser {
|
||||
login_name: String,
|
||||
password: String,
|
||||
|
|
|
@ -5,9 +5,6 @@ pub mod entity;
|
|||
pub mod error;
|
||||
pub mod graphql;
|
||||
|
||||
pub use database_connection::*;
|
||||
pub use error::Error;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[cfg(feature="client")]
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct ClientMigration;
|
||||
|
||||
#[cfg(feature="client")]
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for ClientMigration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
|
@ -290,7 +292,6 @@ impl MigrationTableDefault for ProgressCategory {
|
|||
Table::create()
|
||||
.table(Self::Table)
|
||||
.if_not_exists()
|
||||
.col(uuid(Self::Id))
|
||||
.col(string(Self::Name))
|
||||
.col(timestamp_with_time_zone(Self::CreatedAt))
|
||||
.col(timestamp_with_time_zone(Self::UpdatedAt))
|
||||
|
@ -326,7 +327,7 @@ impl MigrationTableDefault for ProgressCategory {
|
|||
impl MigrationTableClient for ProgressCategory {
|
||||
fn table_create_statement_client() -> TableCreateStatement{
|
||||
let mut tcs = Self::table_create_statement_default();
|
||||
tcs.primary_key(Index::create().name(PK_PROGRESS_CATEGORY).col(Self::Id));
|
||||
tcs.col(pk_uuid(Self::Id));
|
||||
tcs
|
||||
}
|
||||
fn index_create_statements_client() -> Vec<IndexCreateStatement> {
|
||||
|
@ -342,6 +343,8 @@ impl MigrationTableServer for ProgressCategory {
|
|||
|
||||
fn table_create_statement_server() -> TableCreateStatement{
|
||||
let mut tcs = Self::table_create_statement_default();
|
||||
tcs.col(uuid(Self::Id));
|
||||
|
||||
tcs.col(integer(Self::UserId));
|
||||
tcs.foreign_key(ForeignKey::create().name(FK_PROGRESS_CATEGORY_USER).from(Self::Table, Self::UserId)
|
||||
.to(User::Table, User::Id));
|
||||
|
|
Loading…
Add table
Reference in a new issue