Skip to main content

sqlcx_core/generator/go/
mod.rs

1pub mod common;
2pub mod database_sql;
3pub mod pgx;
4pub mod structs;
5
6use crate::config::TargetConfig;
7use crate::error::{Result, SqlcxError};
8use crate::generator::{DriverGenerator, GeneratedFile, LanguagePlugin, SchemaGenerator};
9use crate::ir::SqlcxIR;
10
11pub struct GoPlugin {
12    pub schema_name: String,
13    pub driver_name: String,
14}
15
16impl GoPlugin {
17    pub fn new(schema: &str, driver: &str) -> Result<Self> {
18        resolve_schema(schema)?;
19        resolve_driver(driver)?;
20        Ok(Self {
21            schema_name: schema.to_string(),
22            driver_name: driver.to_string(),
23        })
24    }
25}
26
27fn resolve_schema(name: &str) -> Result<Box<dyn SchemaGenerator>> {
28    match name {
29        "structs" => Ok(Box::new(structs::GoStructGenerator)),
30        _ => Err(SqlcxError::UnknownSchema(name.to_string())),
31    }
32}
33
34fn resolve_driver(name: &str) -> Result<Box<dyn DriverGenerator>> {
35    match name {
36        "database-sql" | "database-sql-postgres" => {
37            Ok(Box::new(database_sql::DatabaseSqlGenerator::postgres()))
38        }
39        "database-sql-mysql" => Ok(Box::new(database_sql::DatabaseSqlGenerator::mysql())),
40        "database-sql-sqlite" => Ok(Box::new(database_sql::DatabaseSqlGenerator::sqlite())),
41        "pgx" => Ok(Box::new(pgx::PgxGenerator)),
42        _ => Err(SqlcxError::UnknownDriver(name.to_string())),
43    }
44}
45
46impl LanguagePlugin for GoPlugin {
47    fn generate(&self, ir: &SqlcxIR, config: &TargetConfig) -> Result<Vec<GeneratedFile>> {
48        let schema_gen = resolve_schema(&self.schema_name)?;
49        let driver_gen = resolve_driver(&self.driver_name)?;
50        let overrides = &config.overrides;
51
52        let mut files = Vec::new();
53        files.push(schema_gen.generate(ir, overrides)?);
54        files.extend(driver_gen.generate(ir)?);
55        Ok(files)
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use crate::generator::LanguagePlugin;
63    use crate::parser::DatabaseParser;
64    use crate::parser::postgres::PostgresParser;
65    use std::collections::HashMap;
66
67    fn parse_fixture_ir() -> SqlcxIR {
68        let schema_sql = include_str!("../../../../../tests/fixtures/schema.sql");
69        let queries_sql = include_str!("../../../../../tests/fixtures/queries/users.sql");
70        let parser = PostgresParser::new();
71        let (tables, enums) = parser.parse_schema(schema_sql).unwrap();
72        let queries = parser
73            .parse_queries(queries_sql, &tables, &enums, "queries/users.sql")
74            .unwrap();
75        SqlcxIR {
76            tables,
77            queries,
78            enums,
79        }
80    }
81
82    #[test]
83    fn generates_three_files() {
84        let ir = parse_fixture_ir();
85        let plugin = GoPlugin::new("structs", "database-sql").unwrap();
86        let config = TargetConfig {
87            language: "go".to_string(),
88            out: "./db".to_string(),
89            schema: "structs".to_string(),
90            driver: "database-sql".to_string(),
91            overrides: HashMap::new(),
92        };
93        let files = plugin.generate(&ir, &config).unwrap();
94        assert_eq!(files.len(), 3);
95        assert!(files.iter().any(|f| f.path == "models.go"));
96        assert!(files.iter().any(|f| f.path == "client.go"));
97        assert!(files.iter().any(|f| f.path == "users.queries.go"));
98    }
99}