weldscli_lib/
lib.rs

1pub mod commands;
2pub mod config;
3pub mod errors;
4pub mod generators;
5
6use anyhow::Result;
7use anyhow::anyhow;
8use config::DbProvider;
9use std::path::PathBuf;
10use welds::model_traits::TableIdent;
11use welds::prelude::*;
12
13pub async fn update(schema_path: PathBuf, identifier: Option<String>) -> Result<()> {
14    use welds::detect::find_all_tables;
15    let identifier = identifier.as_ref().map(|x| TableIdent::parse(x));
16
17    let client = welds::connections::connect_from_env().await?;
18    let mut tables = find_all_tables(client.as_ref()).await?;
19    let provider: DbProvider = client.syntax().into();
20
21    let mut conf_def = config::read(&schema_path).unwrap_or_default();
22
23    match identifier {
24        Some(identifier) => {
25            // update only the specified table
26            tables.retain(|t| t.ident() == &identifier);
27            if tables.is_empty() {
28                log::error!(
29                    "Table not found: no table updated  (HINT: make sure you include the schema)"
30                );
31            }
32            conf_def.add_update(provider, &tables);
33        }
34        None => {
35            conf_def.remove_missing(&tables);
36            conf_def.add_update(provider, &tables);
37        }
38    };
39
40    config::write(&schema_path, &conf_def)?;
41    Ok(())
42}
43
44#[derive(Debug, Default)]
45pub struct GenerateOption {
46    pub schema_path: PathBuf,
47    pub output_path: PathBuf,
48    pub hide_unknown_types: bool,
49    pub table: Option<String>,
50}
51
52pub fn generate(mut opt: GenerateOption) -> Result<()> {
53    use crate::errors::WeldsError;
54    if !opt.schema_path.exists() {
55        return Err(anyhow!(WeldsError::MissingSchemaFile(opt.schema_path)));
56    }
57
58    let conf_def = config::read(&opt.schema_path)?;
59
60    clean_code_output_path(&mut opt);
61    generators::models::run(&conf_def, &opt)?;
62
63    Ok(())
64}
65
66/// If the path is the root of a project, add on ./src/models
67/// If the use is giving a path directly allow it to fly
68fn clean_code_output_path(opt: &mut GenerateOption) {
69    if is_project_path(&opt.output_path) {
70        let mut new_path = PathBuf::from(&opt.output_path);
71        new_path.push("src");
72        new_path.push("models");
73        opt.output_path = new_path;
74    }
75}
76
77fn is_project_path(path: &PathBuf) -> bool {
78    if !path.exists() || !path.is_dir() {
79        return false;
80    }
81    let mut src = PathBuf::from(path);
82    src.push("src");
83    if !src.exists() || !src.is_dir() {
84        return false;
85    }
86    let mut cargo_toml = PathBuf::from(path);
87    cargo_toml.push("Cargo.toml");
88    if !cargo_toml.exists() || !cargo_toml.is_file() {
89        return false;
90    }
91    true
92}
93
94/// tests the underlying database connection set with DATABASE_URL
95pub async fn test_connection() -> Result<()> {
96    let result = welds::connections::connect_from_env().await;
97    match result {
98        Ok(_) => {
99            println!("Database connected successfully");
100            std::process::exit(0);
101        }
102        Err(err) => {
103            eprintln!("Not able to connect to database");
104            log::debug!("{:?}", err);
105            std::process::exit(1);
106        }
107    }
108}