Skip to content

Commit f62cd70

Browse files
committed
sqlpage.set_variable links to "?" when no parameter is present
- Renamed URLParameters module for clarity and removed the deprecated url_parameter_deserializer. - Updated the set_variable function to return parameters directly instead of appending to a URL. - Adjusted related function calls to reflect changes in URL parameter management.
1 parent 544771d commit f62cd70

File tree

10 files changed

+57
-47
lines changed

10 files changed

+57
-47
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# CHANGELOG.md
22

33
## 0.40.0 (unreleased)
4+
- Fixed a bug in `sqlpage.link`: a link with no path (link to the current page) and no url parameter now works as expected. It used to keep the existing url parameters instead of removing them. `sqlpage.link('', '{}')` now returns `'?'` instead of the empty string.
45
- **New Function**: `sqlpage.set_variable(name, value)`
56
- Returns a URL with the specified variable set to the given value, preserving other existing variables.
67
- This is a shorthand for `sqlpage.link(sqlpage.path(), json_patch(sqlpage.variables('get'), json_object(name, value)))`.

src/webserver/database/sqlpage_functions/functions.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{ExecutionContext, RequestInfo};
22
use crate::webserver::{
33
database::{
44
blob_to_data_url::vec_to_data_uri_with_mime, execute_queries::DbConn,
5-
sqlpage_functions::url_parameter_deserializer::URLParameters,
5+
sqlpage_functions::url_parameters::URLParameters,
66
},
77
http_client::make_http_client,
88
request_variables::ParamMap,
@@ -377,7 +377,7 @@ async fn link<'a>(
377377
let encoded = serde_json::from_str::<URLParameters>(&parameters).with_context(|| {
378378
format!("link: invalid URL parameters: not a valid json object:\n{parameters}")
379379
})?;
380-
encoded.append_to_url(&mut url);
380+
encoded.append_to_path(&mut url);
381381
}
382382
if let Some(hash) = hash {
383383
url.push('#');
@@ -627,10 +627,7 @@ async fn set_variable<'a>(
627627
params.push_single_or_vec(&name, SingleOrVec::Single(value.into_owned()));
628628
}
629629

630-
let mut url = context.path.clone();
631-
params.append_to_url(&mut url);
632-
633-
Ok(url)
630+
Ok(params.with_empty_path())
634631
}
635632

636633
#[tokio::test]

src/webserver/database/sqlpage_functions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod function_definition_macro;
22
mod function_traits;
33
pub(super) mod functions;
44
mod http_fetch_request;
5-
mod url_parameter_deserializer;
5+
mod url_parameters;
66

77
use sqlparser::ast::FunctionArg;
88

src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs renamed to src/webserver/database/sqlpage_functions/url_parameters.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,28 @@ pub struct URLParameters(String);
1010

1111
impl URLParameters {
1212
pub fn new() -> Self {
13-
Self::default()
13+
Self(String::new())
1414
}
1515

1616
fn encode_and_push(&mut self, v: &str) {
1717
let val: Cow<str> = percent_encode(v.as_bytes(), NON_ALPHANUMERIC).into();
1818
self.0.push_str(&val);
1919
}
20+
21+
fn start_new_pair(&mut self) {
22+
let char = if self.0.is_empty() { '?' } else { '&' };
23+
self.0.push(char);
24+
}
25+
2026
fn push_kv(&mut self, key: &str, value: &str) {
21-
if !self.0.is_empty() {
22-
self.0.push('&');
23-
}
27+
self.start_new_pair();
2428
self.encode_and_push(key);
2529
self.0.push('=');
2630
self.encode_and_push(value);
2731
}
2832

2933
fn push_array_entry(&mut self, key: &str, value: &str) {
30-
if !self.0.is_empty() {
31-
self.0.push('&');
32-
}
34+
self.start_new_pair();
3335
self.encode_and_push(key);
3436
self.0.push_str("[]=");
3537
self.encode_and_push(value);
@@ -68,9 +70,18 @@ impl URLParameters {
6870
}
6971
}
7072

71-
pub fn append_to_url(&self, url: &mut String) {
72-
if !self.0.is_empty() {
73-
url.push('?');
73+
pub fn with_empty_path(self) -> String {
74+
if self.0.is_empty() {
75+
"?".to_string() // Link to the current page without parameters
76+
} else {
77+
self.0 // Link to the current page with specific parameters
78+
}
79+
}
80+
81+
pub fn append_to_path(self, url: &mut String) {
82+
if url.is_empty() {
83+
*url = self.with_empty_path();
84+
} else {
7485
url.push_str(&self.0);
7586
}
7687
}
@@ -116,6 +127,12 @@ impl std::fmt::Display for URLParameters {
116127
}
117128
}
118129

130+
impl From<URLParameters> for String {
131+
fn from(value: URLParameters) -> Self {
132+
value.0
133+
}
134+
}
135+
119136
#[test]
120137
fn test_url_parameters_deserializer() {
121138
use serde_json::json;
@@ -128,7 +145,7 @@ fn test_url_parameters_deserializer() {
128145
let url_parameters: URLParameters = serde_json::from_value(json).unwrap();
129146
assert_eq!(
130147
url_parameters.0,
131-
"x=hello%20world&num=123&arr[]=1&arr[]=2&arr[]=3"
148+
"?x=hello%20world&num=123&arr[]=1&arr[]=2&arr[]=3"
132149
);
133150
}
134151

@@ -141,7 +158,7 @@ fn test_url_parameters_null() {
141158
});
142159

143160
let url_parameters: URLParameters = serde_json::from_value(json).unwrap();
144-
assert_eq!(url_parameters.0, "x=hello");
161+
assert_eq!(url_parameters.0, "?x=hello");
145162
}
146163

147164
#[test]
@@ -152,7 +169,7 @@ fn test_url_parameters_deserializer_special_chars() {
152169
});
153170

154171
let url_parameters: URLParameters = serde_json::from_value(json).unwrap();
155-
assert_eq!(url_parameters.0, "chars[]=%0A&chars[]=%20&chars[]=%22");
172+
assert_eq!(url_parameters.0, "?chars[]=%0A&chars[]=%20&chars[]=%22");
156173
}
157174

158175
#[test]
@@ -167,20 +184,20 @@ fn test_url_parameters_deserializer_issue_879() {
167184
let url_parameters: URLParameters = serde_json::from_value(json).unwrap();
168185
assert_eq!(
169186
url_parameters.0,
170-
"name=John%20Doe%20%26%20Son%27s&items[]=1&items[]=item%202%20%26%203&items[]=true&special%5Fchar=%25%26%3D%2B%20"
187+
"?name=John%20Doe%20%26%20Son%27s&items[]=1&items[]=item%202%20%26%203&items[]=true&special%5Fchar=%25%26%3D%2B%20"
171188
);
172189
}
173190

174191
#[test]
175192
fn test_push_single_or_vec() {
176193
let mut params = URLParameters(String::new());
177194
params.push_single_or_vec("k", SingleOrVec::Single("v".to_string()));
178-
assert_eq!(params.to_string(), "k=v");
195+
assert_eq!(params.to_string(), "?k=v");
179196

180197
let mut params = URLParameters(String::new());
181198
params.push_single_or_vec(
182199
"arr",
183200
SingleOrVec::Vec(vec!["a".to_string(), "b".to_string()]),
184201
);
185-
assert_eq!(params.to_string(), "arr[]=a&arr[]=b");
202+
assert_eq!(params.to_string(), "?arr[]=a&arr[]=b");
186203
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
set url = sqlpage.set_variable('y', '2');
2+
3+
select 'text' as component,
4+
case $url
5+
when '?x=1&y=2' THEN 'It works !'
6+
else 'It failed ! Expected ?x=1&y=2 but got ' || coalesce($url, 'NULL')
7+
end as contents;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
set url = sqlpage.set_variable('x', null);
2+
select 'text' as component,
3+
case $url
4+
when '?' THEN 'It works !'
5+
else 'It failed ! Expected "?" but got ' || coalesce('"' || $url || '"', 'NULL')
6+
end as contents;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
set url = sqlpage.set_variable('x', '2');
2+
select 'text' as component,
3+
case $url
4+
when '?x=2' THEN 'It works !'
5+
else 'It failed ! Expected ?x=2 but got ' || $url
6+
end as contents;

tests/sql_test_files/it_works_set_variable_nomssql.sql

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/sql_test_files/it_works_set_variable_null.sql

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/sql_test_files/it_works_set_variable_replace.sql

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)