Skip to content

Commit 638a8d2

Browse files
committed
use regexes instead of query parsing
1 parent daa4da0 commit 638a8d2

File tree

3 files changed

+40
-65
lines changed

3 files changed

+40
-65
lines changed

Cargo.lock

Lines changed: 1 addition & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ csv_to_table = "0.5.0"
1111
env_logger = "0.11.5"
1212
log = "0.4.22"
1313
poise = "0.6.1"
14+
regex = "1.11.1"
1415
reqwest = { version = "0.12", features = ["json"] }
15-
sqlparser = "0.52.0"
1616
tabled = "0.16.0"
1717
tokio = { version = "1", features = ["full"] }
1818
url = "2.5.3"

src/main.rs

Lines changed: 38 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ use clap_verbosity_flag::{InfoLevel, Verbosity};
44
use env_logger::Builder;
55
use log::info;
66
use poise::serenity_prelude as serenity;
7+
use regex::Regex;
78
use reqwest::{Client, Response};
8-
use sqlparser::ast::FormatClause::Identifier;
9-
use sqlparser::ast::Statement::Query;
10-
use sqlparser::ast::{Expr, Ident, Value};
11-
use sqlparser::dialect::ClickHouseDialect;
12-
use sqlparser::parser::Parser as SqlParser;
139
use std::io::Write;
1410
use tabled::settings::Style;
1511
use url::{ParseError, Url};
@@ -69,49 +65,39 @@ async fn format_url(cli: &CLI) -> Result<String, ParseError> {
6965
Ok(url.join(&qs)?.to_string())
7066
}
7167

72-
async fn format_query(query: String, output_limit: String) -> Result<String, Error> {
73-
let dialect = ClickHouseDialect {};
74-
let ast = SqlParser::parse_sql(&dialect, &query)?;
75-
if ast.len() != 1 {
76-
return Err(()).map_err(|_| "Only one query is allowed".into());
77-
}
78-
let mut statement = ast[0].clone();
79-
80-
// Check if the query has a limit clause
81-
// If it does, check if the limit is greater than the output limit
82-
// If it is, set the limit to the output limit
83-
match statement {
84-
Query(ref mut query) => match &query.limit {
85-
Some(Expr::Value(Value::Number(limit, b))) => {
86-
let limit: i32 = limit.parse().unwrap();
87-
let output_limit = match output_limit.parse() {
88-
Ok(output_limit) => output_limit,
89-
Err(_) => return Err(()).map_err(|_| "Invalid output limit".into()),
90-
};
91-
if limit > output_limit {
92-
query.limit = Some(Expr::Value(Value::Number(output_limit.to_string(), *b)));
93-
}
94-
}
95-
None => {
96-
query.limit = Some(Expr::Value(Value::Number(output_limit.to_string(), false)));
97-
}
98-
_ => {}
99-
},
100-
_ => {}
101-
};
68+
async fn format_query(query: String, output_limit: i32) -> Result<String, Error> {
69+
let mut formatted_query = query.clone();
10270

103-
// Set the format clause to CSVWithNames
104-
match statement {
105-
Query(ref mut query) => {
106-
query.format_clause = Some(Identifier(Ident {
107-
value: "CSVWithNames".to_string(),
108-
quote_style: None,
109-
}));
71+
let re = Regex::new(r".*LIMIT\s(\d+).*$").unwrap();
72+
let limit: Option<i32> = match re.captures(&query) {
73+
Some(caps) => Some(caps.get(1).unwrap().as_str().parse().unwrap()),
74+
None => None,
75+
};
76+
if let Some(limit) = limit {
77+
if limit > output_limit {
78+
formatted_query = query.replace(
79+
&format!("LIMIT {}", limit),
80+
&format!("LIMIT {}", output_limit),
81+
);
11082
}
111-
_ => {}
83+
} else {
84+
formatted_query = format!("{} LIMIT {}", query, output_limit)
85+
}
86+
87+
let re = Regex::new(r".*FORMAT\s(\S+).*$").unwrap();
88+
let format: Option<String> = match re.captures(&formatted_query) {
89+
Some(caps) => Some(caps.get(1).unwrap().as_str().to_string()),
90+
None => None,
11291
};
92+
if let Some(format) = format {
93+
if format != "CSVWithNames" {
94+
formatted_query = formatted_query.replace(&format, "CSVWithNames");
95+
}
96+
} else {
97+
formatted_query = format!("{} FORMAT CSVWithNames", formatted_query)
98+
}
11399

114-
Ok(statement.to_string())
100+
Ok(formatted_query)
115101
}
116102

117103
async fn do_query(query: String, url: String) -> Result<Response, Error> {
@@ -148,7 +134,8 @@ async fn query(
148134
}
149135
};
150136

151-
let query_text = match format_query(query_text, ctx.data().output_limit.clone()).await {
137+
let output_limit: i32 = ctx.data().output_limit.clone().parse().unwrap();
138+
let query_text = match format_query(query_text, output_limit).await {
152139
Ok(query_text) => query_text,
153140
Err(e) => {
154141
ctx.say(format!("{}", e)).await?;
@@ -201,19 +188,16 @@ mod tests {
201188
#[tokio::test]
202189
async fn test_format_query() {
203190
assert_eq!(
204-
format_query(
205-
"SELECT Count() FROM nxthdr.bgp_updates".to_string(),
206-
"10".to_string()
207-
)
208-
.await
209-
.unwrap(),
191+
format_query("SELECT Count() FROM nxthdr.bgp_updates".to_string(), 10)
192+
.await
193+
.unwrap(),
210194
"SELECT Count() FROM nxthdr.bgp_updates LIMIT 10 FORMAT CSVWithNames".to_string()
211195
);
212196

213197
assert_eq!(
214198
format_query(
215199
"SELECT Count() FROM nxthdr.bgp_updates LIMIT 5".to_string(),
216-
"10".to_string()
200+
10
217201
)
218202
.await
219203
.unwrap(),
@@ -223,7 +207,7 @@ mod tests {
223207
assert_eq!(
224208
format_query(
225209
"SELECT Count() FROM nxthdr.bgp_updates LIMIT 50".to_string(),
226-
"10".to_string()
210+
10
227211
)
228212
.await
229213
.unwrap(),
@@ -233,7 +217,7 @@ mod tests {
233217
assert_eq!(
234218
format_query(
235219
"SELECT Count() FROM nxthdr.bgp_updates LIMIT 50 FORMAT Pretty".to_string(),
236-
"10".to_string()
220+
10
237221
)
238222
.await
239223
.unwrap(),

0 commit comments

Comments
 (0)