Kould commited on
Commit
f102c60
·
1 Parent(s): c6d0d85

impl tags api (#2)

Browse files
.env ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ HOST=127.0.0.1
2
+ PORT=8000
3
+ DATABASE_URL="postgresql://infiniflow:infiniflow@localhost/docgpt"
.env.template ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ HOST=127.0.0.1
2
+ PORT=8000
3
+ DATABASE_URL="postgresql://infiniflow:infiniflow@localhost/docgpt"
.gitignore CHANGED
@@ -14,3 +14,4 @@ Cargo.lock
14
  *.pdb
15
 
16
  .idea/
 
 
14
  *.pdb
15
 
16
  .idea/
17
+ .env
Cargo.toml CHANGED
@@ -8,9 +8,15 @@ edition = "2021"
8
  [dependencies]
9
  actix-web = "4.3.1"
10
  actix-rt = "2.8.0"
 
11
  postgres = "0.19.7"
12
  sea-orm = {version = "0.12.9", features = ["sqlx-postgres", "runtime-tokio-native-tls", "macros"]}
13
  serde = { version = "1", features = ["derive"] }
 
 
 
 
 
14
 
15
  [[bin]]
16
  name = "doc_gpt"
 
8
  [dependencies]
9
  actix-web = "4.3.1"
10
  actix-rt = "2.8.0"
11
+ actix-files = "0.6.2"
12
  postgres = "0.19.7"
13
  sea-orm = {version = "0.12.9", features = ["sqlx-postgres", "runtime-tokio-native-tls", "macros"]}
14
  serde = { version = "1", features = ["derive"] }
15
+ serde_json = "1.0"
16
+ tracing-subscriber = "0.3.18"
17
+ dotenvy = "0.15.7"
18
+ listenfd = "1.0.1"
19
+ migration = { path = "./migration" }
20
 
21
  [[bin]]
22
  name = "doc_gpt"
migration/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Running Migrator CLI
2
 
3
  - Generate a new migration file
4
  ```sh
 
1
+ # Running Migrator CLI
2
 
3
  - Generate a new migration file
4
  ```sh
migration/src/m20220101_000001_create_table.rs CHANGED
@@ -37,12 +37,13 @@ impl MigrationTrait for Migration {
37
  .table(TagInfo::Table)
38
  .if_not_exists()
39
  .col(
40
- ColumnDef::new(TagInfo::Uid)
41
  .big_integer()
42
  .not_null()
43
  .auto_increment()
44
  .primary_key(),
45
  )
 
46
  .col(ColumnDef::new(TagInfo::TagName).string().not_null())
47
  .col(ColumnDef::new(TagInfo::Regx).string())
48
  .col(ColumnDef::new(TagInfo::Color).big_integer().default(1))
@@ -61,8 +62,7 @@ impl MigrationTrait for Migration {
61
  .table(Tag2Doc::Table)
62
  .if_not_exists()
63
  .col(ColumnDef::new(Tag2Doc::TagId).big_integer())
64
- .col(ColumnDef::new(Tag2Doc::Did).big_integer().comment("doc id, did in docinfo"))
65
- .index(Index::create().col(Tag2Doc::TagId))
66
  .to_owned(),
67
  )
68
  .await?;
@@ -73,8 +73,7 @@ impl MigrationTrait for Migration {
73
  .table(Kb2Doc::Table)
74
  .if_not_exists()
75
  .col(ColumnDef::new(Kb2Doc::KbId).big_integer())
76
- .col(ColumnDef::new(Kb2Doc::Did).big_integer().comment("doc id, did in docinfo"))
77
- .index(Index::create().col(Kb2Doc::KbId))
78
  .to_owned(),
79
  )
80
  .await?;
@@ -86,7 +85,6 @@ impl MigrationTrait for Migration {
86
  .if_not_exists()
87
  .col(ColumnDef::new(Dialog2Kb::DialogId).big_integer())
88
  .col(ColumnDef::new(Dialog2Kb::KbId).big_integer())
89
- .index(Index::create().col(Dialog2Kb::DialogId))
90
  .to_owned(),
91
  )
92
  .await?;
@@ -96,9 +94,8 @@ impl MigrationTrait for Migration {
96
  Table::create()
97
  .table(Doc2Doc::Table)
98
  .if_not_exists()
99
- .col(ColumnDef::new(Doc2Doc::ParentId).big_integer().comment("doc id, did in docinfo"))
100
- .col(ColumnDef::new(Doc2Doc::Did).big_integer().comment("doc id, did in docinfo"))
101
- .index(Index::create().col(Doc2Doc::ParentId))
102
  .to_owned(),
103
  )
104
  .await?;
@@ -108,15 +105,16 @@ impl MigrationTrait for Migration {
108
  Table::create()
109
  .table(KbInfo::Table)
110
  .if_not_exists()
111
- .col(ColumnDef::new(KbInfo::KbId).big_integer().auto_increment().not_null())
 
 
 
112
  .col(ColumnDef::new(KbInfo::Uid).big_integer().not_null())
113
  .col(ColumnDef::new(KbInfo::KbName).string().not_null())
114
  .col(ColumnDef::new(KbInfo::Icon).big_integer().default(1))
115
  .col(ColumnDef::new(KbInfo::CreatedAt).date().not_null())
116
  .col(ColumnDef::new(KbInfo::UpdatedAt).date().not_null())
117
  .col(ColumnDef::new(KbInfo::IsDeleted).boolean().default(false))
118
- .index(Index::create().col(KbInfo::KbId))
119
- .index(Index::create().col(KbInfo::Uid))
120
  .to_owned(),
121
  )
122
  .await?;
@@ -126,7 +124,10 @@ impl MigrationTrait for Migration {
126
  Table::create()
127
  .table(DocInfo::Table)
128
  .if_not_exists()
129
- .col(ColumnDef::new(DocInfo::Did).big_integer().auto_increment().not_null())
 
 
 
130
  .col(ColumnDef::new(DocInfo::Uid).big_integer().not_null())
131
  .col(ColumnDef::new(DocInfo::DocName).string().not_null())
132
  .col(ColumnDef::new(DocInfo::Size).big_integer().not_null())
@@ -135,8 +136,6 @@ impl MigrationTrait for Migration {
135
  .col(ColumnDef::new(DocInfo::CreatedAt).date().not_null())
136
  .col(ColumnDef::new(DocInfo::UpdatedAt).date().not_null())
137
  .col(ColumnDef::new(DocInfo::IsDeleted).boolean().default(false))
138
- .index(Index::create().col(DocInfo::Did))
139
- .index(Index::create().col(DocInfo::Uid))
140
  .to_owned(),
141
  )
142
  .await?;
@@ -146,15 +145,17 @@ impl MigrationTrait for Migration {
146
  Table::create()
147
  .table(DialogInfo::Table)
148
  .if_not_exists()
149
- .col(ColumnDef::new(DialogInfo::DialogId).big_integer().auto_increment().not_null())
 
 
 
 
150
  .col(ColumnDef::new(DialogInfo::Uid).big_integer().not_null())
151
  .col(ColumnDef::new(DialogInfo::DialogName).string().not_null())
152
  .col(ColumnDef::new(DialogInfo::History).string().comment("json"))
153
  .col(ColumnDef::new(DialogInfo::CreatedAt).date().not_null())
154
  .col(ColumnDef::new(DialogInfo::UpdatedAt).date().not_null())
155
  .col(ColumnDef::new(DialogInfo::IsDeleted).boolean().default(false))
156
- .index(Index::create().col(DialogInfo::DialogId))
157
- .index(Index::create().col(DialogInfo::Uid))
158
  .to_owned(),
159
  )
160
  .await?;
@@ -221,6 +222,7 @@ enum UserInfo {
221
  #[derive(DeriveIden)]
222
  enum TagInfo {
223
  Table,
 
224
  Uid,
225
  TagName,
226
  Regx,
 
37
  .table(TagInfo::Table)
38
  .if_not_exists()
39
  .col(
40
+ ColumnDef::new(TagInfo::Tid)
41
  .big_integer()
42
  .not_null()
43
  .auto_increment()
44
  .primary_key(),
45
  )
46
+ .col(ColumnDef::new(TagInfo::Uid).big_integer().not_null())
47
  .col(ColumnDef::new(TagInfo::TagName).string().not_null())
48
  .col(ColumnDef::new(TagInfo::Regx).string())
49
  .col(ColumnDef::new(TagInfo::Color).big_integer().default(1))
 
62
  .table(Tag2Doc::Table)
63
  .if_not_exists()
64
  .col(ColumnDef::new(Tag2Doc::TagId).big_integer())
65
+ .col(ColumnDef::new(Tag2Doc::Did).big_integer())
 
66
  .to_owned(),
67
  )
68
  .await?;
 
73
  .table(Kb2Doc::Table)
74
  .if_not_exists()
75
  .col(ColumnDef::new(Kb2Doc::KbId).big_integer())
76
+ .col(ColumnDef::new(Kb2Doc::Did).big_integer())
 
77
  .to_owned(),
78
  )
79
  .await?;
 
85
  .if_not_exists()
86
  .col(ColumnDef::new(Dialog2Kb::DialogId).big_integer())
87
  .col(ColumnDef::new(Dialog2Kb::KbId).big_integer())
 
88
  .to_owned(),
89
  )
90
  .await?;
 
94
  Table::create()
95
  .table(Doc2Doc::Table)
96
  .if_not_exists()
97
+ .col(ColumnDef::new(Doc2Doc::ParentId).big_integer())
98
+ .col(ColumnDef::new(Doc2Doc::Did).big_integer())
 
99
  .to_owned(),
100
  )
101
  .await?;
 
105
  Table::create()
106
  .table(KbInfo::Table)
107
  .if_not_exists()
108
+ .col(ColumnDef::new(KbInfo::KbId).big_integer()
109
+ .auto_increment()
110
+ .not_null()
111
+ .primary_key())
112
  .col(ColumnDef::new(KbInfo::Uid).big_integer().not_null())
113
  .col(ColumnDef::new(KbInfo::KbName).string().not_null())
114
  .col(ColumnDef::new(KbInfo::Icon).big_integer().default(1))
115
  .col(ColumnDef::new(KbInfo::CreatedAt).date().not_null())
116
  .col(ColumnDef::new(KbInfo::UpdatedAt).date().not_null())
117
  .col(ColumnDef::new(KbInfo::IsDeleted).boolean().default(false))
 
 
118
  .to_owned(),
119
  )
120
  .await?;
 
124
  Table::create()
125
  .table(DocInfo::Table)
126
  .if_not_exists()
127
+ .col(ColumnDef::new(DocInfo::Did).big_integer()
128
+ .not_null()
129
+ .auto_increment()
130
+ .primary_key())
131
  .col(ColumnDef::new(DocInfo::Uid).big_integer().not_null())
132
  .col(ColumnDef::new(DocInfo::DocName).string().not_null())
133
  .col(ColumnDef::new(DocInfo::Size).big_integer().not_null())
 
136
  .col(ColumnDef::new(DocInfo::CreatedAt).date().not_null())
137
  .col(ColumnDef::new(DocInfo::UpdatedAt).date().not_null())
138
  .col(ColumnDef::new(DocInfo::IsDeleted).boolean().default(false))
 
 
139
  .to_owned(),
140
  )
141
  .await?;
 
145
  Table::create()
146
  .table(DialogInfo::Table)
147
  .if_not_exists()
148
+ .col(ColumnDef::new(DialogInfo::DialogId)
149
+ .big_integer()
150
+ .not_null()
151
+ .auto_increment()
152
+ .primary_key())
153
  .col(ColumnDef::new(DialogInfo::Uid).big_integer().not_null())
154
  .col(ColumnDef::new(DialogInfo::DialogName).string().not_null())
155
  .col(ColumnDef::new(DialogInfo::History).string().comment("json"))
156
  .col(ColumnDef::new(DialogInfo::CreatedAt).date().not_null())
157
  .col(ColumnDef::new(DialogInfo::UpdatedAt).date().not_null())
158
  .col(ColumnDef::new(DialogInfo::IsDeleted).boolean().default(false))
 
 
159
  .to_owned(),
160
  )
161
  .await?;
 
222
  #[derive(DeriveIden)]
223
  enum TagInfo {
224
  Table,
225
+ Tid,
226
  Uid,
227
  TagName,
228
  Regx,
src/api/mod.rs CHANGED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ use serde::{Deserialize, Serialize};
2
+
3
+ pub(crate) mod tag;
4
+
5
+ #[derive(Debug, Deserialize, Serialize)]
6
+ struct JsonResponse<T> {
7
+ code: u32,
8
+ err: String,
9
+ data: T,
10
+ }
src/api/tag.rs ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::collections::HashMap;
2
+ use actix_web::{get, HttpResponse, post, web};
3
+ use actix_web::http::Error;
4
+ use crate::api::JsonResponse;
5
+ use crate::AppState;
6
+ use crate::entity::tag_info;
7
+ use crate::service::tag_info::{Mutation, Query};
8
+
9
+ #[post("/v1.0/create_tag")]
10
+ async fn create(model: web::Json<tag_info::Model>, data: web::Data<AppState>) -> Result<HttpResponse, Error> {
11
+ let model = Mutation::create_tag(&data.conn, model.into_inner()).await.unwrap();
12
+
13
+ let mut result = HashMap::new();
14
+ result.insert("tid", model.uid.unwrap());
15
+
16
+ let json_response = JsonResponse {
17
+ code: 200,
18
+ err: "".to_owned(),
19
+ data: result,
20
+ };
21
+
22
+ Ok(HttpResponse::Ok()
23
+ .content_type("application/json")
24
+ .body(serde_json::to_string(&json_response).unwrap()))
25
+ }
26
+
27
+ #[post("/v1.0/delete_tag")]
28
+ async fn delete(model: web::Json<tag_info::Model>, data: web::Data<AppState>) -> Result<HttpResponse, Error> {
29
+ let _ = Mutation::delete_tag(&data.conn, model.tid).await.unwrap();
30
+
31
+ let json_response = JsonResponse {
32
+ code: 200,
33
+ err: "".to_owned(),
34
+ data: (),
35
+ };
36
+
37
+ Ok(HttpResponse::Ok()
38
+ .content_type("application/json")
39
+ .body(serde_json::to_string(&json_response).unwrap()))
40
+ }
41
+
42
+ #[get("/v1.0/tags")]
43
+ async fn list(data: web::Data<AppState>) -> Result<HttpResponse, Error> {
44
+ let tags = Query::find_tag_infos(&data.conn).await.unwrap();
45
+
46
+ let mut result = HashMap::new();
47
+ result.insert("tags", tags);
48
+
49
+ let json_response = JsonResponse {
50
+ code: 200,
51
+ err: "".to_owned(),
52
+ data: result,
53
+ };
54
+
55
+ Ok(HttpResponse::Ok()
56
+ .content_type("application/json")
57
+ .body(serde_json::to_string(&json_response).unwrap()))
58
+ }
src/entity/{dialog_2_kb.rs → dialog2_kb.rs} RENAMED
@@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*;
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
- #[sea_orm(table_name = "dialog_2_kb")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
 
8
  pub dialog_id: i64,
9
  #[sea_orm(primary_key, auto_increment = false)]
10
  pub kb_id: i64,
 
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
+ #[sea_orm(table_name = "dialog2_kb")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
+ #[sea_orm(index)]
9
  pub dialog_id: i64,
10
  #[sea_orm(primary_key, auto_increment = false)]
11
  pub kb_id: i64,
src/entity/dialog_info.rs CHANGED
@@ -6,15 +6,13 @@ use serde::{Deserialize, Serialize};
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
  pub dialog_id: i64,
9
- #[sea_orm(primary_key, auto_increment = false)]
10
  pub uid: i64,
11
  pub dialog_name: String,
12
  pub history: String,
13
 
14
- pub created_at: DateTimeWithTimeZone,
15
- pub updated_at: DateTimeWithTimeZone,
16
- #[sea_orm(soft_delete_column)]
17
- pub is_deleted: bool,
18
  }
19
 
20
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -22,11 +20,11 @@ pub enum Relation {}
22
 
23
  impl Related<super::kb_info::Entity> for Entity {
24
  fn to() -> RelationDef {
25
- super::dialog_2_kb::Relation::KbInfo.def()
26
  }
27
 
28
  fn via() -> Option<RelationDef> {
29
- Some(super::dialog_2_kb::Relation::DialogInfo.def().rev())
30
  }
31
  }
32
 
 
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
  pub dialog_id: i64,
9
+ #[sea_orm(index)]
10
  pub uid: i64,
11
  pub dialog_name: String,
12
  pub history: String,
13
 
14
+ pub created_at: Date,
15
+ pub updated_at: Date,
 
 
16
  }
17
 
18
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 
20
 
21
  impl Related<super::kb_info::Entity> for Entity {
22
  fn to() -> RelationDef {
23
+ super::dialog2_kb::Relation::KbInfo.def()
24
  }
25
 
26
  fn via() -> Option<RelationDef> {
27
+ Some(super::dialog2_kb::Relation::DialogInfo.def().rev())
28
  }
29
  }
30
 
src/entity/{doc_2_doc.rs → doc2_doc.rs} RENAMED
@@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*;
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
- #[sea_orm(table_name = "doc_2_doc")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
 
8
  pub parent_id: i64,
9
  #[sea_orm(primary_key, auto_increment = false)]
10
  pub did: i64,
 
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
+ #[sea_orm(table_name = "doc2_doc")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
+ #[sea_orm(index)]
9
  pub parent_id: i64,
10
  #[sea_orm(primary_key, auto_increment = false)]
11
  pub did: i64,
src/entity/doc_info.rs CHANGED
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
  pub did: i64,
9
- #[sea_orm(primary_key, auto_increment = false)]
10
  pub uid: i64,
11
  pub doc_name: String,
12
  pub size: i64,
@@ -14,8 +14,8 @@ pub struct Model {
14
  pub r#type: String,
15
  pub kb_progress: f64,
16
 
17
- pub created_at: DateTimeWithTimeZone,
18
- pub updated_at: DateTimeWithTimeZone,
19
  #[sea_orm(soft_delete_column)]
20
  pub is_deleted: bool,
21
  }
@@ -25,31 +25,31 @@ pub enum Relation {}
25
 
26
  impl Related<super::tag_info::Entity> for Entity {
27
  fn to() -> RelationDef {
28
- super::tag_2_doc::Relation::Tag.def()
29
  }
30
 
31
  fn via() -> Option<RelationDef> {
32
- Some(super::tag_2_doc::Relation::DocInfo.def().rev())
33
  }
34
  }
35
 
36
  impl Related<super::kb_info::Entity> for Entity {
37
  fn to() -> RelationDef {
38
- super::kb_2_doc::Relation::KbInfo.def()
39
  }
40
 
41
  fn via() -> Option<RelationDef> {
42
- Some(super::kb_2_doc::Relation::DocInfo.def().rev())
43
  }
44
  }
45
 
46
  impl Related<Entity> for Entity {
47
  fn to() -> RelationDef {
48
- super::doc_2_doc::Relation::Parent.def()
49
  }
50
 
51
  fn via() -> Option<RelationDef> {
52
- Some(super::doc_2_doc::Relation::Child.def().rev())
53
  }
54
  }
55
 
 
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
  pub did: i64,
9
+ #[sea_orm(index)]
10
  pub uid: i64,
11
  pub doc_name: String,
12
  pub size: i64,
 
14
  pub r#type: String,
15
  pub kb_progress: f64,
16
 
17
+ pub created_at: Date,
18
+ pub updated_at: Date,
19
  #[sea_orm(soft_delete_column)]
20
  pub is_deleted: bool,
21
  }
 
25
 
26
  impl Related<super::tag_info::Entity> for Entity {
27
  fn to() -> RelationDef {
28
+ super::tag2_doc::Relation::Tag.def()
29
  }
30
 
31
  fn via() -> Option<RelationDef> {
32
+ Some(super::tag2_doc::Relation::DocInfo.def().rev())
33
  }
34
  }
35
 
36
  impl Related<super::kb_info::Entity> for Entity {
37
  fn to() -> RelationDef {
38
+ super::kb2_doc::Relation::KbInfo.def()
39
  }
40
 
41
  fn via() -> Option<RelationDef> {
42
+ Some(super::kb2_doc::Relation::DocInfo.def().rev())
43
  }
44
  }
45
 
46
  impl Related<Entity> for Entity {
47
  fn to() -> RelationDef {
48
+ super::doc2_doc::Relation::Parent.def()
49
  }
50
 
51
  fn via() -> Option<RelationDef> {
52
+ Some(super::doc2_doc::Relation::Child.def().rev())
53
  }
54
  }
55
 
src/entity/{kb_2_doc.rs → kb2_doc.rs} RENAMED
@@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*;
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
- #[sea_orm(table_name = "kb_2_doc")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
 
8
  pub kb_id: i64,
9
  #[sea_orm(primary_key, auto_increment = false)]
10
  pub uid: i64,
 
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
+ #[sea_orm(table_name = "kb2_doc")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
+ #[sea_orm(index)]
9
  pub kb_id: i64,
10
  #[sea_orm(primary_key, auto_increment = false)]
11
  pub uid: i64,
src/entity/kb_info.rs CHANGED
@@ -6,15 +6,13 @@ use serde::{Deserialize, Serialize};
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
  pub kb_id: i64,
9
- #[sea_orm(primary_key, auto_increment = false)]
10
  pub uid: i64,
11
  pub kn_name: String,
12
  pub icon: i64,
13
 
14
- pub created_at: DateTimeWithTimeZone,
15
- pub updated_at: DateTimeWithTimeZone,
16
- #[sea_orm(soft_delete_column)]
17
- pub is_deleted: bool,
18
  }
19
 
20
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -22,21 +20,21 @@ pub enum Relation {}
22
 
23
  impl Related<super::doc_info::Entity> for Entity {
24
  fn to() -> RelationDef {
25
- super::kb_2_doc::Relation::DocInfo.def()
26
  }
27
 
28
  fn via() -> Option<RelationDef> {
29
- Some(super::kb_2_doc::Relation::KbInfo.def().rev())
30
  }
31
  }
32
 
33
  impl Related<super::dialog_info::Entity> for Entity {
34
  fn to() -> RelationDef {
35
- super::dialog_2_kb::Relation::DialogInfo.def()
36
  }
37
 
38
  fn via() -> Option<RelationDef> {
39
- Some(super::dialog_2_kb::Relation::KbInfo.def().rev())
40
  }
41
  }
42
 
 
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
  pub kb_id: i64,
9
+ #[sea_orm(index)]
10
  pub uid: i64,
11
  pub kn_name: String,
12
  pub icon: i64,
13
 
14
+ pub created_at: Date,
15
+ pub updated_at: Date,
 
 
16
  }
17
 
18
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 
20
 
21
  impl Related<super::doc_info::Entity> for Entity {
22
  fn to() -> RelationDef {
23
+ super::kb2_doc::Relation::DocInfo.def()
24
  }
25
 
26
  fn via() -> Option<RelationDef> {
27
+ Some(super::kb2_doc::Relation::KbInfo.def().rev())
28
  }
29
  }
30
 
31
  impl Related<super::dialog_info::Entity> for Entity {
32
  fn to() -> RelationDef {
33
+ super::dialog2_kb::Relation::DialogInfo.def()
34
  }
35
 
36
  fn via() -> Option<RelationDef> {
37
+ Some(super::dialog2_kb::Relation::KbInfo.def().rev())
38
  }
39
  }
40
 
src/entity/mod.rs CHANGED
@@ -1,9 +1,9 @@
1
- mod user_info;
2
- mod tag_info;
3
- mod tag_2_doc;
4
- mod kb_2_doc;
5
- mod dialog_2_kb;
6
- mod doc_2_doc;
7
- mod kb_info;
8
- mod doc_info;
9
- mod dialog_info;
 
1
+ pub(crate) mod user_info;
2
+ pub(crate) mod tag_info;
3
+ mod tag2_doc;
4
+ mod kb2_doc;
5
+ mod dialog2_kb;
6
+ mod doc2_doc;
7
+ pub(crate) mod kb_info;
8
+ pub(crate) mod doc_info;
9
+ pub(crate) mod dialog_info;
src/entity/{tag_2_doc.rs → tag2_doc.rs} RENAMED
@@ -2,9 +2,10 @@ use sea_orm::entity::prelude::*;
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
- #[sea_orm(table_name = "tag_2_doc")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
 
8
  pub tag_id: i64,
9
  #[sea_orm(primary_key, auto_increment = false)]
10
  pub uid: i64,
@@ -25,7 +26,7 @@ impl RelationTrait for Relation {
25
  .into(),
26
  Self::Tag => Entity::belongs_to(super::tag_info::Entity)
27
  .from(Column::TagId)
28
- .to(super::tag_info::Column::Uid)
29
  .into(),
30
  }
31
  }
 
2
  use serde::{Deserialize, Serialize};
3
 
4
  #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]
5
+ #[sea_orm(table_name = "tag2_doc")]
6
  pub struct Model {
7
  #[sea_orm(primary_key, auto_increment = false)]
8
+ #[sea_orm(index)]
9
  pub tag_id: i64,
10
  #[sea_orm(primary_key, auto_increment = false)]
11
  pub uid: i64,
 
26
  .into(),
27
  Self::Tag => Entity::belongs_to(super::tag_info::Entity)
28
  .from(Column::TagId)
29
+ .to(super::tag_info::Column::Tid)
30
  .into(),
31
  }
32
  }
src/entity/tag_info.rs CHANGED
@@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
6
  pub struct Model {
7
  #[sea_orm(primary_key)]
8
  #[serde(skip_deserializing)]
 
9
  pub uid: i64,
10
  pub tag_name: String,
11
  pub regx: String,
@@ -13,10 +14,8 @@ pub struct Model {
13
  pub icon: i64,
14
  pub dir: String,
15
 
16
- pub created_at: DateTimeWithTimeZone,
17
- pub updated_at: DateTimeWithTimeZone,
18
- #[sea_orm(soft_delete_column)]
19
- pub is_deleted: bool,
20
  }
21
 
22
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -24,11 +23,11 @@ pub enum Relation {}
24
 
25
  impl Related<super::doc_info::Entity> for Entity {
26
  fn to() -> RelationDef {
27
- super::tag_2_doc::Relation::DocInfo.def()
28
  }
29
 
30
  fn via() -> Option<RelationDef> {
31
- Some(super::tag_2_doc::Relation::Tag.def().rev())
32
  }
33
  }
34
 
 
6
  pub struct Model {
7
  #[sea_orm(primary_key)]
8
  #[serde(skip_deserializing)]
9
+ pub tid: i64,
10
  pub uid: i64,
11
  pub tag_name: String,
12
  pub regx: String,
 
14
  pub icon: i64,
15
  pub dir: String,
16
 
17
+ pub created_at: Date,
18
+ pub updated_at: Date,
 
 
19
  }
20
 
21
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 
23
 
24
  impl Related<super::doc_info::Entity> for Entity {
25
  fn to() -> RelationDef {
26
+ super::tag2_doc::Relation::DocInfo.def()
27
  }
28
 
29
  fn via() -> Option<RelationDef> {
30
+ Some(super::tag2_doc::Relation::Tag.def().rev())
31
  }
32
  }
33
 
src/entity/user_info.rs CHANGED
@@ -16,8 +16,6 @@ pub struct Model {
16
 
17
  pub created_at: DateTimeWithTimeZone,
18
  pub updated_at: DateTimeWithTimeZone,
19
- #[sea_orm(soft_delete_column)]
20
- pub is_deleted: bool,
21
  }
22
 
23
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 
16
 
17
  pub created_at: DateTimeWithTimeZone,
18
  pub updated_at: DateTimeWithTimeZone,
 
 
19
  }
20
 
21
  #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
src/main.rs CHANGED
@@ -2,22 +2,60 @@ mod api;
2
  mod entity;
3
  mod service;
4
 
5
- use actix_web::{get, web, App, HttpServer, Responder};
 
 
 
 
 
6
 
7
- #[get("/")]
8
- async fn index() -> impl Responder {
9
- "Hello, World!"
10
- }
11
-
12
- #[get("/{name}")]
13
- async fn hello(name: web::Path<String>) -> impl Responder {
14
- format!("Hello {}!", &name)
15
  }
16
 
17
  #[actix_web::main]
18
  async fn main() -> std::io::Result<()> {
19
- HttpServer::new(|| App::new().service(index).service(hello))
20
- .bind(("127.0.0.1", 9090))?
21
- .run()
22
- .await
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
 
2
  mod entity;
3
  mod service;
4
 
5
+ use std::env;
6
+ use actix_files::Files;
7
+ use actix_web::{web, App, HttpServer, middleware};
8
+ use listenfd::ListenFd;
9
+ use sea_orm::{Database, DatabaseConnection};
10
+ use migration::{Migrator, MigratorTrait};
11
 
12
+ #[derive(Debug, Clone)]
13
+ struct AppState {
14
+ conn: DatabaseConnection,
 
 
 
 
 
15
  }
16
 
17
  #[actix_web::main]
18
  async fn main() -> std::io::Result<()> {
19
+ std::env::set_var("RUST_LOG", "debug");
20
+ tracing_subscriber::fmt::init();
21
+
22
+ // get env vars
23
+ dotenvy::dotenv().ok();
24
+ let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file");
25
+ let host = env::var("HOST").expect("HOST is not set in .env file");
26
+ let port = env::var("PORT").expect("PORT is not set in .env file");
27
+ let server_url = format!("{host}:{port}");
28
+
29
+ // establish connection to database and apply migrations
30
+ // -> create post table if not exists
31
+ let conn = Database::connect(&db_url).await.unwrap();
32
+ Migrator::up(&conn, None).await.unwrap();
33
+
34
+ let state = AppState { conn };
35
+
36
+ // create server and try to serve over socket if possible
37
+ let mut listenfd = ListenFd::from_env();
38
+ let mut server = HttpServer::new(move || {
39
+ App::new()
40
+ .service(Files::new("/static", "./static"))
41
+ .app_data(web::Data::new(state.clone()))
42
+ .wrap(middleware::Logger::default())
43
+ .configure(init)
44
+ });
45
+
46
+ server = match listenfd.take_tcp_listener(0)? {
47
+ Some(listener) => server.listen(listener)?,
48
+ None => server.bind(&server_url)?,
49
+ };
50
+
51
+ println!("Starting server at {server_url}");
52
+ server.run().await?;
53
+
54
+ Ok(())
55
+ }
56
+
57
+ fn init(cfg: &mut web::ServiceConfig) {
58
+ cfg.service(api::tag::create);
59
+ cfg.service(api::tag::delete);
60
+ cfg.service(api::tag::list);
61
  }
src/service/dialog_info.rs ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use sea_orm::{DbConn, DbErr, EntityTrait, PaginatorTrait, QueryOrder};
2
+ use crate::entity::dialog_info;
3
+ use crate::entity::dialog_info::Entity;
4
+
5
+ pub struct Query;
6
+
7
+ impl Query {
8
+ pub async fn find_dialog_info_by_id(db: &DbConn, id: i64) -> Result<Option<dialog_info::Model>, DbErr> {
9
+ Entity::find_by_id(id).one(db).await
10
+ }
11
+
12
+ pub async fn find_dialog_infos_in_page(
13
+ db: &DbConn,
14
+ page: u64,
15
+ posts_per_page: u64,
16
+ ) -> Result<(Vec<dialog_info::Model>, u64), DbErr> {
17
+ // Setup paginator
18
+ let paginator = Entity::find()
19
+ .order_by_asc(dialog_info::Column::DialogId)
20
+ .paginate(db, posts_per_page);
21
+ let num_pages = paginator.num_pages().await?;
22
+
23
+ // Fetch paginated posts
24
+ paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))
25
+ }
26
+ }
src/service/mod.rs CHANGED
@@ -0,0 +1,2 @@
 
 
 
1
+ pub(crate) mod dialog_info;
2
+ pub(crate) mod tag_info;
src/service/tag_info.rs ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use sea_orm::{ActiveModelTrait, DbConn, DbErr, DeleteResult, EntityTrait, PaginatorTrait, QueryOrder};
2
+ use sea_orm::ActiveValue::Set;
3
+ use crate::entity::tag_info;
4
+ use crate::entity::tag_info::Entity;
5
+
6
+ pub struct Query;
7
+
8
+ impl Query {
9
+ pub async fn find_tag_info_by_id(db: &DbConn, id: i64) -> Result<Option<tag_info::Model>, DbErr> {
10
+ Entity::find_by_id(id).one(db).await
11
+ }
12
+
13
+ pub async fn find_tag_infos(db: &DbConn) -> Result<Vec<tag_info::Model>, DbErr> {
14
+ Entity::find().all(db).await
15
+ }
16
+
17
+ pub async fn find_tag_infos_in_page(
18
+ db: &DbConn,
19
+ page: u64,
20
+ posts_per_page: u64,
21
+ ) -> Result<(Vec<tag_info::Model>, u64), DbErr> {
22
+ // Setup paginator
23
+ let paginator = Entity::find()
24
+ .order_by_asc(tag_info::Column::Uid)
25
+ .paginate(db, posts_per_page);
26
+ let num_pages = paginator.num_pages().await?;
27
+
28
+ // Fetch paginated posts
29
+ paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))
30
+ }
31
+ }
32
+
33
+ pub struct Mutation;
34
+
35
+ impl Mutation {
36
+ pub async fn create_tag(
37
+ db: &DbConn,
38
+ form_data: tag_info::Model,
39
+ ) -> Result<tag_info::ActiveModel, DbErr> {
40
+ tag_info::ActiveModel {
41
+ tid: Set(form_data.tid.to_owned()),
42
+ uid: Set(form_data.uid.to_owned()),
43
+ tag_name: Set(form_data.tag_name.to_owned()),
44
+ regx: Set(form_data.regx.to_owned()),
45
+ color: Set(form_data.color.to_owned()),
46
+ icon: Set(form_data.icon.to_owned()),
47
+ dir: Set(form_data.dir.to_owned()),
48
+ created_at: Default::default(),
49
+ updated_at: Default::default(),
50
+ }
51
+ .save(db)
52
+ .await
53
+ }
54
+
55
+ pub async fn update_tag_by_id(
56
+ db: &DbConn,
57
+ id: i64,
58
+ form_data: tag_info::Model,
59
+ ) -> Result<tag_info::Model, DbErr> {
60
+ let tag: tag_info::ActiveModel = Entity::find_by_id(id)
61
+ .one(db)
62
+ .await?
63
+ .ok_or(DbErr::Custom("Cannot find post.".to_owned()))
64
+ .map(Into::into)?;
65
+
66
+ tag_info::ActiveModel {
67
+ tid: tag.tid,
68
+ uid: tag.uid,
69
+ tag_name: Set(form_data.tag_name.to_owned()),
70
+ regx: Set(form_data.regx.to_owned()),
71
+ color: Set(form_data.color.to_owned()),
72
+ icon: Set(form_data.icon.to_owned()),
73
+ dir: Set(form_data.dir.to_owned()),
74
+ created_at: Default::default(),
75
+ updated_at: Default::default(),
76
+ }
77
+ .update(db)
78
+ .await
79
+ }
80
+
81
+ pub async fn delete_tag(db: &DbConn, tid: i64) -> Result<DeleteResult, DbErr> {
82
+ let tag: tag_info::ActiveModel = Entity::find_by_id(tid)
83
+ .one(db)
84
+ .await?
85
+ .ok_or(DbErr::Custom("Cannot find tag.".to_owned()))
86
+ .map(Into::into)?;
87
+
88
+ tag.delete(db).await
89
+ }
90
+
91
+ pub async fn delete_all_tags(db: &DbConn) -> Result<DeleteResult, DbErr> {
92
+ Entity::delete_many().exec(db).await
93
+ }
94
+ }