Skip to content

Commit af7ec71

Browse files
committed
query parse fix
1 parent 6b5a378 commit af7ec71

File tree

5 files changed

+31
-23
lines changed

5 files changed

+31
-23
lines changed

frameworks/Rust/xitca-web/src/db.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::{
1010
util::{HandleResult, DB_URL},
1111
};
1212

13-
use db_util::{not_found, sort_update_params, update_query, Shared, FORTUNE_STMT, WORLD_STMT};
13+
use db_util::{not_found, sort_update_params, update_query_from_num, Shared, FORTUNE_STMT, WORLD_STMT};
1414

1515
pub struct Client {
1616
pool: Pool,
@@ -23,7 +23,7 @@ pub async fn create() -> HandleResult<Client> {
2323
pool: Pool::builder(DB_URL).capacity(1).build()?,
2424
shared: Default::default(),
2525
updates: core::iter::once(Box::from(""))
26-
.chain((1..=500).map(update_query))
26+
.chain((1..=500).map(update_query_from_num))
2727
.collect(),
2828
})
2929
}

frameworks/Rust/xitca-web/src/db_unrealistic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::{
1313
util::{HandleResult, DB_URL},
1414
};
1515

16-
use db_util::{not_found, sort_update_params, update_query, Shared, FORTUNE_STMT, WORLD_STMT};
16+
use db_util::{not_found, sort_update_params, update_query_from_num, Shared, FORTUNE_STMT, WORLD_STMT};
1717

1818
pub struct Client {
1919
cli: xitca_postgres::Client,
@@ -36,7 +36,7 @@ pub async fn create() -> HandleResult<Client> {
3636

3737
let mut updates = vec![Statement::default()];
3838

39-
for update in (1..=500).map(update_query).into_iter() {
39+
for update in (1..=500).map(update_query_from_num).into_iter() {
4040
let stmt = Statement::named(&update, &[]).execute(&cli).await?.leak();
4141
updates.push(stmt);
4242
}

frameworks/Rust/xitca-web/src/db_util.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
use crate::util::Error;
22

3+
#[cfg(any(feature = "pg-orm", feature = "pg-orm-async"))]
34
// diesel does not support high level bulk update api. use raw sql to bypass the limitation.
45
// relate discussion: https://github.com/diesel-rs/diesel/discussions/2879
56
pub fn update_query_from_ids(ids: &[(i32, i32)]) -> String {
7+
update_query(|query| {
8+
use core::fmt::Write;
9+
ids.iter().for_each(|(w_id, num)| {
10+
write!(query, "({}::int,{}::int),", w_id, num).unwrap();
11+
});
12+
})
13+
}
14+
15+
fn update_query(func: impl FnOnce(&mut String)) -> String {
616
const PREFIX: &str = "UPDATE world SET randomNumber = w.r FROM (VALUES ";
717
const SUFFIX: &str = ") AS w (i,r) WHERE world.id = w.i";
818

919
let mut query = String::from(PREFIX);
1020

11-
use std::fmt::Write;
12-
ids.iter().for_each(|(w_id, num)| {
13-
write!(query, "({}::int,{}::int),", w_id, num).unwrap();
14-
});
21+
func(&mut query);
1522

1623
if query.ends_with(',') {
1724
query.pop();
@@ -46,12 +53,15 @@ pub mod pg {
4653
pub const FORTUNE_STMT: StatementNamed = Statement::named("SELECT * FROM fortune", &[]);
4754
pub const WORLD_STMT: StatementNamed = Statement::named("SELECT * FROM world WHERE id=$1", &[Type::INT4]);
4855

49-
pub fn update_query(num: usize) -> Box<str> {
50-
let (_, ids) = (1..=num).fold((1, Vec::new()), |(id, mut ids), _| {
51-
ids.push((id, id + 1));
52-
(id + 2, ids)
53-
});
54-
super::update_query_from_ids(&ids).into_boxed_str()
56+
pub fn update_query_from_num(num: usize) -> Box<str> {
57+
super::update_query(|query| {
58+
use core::fmt::Write;
59+
(1..=num).fold(1, |idx, _| {
60+
write!(query, "(${}::int,${}::int),", idx, idx + 1).unwrap();
61+
idx + 2
62+
});
63+
})
64+
.into_boxed_str()
5565
}
5666

5767
pub fn sort_update_params(params: &[[i32; 2]]) -> impl ExactSizeIterator<Item = i32> {

frameworks/Rust/xitca-web/src/main_iou.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,13 @@ async fn handler<'h>(req: Request<'h>, res: Response<'h>, state: &State<db::Clie
114114
let world = state.client.get_world().await.unwrap();
115115
json_response(res, state, &world)
116116
}
117-
p if p.starts_with("/queries") => {
118-
let num = p.parse_query();
117+
p if p.starts_with("/q") => {
118+
let num = p["/queries?q=".len()..].parse_query();
119119
let worlds = state.client.get_worlds(num).await.unwrap();
120120
json_response(res, state, &worlds)
121121
}
122-
p if p.starts_with("/updates") => {
123-
let num = p.parse_query();
122+
p if p.starts_with("/u") => {
123+
let num = p["/updates?q=".len()..].parse_query();
124124
let worlds = state.client.update(num).await.unwrap();
125125
json_response(res, state, &worlds)
126126
}

frameworks/Rust/xitca-web/src/util.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@ pub trait QueryParse {
1010

1111
impl QueryParse for Option<&str> {
1212
fn parse_query(self) -> u16 {
13-
self.map(QueryParse::parse_query).unwrap_or(1)
13+
self.and_then(|q| q.find('q').map(|pos| q.split_at(pos + 2).1.parse_query()))
14+
.unwrap_or(1)
1415
}
1516
}
1617

1718
impl QueryParse for &str {
1819
fn parse_query(self) -> u16 {
1920
use atoi::FromRadix10;
20-
self.find('q')
21-
.map(|pos| u16::from_radix_10(self.split_at(pos + 2).1.as_ref()).0)
22-
.unwrap_or(1)
23-
.clamp(1, 500)
21+
u16::from_radix_10(self.as_bytes()).0.clamp(1, 500)
2422
}
2523
}
2624

0 commit comments

Comments
 (0)