Skip to content

Commit 761d61a

Browse files
committed
fix: add schema for enums
1 parent 34cb49b commit 761d61a

File tree

5 files changed

+103
-10
lines changed

5 files changed

+103
-10
lines changed

Cargo.lock

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

crates/sqlx_gen/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlx-gen"
3-
version = "0.5.3"
3+
version = "0.5.4"
44
edition = "2021"
55
description = "Generate Rust structs from database schema introspection"
66
license = "MIT"
@@ -30,7 +30,7 @@ cli = [
3030
]
3131

3232
[dependencies]
33-
sqlx-gen-macros = { path = "../sqlx_gen_macros", version = "0.5.3" }
33+
sqlx-gen-macros = { path = "../sqlx_gen_macros", version = "0.5.4" }
3434
sqlx = { version = "0.8", features = [
3535
"runtime-tokio",
3636
"tls-rustls-ring",

crates/sqlx_gen/src/codegen/composite_gen.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ pub fn generate_composite(
4545
derive_tokens.push(quote! { #ident });
4646
}
4747

48-
let pg_name = &composite.name;
48+
let pg_name = if composite.schema_name != "public" {
49+
format!("{}.{}", composite.schema_name, composite.name)
50+
} else {
51+
composite.name.clone()
52+
};
4953
let type_attr = quote! { #[sqlx(type_name = #pg_name)] };
5054

5155
let fields: Vec<TokenStream> = composite
@@ -190,7 +194,7 @@ mod tests {
190194
let schema = SchemaInfo::default();
191195
let (tokens, _) = generate_composite(&c, DatabaseKind::Postgres, &schema, &[], &HashMap::new(), TimeCrate::Chrono);
192196
let code = parse_and_format(&tokens);
193-
assert!(code.contains("sqlx(type_name = \"point\")"));
197+
assert!(code.contains("sqlx(type_name = \"geo.point\")"));
194198
}
195199

196200
#[test]

crates/sqlx_gen/src/codegen/enum_gen.rs

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@ pub fn generate_enum(
3838
derive_tokens.push(quote! { #ident });
3939
}
4040

41-
// For PG, add #[sqlx(type_name = "...")]
41+
// For PG, add #[sqlx(type_name = "...")] — schema-qualify for non-public schemas
4242
let type_attr = if db_kind == DatabaseKind::Postgres {
43-
let pg_name = &enum_info.name;
43+
let pg_name = if enum_info.schema_name != "public" {
44+
format!("{}.{}", enum_info.schema_name, enum_info.name)
45+
} else {
46+
enum_info.name.clone()
47+
};
4448
quote! { #[sqlx(type_name = #pg_name)] }
4549
} else {
4650
quote! {}
@@ -188,7 +192,7 @@ mod tests {
188192
};
189193
let (tokens, _) = generate_enum(&e, DatabaseKind::Postgres, &[]);
190194
let code = parse_and_format(&tokens);
191-
assert!(code.contains("sqlx(type_name = \"role\")"));
195+
assert!(code.contains("sqlx(type_name = \"auth.role\")"));
192196
}
193197

194198
#[test]
@@ -359,4 +363,89 @@ mod tests {
359363
assert!(code.contains("impl Default for Status"));
360364
assert!(code.contains("Self::InProgress"));
361365
}
366+
367+
// --- public vs named schema integration ---
368+
369+
fn make_enum_in_schema(schema: &str, name: &str, variants: Vec<&str>) -> EnumInfo {
370+
EnumInfo {
371+
schema_name: schema.to_string(),
372+
name: name.to_string(),
373+
variants: variants.into_iter().map(|s| s.to_string()).collect(),
374+
default_variant: None,
375+
}
376+
}
377+
378+
#[test]
379+
fn test_public_schema_full_output() {
380+
let e = make_enum_in_schema("public", "order_status", vec!["pending", "shipped", "delivered"]);
381+
let code = gen(&e, DatabaseKind::Postgres);
382+
383+
assert!(code.contains("Enum: public.order_status"));
384+
assert!(code.contains("pub enum OrderStatus"));
385+
assert!(code.contains("sqlx(type_name = \"order_status\")"));
386+
assert!(!code.contains("sqlx(type_name = \"public.order_status\")"));
387+
assert!(code.contains("sqlx_gen(kind = \"enum\", schema = \"public\", name = \"order_status\")"));
388+
assert!(code.contains("Pending"));
389+
assert!(code.contains("Shipped"));
390+
assert!(code.contains("Delivered"));
391+
}
392+
393+
#[test]
394+
fn test_named_schema_full_output() {
395+
let e = make_enum_in_schema("analysis", "toolcall_status", vec!["PENDING", "RUNNING", "DONE"]);
396+
let code = gen(&e, DatabaseKind::Postgres);
397+
398+
assert!(code.contains("Enum: analysis.toolcall_status"));
399+
assert!(code.contains("pub enum ToolcallStatus"));
400+
assert!(code.contains("sqlx(type_name = \"analysis.toolcall_status\")"));
401+
assert!(!code.contains("sqlx(type_name = \"toolcall_status\")"));
402+
assert!(code.contains("sqlx_gen(kind = \"enum\", schema = \"analysis\", name = \"toolcall_status\")"));
403+
assert!(code.contains("Pending"));
404+
assert!(code.contains("Running"));
405+
assert!(code.contains("Done"));
406+
}
407+
408+
#[test]
409+
fn test_named_schema_with_default_variant() {
410+
let e = EnumInfo {
411+
schema_name: "billing".to_string(),
412+
name: "payment_status".to_string(),
413+
variants: vec!["pending".to_string(), "paid".to_string(), "refunded".to_string()],
414+
default_variant: Some("pending".to_string()),
415+
};
416+
let code = gen(&e, DatabaseKind::Postgres);
417+
418+
assert!(code.contains("sqlx(type_name = \"billing.payment_status\")"));
419+
assert!(code.contains("impl Default for PaymentStatus"));
420+
assert!(code.contains("Self::Pending"));
421+
}
422+
423+
#[test]
424+
fn test_named_schema_variant_rename() {
425+
let e = make_enum_in_schema("audit", "log_level", vec!["info", "warn_high", "CRITICAL"]);
426+
let code = gen(&e, DatabaseKind::Postgres);
427+
428+
assert!(code.contains("sqlx(type_name = \"audit.log_level\")"));
429+
assert!(code.contains("sqlx(rename = \"info\")"));
430+
assert!(code.contains("sqlx(rename = \"warn_high\")"));
431+
assert!(code.contains("WarnHigh"));
432+
assert!(code.contains("sqlx(rename = \"CRITICAL\")"));
433+
assert!(code.contains("Critical"));
434+
}
435+
436+
#[test]
437+
fn test_named_schema_mysql_no_type_name() {
438+
let e = make_enum_in_schema("analytics", "event_type", vec!["click", "view"]);
439+
let code = gen(&e, DatabaseKind::Mysql);
440+
441+
assert!(!code.contains("type_name"));
442+
}
443+
444+
#[test]
445+
fn test_named_schema_sqlite_no_type_name() {
446+
let e = make_enum_in_schema("analytics", "event_type", vec!["click", "view"]);
447+
let code = gen(&e, DatabaseKind::Sqlite);
448+
449+
assert!(!code.contains("type_name"));
450+
}
362451
}

crates/sqlx_gen_macros/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlx-gen-macros"
3-
version = "0.5.3"
3+
version = "0.5.4"
44
edition = "2021"
55
description = "No-op attribute macros for sqlx-gen generated code"
66
license = "MIT"

0 commit comments

Comments
 (0)