feat: one-to-many relation helper

Allow one to specify that a field of a model is a foreign key.
It will generate a bunch of helper methods to query related entities
from one entity.
This commit is contained in:
Matthieu Bessat 2025-11-11 17:10:47 +01:00
parent cbe60d1bd2
commit 5e0ffe67c3
25 changed files with 764 additions and 140 deletions

View file

@ -3,13 +3,15 @@ use attribute_derive::FromAttr;
use argh::FromArgs;
use anyhow::{Result, anyhow};
use gen_migrations::generate_create_table_sql;
use gen_repositories::{generate_repositories_source_files, SourceNodeContainer};
use crate::generators::{SourceNode, SourceNodeContainer};
// use gen_migrations::generate_create_table_sql;
// use gen_repositories::{generate_repositories_source_files, SourceNodeContainer};
pub mod models;
pub mod parse_models;
pub mod gen_migrations;
pub mod gen_repositories;
pub mod generators;
#[derive(FromAttr, PartialEq, Debug, Default)]
#[attribute(ident = sql_generator_model)]
@ -21,7 +23,8 @@ pub struct SqlGeneratorModelAttr {
#[attribute(ident = sql_generator_field)]
pub struct SqlGeneratorFieldAttr {
is_primary: Option<bool>,
is_unique: Option<bool>
is_unique: Option<bool>,
reverse_relation_name: Option<String>
}
@ -68,11 +71,11 @@ struct GeneratorArgs {
fn write_source_code(base_path: &Path, snc: SourceNodeContainer) -> Result<()> {
let path = base_path.join(snc.name);
match snc.inner {
gen_repositories::SourceNode::File(code) => {
SourceNode::File(code) => {
println!("writing file {:?}", path);
std::fs::write(path, code)?;
},
gen_repositories::SourceNode::Directory(dir) => {
SourceNode::Directory(dir) => {
for node in dir {
write_source_code(&path, node)?;
}
@ -126,13 +129,13 @@ pub fn main() -> Result<()> {
if !repositories_mod_path.exists() {
return Err(anyhow!("Could not resolve repositories modules."));
}
let snc = generate_repositories_source_files(&models)?;
let snc = generators::repositories::generate_repositories_source_files(&models)?;
dbg!(&snc);
write_source_code(&repositories_mod_path, snc)?;
},
GeneratorArgsSubCommands::GenerateMigration(opts) => {
eprintln!("Generating migrations…");
let sql_code = generate_create_table_sql(&models)?;
let sql_code = generators::migrations::generate_create_table_sql(&models)?;
if let Some(out_location) = opts.output {
let output_path = Path::new(&out_location);
let write_res = std::fs::write(output_path, sql_code);