1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use crate::common::lazy::DB_SCHEMA;
use crate::ts_generator::errors::TsGeneratorError;
use crate::ts_generator::types::ts_query::TsQuery;
use crate::ts_generator::types::{db_conn::DBConn, ts_query::TsFieldType};
use sqlparser::ast::{Join, Query, SetExpr, TableFactor, TableWithJoins};

pub fn get_all_table_names_from_expr(query: &Query) -> Result<Vec<String>, TsGeneratorError> {
    let table_with_joins: TableWithJoins = match &query.body {
        SetExpr::Select(select) => Ok(select
            .from
            .get(0)
            .ok_or(TsGeneratorError::WildcardStatementWithoutTargetTables)?
            .to_owned()),
        _ => Err(TsGeneratorError::WildcardStatementDeadendExpression),
    }?;

    let primary_table_name = match table_with_joins.relation {
        TableFactor::Table { name, .. } => Ok(name.to_string()),
        _ => Err(TsGeneratorError::WildcardStatementUnsupportedTableExpr),
    }?;

    let mut join_tables = table_with_joins
        .joins
        .into_iter()
        .filter_map(|join| match join {
            Join { relation, .. } => match relation {
                TableFactor::Table { name, .. } => Some(name.to_string()),
                _ => unimplemented!(),
            },
        })
        .collect::<Vec<String>>();

    let tables = &mut vec![primary_table_name];
    tables.append(&mut join_tables);

    Ok(tables.clone())
}

/// Translates a wildcard expression of a SQL statement
/// @example
/// SELECT * FROM items
///
/// and it appends result into the hashmap for type generation
pub fn translate_wildcard_expr(
    query: &Query,
    ts_query: &mut TsQuery,
    db_conn: &DBConn,
) -> Result<(), TsGeneratorError> {
    let table_with_joins = get_all_table_names_from_expr(query)?;
    let table_with_joins = table_with_joins.iter().map(|s| s.as_ref()).collect();
    let all_fields = DB_SCHEMA.fetch_table(&table_with_joins, db_conn);
    if let Some(all_fields) = all_fields {
        for key in all_fields.keys() {
            let field = all_fields.get(key).unwrap();
            let mut field_types = vec![field.field_type.clone()];
            if field.is_nullable {
                field_types.push(TsFieldType::Null);
            }

            ts_query.result.insert(key.to_owned(), field_types);
        }
    }
    Ok(())
}