njord-rs / njord

A versatile, feature-rich Rust ORM ⛵
https://njord.rs
BSD 3-Clause "New" or "Revised" License
409 stars 21 forks source link

Macro with external sql file #179

Open chaseWillden opened 4 weeks ago

chaseWillden commented 4 weeks ago

Alright, I want to propose a new, drastic feature. Just wanted to throw the idea out there. I've seen other ORMs in Rust, but nothing like this idea. There is a Rust lib out there called Pest (https://pest.rs/), the concept is super interesting.

The concept is you have a grammar file the defines what you're parsing and map it to a struct at compile time. The grammar file essentially is compiled with the code:

// https://github.com/pest-parser/pest/blob/master/grammars/src/grammars/sql.pest
pub mod sql {
    #[derive(Parser)]
    #[grammar = "grammars/sql.pest"]
    pub struct SqlParser;
}

They then implemented a macro which pulls that file in at compile time, parses it, and in this case tokenizes it.

What if we take a similar approach:

pub mod near_earth_objects {
    #[derive(Njord)]
    #[sql = "sql/neo.sql"]
    pub struct NeoParser;
}

Then we could have as complex of a query as we want abstracted into it's own isolated sql directory/file and usage of that query could be like this:

fn main() {
    let url = "mysql://njord_user:njord_password@localhost:3306/njord_db";
    let mut conn = mysql::open(url).unwrap();

    let mut params = HashMap::new();
    params.insert(
        "name_limited".to_string(),
        "Eros".to_string()
    );

    let query_results = near_earth_objects::NeoParser::params(params).exec(&mut conn);

    // If you want them converted to actual defined structs
    let results: Vec<NearEarthObjects> = query_results.convert()
}

Thoughts?