chuanyue-service/README.MD

131 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### todo
- [*] 使用Extractor方式提取数据包括Body、Query和Path
- [ ] multipart/form-data的实现
- [*] 参考example中的jwt实现方式移除context对extension的依赖那么language-tag该怎么处理
- [ ] 参考rocket移除参数的元组类型
- [ ] 模拟request_util能否避免涉及到的parts.clone()?
- [-] 能否自定义实现宏路由
- [*] 定向路由的实现
- [ ] 支持多种method的路由
- [ ] 宏路由支持fallback等
### note
- 展开宏cargo expand --manifest-path .\server\Cargo.toml controller::feedback_controller
### sql dynamic query
https://github.com/launchbadge/sqlx/blob/main/FAQ.md#how-can-i-bind-an-array-to-a-values-clause-how-can-i-do-bulk-inserts
```rust
use sqlx::{query_builder::QueryBuilder, Execute};
struct Search {
id: i64,
username: Option<String>,
min_age: Option<i8>,
max_age: Option<i8>,
}
fn search_query(search: Search) -> String {
let mut query = QueryBuilder::new("SELECT * from users where id = ");
query.push_bind(search.id);
if let Some(username) = search.username {
query.push(" AND username = ");
query.push_bind(username);
}
if let Some(min_age) = search.min_age {
query.push(" AND age > ");
query.push_bind(min_age);
}
if let Some(max_age) = search.max_age {
query.push(" AND age < ");
query.push_bind(max_age);
}
query.build().sql().into()
}
fn main() {
dbg!(search_query(Search {
id: 12,
username: None,
min_age: None,
max_age: None,
})); // "SELECT * from users where id = $1"
dbg!(search_query(Search {
id: 12,
username: Some("Bob".into()),
min_age: None,
max_age: None,
})); // "SELECT * from users where id = $1 AND username = $2"
dbg!(search_query(Search {
id: 12,
username: Some("Bob".into()),
min_age: Some(10),
max_age: Some(70),
})); // "SELECT * from users where id = $1 AND username = $2 AND age > $3 AND age < $4"
}
```
```rust
use sqlx::{Execute, MySql, QueryBuilder};
struct User {
id: i32,
username: String,
email: String,
password: String,
}
// The number of parameters in MySQL must fit in a `u16`.
const BIND_LIMIT: usize = 65535;
// This would normally produce values forever!
let users = (0..).map(|i| User {
id: i,
username: format!("test_user_{i}"),
email: format!("test-user-{i}@example.com"),
password: format!("Test!User@Password#{i}"),
});
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
// Note the trailing space; most calls to `QueryBuilder` don't automatically insert
// spaces as that might interfere with identifiers or quoted strings where exact
// values may matter.
"INSERT INTO users(id, username, email, password) "
);
// Note that `.into_iter()` wasn't needed here since `users` is already an iterator.
query_builder.push_values(users.take(BIND_LIMIT / 4), |mut b, user| {
// If you wanted to bind these by-reference instead of by-value,
// you'd need an iterator that yields references that live as long as `query_builder`,
// e.g. collect it to a `Vec` first.
b.push_bind(user.id)
.push_bind(user.username)
.push_bind(user.email)
.push_bind(user.password);
});
let mut query = query_builder.build();
// You can then call `query.execute()`, `.fetch_one()`, `.fetch_all()`, etc.
// For the sake of demonstration though, we're just going to assert the contents
// of the query.
// These are methods of the `Execute` trait, not normally meant to be called in user code.
let sql = query.sql();
let arguments = query.take_arguments().unwrap();
assert!(sql.starts_with(
"INSERT INTO users(id, username, email, password) VALUES (?, ?, ?, ?), (?, ?, ?, ?)"
));
assert!(sql.ends_with("(?, ?, ?, ?)"));
// Not a normally exposed function, only used for this doctest.
// 65535 / 4 = 16383 (rounded down)
// 16383 * 4 = 65532
assert_eq!(arguments.len(), 65532);
```