Skip to content

Commit 546ac28

Browse files
committed
增加最sea-orm的支持
1 parent ca0d0ee commit 546ac28

File tree

11 files changed

+1375
-333
lines changed

11 files changed

+1375
-333
lines changed

Cargo.lock

Lines changed: 1291 additions & 251 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@ libaes = "0.7.0"
2525
utoipa = { version = "5.3.1", features = ["axum_extras"] }
2626
utoipa-rapidoc = { version = "6.0.0", features = ["axum"] }
2727
aliyun-sts-rust-sdk = { version ="0.1.1", path="/Users/alex/Projects/workspace/aliyun-sts-rust-sdk"}
28-
sqlx = { version = "0.7.4", default-features = false, features = ["tls-rustls", "runtime-tokio", "postgres", "json", "uuid", "bigdecimal", "macros"] }
29-
sqlx_struct_enhanced = { version = "*", path = "/Users/alex/Projects/workspace/sqlx_struct_enhanced", features = ["postgres"] }
28+
sea-orm = { version = "1.1.10" , features = ["runtime-tokio", "sqlx-all"] }
29+
sqlx-postgres = "0.8.5"
30+
31+
[dev-dependencies]
32+
sea-orm-cli = "1.1.10"

src/app.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,27 @@ use axum::routing::get;
99
//use http::{header, Request, StatusCode};
1010
use log::{error, info};
1111
use serde_json::json;
12-
use sqlx::postgres::PgPoolOptions;
1312
use utoipa::OpenApi;
1413
use utoipa_rapidoc::RapiDoc;
1514
use crate::errors::ErrResponse;
1615
use crate::conf::Configuration;
1716
use crate::{example, services};
1817
use crate::redis::{RedisHolder, RedisSession};
1918
use redis::AsyncCommands;
19+
use sea_orm::Database;
2020

2121
#[derive(Clone)]
2222
pub struct AppContext {}
2323

2424
pub async fn init(cfg: &Configuration) {
25-
let pool = PgPoolOptions::new()
26-
.max_connections(5)
27-
.acquire_timeout(Duration::from_secs(3))
28-
.connect(&cfg.db_uri.clone())
29-
.await
30-
.expect("can't connect to database");
25+
let db = Database::connect(cfg.db_uri.as_str()).await.unwrap();
26+
3127
let client = redis::Client::open(cfg.redis_uri.clone()).unwrap();
3228
let client_inner = client.clone();
3329
ru_di::Di::register(move |_| {
3430
RedisHolder{client: client_inner.clone()}
3531
});
36-
let pool_inner = pool.clone();
32+
let pool_inner = db.clone();
3733
ru_di::Di::register(move |_| {
3834
pool_inner.clone()
3935
});

src/errors.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use axum::Json;
22
use axum::http::StatusCode;
33
use axum::response::{IntoResponse, Response};
4-
use sqlx::Error;
4+
use sea_orm::DbErr;
55
use reqwest::Error as HttpError;
66
use redis::RedisError;
77
use log::error;
@@ -24,7 +24,7 @@ pub(crate) struct ErrResponse {
2424
#[derive(Debug)]
2525
pub enum AppError {
2626
DbError {
27-
source:Error,
27+
source:DbErr,
2828
backtrace: Backtrace,
2929
},
3030
RedisError {
@@ -48,8 +48,8 @@ pub enum AppError {
4848
LoginFailure,
4949
}
5050

51-
impl From<Error> for AppError {
52-
fn from(value: Error) -> Self {
51+
impl From<DbErr> for AppError {
52+
fn from(value: DbErr) -> Self {
5353
error!("数据库错误:{:?}", value);
5454
Self::DbError{ source: value, backtrace: Backtrace::capture()}
5555
}
@@ -126,19 +126,19 @@ impl IntoResponse for AppError {
126126
eprintln!("Error: {}", self);
127127
let resp = match self {
128128
Self::DbError { source, backtrace}=>{
129-
if let Error::RowNotFound = source {
130-
//error!("查询记录不存在:{:?} {:?}", source, backtrace);
131-
(
132-
StatusCode::NOT_FOUND,
133-
Json(json!(ErrResponse{info: format!("{source:?}")}))
134-
)
135-
}else{
136-
//error!("数据库错误:{:?} {:?}", source, backtrace);
137-
(
138-
StatusCode::INTERNAL_SERVER_ERROR,
139-
Json(json!(ErrResponse{info: format!("{source:?}")}))
140-
)
141-
129+
match source {
130+
DbErr::RecordNotFound(_) => {
131+
(
132+
StatusCode::NOT_FOUND,
133+
Json(json!(ErrResponse{info: format!("{source:?}")}))
134+
)
135+
}
136+
_=>{
137+
(
138+
StatusCode::INTERNAL_SERVER_ERROR,
139+
Json(json!(ErrResponse{info: format!("{source:?}")}))
140+
)
141+
}
142142
}
143143
},
144144
Self::LogicError(msg)=>{

src/example/handlers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use crate::response::StatusResponse;
2222
)]
2323
async fn it_works() -> APIResult<StatusResponse> {
2424
let serv = get_serve::<ExampleServices>();
25-
serv.test().await?;
26-
Ok(Json(StatusResponse{status: "it works".to_string()}))
25+
let resp = serv.test().await?;
26+
Ok(Json(StatusResponse{status: resp}))
2727
}
2828

2929
// 导出路由

src/models.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1-
use sqlx::FromRow;
2-
use sqlx_struct_enhanced::{EnhancedCrud, Scheme};
3-
use sqlx::query::{Query, QueryAs};
4-
use sqlx::Postgres;
5-
use sqlx::database::HasArguments;
6-
use uuid::Uuid;
7-
use sqlx::types::BigDecimal;
81

2+
pub mod UserLogin {
3+
use sea_orm::entity::prelude::*;
4+
use sea_orm::{ActiveModelTrait, Database, DbErr, DeleteResult, EntityTrait, Set};
5+
use serde::{Deserialize, Serialize};
96

10-
#[derive(Debug, Clone, FromRow, EnhancedCrud)]
11-
pub struct UserLogin {
12-
pub username: String,
13-
pub password: String,
14-
pub ts: i32,
15-
7+
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
8+
#[sea_orm(table_name = "user_login")]
9+
pub struct Model {
10+
#[sea_orm(primary_key)]
11+
pub username: String,
12+
13+
pub password: String,
14+
pub ts: i32,
15+
16+
}
17+
18+
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
19+
pub enum Relation {}
20+
impl ActiveModelBehavior for ActiveModel {}
1621
}
1722

23+

src/response.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
use axum::Json;
2-
use axum::response::IntoResponse;
3-
use sqlx::Error;
4-
use serde_json::json;
5-
use redis::RedisError;
6-
use reqwest::Error as HttpError;
7-
use log::error;
81
use serde::{Deserialize, Serialize};
9-
use serde_json::{Error as JsonError, Value};
2+
use serde_json::Value;
103
use utoipa::ToSchema;
114

125

6+
137
#[derive(Debug, Clone, ToSchema, Deserialize, Serialize)]
148
pub struct StatusResponse {
159
pub status: String,

src/services/example_service.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
use log::info;
2-
use sqlx_struct_enhanced::EnhancedCrud;
3-
use crate::errors::APIResult;
4-
use crate::models::UserLogin;
2+
use sea_orm::{DatabaseConnection, EntityTrait};
3+
use crate::errors::{APIResult, AppError};
54
use crate::redis::RedisHolder;
65
use crate::types::Service;
76
use crate::utilities::current_ts;
7+
use crate::models::UserLogin::{ActiveModel, Entity};
88

99
pub struct ExampleServices {
10-
pub(crate) db: sqlx::Pool<sqlx::Postgres>,
10+
pub(crate) db: DatabaseConnection,
1111
pub(crate) redis: RedisHolder,
1212
}
1313

1414
impl Service for ExampleServices {
15-
fn init(db: sqlx::Pool<sqlx::Postgres>, redis: RedisHolder) -> Self {
15+
fn init(db: DatabaseConnection, redis: RedisHolder) -> Self {
1616
Self{db, redis}
1717
}
1818
}
1919

2020
impl ExampleServices {
21-
pub(crate) async fn test(&self) -> APIResult<()> {
22-
let user = UserLogin::where_query("name=$1").bind("test").fetch_one(&self.db).await?;
23-
info!("Running test:{:?}", user);
24-
Ok(())
21+
pub(crate) async fn test(&self) -> APIResult<String> {
22+
if let Some(entity) = Entity::find_by_id::<String>("Alex".to_string()).one(&self.db).await? {
23+
Ok(entity.username.to_string())
24+
} else {
25+
Err(AppError::NotFound)
26+
}
2527
}
26-
2728
}

src/types.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use axum::Json;
2+
use sea_orm::DatabaseConnection;
23
use crate::errors::AppError;
34
use crate::redis::RedisHolder;
45

@@ -9,12 +10,12 @@ pub fn get_serve<T: 'static>() -> T {
910
}
1011

1112
pub trait Service {
12-
fn init(db: sqlx::Pool<sqlx::Postgres>, redis: RedisHolder) -> Self;
13+
fn init(db: DatabaseConnection, redis: RedisHolder) -> Self;
1314
}
1415

1516
pub fn register_service<T: Service + 'static + Send + Sync>() {
1617
ru_di::Di::register(move |di| {
17-
let db = di.get_inner::<sqlx::Pool<sqlx::Postgres>>().unwrap();
18+
let db = di.get_inner::<DatabaseConnection>().unwrap();
1819
let redis = di.get_inner::<RedisHolder>().unwrap();
1920
T::init(db, redis)
2021
});

templates/models.txt

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1-
use sqlx::FromRow;
2-
use sqlx_struct_enhanced::{EnhancedCrud, Scheme};
3-
use sqlx::query::{Query, QueryAs};
4-
use sqlx::Postgres;
5-
use sqlx::database::HasArguments;
6-
use uuid::Uuid;
7-
use sqlx::types::BigDecimal;
8-
91
{% for entity in entities %}
10-
#[derive(Debug, Clone, FromRow, EnhancedCrud)]
11-
pub struct {{ entity.name }} {
12-
{% for fd in entity.fields %}pub {{fd.name}}: {{ fd.types.rust.name }},
13-
{% endfor %}
2+
pub mod {{ entity.name }} {
3+
use sea_orm::entity::prelude::*;
4+
use sea_orm::{ActiveModelTrait, Database, DbErr, DeleteResult, EntityTrait, Set};
5+
use serde::{Deserialize, Serialize};
6+
7+
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
8+
#[sea_orm(table_name = "{{ entity.name | snake_case }}")]
9+
pub struct Model {
10+
#[sea_orm(primary_key)]
11+
{% for fd in entity.fields | slice(start=0, end=1) %}pub {{fd.name}}: {{ fd.types.rust.name }},
12+
{% endfor %}
13+
{% for fd in entity.fields | slice(start=1) %}pub {{fd.name}}: {{ fd.types.rust.name }},
14+
{% endfor %}
15+
}
16+
17+
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
18+
pub enum Relation {}
19+
impl ActiveModelBehavior for ActiveModel {}
1420
}
21+
1522
{% endfor %}

0 commit comments

Comments
 (0)