Skip to content

Commit 0d467c6

Browse files
committed
fix
1 parent fdc2f78 commit 0d467c6

2 files changed

Lines changed: 139 additions & 5 deletions

File tree

test-utils/src/sandbox.rs

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,139 @@ impl TestConfig {
9696
}
9797
}
9898

99+
/// Checks if the MySQL server at the given host:port is above the specified major.minor version.
100+
/// Uses `docker exec` to query the version. Returns true if version cannot be determined.
101+
pub fn is_mysql_version_above(db_host: &str, db_port: i32, major: u32, minor: u32) -> bool {
102+
let output = std::process::Command::new("docker")
103+
.args(["exec", "sqlx-ts-mysql-1", "mysql", "-u", "root", "-N", "-e", "SELECT VERSION();"])
104+
.output();
105+
match output {
106+
Ok(out) => {
107+
let version = String::from_utf8_lossy(&out.stdout);
108+
let version = version.trim();
109+
let parts: Vec<&str> = version.split('.').collect();
110+
if parts.len() >= 2 {
111+
let srv_major: u32 = parts[0].parse().unwrap_or(0);
112+
let srv_minor: u32 = parts[1].parse().unwrap_or(0);
113+
srv_major > major || (srv_major == major && srv_minor > minor)
114+
} else {
115+
true
116+
}
117+
}
118+
Err(_) => true,
119+
}
120+
}
121+
99122
#[macro_export]
100123
macro_rules! run_test {
124+
// Arm with minimum MySQL version requirement: (major, minor)
125+
($($name: ident, $test_config: expr, $ts_content: expr, $generated_types: expr, min_mysql: ($maj:expr, $min:expr))*) => {
126+
$(
127+
#[test]
128+
fn $name() -> Result<(), Box<dyn std::error::Error>> {
129+
use assert_cmd::cargo::cargo_bin_cmd;
130+
let ts_content = $ts_content;
131+
let test_config: TestConfig = $test_config;
132+
133+
// Check minimum MySQL version requirement
134+
if test_config.db_type == "mysql" {
135+
if !test_utils::sandbox::is_mysql_version_above(&test_config.db_host, test_config.db_port, $maj, $min) {
136+
eprintln!("Skipping test {}: requires MySQL > {}.{}", stringify!($name), $maj, $min);
137+
return Ok(());
138+
}
139+
}
140+
141+
println!("checking test config {:?}", test_config);
142+
let file_extension = test_config.file_extension;
143+
let db_type = test_config.db_type;
144+
let db_host = test_config.db_host;
145+
let db_port = test_config.db_port;
146+
let db_user = test_config.db_user;
147+
let db_pass = test_config.db_pass;
148+
let db_name = test_config.db_name;
149+
let config_file_name = test_config.config_file_name;
150+
let generate_path = test_config.generate_path;
151+
152+
// SETUP
153+
let dir = tempdir()?;
154+
let parent_path = dir.path();
155+
let file_path = parent_path.join(format!("index.{file_extension}"));
156+
157+
let mut temp_file = fs::File::create(&file_path)?;
158+
writeln!(temp_file, "{}", ts_content)?;
159+
let file_result = fs::read_to_string(&file_path)?;
160+
161+
// EXECUTE
162+
let mut cmd = cargo_bin_cmd!("sqlx-ts");
163+
164+
cmd.arg(parent_path.to_str().unwrap())
165+
.arg(format!("--ext={file_extension}"))
166+
.arg(format!("--db-type={db_type}"))
167+
.arg(format!("--db-host={db_host}"))
168+
.arg(format!("--db-port={db_port}"))
169+
.arg(format!("--db-user={db_user}"))
170+
.arg(format!("--db-name={db_name}"));
171+
172+
if &generate_path.is_some() == &true {
173+
let generate_path = generate_path.clone();
174+
let generate_path = generate_path.unwrap();
175+
let generate_path = generate_path.as_path();
176+
let generate_path = parent_path.join(generate_path);
177+
let generate_path = generate_path.display();
178+
cmd.arg(format!("--generate-path={generate_path}"));
179+
}
180+
181+
if (test_config.generate_types) {
182+
cmd.arg("-g");
183+
}
184+
185+
if (config_file_name.is_some()) {
186+
let cwd = env::current_dir()?;
187+
let config_file_name = format!("{}", config_file_name.unwrap());
188+
let config_path = cwd.join(format!("tests/configs/{config_file_name}"));
189+
let config_path = config_path.display();
190+
cmd.arg(format!("--config={config_path}"));
191+
}
192+
193+
if (db_pass.is_some()) {
194+
let db_pass = db_pass.unwrap();
195+
cmd.arg(format!("--db-pass={db_pass}"));
196+
} else {
197+
cmd.arg("--db-pass=");
198+
}
199+
200+
cmd.assert()
201+
.success()
202+
.stdout(predicates::str::contains("No SQL errors detected!"));
203+
204+
let generated_types: &str = $generated_types.clone();
205+
206+
if generate_path.is_some() {
207+
let generate_path = parent_path.join(generate_path.unwrap().as_path());
208+
let type_file = fs::read_to_string(generate_path);
209+
let type_file = type_file.unwrap();
210+
211+
assert_eq!(
212+
generated_types.trim().to_string().flatten(),
213+
type_file.trim().to_string().flatten()
214+
);
215+
return Ok(());
216+
}
217+
218+
let type_file = fs::read_to_string(parent_path.join("index.queries.ts"));
219+
if type_file.is_ok() {
220+
let type_file = type_file.unwrap().clone();
221+
let type_file = type_file.trim();
222+
assert_eq!(
223+
generated_types.trim().to_string().flatten(),
224+
type_file.to_string().flatten()
225+
);
226+
}
227+
Ok(())
228+
}
229+
)*};
230+
231+
// Original arm without version requirement
101232
($($name: ident, $test_config: expr, $ts_content: expr, $generated_types: expr)*) => {
102233
$(
103234
// MACRO STARTS
@@ -117,7 +248,7 @@ $(
117248
let db_name = test_config.db_name;
118249
let config_file_name = test_config.config_file_name;
119250
let generate_path = test_config.generate_path;
120-
251+
121252
// SETUP
122253
let dir = tempdir()?;
123254
let parent_path = dir.path();
@@ -126,7 +257,7 @@ $(
126257
let mut temp_file = fs::File::create(&file_path)?;
127258
writeln!(temp_file, "{}", ts_content)?;
128259
let file_result = fs::read_to_string(&file_path)?;
129-
260+
130261
// EXECUTE
131262
let mut cmd = cargo_bin_cmd!("sqlx-ts");
132263

tests/mysql_query_parameters.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export interface ISomeQueryQuery {
149149
"#);
150150

151151
// Issue #266: Query params should be detected when placeholder is on the left side of a comparison
152+
// Skipped on MySQL <= 5.7 because TIMESTAMP nullability defaults differ between versions
152153
#[rustfmt::skip]
153154
run_test!(should_pick_query_params_when_placeholder_before_comparison, TestConfig::new("mysql", true, None, None),
154155

@@ -186,9 +187,10 @@ export interface ISomeQueryQuery {
186187
params: SomeQueryParams;
187188
result: ISomeQueryResult;
188189
}
189-
"#);
190+
"#, min_mysql: (5, 7));
190191

191192
// Issue #266: Query params should be detected in BETWEEN clause when placeholder is the expr
193+
// Skipped on MySQL <= 5.7 because TIMESTAMP nullability defaults differ between versions
192194
#[rustfmt::skip]
193195
run_test!(should_pick_query_params_from_between_with_placeholder_expr, TestConfig::new("mysql", true, None, None),
194196

@@ -225,9 +227,10 @@ export interface ISomeQueryQuery {
225227
params: SomeQueryParams;
226228
result: ISomeQueryResult;
227229
}
228-
"#);
230+
"#, min_mysql: (5, 7));
229231

230232
// Issue #266: Standard BETWEEN with placeholders as low/high should still work
233+
// Skipped on MySQL <= 5.7 because TIMESTAMP nullability defaults differ between versions
231234
#[rustfmt::skip]
232235
run_test!(should_pick_query_params_from_between_with_placeholder_bounds, TestConfig::new("mysql", true, None, None),
233236

@@ -263,5 +266,5 @@ export interface ISomeQueryQuery {
263266
params: SomeQueryParams;
264267
result: ISomeQueryResult;
265268
}
266-
"#);
269+
"#, min_mysql: (5, 7));
267270
}

0 commit comments

Comments
 (0)